diff_test.gno
2.51 Kb · 90 lines
1package wiki
2
3import (
4 "strings"
5 "testing"
6
7 "gno.land/p/nt/uassert/v0"
8)
9
10// render turns a diff into the compact "+a -b =c" form the tests assert on.
11func render(lines []DiffLine) string {
12 var b strings.Builder
13 for _, l := range lines {
14 switch l.Op {
15 case OpInsert:
16 b.WriteString("+")
17 case OpDelete:
18 b.WriteString("-")
19 default:
20 b.WriteString("=")
21 }
22 b.WriteString(l.Text)
23 b.WriteString(";")
24 }
25 return b.String()
26}
27
28func TestDiffLines(t *testing.T) {
29 cases := []struct {
30 name string
31 old, new string
32 want string
33 }{
34 {"identical", "a\nb\n", "a\nb\n", "=a;=b;"},
35 {"append", "a\n", "a\nb\n", "=a;+b;"},
36 {"prepend", "b\n", "a\nb\n", "+a;=b;"},
37 {"delete", "a\nb\n", "a\n", "=a;-b;"},
38 {"replace middle", "a\nb\nc\n", "a\nx\nc\n", "=a;-b;+x;=c;"},
39 {"from empty", "", "a\n", "+a;"},
40 {"to empty", "a\n", "", "-a;"},
41 {"both empty", "", "", ""},
42 {"no trailing newline", "a\nb", "a\nc", "=a;-b;+c;"},
43 }
44 for _, tc := range cases {
45 got, exact := DiffLines(tc.old, tc.new)
46 uassert.True(t, exact, tc.name+" must be exact")
47 uassert.Equal(t, tc.want, render(got), tc.name)
48 }
49}
50
51func TestDiffStat(t *testing.T) {
52 lines, _ := DiffLines("a\nb\nc\n", "a\nx\ny\nc\n")
53 added, removed := DiffStat(lines)
54 uassert.Equal(t, 2, added)
55 uassert.Equal(t, 1, removed)
56}
57
58// TestDiffCommonPrefixKeepsLongArticlesExact is the property that makes the
59// DiffMaxLines bound usable in practice: a one-line edit to a 500-line article
60// still diffs exactly, because only the changed region is fed to the LCS.
61func TestDiffCommonPrefixKeepsLongArticlesExact(t *testing.T) {
62 var b strings.Builder
63 for i := 0; i < 500; i++ {
64 b.WriteString("line\n")
65 }
66 old := b.String()
67 updated := old + "added\n"
68
69 lines, exact := DiffLines(old, updated)
70 uassert.True(t, exact, "a one-line change to a 500-line article must diff exactly")
71 added, removed := DiffStat(lines)
72 uassert.Equal(t, 1, added)
73 uassert.Equal(t, 0, removed)
74}
75
76// TestDiffDegradesInsteadOfBlowingTheGasBudget locks the documented fallback:
77// past DiffMaxLines the diff becomes a block replacement rather than an
78// unrenderable page.
79func TestDiffDegradesInsteadOfBlowingTheGasBudget(t *testing.T) {
80 var a, b strings.Builder
81 for i := 0; i < DiffMaxLines+1; i++ {
82 a.WriteString("old\n")
83 b.WriteString("new\n")
84 }
85 lines, exact := DiffLines(a.String(), b.String())
86 uassert.False(t, exact, "past the bound the diff must report itself inexact")
87 added, removed := DiffStat(lines)
88 uassert.Equal(t, DiffMaxLines+1, added)
89 uassert.Equal(t, DiffMaxLines+1, removed)
90}