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