UNPKG

hey-api-builders

Version:

A custom plugin for @hey-api/openapi-ts that generates mock data builders with a lightweight custom runtime, Zod integration, or static mock generation.

230 lines (191 loc) 7.39 kB
import { describe, it, expect } from 'vitest'; import { generateEnumBuilder, generateObjectBuilder } from './builder-generator'; import type { GeneratedSchemaMeta } from '../types'; import type { Schema } from '../types'; describe('Builder Generator', () => { describe('generateEnumBuilder', () => { const enumMeta: GeneratedSchemaMeta = { typeName: 'Status', constName: 'StatusSchema', isEnum: true, schema: { enum: ['active', 'inactive'] } as Schema, isObject: false, }; it('generates basic enum builder structure', () => { const result = generateEnumBuilder(enumMeta, { mockStrategy: 'runtime', }); expect(result).toContain('export class StatusBuilder'); expect(result).toContain('private options: BuilderOptions'); expect(result).toContain('setOptions(o: BuilderOptions)'); expect(result).toContain('build(): types.Status'); }); it('generates custom runtime build method by default', () => { const result = generateEnumBuilder(enumMeta, { mockStrategy: 'runtime', }); expect(result).toContain('generateMock'); expect(result).toContain('schemas.StatusSchema'); expect(result).toContain('useDefault'); expect(result).toContain('useExamples'); }); it('generates static mock build method when mockStrategy is static', () => { const result = generateEnumBuilder(enumMeta, { mockStrategy: 'static', }); expect(result).not.toContain('generateMock'); expect(result).toContain('return'); expect(result).toContain('as types.Status'); }); it('generates Zod build method when mockStrategy is zod', () => { const result = generateEnumBuilder(enumMeta, { mockStrategy: 'zod', }); expect(result).toContain('generateMockFromZodSchema'); expect(result).toContain('zodSchemaString'); expect(result).toContain('useDefault'); expect(result).toContain('alwaysIncludeOptionals'); }); it('includes all builder option properties', () => { const result = generateEnumBuilder(enumMeta, { mockStrategy: 'runtime', }); expect(result).toContain('useDefault'); expect(result).toContain('useExamples'); expect(result).toContain('alwaysIncludeOptionals'); expect(result).toContain('optionalsProbability'); expect(result).toContain('omitNulls'); }); }); describe('generateObjectBuilder', () => { const objectMeta: GeneratedSchemaMeta = { typeName: 'User', constName: 'UserSchema', isEnum: false, schema: { type: 'object', properties: { name: { type: 'string' }, email: { type: 'string', format: 'email' }, age: { type: 'number' }, }, required: ['name', 'email'], } as Schema, isObject: true, }; it('generates basic object builder structure', () => { const result = generateObjectBuilder(objectMeta, { mockStrategy: 'runtime', }); expect(result).toContain('export class UserBuilder'); expect(result).toContain('private overrides: Partial<types.User>'); expect(result).toContain('private options: BuilderOptions'); expect(result).toContain('build(): types.User'); }); it('generates with methods for properties', () => { const result = generateObjectBuilder(objectMeta, { mockStrategy: 'runtime', }); expect(result).toContain('withName'); expect(result).toContain('withEmail'); expect(result).toContain('withAge'); }); it('generates runtime build method with override merging', () => { const result = generateObjectBuilder(objectMeta, { mockStrategy: 'runtime', }); expect(result).toContain('const mock = generateMock'); expect(result).toContain('for (const k in this.overrides)'); expect(result).toContain('Object.prototype.hasOwnProperty.call'); expect(result).toContain('return mock'); }); it('generates static mock build method when mockStrategy is static', () => { const result = generateObjectBuilder(objectMeta, { mockStrategy: 'static', }); expect(result).toContain('const baseMock ='); expect(result).toContain('{ ...baseMock, ...this.overrides }'); expect(result).not.toContain('generateMock'); }); it('generates Zod build method when mockStrategy is zod', () => { const result = generateObjectBuilder(objectMeta, { mockStrategy: 'zod', }); expect(result).toContain('generateMockFromZodSchema'); expect(result).toContain('this.overrides'); expect(result).not.toContain('for (const k in this.overrides)'); }); it('handles objects without properties', () => { const emptyMeta: GeneratedSchemaMeta = { typeName: 'Empty', constName: 'EmptySchema', isEnum: false, schema: { type: 'object' } as Schema, isObject: true, }; const result = generateObjectBuilder(emptyMeta, { mockStrategy: 'runtime', }); expect(result).toContain('export class EmptyBuilder'); expect(result).toContain('build(): types.Empty'); }); it('preserves type safety in generated code', () => { const result = generateObjectBuilder(objectMeta, { mockStrategy: 'runtime', }); expect(result).toContain('types.User'); expect(result).toContain('Partial<types.User>'); expect(result).toContain('types.User["name"]'); }); it('includes setOptions method', () => { const result = generateObjectBuilder(objectMeta, { mockStrategy: 'runtime', }); expect(result).toContain('setOptions(o: BuilderOptions): this'); expect(result).toContain('this.options = o || {}'); expect(result).toContain('return this'); }); it('uses correct schema reference in runtime mode', () => { const result = generateObjectBuilder(objectMeta, { mockStrategy: 'runtime', }); expect(result).toContain('schemas.UserSchema'); }); it('generates type-safe override assignment', () => { const result = generateObjectBuilder(objectMeta, { mockStrategy: 'runtime', }); expect(result).toContain('const typedMock = mock as Record<string, unknown>'); expect(result).toContain('const typedOverrides = this.overrides as Record<string, unknown>'); expect(result).toContain('typedMock[k] = typedOverrides[k]'); }); }); describe('Builder Options', () => { it('generates consistent builder options across all modes', () => { const meta: GeneratedSchemaMeta = { typeName: 'Test', constName: 'TestSchema', isEnum: false, schema: { type: 'object' } as Schema, isObject: true, }; const runtimeResult = generateObjectBuilder(meta, { mockStrategy: 'runtime', }); const zodResult = generateObjectBuilder(meta, { mockStrategy: 'zod', }); const options = [ 'useDefault', 'useExamples', 'alwaysIncludeOptionals', 'optionalsProbability', 'omitNulls', ]; options.forEach((option) => { expect(runtimeResult).toContain(option); expect(zodResult).toContain(option); }); }); }); });