UNPKG

cmte

Version:

Design by Committee™ except it's just you and LLMs

136 lines (118 loc) 5.74 kB
import { describe, beforeEach, test, expect, vi } from 'vitest'; import { TemplateRenderer } from '../task/template-renderer.js'; import { FileCollectionManager } from '../file-collection-manager.js'; import { OutputReferenceResolver } from '../task/output-reference-resolver.js'; // Mock dependencies vi.mock('../file-collection-manager.js'); vi.mock('../task/output-reference-resolver.js'); describe('TemplateRenderer', () => { let renderer; const basePath = '/test/base/path'; const context = { variable: 'value' }; let mockFileCollectionManagerInstance; let mockOutputReferenceResolverInstance; beforeEach(() => { // Create mock instances mockFileCollectionManagerInstance = { loadAndRenderFiles: vi.fn(), getFiles: vi.fn(), readFileFromCollection: vi.fn(), hasCollection: vi.fn().mockReturnValue(true) }; mockOutputReferenceResolverInstance = { resolveReference: vi.fn(), }; // Instantiate TemplateRenderer with mock instances renderer = new TemplateRenderer( context, basePath, mockOutputReferenceResolverInstance, mockFileCollectionManagerInstance ); }); describe('constructor', () => { test('initializes with context, basePath, resolver, and manager', () => { expect(renderer.context).toBe(context); expect(renderer.basePath).toBe(basePath); expect(renderer.referenceResolver).toBe(mockOutputReferenceResolverInstance); expect(renderer.fileCollectionManager).toBe(mockFileCollectionManagerInstance); }); }); describe('render', () => { beforeEach(() => { mockFileCollectionManagerInstance.hasCollection.mockImplementation( name => name === 'test' ); mockFileCollectionManagerInstance.getFiles.mockImplementation((name, pattern) => { if (name !== 'test') return []; if (!pattern) return ['file1.js', 'file2.js']; if (pattern === '*.js') return ['file1.js']; return []; }); mockFileCollectionManagerInstance.readFileFromCollection.mockImplementation(async (collectionName, filePath) => { if (collectionName === 'test' && filePath === 'file1.js') return 'content1'; if (collectionName === 'test' && filePath === 'file2.js') return 'content2'; throw new Error(`Mock readFileFromCollection: Unknown file ${collectionName}/${filePath}`); }); mockOutputReferenceResolverInstance.resolveReference.mockImplementation((ref) => { if (ref === 'task.output') return 'output_value'; throw new Error(`Mock resolveReference: Unknown reference ${ref}`); }); }); test('renders collection references', async () => { mockFileCollectionManagerInstance.loadAndRenderFiles.mockResolvedValue('content1\\ncontent2'); const template = 'Files: {{files.test}}'; const result = await renderer.render(template); expect(result).toBe('Files: content1\\ncontent2'); expect(mockFileCollectionManagerInstance.loadAndRenderFiles).toHaveBeenCalledWith('test'); }); test('renders context variables', async () => { const template = 'Value: {{variable}}'; const result = await renderer.render(template); expect(result).toBe('Value: value'); }); test('renders output references', async () => { const template = 'Output: {{task.output}}'; const result = await renderer.render(template); expect(result).toBe('Output: output_value'); expect(mockOutputReferenceResolverInstance.resolveReference).toHaveBeenCalledWith('task.output'); }); test('preserves unknown placeholders (non-collection, non-output, non-context)', async () => { const template = 'Keep: {{unknown.ref}}'; const result = await renderer.render(template); // Expect empty string for unresolved variables expect(result).toBe('Keep: '); }); test('handles empty collection file list', async () => { mockFileCollectionManagerInstance.loadAndRenderFiles.mockResolvedValue(''); const template = 'Empty: {{files.test}}'; const result = await renderer.render(template); expect(result).toBe('Empty: '); expect(mockFileCollectionManagerInstance.loadAndRenderFiles).toHaveBeenCalledWith('test'); }); test('handles error during file collection loading', async () => { const collectionError = new Error("Test loadAndRenderFiles error"); mockFileCollectionManagerInstance.loadAndRenderFiles.mockRejectedValue(collectionError); const template = 'Error: {{files.test}}'; const result = await renderer.render(template); expect(result).toBe(`Error: [Error: ${collectionError.message}]`); expect(mockFileCollectionManagerInstance.loadAndRenderFiles).toHaveBeenCalledWith('test'); }); test('handles error during output reference resolution', async () => { mockOutputReferenceResolverInstance.resolveReference.mockImplementation(() => { throw new Error('Test output resolve error'); }); const template = 'Output Error: {{task.output}}'; const result = await renderer.render(template); expect(result).toBe('Output Error: [Error: Test output resolve error]'); }); test('handles collection errors gracefully', async () => { const collectionError = new Error("Test loadAndRenderFiles error"); mockFileCollectionManagerInstance.loadAndRenderFiles.mockRejectedValue(collectionError); const template = 'Error: {{files.test}}'; const result = await renderer.render(template); expect(result).toBe(`Error: [Error: ${collectionError.message}]`); expect(mockFileCollectionManagerInstance.loadAndRenderFiles).toHaveBeenCalledWith('test'); }); }); });