Przeglądaj źródła

test(session): preserve surface boundary coverage

Tianyi Cui 2 miesięcy temu
rodzic
commit
0234a01ac9
1 zmienionych plików z 49 dodań i 0 usunięć
  1. 49 0
      packages/core/session/tests/surface.spec.ts

+ 49 - 0
packages/core/session/tests/surface.spec.ts

@@ -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'))