Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/ace/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,14 @@ const commands = [
},
readOnly: true,
},
{
name: "run-tests",
description: "Run Tests",
exec() {
acode.exec("run-tests");
},
readOnly: true,
},
];

export function setCommands(editor) {
Expand Down
4 changes: 4 additions & 0 deletions src/lib/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import findFile from "palettes/findFile";
import browser from "plugins/browser";
import help from "settings/helpSettings";
import mainSettings from "settings/mainSettings";
import { runAllTests } from "test/tester";
import { getColorRange } from "utils/color/regex";
import helpers from "utils/helpers";
import Url from "utils/Url";
Expand All @@ -34,6 +35,9 @@ import appSettings from "./settings";
import showFileInfo from "./showFileInfo";

export default {
async "run-tests"() {
await runAllTests();
},
async "close-all-tabs"() {
let save = false;
const unsavedFiles = editorManager.files.filter(
Expand Down
6 changes: 6 additions & 0 deletions src/lib/keyBindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -697,4 +697,10 @@ export default {
readOnly: true,
action: "new-terminal",
},
"run-tests": {
description: "Run Tests",
key: "Ctrl-Shift-T",
readOnly: true,
action: "run-tests",
},
};
217 changes: 217 additions & 0 deletions src/test/editor.tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
import { TestRunner } from "./tester";

export async function runAceEditorTests(writeOutput) {
const runner = new TestRunner("Ace Editor API Tests");

function createEditor() {
const container = document.createElement("div");
container.style.width = "500px";
container.style.height = "300px";
container.style.backgroundColor = "#a02f2f";
document.body.appendChild(container);

const editor = ace.edit(container);
return { editor, container };
}

async function withEditor(test, fn) {
let editor, container;

try {
({ editor, container } = createEditor());
test.assert(editor != null, "Editor instance should be created");
await new Promise((resolve) => setTimeout(resolve, 100));
await fn(editor);
await new Promise((resolve) => setTimeout(resolve, 200));
} finally {
if (editor) editor.destroy();
if (container) container.remove();
}
}

// Test 1: Ace is available
runner.test("Ace is loaded", async (test) => {
test.assert(typeof ace !== "undefined", "Ace should be available globally");
test.assert(
typeof ace.edit === "function",
"ace.edit should be a function",
);
});

// Test 2: Editor creation
runner.test("Editor creation", async (test) => {
const { editor, container } = createEditor();
test.assert(editor != null, "Editor instance should be created");
test.assert(
typeof editor.getSession === "function",
"Editor should expose getSession",
);
editor.destroy();
container.remove();
Comment on lines +42 to +50
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test manually creates and destroys the editor instead of using the withEditor helper like all other tests. This creates inconsistency and doesn't include the wait delays that other tests have. Consider using withEditor for consistency.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/test/editor.tests.js
Line: 42:50

Comment:
this test manually creates and destroys the editor instead of using the `withEditor` helper like all other tests. This creates inconsistency and doesn't include the wait delays that other tests have. Consider using `withEditor` for consistency.

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

});

// Test 3: Session access
runner.test("Session access", async (test) => {
await withEditor(test, async (editor) => {
const session = editor.getSession();
test.assert(session != null, "Editor session should exist");
test.assert(
typeof session.getValue === "function",
"Session should expose getValue",
);
});
});

// Test 4: Set and get value
runner.test("Set and get value", async (test) => {
await withEditor(test, async (editor) => {
const text = "Hello Ace Editor";
editor.setValue(text, -1);
test.assertEqual(editor.getValue(), text);
});
});

// Test 5: Cursor movement
runner.test("Cursor movement", async (test) => {
await withEditor(test, async (editor) => {
editor.setValue("line1\nline2\nline3", -1);
editor.moveCursorTo(1, 2);

const pos = editor.getCursorPosition();
test.assertEqual(pos.row, 1);
test.assertEqual(pos.column, 2);
});
});

// Test 6: Selection API
runner.test("Selection handling", async (test) => {
await withEditor(test, async (editor) => {
editor.setValue("abc\ndef", -1);
editor.selectAll();
test.assert(editor.getSelectedText().length > 0);
});
});

// Test 7: Undo manager
runner.test("Undo manager works", async (test) => {
await withEditor(test, async (editor) => {
const session = editor.getSession();
const undoManager = session.getUndoManager();

session.setValue("one");
undoManager.reset();

editor.insert("\ntwo");
editor.undo();

test.assertEqual(editor.getValue(), "one");
});
});

// Test 8: Mode setting
runner.test("Mode setting", async (test) => {
await withEditor(test, async (editor) => {
const session = editor.getSession();
session.setMode("ace/mode/javascript");

const mode = session.getMode();
test.assert(mode && mode.$id === "ace/mode/javascript");
});
});

// Test 9: Theme setting
runner.test("Theme setting", async (test) => {
await withEditor(test, async (editor) => {
editor.setTheme("ace/theme/monokai");
test.assert(editor.getTheme().includes("monokai"));
});
});

// Test 11: Line count
runner.test("Line count", async (test) => {
await withEditor(test, async (editor) => {
editor.setValue("a\nb\nc\nd", -1);
test.assertEqual(editor.session.getLength(), 4);
});
});
Comment on lines +130 to +136
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test numbering jumps from Test 9 to Test 11, skipping Test 10. Either add the missing test or renumber this test to maintain sequential ordering.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/test/editor.tests.js
Line: 130:136

Comment:
test numbering jumps from Test 9 to Test 11, skipping Test 10. Either add the missing test or renumber this test to maintain sequential ordering.

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.


// Test 12: Replace text
runner.test("Replace text", async (test) => {
await withEditor(test, async (editor) => {
editor.setValue("hello world", -1);
editor.find("world");
editor.replace("ace");

test.assertEqual(editor.getValue(), "hello ace");
});
});

// Test 13: Search API
runner.test("Search API", async (test) => {
await withEditor(test, async (editor) => {
editor.setValue("foo bar foo", -1);
editor.find("foo");

const range = editor.getSelectionRange();
test.assert(range.start.column === 0);
});
});

// Test 14: Renderer availability
runner.test("Renderer exists", async (test) => {
await withEditor(test, async (editor) => {
const renderer = editor.renderer;
test.assert(renderer != null);
test.assert(typeof renderer.updateFull === "function");
});
});

// Test 15: Editor options
runner.test("Editor options", async (test) => {
await withEditor(test, async (editor) => {
editor.setOption("showPrintMargin", false);
test.assertEqual(editor.getOption("showPrintMargin"), false);
});
});

// Test 16: Scroll API
runner.test("Scroll API", async (test) => {
await withEditor(test, async (editor) => {
editor.setValue(Array(100).fill("line").join("\n"), -1);
editor.scrollToLine(50, true, true, () => {});

const firstVisibleRow = editor.renderer.getFirstVisibleRow();
test.assert(firstVisibleRow >= 0);
});
});

// Test 17: Redo manager
runner.test("Redo manager works", async (test) => {
await withEditor(test, async (editor) => {
const session = editor.getSession();
const undoManager = session.getUndoManager();

session.setValue("one");
undoManager.reset();

session.insert({ row: 0, column: 3 }, "\ntwo");
editor.undo();
editor.redo();

test.assertEqual(editor.getValue(), "one\ntwo");
});
});

// Test 18: Focus and blur
runner.test("Focus and blur", async (test) => {
await withEditor(test, async (editor) => {
editor.focus();
test.assert(editor.isFocused());

editor.blur();
test.assert(!editor.isFocused());
});
});

return await runner.run(writeOutput);
}
69 changes: 69 additions & 0 deletions src/test/sanity.tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { TestRunner } from "./tester";

export async function runSanityTests(writeOutput) {
const runner = new TestRunner("JS (WebView) Sanity Tests");

// Test 1: String operations
runner.test("String concatenation", (test) => {
const result = "Hello" + " " + "World";
test.assertEqual(result, "Hello World", "String concatenation should work");
});

// Test 2: Number operations
runner.test("Basic arithmetic", (test) => {
const sum = 5 + 3;
test.assertEqual(sum, 8, "Addition should work correctly");
});

// Test 3: Array operations
runner.test("Array operations", (test) => {
const arr = [1, 2, 3];
test.assertEqual(arr.length, 3, "Array length should be correct");
test.assert(arr.includes(2), "Array should include 2");
});

// Test 4: Object operations
runner.test("Object operations", (test) => {
const obj = { name: "Test", value: 42 };
test.assertEqual(obj.name, "Test", "Object property should be accessible");
test.assertEqual(obj.value, 42, "Object value should be correct");
});

// Test 5: Function execution
runner.test("Function execution", (test) => {
const add = (a, b) => a + b;
const result = add(10, 20);
test.assertEqual(result, 30, "Function should return correct value");
});

// Test 6: Async function
runner.test("Async function handling", async (test) => {
const asyncFunc = async () => {
return new Promise((resolve) => {
setTimeout(() => resolve("done"), 10);
});
};

const result = await asyncFunc();
test.assertEqual(result, "done", "Async function should work correctly");
});

// Test 7: Error handling
runner.test("Error handling", (test) => {
try {
throw new Error("Test error");
} catch (e) {
test.assert(e instanceof Error, "Should catch Error instances");
}
});

// Test 8: Conditional logic
runner.test("Conditional logic", (test) => {
const value = 10;
test.assert(value > 5, "Condition should be true");
test.assert(!(value < 5), "Negation should work");
});

// Run all tests
return await runner.run(writeOutput);
}
Loading