This commit is contained in:
181
.ai-context-generator-cli/tests/cli.test.ts
Normal file
181
.ai-context-generator-cli/tests/cli.test.ts
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import { execSync } from 'child_process';
|
||||||
|
|
||||||
|
describe('CLI', () => {
|
||||||
|
let testDir: string;
|
||||||
|
const projectPath = path.join(__dirname, '..');
|
||||||
|
const cliPath = path.join(projectPath, 'dist', 'index.js');
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
if (!fs.existsSync(cliPath)) {
|
||||||
|
throw new Error('CLI not built. Run npm run build first.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
testDir = path.join(__dirname, 'test-projects', `test-${Date.now()}`);
|
||||||
|
await fs.promises.mkdir(testDir, { recursive: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
if (await fs.promises.stat(testDir).catch(() => null)) {
|
||||||
|
await fs.promises.rm(testDir, { recursive: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('--version', () => {
|
||||||
|
it('should display version information', () => {
|
||||||
|
const output = execSync(`node ${cliPath} --version`, { encoding: 'utf-8' });
|
||||||
|
expect(output).toContain('1.0.0');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('--help', () => {
|
||||||
|
it('should display help information', () => {
|
||||||
|
const output = execSync(`node ${cliPath} --help`, { encoding: 'utf-8' });
|
||||||
|
expect(output).toContain('Usage:');
|
||||||
|
expect(output).toContain('Options:');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('--dir option', () => {
|
||||||
|
it('should analyze specified directory', async () => {
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'tsconfig.json'),
|
||||||
|
JSON.stringify({})
|
||||||
|
);
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
path.join(testDir, 'index.ts'),
|
||||||
|
'const x = 1;'
|
||||||
|
);
|
||||||
|
|
||||||
|
const outputPath = path.join(testDir, 'output.json');
|
||||||
|
execSync(
|
||||||
|
`node ${cliPath} --dir "${testDir}" --output "${outputPath}" --no-conventions`,
|
||||||
|
{ encoding: 'utf-8' }
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(fs.existsSync(outputPath)).toBe(true);
|
||||||
|
const content = fs.readFileSync(outputPath, 'utf-8');
|
||||||
|
expect(() => JSON.parse(content)).not.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('--output option', () => {
|
||||||
|
it('should save to specified file path', async () => {
|
||||||
|
await fs.promises.writeFile(path.join(testDir, 'tsconfig.json'), '{}');
|
||||||
|
|
||||||
|
const customPath = path.join(testDir, 'custom-context');
|
||||||
|
execSync(
|
||||||
|
`node ${cliPath} --dir "${testDir}" --output "${customPath}" --format json --no-conventions`,
|
||||||
|
{ encoding: 'utf-8' }
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(fs.existsSync(`${customPath}.json`)).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('--format option', () => {
|
||||||
|
it('should generate JSON output', async () => {
|
||||||
|
await fs.promises.writeFile(path.join(testDir, 'tsconfig.json'), '{}');
|
||||||
|
|
||||||
|
const outputPath = path.join(testDir, 'output');
|
||||||
|
execSync(
|
||||||
|
`node ${cliPath} --dir "${testDir}" --output "${outputPath}" --format json --no-conventions`,
|
||||||
|
{ encoding: 'utf-8' }
|
||||||
|
);
|
||||||
|
|
||||||
|
const content = fs.readFileSync(`${outputPath}.json`, 'utf-8');
|
||||||
|
expect(() => JSON.parse(content)).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should generate YAML output', async () => {
|
||||||
|
await fs.promises.writeFile(path.join(testDir, 'tsconfig.json'), '{}');
|
||||||
|
|
||||||
|
const outputPath = path.join(testDir, 'output');
|
||||||
|
execSync(
|
||||||
|
`node ${cliPath} --dir "${testDir}" --output "${outputPath}" --format yaml --no-conventions`,
|
||||||
|
{ encoding: 'utf-8' }
|
||||||
|
);
|
||||||
|
|
||||||
|
const content = fs.readFileSync(`${outputPath}.yaml`, 'utf-8');
|
||||||
|
expect(content).toContain('projectInfo:');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('--template option', () => {
|
||||||
|
it('should accept default template', async () => {
|
||||||
|
await fs.promises.writeFile(path.join(testDir, 'tsconfig.json'), '{}');
|
||||||
|
|
||||||
|
const outputPath = path.join(testDir, 'output');
|
||||||
|
execSync(
|
||||||
|
`node ${cliPath} --dir "${testDir}" --output "${outputPath}" --template default --no-conventions`,
|
||||||
|
{ encoding: 'utf-8' }
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(fs.existsSync(`${outputPath}.json`)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should accept cursor template', async () => {
|
||||||
|
await fs.promises.writeFile(path.join(testDir, 'tsconfig.json'), '{}');
|
||||||
|
|
||||||
|
const outputPath = path.join(testDir, 'output');
|
||||||
|
execSync(
|
||||||
|
`node ${cliPath} --dir "${testDir}" --output "${outputPath}" --template cursor --no-conventions`,
|
||||||
|
{ encoding: 'utf-8' }
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(fs.existsSync(`${outputPath}.json`)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should accept copilot template', async () => {
|
||||||
|
await fs.promises.writeFile(path.join(testDir, 'tsconfig.json'), '{}');
|
||||||
|
|
||||||
|
const outputPath = path.join(testDir, 'output');
|
||||||
|
execSync(
|
||||||
|
`node ${cliPath} --dir "${testDir}" --output "${outputPath}" --template copilot --no-conventions`,
|
||||||
|
{ encoding: 'utf-8' }
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(fs.existsSync(`${outputPath}.json`)).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('--no-conventions option', () => {
|
||||||
|
it('should skip convention analysis', async () => {
|
||||||
|
await fs.promises.writeFile(path.join(testDir, 'tsconfig.json'), '{}');
|
||||||
|
|
||||||
|
const outputPath = path.join(testDir, 'output');
|
||||||
|
execSync(
|
||||||
|
`node ${cliPath} --dir "${testDir}" --output "${outputPath}" --no-conventions`,
|
||||||
|
{ encoding: 'utf-8' }
|
||||||
|
);
|
||||||
|
|
||||||
|
const content = fs.readFileSync(`${outputPath}.json`, 'utf-8');
|
||||||
|
const parsed = JSON.parse(content);
|
||||||
|
expect(parsed.projectInfo.conventions).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('--verbose option', () => {
|
||||||
|
it('should output verbose information', () => {
|
||||||
|
const output = execSync(
|
||||||
|
`node ${cliPath} --dir . --output /dev/null --format json --verbose --no-conventions 2>&1 || true`,
|
||||||
|
{ encoding: 'utf-8' }
|
||||||
|
);
|
||||||
|
expect(output).toContain('Analyzing directory');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('error handling', () => {
|
||||||
|
it('should handle non-existent directory', () => {
|
||||||
|
expect(() => {
|
||||||
|
execSync(
|
||||||
|
`node ${cliPath} --dir "/non/existent/path" --output /dev/null --no-conventions`,
|
||||||
|
{ encoding: 'utf-8' }
|
||||||
|
);
|
||||||
|
}).toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user