import * as fs from 'fs'; import * as path from 'path'; import { ContextGenerator } from '../src/generators/contextGenerator'; import { ContextConfig } from '../src/types'; describe('ContextGenerator', () => { let generator: ContextGenerator; let testDir: string; beforeEach(async () => { generator = new ContextGenerator(); 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('generate', () => { it('should generate project info for TypeScript project', async () => { await fs.promises.writeFile( path.join(testDir, 'tsconfig.json'), JSON.stringify({ compilerOptions: { target: 'ES2020' } }) ); await fs.promises.writeFile( path.join(testDir, 'package.json'), JSON.stringify({ dependencies: { express: '^4.18.0' }, devDependencies: { jest: '^29.0.0' }, }) ); await fs.promises.writeFile( path.join(testDir, 'index.ts'), 'const x: string = "hello";\nexport { x };' ); const config: ContextConfig = { includes: ['**/*.ts', '**/*.json'], excludes: [], outputFormat: 'json', template: 'default', outputFile: 'test.json', analyzeConventions: false, includeDevDependencies: false, respectGitignore: false, }; const result = await generator.generate(testDir, config); expect(result.projectType.primaryLanguage).toBe('TypeScript'); expect(result.fileCount).toBe(3); expect(result.analysisDate).toBeDefined(); }); it('should include conventions when enabled', async () => { await fs.promises.writeFile( path.join(testDir, 'tsconfig.json'), JSON.stringify({}) ); await fs.promises.writeFile( path.join(testDir, 'index.ts'), `const myVariable = "test"; function myFunction() { return myVariable; } export class MyClass {}` ); const result = await generator.generate(testDir); expect(result.conventions).toBeDefined(); expect(result.conventions?.namingConvention.files).toBeDefined(); expect(result.conventions?.importStyle).toBeDefined(); }); it('should analyze file count correctly', async () => { await fs.promises.writeFile(path.join(testDir, 'file1.ts'), '// file 1'); await fs.promises.writeFile(path.join(testDir, 'file2.ts'), '// file 2'); await fs.promises.writeFile(path.join(testDir, 'file3.ts'), '// file 3'); await fs.promises.writeFile(path.join(testDir, 'tsconfig.json'), '{}'); const config: ContextConfig = { includes: ['**/*.ts', '**/*.json'], excludes: [], outputFormat: 'json', template: 'default', outputFile: 'test.json', analyzeConventions: false, includeDevDependencies: false, respectGitignore: false, }; const result = await generator.generate(testDir, config); expect(result.fileCount).toBe(4); }); }); describe('generateJson', () => { it('should generate valid JSON output', async () => { await fs.promises.writeFile(path.join(testDir, 'tsconfig.json'), '{}'); await fs.promises.writeFile(path.join(testDir, 'index.ts'), 'const x = 1;'); const result = await generator.generateJson(testDir); expect(() => JSON.parse(result)).not.toThrow(); const parsed = JSON.parse(result); expect(parsed.projectInfo).toBeDefined(); expect(parsed.files).toBeDefined(); expect(parsed.generatedAt).toBeDefined(); }); }); describe('generateYaml', () => { it('should generate valid YAML output', async () => { await fs.promises.writeFile(path.join(testDir, 'tsconfig.json'), '{}'); await fs.promises.writeFile(path.join(testDir, 'index.ts'), 'const x = 1;'); const result = await generator.generateYaml(testDir); expect(result).toContain('projectInfo:'); expect(result).toContain('files:'); }); }); describe('saveContext', () => { it('should save JSON file correctly', async () => { const outputPath = path.join(testDir, 'output'); await fs.promises.writeFile(path.join(testDir, 'tsconfig.json'), '{}'); await fs.promises.writeFile(path.join(testDir, 'index.ts'), 'const x = 1;'); await generator.saveContext(testDir, outputPath, 'json'); const filePath = outputPath.endsWith('.json') ? outputPath : `${outputPath}.json`; const content = await fs.promises.readFile(filePath, 'utf-8'); expect(() => JSON.parse(content)).not.toThrow(); }); it('should save YAML file correctly', async () => { const outputPath = path.join(testDir, 'output'); await fs.promises.writeFile(path.join(testDir, 'tsconfig.json'), '{}'); await fs.promises.writeFile(path.join(testDir, 'index.ts'), 'const x = 1;'); await generator.saveContext(testDir, outputPath, 'yaml'); const filePath = outputPath.endsWith('.yaml') ? outputPath : `${outputPath}.yaml`; const content = await fs.promises.readFile(filePath, 'utf-8'); expect(content).toContain('projectInfo:'); }); it('should auto-add extension when missing', async () => { const outputPath = path.join(testDir, 'output'); await fs.promises.writeFile(path.join(testDir, 'tsconfig.json'), '{}'); await generator.saveContext(testDir, outputPath, 'json'); const exists = await fs.promises.access(`${outputPath}.json`).then(() => true).catch(() => false); expect(exists).toBe(true); }); }); });