241 lines
8.0 KiB
TypeScript
241 lines
8.0 KiB
TypeScript
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';
|
||
|
||
describe('Generator', () => {
|
||
let tempDir: string;
|
||
let cleanup: () => Promise<void>;
|
||
|
||
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 config: GeneratorConfig = {
|
||
inputPath: FIXTURES.MINIMAL,
|
||
outputPath,
|
||
fileName: 'TestApi',
|
||
};
|
||
|
||
await generate(config);
|
||
|
||
const generatedFile = join(outputPath, 'TestApi.ts');
|
||
const exists = await fileExists(generatedFile);
|
||
expect(exists).toBe(true);
|
||
}, 30000);
|
||
|
||
test('должен генерировать корректную структуру кода', async () => {
|
||
const outputPath = join(tempDir, 'output');
|
||
const config: GeneratorConfig = {
|
||
inputPath: FIXTURES.MINIMAL,
|
||
outputPath,
|
||
fileName: 'TestApi',
|
||
};
|
||
|
||
await generate(config);
|
||
|
||
const generatedFile = join(outputPath, 'TestApi.ts');
|
||
const content = await readTextFile(generatedFile);
|
||
|
||
// Проверяем наличие основных элементов
|
||
expect(content).toContain('export class');
|
||
expect(content).toContain('HttpClient');
|
||
}, 30000);
|
||
|
||
test('должен обработать все HTTP методы', 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);
|
||
|
||
// Проверяем что методы UserController переименованы
|
||
// UserController_getAll -> getAll
|
||
// UserController_create -> create
|
||
expect(content).toContain('getAll');
|
||
expect(content).toContain('create');
|
||
expect(content).toContain('getById');
|
||
expect(content).toContain('update');
|
||
expect(content).toContain('delete');
|
||
}, 30000);
|
||
|
||
test('должен генерировать типы для request и response', 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('User');
|
||
expect(content).toContain('CreateUserDto');
|
||
expect(content).toContain('UpdateUserDto');
|
||
}, 30000);
|
||
|
||
test('должен генерировать enum типы', 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);
|
||
|
||
// Проверяем наличие enum
|
||
expect(content).toContain('UserRole');
|
||
expect(content).toContain('admin');
|
||
expect(content).toContain('user');
|
||
expect(content).toContain('guest');
|
||
}, 30000);
|
||
|
||
test('должен обработать Bearer authentication', async () => {
|
||
const outputPath = join(tempDir, 'output');
|
||
const config: GeneratorConfig = {
|
||
inputPath: FIXTURES.WITH_AUTH,
|
||
outputPath,
|
||
fileName: 'TestApi',
|
||
};
|
||
|
||
await generate(config);
|
||
|
||
const generatedFile = join(outputPath, 'TestApi.ts');
|
||
const content = await readTextFile(generatedFile);
|
||
|
||
// Проверяем наличие методов для работы с токеном
|
||
expect(content).toContain('setSecurityData');
|
||
}, 30000);
|
||
|
||
test('должен использовать baseUrl из servers', 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);
|
||
|
||
// Проверяем что baseUrl установлен
|
||
expect(content).toContain('https://api.example.com');
|
||
}, 30000);
|
||
|
||
test('должен применять хук onFormatRouteName', 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);
|
||
});
|
||
|
||
describe('edge cases', () => {
|
||
test('должен обработать пустую спецификацию', async () => {
|
||
const outputPath = join(tempDir, 'output');
|
||
const config: GeneratorConfig = {
|
||
inputPath: FIXTURES.EMPTY,
|
||
outputPath,
|
||
fileName: 'TestApi',
|
||
};
|
||
|
||
// Генерация должна пройти успешно
|
||
await generate(config);
|
||
const generatedFile = join(outputPath, 'TestApi.ts');
|
||
const exists = await fileExists(generatedFile);
|
||
expect(exists).toBe(true);
|
||
}, 30000);
|
||
|
||
test('должен обработать минимальную спецификацию', async () => {
|
||
const outputPath = join(tempDir, 'output');
|
||
const config: GeneratorConfig = {
|
||
inputPath: FIXTURES.MINIMAL,
|
||
outputPath,
|
||
fileName: 'TestApi',
|
||
};
|
||
|
||
await generate(config);
|
||
|
||
const generatedFile = join(outputPath, 'TestApi.ts');
|
||
const exists = await fileExists(generatedFile);
|
||
expect(exists).toBe(true);
|
||
}, 30000);
|
||
|
||
test('должен обработать сложную спецификацию', async () => {
|
||
const outputPath = join(tempDir, 'output');
|
||
const config: GeneratorConfig = {
|
||
inputPath: FIXTURES.COMPLEX,
|
||
outputPath,
|
||
fileName: 'TestApi',
|
||
};
|
||
|
||
await generate(config);
|
||
|
||
const generatedFile = join(outputPath, 'TestApi.ts');
|
||
const content = await readTextFile(generatedFile);
|
||
|
||
// Проверяем что все контроллеры присутствуют
|
||
expect(content).toContain('list'); // ProductController_list -> list
|
||
expect(content).toContain('create');
|
||
expect(content).toContain('getById');
|
||
}, 30000);
|
||
|
||
test('должен обработать Unicode символы', async () => {
|
||
const outputPath = join(tempDir, 'output');
|
||
const config: GeneratorConfig = {
|
||
inputPath: FIXTURES.EDGE_CASES,
|
||
outputPath,
|
||
fileName: 'TestApi',
|
||
};
|
||
|
||
// Генерация должна пройти успешно даже с Unicode
|
||
await generate(config);
|
||
const generatedFile = join(outputPath, 'TestApi.ts');
|
||
const exists = await fileExists(generatedFile);
|
||
expect(exists).toBe(true);
|
||
}, 30000);
|
||
});
|
||
}); |