Skip to content

Commit 097be77

Browse files
feat: added tests
1 parent 0284b2c commit 097be77

File tree

5 files changed

+518
-0
lines changed

5 files changed

+518
-0
lines changed

src/lib/commands.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,12 @@ import run from "./run";
3232
import saveState from "./saveState";
3333
import appSettings from "./settings";
3434
import showFileInfo from "./showFileInfo";
35+
import { runAllTests } from "test/tester";
3536

3637
export default {
38+
async "run-tests"() {
39+
runAllTests();
40+
},
3741
async "close-all-tabs"() {
3842
let save = false;
3943
const unsavedFiles = editorManager.files.filter(

src/lib/keyBindings.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import { description } from "components/quickTools/items";
2+
import actions, { key } from "handlers/quickTools";
3+
14
export default {
25
focusEditor: {
36
description: "Focus editor",
@@ -697,4 +700,10 @@ export default {
697700
readOnly: true,
698701
action: "new-terminal",
699702
},
703+
runTests: {
704+
description: "Run Tests",
705+
key: "Ctrl-T",
706+
readOnly: true,
707+
actions: "run-tests"
708+
}
700709
};

src/test/editor.tests.js

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
import { TestRunner } from '../tester.js';
2+
3+
export async function runAceEditorTests(writeOutput) {
4+
const runner = new TestRunner('Ace Editor API Tests');
5+
6+
let editor;
7+
let container;
8+
9+
// Helper to create editor safely
10+
function createEditor() {
11+
container = document.createElement('div');
12+
container.style.width = '500px';
13+
container.style.height = '300px';
14+
container.style.backgroundColor = '#a02f2fff';
15+
document.body.appendChild(container);
16+
return ace.edit(container);
17+
}
18+
19+
// Test 1: Ace is available
20+
runner.test('Ace is loaded', async (test) => {
21+
test.assert(typeof ace !== 'undefined', 'Ace should be available globally');
22+
test.assert(typeof ace.edit === 'function', 'ace.edit should be a function');
23+
});
24+
25+
// Test 2: Editor creation
26+
runner.test('Editor creation', async (test) => {
27+
editor = createEditor();
28+
test.assert(editor != null, 'Editor instance should be created');
29+
test.assert(typeof editor.getSession === 'function', 'Editor should expose getSession');
30+
});
31+
32+
// Test 3: Session access
33+
runner.test('Session access', async (test) => {
34+
const session = editor.getSession();
35+
test.assert(session != null, 'Editor session should exist');
36+
test.assert(typeof session.getValue === 'function', 'Session should expose getValue');
37+
});
38+
39+
// Test 4: Set and get value
40+
runner.test('Set and get value', async (test) => {
41+
const text = 'Hello Ace Editor';
42+
editor.setValue(text, -1);
43+
const value = editor.getValue();
44+
test.assertEqual(value, text, 'Editor value should match the set value');
45+
});
46+
47+
// Test 5: Cursor movement
48+
runner.test('Cursor movement', async (test) => {
49+
editor.setValue('line1\nline2\nline3', -1);
50+
editor.moveCursorTo(1, 2);
51+
52+
const pos = editor.getCursorPosition();
53+
test.assertEqual(pos.row, 1, 'Cursor row should be correct');
54+
test.assertEqual(pos.column, 2, 'Cursor column should be correct');
55+
});
56+
57+
// Test 6: Selection API
58+
runner.test('Selection handling', async (test) => {
59+
editor.setValue('abc\ndef', -1);
60+
editor.selectAll();
61+
62+
const selected = editor.getSelectedText();
63+
test.assert(selected.length > 0, 'Selected text should not be empty');
64+
});
65+
66+
// Test 7: Undo manager
67+
runner.test('Undo manager works', async (test) => {
68+
const session = editor.getSession();
69+
const undoManager = session.getUndoManager();
70+
71+
session.setValue('one');
72+
undoManager.reset();
73+
74+
editor.insert('\ntwo');
75+
editor.undo();
76+
77+
const value = editor.getValue();
78+
test.assertEqual(value, 'one', 'Undo should revert last change');
79+
});
80+
81+
82+
// Test 8: Mode setting
83+
runner.test('Mode setting', async (test) => {
84+
const session = editor.getSession();
85+
session.setMode('ace/mode/javascript');
86+
87+
const mode = session.getMode();
88+
test.assert(
89+
mode && mode.$id === 'ace/mode/javascript',
90+
'Editor mode should be JavaScript'
91+
);
92+
});
93+
94+
// Test 9: Theme setting
95+
runner.test('Theme setting', async (test) => {
96+
editor.setTheme('ace/theme/monokai');
97+
const theme = editor.getTheme();
98+
test.assert(
99+
theme && theme.includes('monokai'),
100+
'Editor theme should be monokai'
101+
);
102+
});
103+
104+
105+
// Test 11: Line count
106+
runner.test('Line count', async (test) => {
107+
editor.setValue('a\nb\nc\nd', -1);
108+
const lines = editor.session.getLength();
109+
test.assertEqual(lines, 4, 'Editor should report correct number of lines');
110+
});
111+
112+
// Test 12: Replace text
113+
runner.test('Replace text', async (test) => {
114+
editor.setValue('hello world', -1);
115+
editor.find('world');
116+
editor.replace('ace');
117+
118+
const value = editor.getValue();
119+
test.assertEqual(value, 'hello ace', 'Replace should work correctly');
120+
});
121+
122+
// Test 13: Search API
123+
runner.test('Search API', async (test) => {
124+
editor.setValue('foo bar foo', -1);
125+
editor.find('foo');
126+
127+
const range = editor.getSelectionRange();
128+
test.assert(
129+
range.start.column === 0,
130+
'Search should select first match'
131+
);
132+
});
133+
134+
// Test 14: Renderer availability
135+
runner.test('Renderer exists', async (test) => {
136+
const renderer = editor.renderer;
137+
test.assert(renderer != null, 'Editor renderer should exist');
138+
test.assert(
139+
typeof renderer.updateFull === 'function',
140+
'Renderer should expose updateFull'
141+
);
142+
});
143+
144+
// Test 15: Editor options
145+
runner.test('Editor options', async (test) => {
146+
editor.setOption('showPrintMargin', false);
147+
const value = editor.getOption('showPrintMargin');
148+
test.assertEqual(value, false, 'Editor option should be applied');
149+
});
150+
151+
// Test 16: Scroll API
152+
runner.test('Scroll API', async (test) => {
153+
editor.setValue(Array(100).fill('line').join('\n'), -1);
154+
editor.scrollToLine(50, true, true, () => { });
155+
156+
const firstVisibleRow = editor.renderer.getFirstVisibleRow();
157+
test.assert(
158+
firstVisibleRow >= 0,
159+
'Editor should support scrolling'
160+
);
161+
});
162+
163+
// Test 17: Redo manager
164+
runner.test('Redo manager works', (test) => {
165+
const session = editor.getSession();
166+
const undoManager = session.getUndoManager();
167+
168+
session.setValue('one');
169+
undoManager.reset();
170+
171+
session.insert({ row: 0, column: 3 }, '\ntwo');
172+
173+
editor.undo();
174+
editor.redo();
175+
176+
const value = editor.getValue();
177+
test.assertEqual(value, 'one\ntwo', 'Redo should restore undone change');
178+
});
179+
180+
181+
// Test 18: Focus and blur
182+
runner.test('Focus and blur', async (test) => {
183+
editor.focus();
184+
test.assert(editor.isFocused(), 'Editor should be focused');
185+
186+
editor.blur();
187+
test.assert(!editor.isFocused(), 'Editor should be blurred');
188+
});
189+
190+
191+
// Cleanup
192+
runner.test('Cleanup editor', async (test) => {
193+
editor.destroy();
194+
container.remove();
195+
test.assert(true, 'Editor destroyed and DOM cleaned');
196+
});
197+
198+
// Run all tests
199+
return await runner.run(writeOutput);
200+
}

src/test/sanity.tests.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { TestRunner } from '../tester.js';
2+
3+
4+
5+
export async function runSanityTests(writeOutput) {
6+
const runner = new TestRunner('JS (WebView) Sanity Tests');
7+
8+
// Test 1: String operations
9+
runner.test('String concatenation', (test) => {
10+
const result = 'Hello' + ' ' + 'World';
11+
test.assertEqual(result, 'Hello World', 'String concatenation should work');
12+
});
13+
14+
// Test 2: Number operations
15+
runner.test('Basic arithmetic', (test) => {
16+
const sum = 5 + 3;
17+
test.assertEqual(sum, 8, 'Addition should work correctly');
18+
});
19+
20+
// Test 3: Array operations
21+
runner.test('Array operations', (test) => {
22+
23+
const arr = [1, 2, 3];
24+
test.assertEqual(arr.length, 3, 'Array length should be correct');
25+
test.assert(arr.includes(2), 'Array should include 2');
26+
});
27+
28+
// Test 4: Object operations
29+
runner.test('Object operations', (test) => {
30+
const obj = { name: 'Test', value: 42 };
31+
test.assertEqual(obj.name, 'Test', 'Object property should be accessible');
32+
test.assertEqual(obj.value, 42, 'Object value should be correct');
33+
});
34+
35+
// Test 5: Function execution
36+
runner.test('Function execution', (test) => {
37+
const add = (a, b) => a + b;
38+
const result = add(10, 20);
39+
test.assertEqual(result, 30, 'Function should return correct value');
40+
});
41+
42+
// Test 6: Async function
43+
runner.test('Async function handling', async (test) => {
44+
const asyncFunc = async () => {
45+
return new Promise((resolve) => {
46+
setTimeout(() => resolve('done'), 10);
47+
});
48+
};
49+
50+
const result = await asyncFunc();
51+
test.assertEqual(result, 'done', 'Async function should work correctly');
52+
});
53+
54+
55+
// Test 7: Error handling
56+
runner.test('Error handling', (test) => {
57+
try {
58+
throw new Error('Test error');
59+
} catch (e) {
60+
test.assert(e instanceof Error, 'Should catch Error instances');
61+
}
62+
});
63+
64+
// Test 8: Conditional logic
65+
runner.test('Conditional logic', (test) => {
66+
const value = 10;
67+
test.assert(value > 5, 'Condition should be true');
68+
test.assert(!(value < 5), 'Negation should work');
69+
});
70+
71+
// Run all tests
72+
return await runner.run(writeOutput);
73+
}

0 commit comments

Comments
 (0)