cmte
Version:
Design by Committee™ except it's just you and LLMs
193 lines (172 loc) • 5.82 kB
text/typescript
import { describe, it, expect } from 'vitest';
import { PathResolver } from '../PathResolver';
import { ValidationError } from '../errors';
import { IterationContext } from '../types';
describe('PathResolver', () => {
describe('parsePath', () => {
it('should parse simple paths', () => {
const result = PathResolver.parsePath('phase1.set1.output');
expect(result).toEqual([
{ name: 'phase1', choice: null, isAll: false },
{ name: 'set1', choice: null, isAll: false },
{ name: 'output', choice: null, isAll: false }
]);
});
it('should handle $ prefix', () => {
const result = PathResolver.parsePath('$phase1.set1.output');
expect(result).toEqual([
{ name: 'phase1', choice: null, isAll: false },
{ name: 'set1', choice: null, isAll: false },
{ name: 'output', choice: null, isAll: false }
]);
});
it('should parse paths with choices', () => {
const result = PathResolver.parsePath('phase1.set1[auth].output');
expect(result).toEqual([
{ name: 'phase1', choice: null, isAll: false },
{ name: 'set1', choice: 'auth', isAll: false },
{ name: 'output', choice: null, isAll: false }
]);
});
it('should parse paths with $this choices', () => {
const result = PathResolver.parsePath('phase1.set1[$this].output');
expect(result).toEqual([
{ name: 'phase1', choice: null, isAll: false },
{ name: 'set1', choice: '$this', isAll: false },
{ name: 'output', choice: null, isAll: false }
]);
});
it('should handle all keyword', () => {
const result = PathResolver.parsePath('phase1.set1.all');
expect(result).toEqual([
{ name: 'phase1', choice: null, isAll: false },
{ name: 'set1', choice: null, isAll: false },
{ name: 'all', choice: null, isAll: true }
]);
});
it('should throw on invalid path segments', () => {
expect(() => {
PathResolver.parsePath('phase1.set1[].output');
}).toThrow(ValidationError);
expect(() => {
PathResolver.parsePath('phase1.set1[invalid[.output');
}).toThrow(ValidationError);
});
});
describe('resolveChoice', () => {
const context: IterationContext = {
currentIteration: 'auth',
parentIterations: ['services']
};
const objectsForIteration = {
services: {
auth: { code: 'auth.ts' },
user: { code: 'user.ts' }
},
set1: {
auth: { output: 'auth-result' },
user: { output: 'user-result' }
}
};
it('should resolve $this to current iteration', () => {
const segment = { name: 'services', choice: '$this', isAll: false };
const result = PathResolver.resolveChoice(
segment,
context,
objectsForIteration
);
expect(result).toBe('auth');
});
it('should throw when using $this outside iteration context', () => {
const segment = { name: 'services', choice: '$this', isAll: false };
expect(() => {
PathResolver.resolveChoice(segment, {}, objectsForIteration);
}).toThrow(ValidationError);
});
it('should validate choices against objectsForIteration', () => {
const segment = { name: 'services', choice: 'invalid', isAll: false };
expect(() => {
PathResolver.resolveChoice(segment, context, objectsForIteration);
}).toThrow(ValidationError);
});
it('should return empty string for no choice', () => {
const segment = { name: 'services', choice: null, isAll: false };
const result = PathResolver.resolveChoice(
segment,
context,
objectsForIteration
);
expect(result).toBe('');
});
});
describe('walkPath', () => {
const root = {
set1: {
auth: { output: 'auth-result' },
user: { output: 'user-result' }
},
set2: {
output: 'direct-result'
}
};
const context: IterationContext = {
currentIteration: 'auth',
parentIterations: ['services']
};
const objectsForIteration = {
services: {
auth: { code: 'auth.ts' },
user: { code: 'user.ts' }
},
set1: {
auth: { output: 'auth-result' },
user: { output: 'user-result' }
}
};
it('should walk simple paths', () => {
const segments = PathResolver.parsePath('set2.output');
const result = PathResolver.walkPath(
root,
segments,
context,
objectsForIteration
);
expect(result).toBe('direct-result');
});
it('should walk paths with choices', () => {
const segments = PathResolver.parsePath('set1[auth].output');
const result = PathResolver.walkPath(
root,
segments,
context,
objectsForIteration
);
expect(result).toBe('auth-result');
});
it('should handle all keyword', () => {
const segments = PathResolver.parsePath('set1.all');
const result = PathResolver.walkPath(
root,
segments,
context,
objectsForIteration
);
expect(result).toEqual([
{ output: 'auth-result' },
{ output: 'user-result' }
]);
});
it('should throw on invalid path segments', () => {
const segments = PathResolver.parsePath('invalid.output');
expect(() => {
PathResolver.walkPath(root, segments, context, objectsForIteration);
}).toThrow(ValidationError);
});
it('should throw on invalid choices', () => {
const segments = PathResolver.parsePath('set1[invalid].output');
expect(() => {
PathResolver.walkPath(root, segments, context, objectsForIteration);
}).toThrow(ValidationError);
});
});
});