Ver Fonte

test(editor): restore typing → split → typing → undo integration test lost during rebase conflict resolution

Zander Hawke há 3 dias atrás
pai
commit
94fbb8f181

+ 70 - 0
packages/editor/src/components/__tests__/editor-integration.test.ts

@@ -256,6 +256,76 @@ describe("content-change-op coalescing", () => {
     expect(history.canUndo).toBe(true)
     expect(history.undo()).not.toBeNull()
   })
+
+  it("typing → split → typing → undo cycles through operations correctly", () => {
+    const history = createOperationHistory()
+    const COALESCE_MS = 500
+
+    function handleContentOp(op: {
+      blockId: string
+      previousContent: string
+      newContent: string
+      timestamp: number
+    }) {
+      const last = history.peek()
+      if (
+        last?.type === "set-block-content" &&
+        last.blockId === op.blockId &&
+        op.timestamp - last.timestamp < COALESCE_MS
+      ) {
+        ;(last as SetBlockContentOp).newContent = op.newContent
+        last.timestamp = op.timestamp
+      } else {
+        void history.execute({
+          type: "set-block-content",
+          blockId: op.blockId,
+          previousContent: op.previousContent,
+          newContent: op.newContent,
+          timestamp: op.timestamp,
+        })
+      }
+    }
+
+    // 1. Type "hello" in block A
+    handleContentOp({ blockId: "a", previousContent: "", newContent: "hello", timestamp: 1000 })
+
+    // 2. Split at index 0 (creates block B with "world")
+    history.execute({
+      type: "split-block",
+      index: 0,
+      splitBlockId: "b",
+      depth: 0,
+      beforeContent: "hello",
+      afterContent: "world",
+      timestamp: 2000,
+    })
+
+    // 3. Type " test" in block B
+    handleContentOp({ blockId: "b", previousContent: "", newContent: " test", timestamp: 2100 })
+
+    // Step 3 undo — revert block B typing
+    const undo1 = history.undo()
+    expect(undo1).not.toBeNull()
+    expect(undo1!.type).toBe("set-block-content")
+    expect((undo1 as SetBlockContentOp).blockId).toBe("b")
+    expect((undo1 as SetBlockContentOp).newContent).toBe("")
+    expect(history.canUndo).toBe(true)
+
+    // Step 2 undo — revert the split (merge block B back into block A)
+    const undo2 = history.undo()
+    expect(undo2).not.toBeNull()
+    expect(undo2!.type).toBe("merge-block")
+    expect(history.canUndo).toBe(true)
+
+    // Step 1 undo — revert block A typing
+    const undo3 = history.undo()
+    expect(undo3).not.toBeNull()
+    expect(undo3!.type).toBe("set-block-content")
+    expect((undo3 as SetBlockContentOp).blockId).toBe("a")
+    expect((undo3 as SetBlockContentOp).newContent).toBe("")
+    expect(history.canUndo).toBe(false)
+    expect(history.undo()).toBeNull()
+  })
 })
 
 describe("paste handling", () => {