Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

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}