import { describe, test, expect, beforeEach, afterEach } from 'bun:test'; import { execa } from 'execa'; import { setupTest } from '../helpers/setup.js'; import { FIXTURES } from '../helpers/fixtures.js'; import { join } from 'path'; import { fileExists } from '../../src/utils/file.js'; import { fileURLToPath } from 'url'; import { dirname } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const CLI_PATH = join(__dirname, '../../src/cli.ts'); describe('CLI', () => { let tempDir: string; let cleanup: () => Promise; beforeEach(async () => { const setup = await setupTest(); tempDir = setup.tempDir; cleanup = setup.cleanup; }); afterEach(async () => { await cleanup(); }); describe('базовые сценарии', () => { test('должен запуститься с корректными параметрами (локальный файл)', async () => { const outputPath = join(tempDir, 'output'); const { exitCode } = await execa('bun', [ 'run', CLI_PATH, '--input', FIXTURES.MINIMAL, '--output', outputPath, ]); expect(exitCode).toBe(0); const generatedFile = join(outputPath, 'MinimalAPI.ts'); const exists = await fileExists(generatedFile); expect(exists).toBe(true); }, 30000); test('должен генерировать с кастомным именем файла', async () => { const outputPath = join(tempDir, 'output'); const customName = 'CustomApi'; const { exitCode } = await execa('bun', [ 'run', CLI_PATH, '--input', FIXTURES.MINIMAL, '--output', outputPath, '--name', customName, ]); expect(exitCode).toBe(0); const generatedFile = join(outputPath, `${customName}.ts`); const exists = await fileExists(generatedFile); expect(exists).toBe(true); }, 30000); test('должен отображать версию с --version', async () => { const { stdout } = await execa('bun', ['run', CLI_PATH, '--version']); expect(stdout).toContain('1.0.0'); }); test('должен отображать help с --help', async () => { const { stdout } = await execa('bun', ['run', CLI_PATH, '--help']); expect(stdout).toContain('Generate TypeScript API client'); expect(stdout).toContain('--input'); expect(stdout).toContain('--output'); }); }); describe('обработка ошибок', () => { test('должен выбросить ошибку без параметра --input', async () => { const outputPath = join(tempDir, 'output'); try { await execa('bun', ['run', CLI_PATH, '--output', outputPath]); throw new Error('Should have thrown'); } catch (error: any) { expect(error.exitCode).not.toBe(0); } }); test('должен выбросить ошибку без параметра --output', async () => { try { await execa('bun', ['run', CLI_PATH, '--input', FIXTURES.MINIMAL]); throw new Error('Should have thrown'); } catch (error: any) { expect(error.exitCode).not.toBe(0); } }); test('должен выбросить ошибку для несуществующего файла', async () => { const outputPath = join(tempDir, 'output'); const nonexistentFile = join(tempDir, 'nonexistent.json'); try { await execa('bun', [ 'run', CLI_PATH, '--input', nonexistentFile, '--output', outputPath, ]); throw new Error('Should have thrown'); } catch (error: any) { expect(error.exitCode).not.toBe(0); } }); test('должен выбросить ошибку для невалидного JSON', async () => { const outputPath = join(tempDir, 'output'); try { await execa('bun', [ 'run', CLI_PATH, '--input', FIXTURES.INVALID, '--output', outputPath, ]); throw new Error('Should have thrown'); } catch (error: any) { expect(error.exitCode).not.toBe(0); } }, 30000); }); });