From ff6a43c1e1f5ed5d65e213b69679d3a5d95c1bc4 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Sat, 31 Jan 2026 12:25:59 +0000 Subject: [PATCH] Initial upload with CI/CD workflow --- tests/dts-generator.test.ts | 229 ++++++++++++++++++++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 tests/dts-generator.test.ts diff --git a/tests/dts-generator.test.ts b/tests/dts-generator.test.ts new file mode 100644 index 0000000..bdcdb42 --- /dev/null +++ b/tests/dts-generator.test.ts @@ -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:'); + }); + }); +});