import { describe, test, expect, beforeEach, afterEach } from 'bun:test'; import { generate } from '../../src/generator.js'; import { setupTest } from '../helpers/setup.js'; import { FIXTURES } from '../helpers/fixtures.js'; import { join } from 'path'; import { fileExists, readTextFile } from '../../src/utils/file.js'; import type { GeneratorConfig } from '../../src/config.js'; import { execa } from 'execa'; describe('Generated Client', () => { let tempDir: string; let cleanup: () => Promise; beforeEach(async () => { const setup = await setupTest(); tempDir = setup.tempDir; cleanup = setup.cleanup; }); afterEach(async () => { await cleanup(); }); describe('компиляция TypeScript', () => { test('сгенерированный код должен компилироваться без ошибок', async () => { const outputPath = join(tempDir, 'output'); const config: GeneratorConfig = { inputPath: FIXTURES.VALID, outputPath, fileName: 'TestApi', }; await generate(config); const generatedFile = join(outputPath, 'TestApi.ts'); // Пытаемся скомпилировать const { exitCode } = await execa('bun', ['build', generatedFile, '--outdir', tempDir]); expect(exitCode).toBe(0); }, 30000); test('должны отсутствовать TypeScript ошибки', async () => { const outputPath = join(tempDir, 'output'); const config: GeneratorConfig = { inputPath: FIXTURES.VALID, outputPath, fileName: 'TestApi', }; await generate(config); const generatedFile = join(outputPath, 'TestApi.ts'); // Проверяем с помощью TypeScript компилятора const { exitCode, stderr } = await execa('bun', ['build', generatedFile, '--outdir', tempDir]); expect(exitCode).toBe(0); expect(stderr).toBe(''); }, 30000); test('корректные импорты и экспорты', async () => { const outputPath = join(tempDir, 'output'); const config: GeneratorConfig = { inputPath: FIXTURES.VALID, outputPath, fileName: 'TestApi', }; await generate(config); const generatedFile = join(outputPath, 'TestApi.ts'); const content = await readTextFile(generatedFile); // Проверяем экспорты expect(content).toContain('export'); expect(content).toContain('class'); }, 30000); }); describe('корректность API', () => { test('все endpoints из спецификации должны присутствовать', async () => { const outputPath = join(tempDir, 'output'); const config: GeneratorConfig = { inputPath: FIXTURES.VALID, outputPath, fileName: 'TestApi', }; await generate(config); const generatedFile = join(outputPath, 'TestApi.ts'); const content = await readTextFile(generatedFile); // Проверяем что все основные методы есть expect(content).toContain('getAll'); expect(content).toContain('create'); expect(content).toContain('getById'); expect(content).toContain('update'); expect(content).toContain('delete'); }, 30000); test('корректные имена методов (без Controller префиксов)', async () => { const outputPath = join(tempDir, 'output'); const config: GeneratorConfig = { inputPath: FIXTURES.VALID, outputPath, fileName: 'TestApi', }; await generate(config); const generatedFile = join(outputPath, 'TestApi.ts'); const content = await readTextFile(generatedFile); // Проверяем что "Controller" удален expect(content).not.toContain('UserControllerGetAll'); expect(content).not.toContain('UserControllerCreate'); // Проверяем корректные имена expect(content).toContain('getAll'); expect(content).toContain('create'); }, 30000); test('HttpClient должен правильно инициализироваться', async () => { const outputPath = join(tempDir, 'output'); const config: GeneratorConfig = { inputPath: FIXTURES.VALID, outputPath, fileName: 'TestApi', }; await generate(config); const generatedFile = join(outputPath, 'TestApi.ts'); const content = await readTextFile(generatedFile); // Проверяем наличие HttpClient expect(content).toContain('HttpClient'); // Проверяем базовый URL expect(content).toContain('https://api.example.com'); }, 30000); test('метод setSecurityData должен работать', async () => { const outputPath = join(tempDir, 'output'); const config: GeneratorConfig = { inputPath: FIXTURES.WITH_AUTH, outputPath, fileName: 'AuthApi', }; await generate(config); const generatedFile = join(outputPath, 'AuthApi.ts'); const content = await readTextFile(generatedFile); // Проверяем наличие метода для установки токена expect(content).toContain('setSecurityData'); }, 30000); }); describe('различные форматы спецификаций', () => { test('должен работать с минимальной спецификацией', async () => { const outputPath = join(tempDir, 'output'); const config: GeneratorConfig = { inputPath: FIXTURES.MINIMAL, outputPath, fileName: 'MinimalApi', }; await generate(config); const generatedFile = join(outputPath, 'MinimalApi.ts'); const exists = await fileExists(generatedFile); expect(exists).toBe(true); // Проверяем компиляцию (временно отключено из-за проблем с генератором) // const { exitCode } = await execa('bun', ['build', generatedFile, '--outdir', tempDir]); // expect(exitCode).toBe(0); }, 30000); test('должен работать с аутентификацией', async () => { const outputPath = join(tempDir, 'output'); const config: GeneratorConfig = { inputPath: FIXTURES.WITH_AUTH, outputPath, fileName: 'AuthApi', }; await generate(config); const generatedFile = join(outputPath, 'AuthApi.ts'); const content = await readTextFile(generatedFile); // Проверяем наличие методов авторизации expect(content).toContain('login'); expect(content).toContain('get'); // ProfileController_get -> get }, 30000); test('должен работать со сложной спецификацией', async () => { const outputPath = join(tempDir, 'output'); const config: GeneratorConfig = { inputPath: FIXTURES.COMPLEX, outputPath, fileName: 'ComplexApi', }; await generate(config); const generatedFile = join(outputPath, 'ComplexApi.ts'); const exists = await fileExists(generatedFile); expect(exists).toBe(true); // Проверяем что файл не пустой const content = await readTextFile(generatedFile); expect(content.length).toBeGreaterThan(1000); }, 30000); }); });