test(session): preserve surface boundary coverage
This commit is contained in:
@@ -30,6 +30,28 @@ function provenanceEvent(seq: number, sourceEventSeqs: unknown): SessionEvent {
|
|||||||
} as unknown as SessionEvent
|
} as unknown as SessionEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toolResultEvent(
|
||||||
|
seq: number,
|
||||||
|
callId: string,
|
||||||
|
surfaceOp: SurfaceEvent['surfaceOp'] = 'append',
|
||||||
|
sourceEventSeqs?: number[],
|
||||||
|
): SessionEvent {
|
||||||
|
return {
|
||||||
|
type: 'tool/result',
|
||||||
|
seq,
|
||||||
|
time: seq,
|
||||||
|
data: {
|
||||||
|
turn: 1,
|
||||||
|
step: 1,
|
||||||
|
callId: CallId(callId),
|
||||||
|
content: [{ type: 'text', text: `result ${seq}` }],
|
||||||
|
isError: false,
|
||||||
|
},
|
||||||
|
surfaceOp,
|
||||||
|
...sourceEventSeqs === undefined ? {} : { sourceEventSeqs },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
describe('foldSurface provenance', () => {
|
describe('foldSurface provenance', () => {
|
||||||
it('accepts absent or valid provenance and complete replacement coverage', () => {
|
it('accepts absent or valid provenance and complete replacement coverage', () => {
|
||||||
const events = [
|
const events = [
|
||||||
@@ -94,6 +116,33 @@ describe('foldSurface provenance', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('foldSurface tool-result rewrites', () => {
|
||||||
|
it('rejects a replacement spanning multiple current nodes', () => {
|
||||||
|
const events = [
|
||||||
|
provenanceEvent(0, undefined),
|
||||||
|
provenanceEvent(1, undefined),
|
||||||
|
toolResultEvent(2, 'rewrite', { op: 'replace', start: 0, end: 1 }, [0, 1]),
|
||||||
|
]
|
||||||
|
expect(() => foldSurface(events)).toThrow(/must rewrite exactly one current node/)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('rejects a replacement targeting a non-result node', () => {
|
||||||
|
const events = [
|
||||||
|
provenanceEvent(0, undefined),
|
||||||
|
toolResultEvent(1, 'rewrite', { op: 'replace', start: 0, end: 0 }, [0]),
|
||||||
|
]
|
||||||
|
expect(() => foldSurface(events)).toThrow(/must target a current tool\/result/)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('rejects changes outside tool-result content', () => {
|
||||||
|
const events = [
|
||||||
|
toolResultEvent(0, 'original'),
|
||||||
|
toolResultEvent(1, 'changed', { op: 'replace', start: 0, end: 0 }, [0]),
|
||||||
|
]
|
||||||
|
expect(() => foldSurface(events)).toThrow(/may change only content/)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('SurfaceManager', () => {
|
describe('SurfaceManager', () => {
|
||||||
it('shares ordered entries and nested replacement ranges with foldSurface', () => {
|
it('shares ordered entries and nested replacement ranges with foldSurface', () => {
|
||||||
const s = new Session(SessionId('shared-fold'))
|
const s = new Session(SessionId('shared-fold'))
|
||||||
|
|||||||
Reference in New Issue
Block a user