Skip to content

Commit f338af2

Browse files
committed
feat: Add tests for watch functionality in CLI to handle input file changes
1 parent b30fee9 commit f338af2

1 file changed

Lines changed: 112 additions & 1 deletion

File tree

test/cli.test.js

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { expect } from 'chai';
2-
import { exec } from 'child_process';
2+
import { exec, spawn } from 'child_process';
33
import path from 'path';
44
import { fileURLToPath } from 'url';
5+
import { writeFileSync, unlinkSync, existsSync, readFileSync } from 'fs';
56

67
const __filename = fileURLToPath(import.meta.url);
78
const __dirname = path.dirname(__filename);
@@ -23,4 +24,114 @@ describe('CLI', () => {
2324
done();
2425
});
2526
});
27+
28+
describe('watch functionality', () => {
29+
const testInputPath = path.join(__dirname, 'test-input.json');
30+
const testOutputPath = path.join(__dirname, 'test-output.js');
31+
const sampleSpec = {
32+
"openapi": "3.0.1",
33+
"info": { "title": "Watch Test API", "version": "1.0.0" },
34+
"paths": {
35+
"/test": {
36+
"get": {
37+
"operationId": "getTest",
38+
"responses": { "200": { "description": "OK" } }
39+
}
40+
}
41+
}
42+
};
43+
44+
beforeEach(() => {
45+
writeFileSync(testInputPath, JSON.stringify(sampleSpec, null, 2));
46+
});
47+
48+
afterEach(() => {
49+
[testInputPath, testOutputPath].forEach(file => {
50+
if (existsSync(file)) {
51+
unlinkSync(file);
52+
}
53+
});
54+
});
55+
56+
it('should regenerate client when input file changes', function(done) {
57+
this.timeout(5000);
58+
59+
const cliPath = path.join(__dirname, '../bin/cli.js');
60+
const child = spawn('node', [cliPath, 'generate', '-i', testInputPath, '-o', testOutputPath, '--watch'], {
61+
stdio: ['pipe', 'pipe', 'pipe']
62+
});
63+
64+
let outputReceived = false;
65+
let regenerateReceived = false;
66+
67+
child.stdout.on('data', (data) => {
68+
const output = data.toString();
69+
70+
if (output.includes('✓ Fetch client generated successfully!') && !outputReceived) {
71+
outputReceived = true;
72+
expect(existsSync(testOutputPath)).to.be.true;
73+
74+
setTimeout(() => {
75+
const updatedSpec = { ...sampleSpec };
76+
updatedSpec.info.title = "Updated Watch Test API";
77+
writeFileSync(testInputPath, JSON.stringify(updatedSpec, null, 2));
78+
}, 100);
79+
}
80+
81+
if (output.includes('File changed, regenerating...') && !regenerateReceived) {
82+
regenerateReceived = true;
83+
}
84+
85+
if (outputReceived && regenerateReceived && output.includes('✓ Fetch client generated successfully!')) {
86+
const clientCode = readFileSync(testOutputPath, 'utf8');
87+
expect(clientCode).to.include('class ApiClient');
88+
child.kill('SIGINT');
89+
done();
90+
}
91+
});
92+
93+
child.stderr.on('data', (data) => {
94+
console.error('CLI stderr:', data.toString());
95+
});
96+
97+
child.on('error', (error) => {
98+
done(error);
99+
});
100+
});
101+
102+
it('should handle watch mode with invalid input gracefully', function(done) {
103+
this.timeout(3000);
104+
105+
const cliPath = path.join(__dirname, '../bin/cli.js');
106+
const child = spawn('node', [cliPath, 'generate', '-i', testInputPath, '-o', testOutputPath, '--watch'], {
107+
stdio: ['pipe', 'pipe', 'pipe']
108+
});
109+
110+
let initialGeneration = false;
111+
112+
child.stdout.on('data', (data) => {
113+
const output = data.toString();
114+
115+
if (output.includes('✓ Fetch client generated successfully!') && !initialGeneration) {
116+
initialGeneration = true;
117+
118+
setTimeout(() => {
119+
writeFileSync(testInputPath, 'invalid json');
120+
}, 100);
121+
}
122+
});
123+
124+
child.stderr.on('data', (data) => {
125+
const errorOutput = data.toString();
126+
if (errorOutput.includes('Error generating client:')) {
127+
child.kill('SIGINT');
128+
done();
129+
}
130+
});
131+
132+
child.on('error', (error) => {
133+
done(error);
134+
});
135+
});
136+
});
26137
});

0 commit comments

Comments
 (0)