UNPKG

meld

Version:

Meld: A template language for LLM prompts

133 lines (116 loc) 4.33 kB
import { describe, it, expect, beforeEach } from 'vitest'; import { ContentResolver } from './ContentResolver.js'; import type { MeldNode, TextNode, CodeFenceNode, CommentNode, DirectiveNode } from 'meld-spec'; import { createMockStateService } from '@tests/utils/testFactories.js'; import { ResolutionContext } from '@services/resolution/ResolutionService/IResolutionService.js'; describe('ContentResolver', () => { let resolver: ContentResolver; let stateService: ReturnType<typeof createMockStateService>; let context: ResolutionContext; beforeEach(() => { stateService = createMockStateService(); resolver = new ContentResolver(stateService); context = { allowedVariableTypes: { text: true, data: true, path: true, command: true }, currentFilePath: '', state: stateService }; }); it('should preserve text content exactly as is', async () => { const nodes: MeldNode[] = [{ type: 'Text', content: ' Hello world \n with spaces ', location: { start: { line: 1, column: 1 }, end: { line: 2, column: 13 } } } as TextNode]; const result = await resolver.resolve(nodes, context); expect(result).toBe(' Hello world \n with spaces '); }); it('should preserve code blocks exactly as is', async () => { const nodes: MeldNode[] = [{ type: 'CodeFence', content: '```typescript\n const x = 42;\n console.log(x);\n```', language: 'typescript', location: { start: { line: 1, column: 1 }, end: { line: 4, column: 1 } } } as CodeFenceNode]; const result = await resolver.resolve(nodes, context); expect(result).toBe('```typescript\n const x = 42;\n console.log(x);\n```'); }); it('should skip comments while preserving surrounding whitespace', async () => { const nodes: MeldNode[] = [ { type: 'Text', content: 'Before ', location: { start: { line: 1, column: 1 }, end: { line: 1, column: 8 } } } as TextNode, { type: 'Comment', content: 'This is a comment', location: { start: { line: 1, column: 9 }, end: { line: 1, column: 25 } } } as CommentNode, { type: 'Text', content: ' After', location: { start: { line: 1, column: 26 }, end: { line: 1, column: 33 } } } as TextNode ]; const result = await resolver.resolve(nodes, context); expect(result).toBe('Before After'); }); it('should preserve whitespace in mixed content', async () => { const nodes: MeldNode[] = [ { type: 'Text', content: 'Text before\n\n', location: { start: { line: 1, column: 1 }, end: { line: 3, column: 1 } } } as TextNode, { type: 'CodeFence', content: '```typescript\nconsole.log("test");\n```', language: 'typescript', location: { start: { line: 3, column: 1 }, end: { line: 5, column: 1 } } } as CodeFenceNode, { type: 'Comment', content: 'Skip this comment', location: { start: { line: 5, column: 1 }, end: { line: 5, column: 17 } } } as CommentNode, { type: 'Text', content: '\n\nText after', location: { start: { line: 5, column: 18 }, end: { line: 7, column: 10 } } } as TextNode ]; const result = await resolver.resolve(nodes, context); expect(result).toBe('Text before\n\n```typescript\nconsole.log("test");\n```\n\nText after'); }); it('should skip directive nodes while preserving surrounding whitespace', async () => { const nodes: MeldNode[] = [ { type: 'Text', content: 'Before ', location: { start: { line: 1, column: 1 }, end: { line: 1, column: 8 } } } as TextNode, { type: 'Directive', directive: { kind: 'text' as const, identifier: 'test', value: 'value' }, location: { start: { line: 1, column: 9 }, end: { line: 1, column: 28 } } } as DirectiveNode, { type: 'Text', content: ' After', location: { start: { line: 1, column: 29 }, end: { line: 1, column: 36 } } } as TextNode ]; const result = await resolver.resolve(nodes, context); expect(result).toBe('Before After'); }); });