Initial upload with CI/CD workflow
Some checks failed
CI / test (push) Has been cancelled

This commit is contained in:
2026-01-31 12:25:59 +00:00
parent 69aaff96e7
commit ff6a43c1e1

229
tests/dts-generator.test.ts Normal file
View File

@@ -0,0 +1,229 @@
import { DeclarationGenerator } from '../src/declaration-generator.js';
import { TypeDefinition, ObjectType, ArrayType, UnionType } from '../src/types.js';
describe('DeclarationGenerator', () => {
let generator: DeclarationGenerator;
beforeEach(() => {
generator = new DeclarationGenerator(2);
});
describe('generate', () => {
it('should generate primitive type declarations', () => {
const types: TypeDefinition[] = [
{ name: 'MyString', type: { kind: 'primitive', type: 'string' } },
];
const result = generator.generate(types);
expect(result).toBe('export type MyString = string;');
});
it('should generate number type declarations', () => {
const types: TypeDefinition[] = [
{ name: 'MyNumber', type: { kind: 'primitive', type: 'number' } },
];
const result = generator.generate(types);
expect(result).toBe('export type MyNumber = number;');
});
it('should generate boolean type declarations', () => {
const types: TypeDefinition[] = [
{ name: 'MyBoolean', type: { kind: 'primitive', type: 'boolean' } },
];
const result = generator.generate(types);
expect(result).toBe('export type MyBoolean = boolean;');
});
it('should generate null type declarations', () => {
const types: TypeDefinition[] = [
{ name: 'MyNull', type: { kind: 'primitive', type: 'null' } },
];
const result = generator.generate(types);
expect(result).toBe('export type MyNull = null;');
});
});
describe('generate interface declarations', () => {
it('should generate interface declarations for objects', () => {
const objectType: ObjectType = {
kind: 'object',
properties: [
{ name: 'name', type: { kind: 'primitive', type: 'string' }, optional: false },
{ name: 'age', type: { kind: 'primitive', type: 'number' }, optional: false },
],
};
const types: TypeDefinition[] = [
{ name: 'User', type: objectType },
];
const result = generator.generate(types);
expect(result).toContain('export interface User');
expect(result).toContain('name: string;');
expect(result).toContain('age: number;');
});
it('should generate optional properties', () => {
const objectType: ObjectType = {
kind: 'object',
properties: [
{ name: 'required', type: { kind: 'primitive', type: 'string' }, optional: false },
{ name: 'optional', type: { kind: 'primitive', type: 'number' }, optional: true },
],
};
const types: TypeDefinition[] = [
{ name: 'Test', type: objectType },
];
const result = generator.generate(types);
expect(result).toContain('required: string;');
expect(result).toContain('optional?: number;');
});
it('should generate nested object interfaces', () => {
const nestedType: ObjectType = {
kind: 'object',
properties: [
{ name: 'street', type: { kind: 'primitive', type: 'string' }, optional: false },
],
name: 'Address',
};
const rootType: ObjectType = {
kind: 'object',
properties: [
{ name: 'name', type: { kind: 'primitive', type: 'string' }, optional: false },
{ name: 'address', type: nestedType, optional: false },
],
name: 'User',
};
const types: TypeDefinition[] = [
{ name: 'User', type: rootType },
{ name: 'Address', type: nestedType },
];
const result = generator.generate(types);
expect(result).toContain('export interface User');
expect(result).toContain('export interface Address');
expect(result).toContain('address:');
});
it('should generate array types', () => {
const arrayType: ArrayType = {
kind: 'array',
elementType: { kind: 'primitive', type: 'string' },
};
const types: TypeDefinition[] = [
{ name: 'StringList', type: arrayType },
];
const result = generator.generate(types);
expect(result).toBe('export type StringList = string[];');
});
it('should generate array of objects', () => {
const objectType: ObjectType = {
kind: 'object',
properties: [
{ name: 'id', type: { kind: 'primitive', type: 'number' }, optional: false },
],
};
const arrayType: ArrayType = {
kind: 'array',
elementType: objectType,
};
const types: TypeDefinition[] = [
{ name: 'ItemList', type: arrayType },
];
const result = generator.generate(types);
expect(result).toContain('export type ItemList');
expect(result).toContain('id: number;');
});
it('should generate union types', () => {
const unionType: UnionType = {
kind: 'union',
types: [
{ kind: 'primitive', type: 'string' },
{ kind: 'primitive', type: 'number' },
],
};
const types: TypeDefinition[] = [
{ name: 'StringOrNumber', type: unionType },
];
const result = generator.generate(types);
expect(result).toBe('export type StringOrNumber = string | number;');
});
it('should format union types with proper spacing', () => {
const unionType: UnionType = {
kind: 'union',
types: [
{ kind: 'literal', value: 'active' },
{ kind: 'literal', value: 'inactive' },
{ kind: 'primitive', type: 'null' },
],
};
const types: TypeDefinition[] = [
{ name: 'Status', type: unionType },
];
const result = generator.generate(types);
expect(result).toBe("export type Status = 'active' | 'inactive' | null;");
});
});
describe('generateStandalone', () => {
it('should generate multiple declarations', () => {
const userType: ObjectType = {
kind: 'object',
properties: [
{ name: 'id', type: { kind: 'primitive', type: 'number' }, optional: false },
],
name: 'User',
};
const addressType: ObjectType = {
kind: 'object',
properties: [
{ name: 'city', type: { kind: 'primitive', type: 'string' }, optional: false },
],
name: 'Address',
};
const types: TypeDefinition[] = [
{ name: 'User', type: userType },
{ name: 'Address', type: addressType },
];
const result = generator.generateStandalone(types);
expect(result).toContain('export interface User');
expect(result).toContain('export interface Address');
});
it('should handle empty types array', () => {
const result = generator.generateStandalone([]);
expect(result).toBe('');
});
});
describe('nested structures', () => {
it('should generate complex nested structures', () => {
const addressType: ObjectType = {
kind: 'object',
properties: [
{ name: 'street', type: { kind: 'primitive', type: 'string' }, optional: false },
{ name: 'zipCode', type: { kind: 'primitive', type: 'number' }, optional: false },
],
name: 'Address',
};
const userType: ObjectType = {
kind: 'object',
properties: [
{ name: 'name', type: { kind: 'primitive', type: 'string' }, optional: false },
{ name: 'age', type: { kind: 'primitive', type: 'number' }, optional: true },
{ name: 'address', type: addressType, optional: false },
{ name: 'tags', type: { kind: 'array', elementType: { kind: 'primitive', type: 'string' } }, optional: false },
],
name: 'User',
};
const types: TypeDefinition[] = [
{ name: 'User', type: userType },
{ name: 'Address', type: addressType },
];
const result = generator.generate(types);
expect(result).toContain('export interface User');
expect(result).toContain('export interface Address');
expect(result).toContain('tags:');
});
});
});