1package wiki23import (4 "strings"5 "testing"67 "gno.land/p/nt/uassert/v0"8)910// render turns a diff into the compact "+a -b =c" form the tests assert on.11func render(lines []DiffLine) string {12 var b strings.Builder13 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}2728func TestDiffLines(t *testing.T) {29 cases := []struct {30 name string31 old, new string32 want string33 }{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}5051func 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}5758// TestDiffCommonPrefixKeepsLongArticlesExact is the property that makes the59// DiffMaxLines bound usable in practice: a one-line edit to a 500-line article60// still diffs exactly, because only the changed region is fed to the LCS.61func TestDiffCommonPrefixKeepsLongArticlesExact(t *testing.T) {62 var b strings.Builder63 for i := 0; i < 500; i++ {64 b.WriteString("line\n")65 }66 old := b.String()67 updated := old + "added\n"6869 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}7576// TestDiffDegradesInsteadOfBlowingTheGasBudget locks the documented fallback:77// past DiffMaxLines the diff becomes a block replacement rather than an78// unrenderable page.79func TestDiffDegradesInsteadOfBlowingTheGasBudget(t *testing.T) {80 var a, b strings.Builder81 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}91Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.