mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-10-26 22:37:03 +00:00
0cc033edd8
POST /workspaces/{ws}/items/{ref}/patch {edits:[{old,new,line_hint?}],
expected_seq?} replaces exact text in the body. It runs through updateItem,
so it takes every PATCH guard; the body is computed inside the store
transaction from the row it replaces. Each old must occur exactly once;
edits apply in order, all or nothing; every patch writes a version. The
answer carries a unified diff of what changed.
expected_seq does not refuse: a moved seq is applied over when the
anchors still match, and answered rebased with the intervening writes,
read from a seq chain stamped into item activity entries ({prev_seq, seq,
version_id}). complete is decided at runtime, so any write that left no
stamp reads incomplete; a guard test classifies every seq-moving store
statement. Refusals write nothing: patch_anchor_missing,
patch_anchor_ambiguous, patch_room_open (an open editor; step 2).
CLI: pad item patch, pad item show --lines. MCP 0.87 (additive):
pad_item.patch, get lines, three allow-listed codes. The timeline treats
the chain and patch keys as bookkeeping, not a change.
Claude-Session: https://claude.ai/code/session_01Q9WssCjFuHjSfLABoW4tmS
28 lines
993 B
Go
28 lines
993 B
Go
package diff
|
|
|
|
import "testing"
|
|
|
|
func TestUnified(t *testing.T) {
|
|
for _, c := range []struct{ name, a, b, want string }{
|
|
{"equal", "x\n", "x\n", ""},
|
|
{"one line changed in the middle",
|
|
"1\n2\n3\n4\n5\n6\n7\n8\n9\n", "1\n2\n3\n4\nFIVE\n6\n7\n8\n9\n",
|
|
"--- before\n+++ after\n@@ -2,7 +2,7 @@\n 2\n 3\n 4\n-5\n+FIVE\n 6\n 7\n 8\n"},
|
|
{"insert at start",
|
|
"a\nb\n", "z\na\nb\n",
|
|
"--- before\n+++ after\n@@ -1,2 +1,3 @@\n+z\n a\n b\n"},
|
|
{"two far changes make two hunks",
|
|
"1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n", "ONE\n2\n3\n4\n5\n6\n7\n8\n9\nTEN\n",
|
|
"--- before\n+++ after\n@@ -1,4 +1,4 @@\n-1\n+ONE\n 2\n 3\n 4\n@@ -7,4 +7,4 @@\n 7\n 8\n 9\n-10\n+TEN\n"},
|
|
{"no trailing newline",
|
|
"a\nb", "a\nc",
|
|
"--- before\n+++ after\n@@ -1,2 +1,2 @@\n a\n-b\n\\ No newline at end of file\n+c\n\\ No newline at end of file\n"},
|
|
} {
|
|
t.Run(c.name, func(t *testing.T) {
|
|
if got := Unified(c.a, c.b, 3); got != c.want {
|
|
t.Fatalf("got:\n%s\nwant:\n%s", got, c.want)
|
|
}
|
|
})
|
|
}
|
|
}
|