import { describe, it, expect } from 'vitest';
import {
specToXml,
getStructuredSpecPromptInstruction,
getAppSpecFormatInstruction,
APP_SPEC_XML_FORMAT,
type SpecOutput,
} from '@/lib/app-spec-format.js';
describe('app-spec-format.ts', () => {
describe('specToXml', () => {
it('should convert minimal spec to XML', () => {
const spec: SpecOutput = {
project_name: 'Test Project',
overview: 'A test project',
technology_stack: ['TypeScript', 'Node.js'],
core_capabilities: ['Testing', 'Development'],
implemented_features: [{ name: 'Feature 1', description: 'First feature' }],
};
const xml = specToXml(spec);
expect(xml).toContain('');
expect(xml).toContain('');
expect(xml).toContain('');
expect(xml).toContain('Test Project');
expect(xml).toContain('TypeScript');
expect(xml).toContain('Testing');
});
it('should escape XML special characters', () => {
const spec: SpecOutput = {
project_name: 'Test & Project',
overview: 'Description with ',
technology_stack: ['TypeScript'],
core_capabilities: ['Cap'],
implemented_features: [],
};
const xml = specToXml(spec);
expect(xml).toContain('Test & Project');
expect(xml).toContain('<tags>');
});
it('should include file_locations when provided', () => {
const spec: SpecOutput = {
project_name: 'Test',
overview: 'Test',
technology_stack: ['TS'],
core_capabilities: ['Cap'],
implemented_features: [
{
name: 'Feature',
description: 'Desc',
file_locations: ['src/index.ts'],
},
],
};
const xml = specToXml(spec);
expect(xml).toContain('');
expect(xml).toContain('src/index.ts');
});
it('should not include file_locations when empty', () => {
const spec: SpecOutput = {
project_name: 'Test',
overview: 'Test',
technology_stack: ['TS'],
core_capabilities: ['Cap'],
implemented_features: [{ name: 'Feature', description: 'Desc', file_locations: [] }],
};
const xml = specToXml(spec);
expect(xml).not.toContain('');
});
it('should include additional_requirements when provided', () => {
const spec: SpecOutput = {
project_name: 'Test',
overview: 'Test',
technology_stack: ['TS'],
core_capabilities: ['Cap'],
implemented_features: [],
additional_requirements: ['Node.js 18+'],
};
const xml = specToXml(spec);
expect(xml).toContain('');
expect(xml).toContain('Node.js 18+');
});
it('should include development_guidelines when provided', () => {
const spec: SpecOutput = {
project_name: 'Test',
overview: 'Test',
technology_stack: ['TS'],
core_capabilities: ['Cap'],
implemented_features: [],
development_guidelines: ['Use ESLint'],
};
const xml = specToXml(spec);
expect(xml).toContain('');
expect(xml).toContain('Use ESLint');
});
it('should include implementation_roadmap when provided', () => {
const spec: SpecOutput = {
project_name: 'Test',
overview: 'Test',
technology_stack: ['TS'],
core_capabilities: ['Cap'],
implemented_features: [],
implementation_roadmap: [{ phase: 'Phase 1', status: 'completed', description: 'Setup' }],
};
const xml = specToXml(spec);
expect(xml).toContain('');
expect(xml).toContain('completed');
});
it('should not include optional sections when empty', () => {
const spec: SpecOutput = {
project_name: 'Test',
overview: 'Test',
technology_stack: ['TS'],
core_capabilities: ['Cap'],
implemented_features: [],
additional_requirements: [],
development_guidelines: [],
implementation_roadmap: [],
};
const xml = specToXml(spec);
expect(xml).not.toContain('');
expect(xml).not.toContain('');
expect(xml).not.toContain('');
});
});
describe('getStructuredSpecPromptInstruction', () => {
it('should return non-empty prompt instruction', () => {
const instruction = getStructuredSpecPromptInstruction();
expect(instruction).toBeTruthy();
expect(instruction.length).toBeGreaterThan(100);
});
it('should mention required fields', () => {
const instruction = getStructuredSpecPromptInstruction();
expect(instruction).toContain('project_name');
expect(instruction).toContain('overview');
expect(instruction).toContain('technology_stack');
});
});
describe('getAppSpecFormatInstruction', () => {
it('should return non-empty format instruction', () => {
const instruction = getAppSpecFormatInstruction();
expect(instruction).toBeTruthy();
expect(instruction.length).toBeGreaterThan(100);
});
it('should include critical formatting requirements', () => {
const instruction = getAppSpecFormatInstruction();
expect(instruction).toContain('CRITICAL FORMATTING REQUIREMENTS');
});
});
describe('APP_SPEC_XML_FORMAT', () => {
it('should contain valid XML template structure', () => {
expect(APP_SPEC_XML_FORMAT).toContain('');
expect(APP_SPEC_XML_FORMAT).toContain('');
});
});
});