diff_test.gno

4.53 Kb · 183 lines
  1package diff
  2
  3import (
  4	"strings"
  5	"testing"
  6)
  7
  8func TestMyersDiff(t *testing.T) {
  9	tests := []struct {
 10		name     string
 11		old      string
 12		new      string
 13		expected string
 14	}{
 15		{
 16			name:     "No difference",
 17			old:      "abc",
 18			new:      "abc",
 19			expected: "abc",
 20		},
 21		{
 22			name:     "Simple insertion",
 23			old:      "ac",
 24			new:      "abc",
 25			expected: "a[+b]c",
 26		},
 27		{
 28			name:     "Simple deletion",
 29			old:      "abc",
 30			new:      "ac",
 31			expected: "a[-b]c",
 32		},
 33		{
 34			name:     "Simple substitution",
 35			old:      "abc",
 36			new:      "abd",
 37			expected: "ab[-c][+d]",
 38		},
 39		{
 40			name:     "Multiple changes",
 41			old:      "The quick brown fox jumps over the lazy dog",
 42			new:      "The quick brown cat jumps over the lazy dog",
 43			expected: "The quick brown [-fox][+cat] jumps over the lazy dog",
 44		},
 45		{
 46			name:     "Prefix and suffix",
 47			old:      "Hello, world!",
 48			new:      "Hello, beautiful world!",
 49			expected: "Hello, [+beautiful ]world!",
 50		},
 51		{
 52			name:     "Complete change",
 53			old:      "abcdef",
 54			new:      "ghijkl",
 55			expected: "[-abcdef][+ghijkl]",
 56		},
 57		{
 58			name:     "Empty strings",
 59			old:      "",
 60			new:      "",
 61			expected: "",
 62		},
 63		{
 64			name:     "Old empty",
 65			old:      "",
 66			new:      "abc",
 67			expected: "[+abc]",
 68		},
 69		{
 70			name:     "New empty",
 71			old:      "abc",
 72			new:      "",
 73			expected: "[-abc]",
 74		},
 75		{
 76			name:     "non-ascii (Korean characters)",
 77			old:      "ASCII 문자가 아닌 것도 되나?",
 78			new:      "ASCII 문자가 아닌 것도 됨.",
 79			expected: "ASCII 문자가 아닌 것도 [-되나?][+됨.]",
 80		},
 81		{
 82			name:     "Emoji diff",
 83			old:      "Hello 👋 World 🌍",
 84			new:      "Hello 👋 Beautiful 🌸 World 🌍",
 85			expected: "Hello 👋 [+Beautiful 🌸 ]World 🌍",
 86		},
 87		{
 88			name:     "Mixed multibyte and ASCII",
 89			old:      "こんにちは World",
 90			new:      "こんばんは World",
 91			expected: "こん[-にち][+ばん]は World",
 92		},
 93		{
 94			name:     "Chinese characters",
 95			old:      "我喜欢编程",
 96			new:      "我喜欢看书和编程",
 97			expected: "我喜欢[+看书和]编程",
 98		},
 99		{
100			name:     "Combining characters",
101			old:      "e\u0301", // é (e + ´)
102			new:      "e\u0300", // è (e + `)
103			expected: "e[-\u0301][+\u0300]",
104		},
105		{
106			name:     "Right-to-Left languages",
107			old:      "שלום",
108			new:      "שלום עולם",
109			expected: "שלום[+ עולם]",
110		},
111		{
112			name:     "Normalization NFC and NFD",
113			old:      "e\u0301", // NFD (decomposed)
114			new:      "\u00e9",  // NFC (precomposed)
115			expected: "[-e\u0301][+\u00e9]",
116		},
117		{
118			name:     "Case sensitivity",
119			old:      "abc",
120			new:      "Abc",
121			expected: "[-a][+A]bc",
122		},
123		{
124			name:     "Surrogate pairs",
125			old:      "Hello 🌍",
126			new:      "Hello 🌎",
127			expected: "Hello [-🌍][+🌎]",
128		},
129		{
130			name:     "Control characters",
131			old:      "Line1\nLine2",
132			new:      "Line1\r\nLine2",
133			expected: "Line1[+\r]\nLine2",
134		},
135		{
136			name:     "Mixed scripts",
137			old:      "Hello नमस्ते こんにちは",
138			new:      "Hello สวัสดี こんにちは",
139			expected: "Hello [-नमस्ते][+สวัสดี] こんにちは",
140		},
141		{
142			name:     "Unicode normalization",
143			old:      "é",       // U+00E9 (precomposed)
144			new:      "e\u0301", // U+0065 U+0301 (decomposed)
145			expected: "[-é][+e\u0301]",
146		},
147		{
148			name:     "Directional marks",
149			old:      "Hello\u200Eworld", // LTR mark
150			new:      "Hello\u200Fworld", // RTL mark
151			expected: "Hello[-\u200E][+\u200F]world",
152		},
153		{
154			name:     "Zero-width characters",
155			old:      "ab\u200Bc", // Zero-width space
156			new:      "abc",
157			expected: "ab[-\u200B]c",
158		},
159		{
160			name:     "Worst-case scenario (completely different strings)",
161			old:      strings.Repeat("a", 1000),
162			new:      strings.Repeat("b", 1000),
163			expected: "[-" + strings.Repeat("a", 1000) + "][+" + strings.Repeat("b", 1000) + "]",
164		},
165		//{ // disabled for testing performance
166		// XXX: consider adding a flag to run such tests, not like `-short`, or switching to a `-bench`, maybe.
167		//	name:     "Very long strings",
168		//	old:      strings.Repeat("a", 10000) + "b" + strings.Repeat("a", 10000),
169		//	new:      strings.Repeat("a", 10000) + "c" + strings.Repeat("a", 10000),
170		//	expected: strings.Repeat("a", 10000) + "[-b][+c]" + strings.Repeat("a", 10000),
171		//},
172	}
173
174	for _, tc := range tests {
175		t.Run(tc.name, func(t *testing.T) {
176			diff := MyersDiff(tc.old, tc.new)
177			result := Format(diff)
178			if result != tc.expected {
179				t.Errorf("Expected: %s, got: %s", tc.expected, result)
180			}
181		})
182	}
183}