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}