UNPKG

meld

Version:

Meld: A template language for LLM prompts

119 lines (97 loc) 3.51 kB
import { describe, it, expect, beforeEach } from 'vitest'; import { CircularityService } from './CircularityService.js'; import { MeldImportError } from '@core/errors/MeldImportError.js'; describe('CircularityService', () => { let service: CircularityService; beforeEach(() => { service = new CircularityService(); }); describe('Basic import tracking', () => { it('should track imports in stack', () => { service.beginImport('fileA.meld'); expect(service.isInStack('fileA.meld')).toBe(true); expect(service.getImportStack()).toEqual(['fileA.meld']); }); it('should remove imports from stack', () => { service.beginImport('fileA.meld'); service.endImport('fileA.meld'); expect(service.isInStack('fileA.meld')).toBe(false); expect(service.getImportStack()).toEqual([]); }); it('should handle multiple imports in LIFO order', () => { service.beginImport('fileA.meld'); service.beginImport('fileB.meld'); service.beginImport('fileC.meld'); expect(service.getImportStack()).toEqual([ 'fileA.meld', 'fileB.meld', 'fileC.meld' ]); service.endImport('fileC.meld'); expect(service.getImportStack()).toEqual([ 'fileA.meld', 'fileB.meld' ]); }); }); describe('Circular import detection', () => { it('should detect direct circular imports', () => { service.beginImport('fileA.meld'); expect(() => service.beginImport('fileA.meld')) .toThrow(MeldImportError); }); it('should detect indirect circular imports', () => { service.beginImport('fileA.meld'); service.beginImport('fileB.meld'); expect(() => service.beginImport('fileA.meld')) .toThrow(MeldImportError); }); it('should include import chain in error', () => { service.beginImport('fileA.meld'); service.beginImport('fileB.meld'); try { service.beginImport('fileA.meld'); fail('Should have thrown'); } catch (error) { expect(error).toBeInstanceOf(MeldImportError); if (error instanceof MeldImportError) { expect(error.details?.importChain).toEqual([ 'fileA.meld', 'fileB.meld', 'fileA.meld' ]); } } }); it('should allow reimporting after file is removed from stack', () => { service.beginImport('fileA.meld'); service.endImport('fileA.meld'); expect(() => service.beginImport('fileA.meld')) .not.toThrow(); }); }); describe('Stack management', () => { it('should reset the stack', () => { service.beginImport('fileA.meld'); service.beginImport('fileB.meld'); service.reset(); expect(service.getImportStack()).toEqual([]); expect(service.isInStack('fileA.meld')).toBe(false); expect(service.isInStack('fileB.meld')).toBe(false); }); it('should handle ending import for file not in stack', () => { expect(() => service.endImport('nonexistent.meld')) .not.toThrow(); }); it('should maintain stack order when ending imports out of order', () => { service.beginImport('fileA.meld'); service.beginImport('fileB.meld'); service.beginImport('fileC.meld'); service.endImport('fileB.meld'); expect(service.getImportStack()).toEqual([ 'fileA.meld', 'fileC.meld' ]); }); }); });