1
1
// SPDX-FileCopyrightText: Copyright (c) 2025 Yegor Bugayenko
2
2
// SPDX-License-Identifier: MIT
3
3
4
- import { describe , expect , test } from '@jest/globals' ;
4
+ import { describe , expect , test , jest , beforeEach } from '@jest/globals' ;
5
5
import { aibolit } from '../src/aibolit' ;
6
6
import { mkdtempSync , writeFileSync , rmSync } from 'fs' ;
7
7
import { join } from 'path' ;
8
8
import { tmpdir } from 'os' ;
9
9
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
+
10
17
describe ( 'aibolit' , ( ) => {
18
+ beforeEach ( ( ) => {
19
+ jest . clearAllMocks ( ) ;
20
+ } ) ;
21
+
11
22
test ( 'accepts perfect code' , async ( ) => {
12
23
const tmp = mkdtempSync ( join ( tmpdir ( ) , 'aibolit-test-' ) ) ;
13
24
const path = join ( tmp , 'Test.java' ) ;
@@ -23,6 +34,8 @@ describe('aibolit', () => {
23
34
}
24
35
`
25
36
) ;
37
+ mockExecSync . mockReturnValueOnce ( Buffer . from ( 'aibolit 1.3.0\n' ) ) ;
38
+ mockExecSync . mockReturnValueOnce ( Buffer . from ( '' ) ) ;
26
39
try {
27
40
const issue = await aibolit ( path ) ;
28
41
expect ( issue ) . toContain ( 'Your code is perfect' ) ;
@@ -46,6 +59,8 @@ describe('aibolit', () => {
46
59
}
47
60
`
48
61
) ;
62
+ mockExecSync . mockReturnValueOnce ( Buffer . from ( 'aibolit 1.3.0\n' ) ) ;
63
+ mockExecSync . mockReturnValueOnce ( Buffer . from ( 'Missing final keyword (P13: 5.0)\n' ) ) ;
49
64
try {
50
65
const issue = await aibolit ( path ) ;
51
66
expect ( issue ) . not . toContain ( 'Your code is perfect' ) ;
@@ -56,7 +71,114 @@ describe('aibolit', () => {
56
71
57
72
test ( 'handles non-existent file' , async ( ) => {
58
73
const path = '/path/to/nonexistent/file.java' ;
74
+ mockExecSync . mockReturnValueOnce ( Buffer . from ( 'aibolit 1.3.0\n' ) ) ;
59
75
const result = await aibolit ( path ) ;
60
76
expect ( result ) . toBe ( `File does not exist: ${ path } ` ) ;
61
77
} ) ;
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