Skip to content

Commit 73f7d01

Browse files
Add runtime tests
1 parent 6a3b5bb commit 73f7d01

2 files changed

Lines changed: 476 additions & 0 deletions

File tree

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
import { describe, it, expect } from 'vitest';
2+
import { validateCode } from '~/lib/runtime/code-validator';
3+
4+
describe('code-validator', () => {
5+
describe('validateCode - General', () => {
6+
it('should detect placeholder comments', () => {
7+
const code = `
8+
function test() {
9+
// rest of code here
10+
return true;
11+
}
12+
`;
13+
const result = validateCode('test.js', code);
14+
expect(result.isValid).toBe(false);
15+
expect(result.errors).toContain('Code contains placeholder comment "// rest of code here"');
16+
});
17+
18+
it('should detect ellipsis placeholders', () => {
19+
const code = `
20+
function test() {
21+
const x = 1;
22+
/* ... */
23+
return x;
24+
}
25+
`;
26+
const result = validateCode('test.js', code);
27+
expect(result.isValid).toBe(false);
28+
expect(result.errors).toContain('Code contains ellipsis placeholders');
29+
});
30+
31+
it('should warn about markdown code blocks', () => {
32+
const code = '```javascript\nconst x = 1;\n```';
33+
const result = validateCode('test.js', code);
34+
expect(result.warnings).toContain('File contains markdown code block syntax (```)');
35+
});
36+
37+
it('should pass valid code without placeholders', () => {
38+
const code = `
39+
function add(a, b) {
40+
return a + b;
41+
}
42+
`;
43+
const result = validateCode('test.js', code);
44+
expect(result.isValid).toBe(true);
45+
expect(result.errors).toHaveLength(0);
46+
});
47+
});
48+
49+
describe('validateCode - JavaScript/TypeScript', () => {
50+
it('should detect mismatched braces', () => {
51+
const code = `
52+
function test() {
53+
if (true) {
54+
console.log('test');
55+
// missing closing brace
56+
}
57+
`;
58+
const result = validateCode('test.js', code);
59+
expect(result.isValid).toBe(false);
60+
expect(result.errors.some((e) => e.includes('Mismatched braces'))).toBe(true);
61+
});
62+
63+
it('should detect mismatched parentheses', () => {
64+
const code = 'function test(a, b {\n return a + b;\n}';
65+
const result = validateCode('test.js', code);
66+
expect(result.isValid).toBe(false);
67+
expect(result.errors.some((e) => e.includes('parentheses'))).toBe(true);
68+
});
69+
70+
it('should detect mismatched brackets', () => {
71+
const code = 'const arr = [1, 2, 3;';
72+
const result = validateCode('test.js', code);
73+
expect(result.isValid).toBe(false);
74+
expect(result.errors.some((e) => e.includes('brackets'))).toBe(true);
75+
});
76+
77+
it('should pass valid JavaScript', () => {
78+
const code = `
79+
function fibonacci(n) {
80+
if (n <= 1) return n;
81+
return fibonacci(n - 1) + fibonacci(n - 2);
82+
}
83+
84+
const result = fibonacci(10);
85+
console.log(result);
86+
`;
87+
const result = validateCode('fib.js', code);
88+
expect(result.isValid).toBe(true);
89+
});
90+
91+
it('should pass valid TypeScript', () => {
92+
const code = `
93+
interface User {
94+
name: string;
95+
age: number;
96+
}
97+
98+
function greet(user: User): string {
99+
return \`Hello, \${user.name}!\`;
100+
}
101+
`;
102+
const result = validateCode('greet.ts', code);
103+
expect(result.isValid).toBe(true);
104+
});
105+
106+
it('should detect mixed Python/JS syntax', () => {
107+
const code = 'import from http';
108+
const result = validateCode('test.js', code);
109+
expect(result.isValid).toBe(false);
110+
expect(result.errors.some((e) => e.includes('mixing JavaScript and Python'))).toBe(true);
111+
});
112+
113+
it('should ignore comments when counting braces', () => {
114+
const code = `
115+
function test() {
116+
// This is a comment with {braces}
117+
/* Another comment { with } braces */
118+
return true;
119+
}
120+
`;
121+
const result = validateCode('test.js', code);
122+
expect(result.isValid).toBe(true);
123+
});
124+
});
125+
126+
describe('validateCode - Python', () => {
127+
it('should warn about tabs instead of spaces', () => {
128+
const code = 'def test():\n\treturn True';
129+
const result = validateCode('test.py', code);
130+
expect(result.warnings.some((w) => w.includes('tabs instead of spaces'))).toBe(true);
131+
});
132+
133+
it('should detect JavaScript keywords in Python', () => {
134+
const code = `
135+
const x = 5
136+
let y = 10
137+
var z = 15
138+
`;
139+
const result = validateCode('test.py', code);
140+
expect(result.isValid).toBe(false);
141+
expect(result.errors.some((e) => e.includes('JavaScript variable declarations'))).toBe(true);
142+
});
143+
144+
it('should warn about function keyword', () => {
145+
const code = 'function greet(name):\n return f"Hello {name}"';
146+
const result = validateCode('test.py', code);
147+
expect(result.warnings.some((w) => w.includes('function'))).toBe(true);
148+
});
149+
150+
it('should pass valid Python code', () => {
151+
const code = `
152+
def factorial(n):
153+
if n <= 1:
154+
return 1
155+
return n * factorial(n - 1)
156+
157+
result = factorial(5)
158+
print(result)
159+
`;
160+
const result = validateCode('factorial.py', code);
161+
expect(result.isValid).toBe(true);
162+
});
163+
164+
it('should handle Python classes', () => {
165+
const code = `
166+
class User:
167+
def __init__(self, name, age):
168+
self.name = name
169+
self.age = age
170+
171+
def greet(self):
172+
return f"Hello, {self.name}!"
173+
`;
174+
const result = validateCode('user.py', code);
175+
expect(result.isValid).toBe(true);
176+
});
177+
});
178+
179+
describe('validateCode - JSON', () => {
180+
it('should detect invalid JSON', () => {
181+
const code = '{ "name": "test", invalid }';
182+
const result = validateCode('config.json', code);
183+
expect(result.isValid).toBe(false);
184+
expect(result.errors.some((e) => e.includes('Invalid JSON'))).toBe(true);
185+
});
186+
187+
it('should pass valid JSON', () => {
188+
const code = `{
189+
"name": "test-project",
190+
"version": "1.0.0",
191+
"dependencies": {
192+
"react": "^18.0.0"
193+
}
194+
}`;
195+
const result = validateCode('package.json', code);
196+
expect(result.isValid).toBe(true);
197+
});
198+
199+
it('should detect trailing commas', () => {
200+
const code = '{ "name": "test", }';
201+
const result = validateCode('config.json', code);
202+
expect(result.isValid).toBe(false);
203+
});
204+
});
205+
206+
describe('validateCode - Complex scenarios', () => {
207+
it('should handle nested structures', () => {
208+
const code = `
209+
const obj = {
210+
nested: {
211+
deep: {
212+
value: [1, 2, [3, 4]]
213+
}
214+
}
215+
};
216+
`;
217+
const result = validateCode('nested.js', code);
218+
expect(result.isValid).toBe(true);
219+
});
220+
221+
it('should handle JSX syntax', () => {
222+
const code = `
223+
export function Button({ children, onClick }) {
224+
return (
225+
<button onClick={onClick}>
226+
{children}
227+
</button>
228+
);
229+
}
230+
`;
231+
const result = validateCode('Button.jsx', code);
232+
expect(result.isValid).toBe(true);
233+
});
234+
235+
it('should detect multiple errors', () => {
236+
const code = `
237+
function test( {
238+
const x = [1, 2, 3;
239+
// rest of code here
240+
}
241+
`;
242+
const result = validateCode('test.js', code);
243+
expect(result.isValid).toBe(false);
244+
expect(result.errors.length).toBeGreaterThan(1);
245+
});
246+
});
247+
});

0 commit comments

Comments
 (0)