Skip to content

Commit f5af603

Browse files
committed
#9: all clean
1 parent d216c62 commit f5af603

File tree

1 file changed

+124
-2
lines changed

1 file changed

+124
-2
lines changed

test/aibolit.test.ts

Lines changed: 124 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
// SPDX-FileCopyrightText: Copyright (c) 2025 Yegor Bugayenko
22
// SPDX-License-Identifier: MIT
33

4-
import { describe, expect, test } from '@jest/globals';
4+
import { describe, expect, test, jest, beforeEach } from '@jest/globals';
55
import { aibolit } from '../src/aibolit';
66
import { mkdtempSync, writeFileSync, rmSync } from 'fs';
77
import { join } from 'path';
88
import { tmpdir } from 'os';
99

10+
jest.mock('child_process', () => ({
11+
execSync: jest.fn()
12+
}));
13+
14+
import { execSync } from 'child_process';
15+
const mockExecSync = execSync as jest.MockedFunction<typeof execSync>;
16+
1017
describe('aibolit', () => {
18+
beforeEach(() => {
19+
jest.clearAllMocks();
20+
});
21+
1122
test('accepts perfect code', async () => {
1223
const tmp = mkdtempSync(join(tmpdir(), 'aibolit-test-'));
1324
const path = join(tmp, 'Test.java');
@@ -23,6 +34,8 @@ describe('aibolit', () => {
2334
}
2435
`
2536
);
37+
mockExecSync.mockReturnValueOnce(Buffer.from('aibolit 1.3.0\n'));
38+
mockExecSync.mockReturnValueOnce(Buffer.from(''));
2639
try {
2740
const issue = await aibolit(path);
2841
expect(issue).toContain('Your code is perfect');
@@ -46,6 +59,8 @@ describe('aibolit', () => {
4659
}
4760
`
4861
);
62+
mockExecSync.mockReturnValueOnce(Buffer.from('aibolit 1.3.0\n'));
63+
mockExecSync.mockReturnValueOnce(Buffer.from('Missing final keyword (P13: 5.0)\n'));
4964
try {
5065
const issue = await aibolit(path);
5166
expect(issue).not.toContain('Your code is perfect');
@@ -56,7 +71,114 @@ describe('aibolit', () => {
5671

5772
test('handles non-existent file', async () => {
5873
const path = '/path/to/nonexistent/file.java';
74+
mockExecSync.mockReturnValueOnce(Buffer.from('aibolit 1.3.0\n'));
5975
const result = await aibolit(path);
6076
expect(result).toBe(`File does not exist: ${path}`);
6177
});
62-
});
78+
79+
describe('check_version', () => {
80+
test('throws when aibolit outputs invalid format', async () => {
81+
mockExecSync.mockReturnValue(Buffer.from('invalid output'));
82+
const path = '/tmp/test.java';
83+
writeFileSync(path, 'public class Test {}');
84+
try {
85+
await aibolit(path);
86+
fail('Should have thrown');
87+
} catch (error) {
88+
expect(error).toBe('Probably Aibolit is not installed: "invalid output"');
89+
}
90+
});
91+
92+
test('throws when version pattern not found', async () => {
93+
mockExecSync.mockReturnValue(Buffer.from('aibolit no-version-here\n'));
94+
const path = '/tmp/test.java';
95+
writeFileSync(path, 'public class Test {}');
96+
try {
97+
await aibolit(path);
98+
fail('Should have thrown');
99+
} catch (error) {
100+
expect(error).toContain('Probably Aibolit is not installed');
101+
}
102+
});
103+
104+
test('throws when version is too old', async () => {
105+
mockExecSync.mockReturnValue(Buffer.from('aibolit 1.2.0\n'));
106+
const path = '/tmp/test.java';
107+
writeFileSync(path, 'public class Test {}');
108+
try {
109+
await aibolit(path);
110+
fail('Should have thrown');
111+
} catch (error) {
112+
expect(error).toContain('is not recent enough');
113+
expect(error).toContain('older than 1.3.0');
114+
}
115+
});
116+
117+
test('executes normally when version is exactly required', async () => {
118+
mockExecSync.mockReturnValueOnce(Buffer.from('aibolit 1.3.0\n'));
119+
mockExecSync.mockReturnValueOnce(Buffer.from(''));
120+
const path = '/tmp/test.java';
121+
writeFileSync(path, 'public class Test {}');
122+
const result = await aibolit(path);
123+
expect(result).toBe('Your code is perfect');
124+
});
125+
126+
test('executes normally when version is newer than required', async () => {
127+
mockExecSync.mockReturnValueOnce(Buffer.from('aibolit 1.4.0\n'));
128+
mockExecSync.mockReturnValueOnce(Buffer.from(''));
129+
const path = '/tmp/test.java';
130+
writeFileSync(path, 'public class Test {}');
131+
const result = await aibolit(path);
132+
expect(result).toBe('Your code is perfect');
133+
});
134+
135+
test('throws when execSync fails completely', async () => {
136+
mockExecSync.mockImplementation(() => {
137+
throw new Error('Command failed');
138+
});
139+
const path = '/tmp/test.java';
140+
writeFileSync(path, 'public class Test {}');
141+
try {
142+
await aibolit(path);
143+
fail('Should have thrown');
144+
} catch (error) {
145+
expect(error).toBeInstanceOf(Error);
146+
expect((error as Error).message).toBe('Command failed');
147+
}
148+
});
149+
150+
test('handles empty version output', async () => {
151+
mockExecSync.mockReturnValue(Buffer.from(''));
152+
const path = '/tmp/test.java';
153+
writeFileSync(path, 'public class Test {}');
154+
try {
155+
await aibolit(path);
156+
fail('Should have thrown');
157+
} catch (error) {
158+
expect(error).toContain('Probably Aibolit is not installed');
159+
}
160+
});
161+
162+
test('handles version with extra spaces', async () => {
163+
mockExecSync.mockReturnValue(Buffer.from('aibolit 1.3.0 \n'));
164+
const path = '/tmp/test.java';
165+
writeFileSync(path, 'public class Test {}');
166+
try {
167+
await aibolit(path);
168+
fail('Should have thrown');
169+
} catch (error) {
170+
expect(error).toContain('Probably Aibolit is not installed');
171+
}
172+
});
173+
174+
test('handles aibolit output with invalid warning format', async () => {
175+
mockExecSync.mockReturnValueOnce(Buffer.from('aibolit 1.3.0\n'));
176+
mockExecSync.mockReturnValueOnce(
177+
Buffer.from('Invalid warning format\nAnother invalid line\n'));
178+
const path = '/tmp/test.java';
179+
writeFileSync(path, 'public class Test {}');
180+
const result = await aibolit(path);
181+
expect(result).toBe('Your code is perfect');
182+
});
183+
});
184+
});

0 commit comments

Comments
 (0)