1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.merge;
12
13 import static java.nio.charset.StandardCharsets.UTF_8;
14 import static org.junit.Assert.assertEquals;
15
16 import java.io.ByteArrayOutputStream;
17 import java.io.IOException;
18
19 import org.eclipse.jgit.diff.RawText;
20 import org.eclipse.jgit.diff.RawTextComparator;
21 import org.eclipse.jgit.lib.Constants;
22 import org.junit.Assume;
23 import org.junit.Test;
24 import org.junit.experimental.theories.DataPoints;
25 import org.junit.experimental.theories.Theories;
26 import org.junit.runner.RunWith;
27
28 @RunWith(Theories.class)
29 public class MergeAlgorithmTest {
30 MergeFormatter fmt=new MergeFormatter();
31
32 private final boolean newlineAtEnd;
33
34 @DataPoints
35 public static boolean[] newlineAtEndDataPoints = { false, true };
36
37 public MergeAlgorithmTest(boolean newlineAtEnd) {
38 this.newlineAtEnd = newlineAtEnd;
39 }
40
41
42
43
44
45
46
47 @Test
48 public void testTwoConflictingModifications() throws IOException {
49 assertEquals(t("a<b=Z>Zdefghij"),
50 merge("abcdefghij", "abZdefghij", "aZZdefghij"));
51 }
52
53
54
55
56
57
58
59
60 @Test
61 public void testOneAgainstTwoConflictingModifications() throws IOException {
62 assertEquals(t("aZ<Z=c>Zefghij"),
63 merge("abcdefghij", "aZZZefghij", "aZcZefghij"));
64 }
65
66
67
68
69
70
71
72 @Test
73 public void testNoAgainstOneModification() throws IOException {
74 assertEquals(t("aZcZefghij"),
75 merge("abcdefghij", "abcdefghij", "aZcZefghij"));
76 }
77
78
79
80
81
82
83
84 @Test
85 public void testTwoNonConflictingModifications() throws IOException {
86 assertEquals(t("YbZdefghij"),
87 merge("abcdefghij", "abZdefghij", "Ybcdefghij"));
88 }
89
90
91
92
93
94
95
96 @Test
97 public void testTwoComplicatedModifications() throws IOException {
98 assertEquals(t("a<ZZZZfZhZj=bYdYYYYiY>"),
99 merge("abcdefghij", "aZZZZfZhZj", "abYdYYYYiY"));
100 }
101
102
103
104
105
106
107
108
109 @Test
110 public void testTwoModificationsWithSharedDelete() throws IOException {
111 assertEquals(t("Cb}n}"),
112 merge("ab}n}n}", "ab}n}", "Cb}n}"));
113 }
114
115
116
117
118
119
120
121
122 @Test
123 public void testModificationsWithMiddleInsert() throws IOException {
124 assertEquals(t("aBcd123123uvwxPq"),
125 merge("abcd123uvwxpq", "aBcd123123uvwxPq", "abcd123123uvwxpq"));
126 }
127
128
129
130
131
132
133
134
135 @Test
136 public void testModificationsWithMiddleDelete() throws IOException {
137 assertEquals(t("Abz}z123Q"),
138 merge("abz}z}z123q", "Abz}z123Q", "abz}z123q"));
139 }
140
141
142
143
144
145
146 @Test
147 public void testConflictAtStart() throws IOException {
148 assertEquals(t("<Z=Y>bcdefghij"),
149 merge("abcdefghij", "Zbcdefghij", "Ybcdefghij"));
150 }
151
152
153
154
155
156
157 @Test
158 public void testConflictAtEnd() throws IOException {
159 assertEquals(t("abcdefghi<Z=Y>"),
160 merge("abcdefghij", "abcdefghiZ", "abcdefghiY"));
161 }
162
163
164
165
166
167
168
169 @Test
170 public void testSameModification() throws IOException {
171 assertEquals(t("abZdefghij"),
172 merge("abcdefghij", "abZdefghij", "abZdefghij"));
173 }
174
175
176
177
178
179
180
181 @Test
182 public void testDeleteVsModify() throws IOException {
183 assertEquals(t("ab<=Z>defghij"),
184 merge("abcdefghij", "abdefghij", "abZdefghij"));
185 }
186
187 @Test
188 public void testInsertVsModify() throws IOException {
189 assertEquals(t("a<bZ=XY>"), merge("ab", "abZ", "aXY"));
190 }
191
192 @Test
193 public void testAdjacentModifications() throws IOException {
194 assertEquals(t("a<Zc=bY>d"), merge("abcd", "aZcd", "abYd"));
195 }
196
197 @Test
198 public void testSeparateModifications() throws IOException {
199 assertEquals(t("aZcYe"), merge("abcde", "aZcde", "abcYe"));
200 }
201
202 @Test
203 public void testBlankLines() throws IOException {
204 assertEquals(t("aZc\nYe"), merge("abc\nde", "aZc\nde", "abc\nYe"));
205 }
206
207
208
209
210
211
212
213
214
215 @Test
216 public void testTwoSimilarModsAndOneInsert() throws IOException {
217 assertEquals(t("aBcDde"), merge("abcde", "aBcde", "aBcDde"));
218 assertEquals(t("IAAAJCAB"), merge("iACAB", "IACAB", "IAAAJCAB"));
219 assertEquals(t("HIAAAJCAB"), merge("HiACAB", "HIACAB", "HIAAAJCAB"));
220 assertEquals(t("AGADEFHIAAAJCAB"),
221 merge("AGADEFHiACAB", "AGADEFHIACAB", "AGADEFHIAAAJCAB"));
222 }
223
224
225
226
227
228
229
230
231
232 @Test
233 public void testTwoSimilarModsAndOneInsertAtEnd() throws IOException {
234 Assume.assumeTrue(newlineAtEnd);
235 assertEquals(t("IAAJ"), merge("iA", "IA", "IAAJ"));
236 assertEquals(t("IAJ"), merge("iA", "IA", "IAJ"));
237 assertEquals(t("IAAAJ"), merge("iA", "IA", "IAAAJ"));
238 }
239
240 @Test
241 public void testTwoSimilarModsAndOneInsertAtEndNoNewlineAtEnd()
242 throws IOException {
243 Assume.assumeFalse(newlineAtEnd);
244 assertEquals(t("I<A=AAJ>"), merge("iA", "IA", "IAAJ"));
245 assertEquals(t("I<A=AJ>"), merge("iA", "IA", "IAJ"));
246 assertEquals(t("I<A=AAAJ>"), merge("iA", "IA", "IAAAJ"));
247 }
248
249
250
251
252
253
254 @Test
255 public void testEmptyTexts() throws IOException {
256
257 assertEquals(t("<AB=>"), merge("A", "AB", ""));
258 assertEquals(t("<=AB>"), merge("A", "", "AB"));
259
260
261 assertEquals(t(""), merge("AB", "AB", ""));
262 assertEquals(t(""), merge("AB", "", "AB"));
263
264
265 assertEquals(t(""), merge("AB", "", ""));
266 }
267
268 private String merge(String commonBase, String ours, String theirs) throws IOException {
269 MergeResult r = new MergeAlgorithm().merge(RawTextComparator.DEFAULT,
270 T(commonBase), T(ours), T(theirs));
271 ByteArrayOutputStream bo=new ByteArrayOutputStream(50);
272 fmt.formatMerge(bo, r, "B", "O", "T", UTF_8);
273 return new String(bo.toByteArray(), UTF_8);
274 }
275
276 public String t(String text) {
277 StringBuilder r = new StringBuilder();
278 for (int i = 0; i < text.length(); i++) {
279 char c = text.charAt(i);
280 switch (c) {
281 case '<':
282 r.append("<<<<<<< O\n");
283 break;
284 case '=':
285 r.append("=======\n");
286 break;
287 case '>':
288 r.append(">>>>>>> T\n");
289 break;
290 default:
291 r.append(c);
292 if (newlineAtEnd || i < text.length() - 1)
293 r.append('\n');
294 }
295 }
296 return r.toString();
297 }
298
299 public RawText T(String text) {
300 return new RawText(Constants.encode(t(text)));
301 }
302 }