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.util;
45
46 import static org.junit.Assert.assertEquals;
47 import static org.junit.Assert.assertFalse;
48 import static org.junit.Assert.assertNull;
49 import static org.junit.Assert.assertSame;
50 import static org.junit.Assert.assertTrue;
51 import static org.junit.Assert.fail;
52
53 import java.util.Iterator;
54 import java.util.Map;
55 import java.util.NoSuchElementException;
56
57 import org.eclipse.jgit.lib.ObjectId;
58 import org.eclipse.jgit.lib.ObjectIdRef;
59 import org.eclipse.jgit.lib.Ref;
60 import org.eclipse.jgit.lib.SymbolicRef;
61 import org.junit.Before;
62 import org.junit.Test;
63
64 public class RefMapTest {
65 private static final ObjectId ID_ONE = ObjectId
66 .fromString("41eb0d88f833b558bddeb269b7ab77399cdf98ed");
67
68 private static final ObjectId ID_TWO = ObjectId
69 .fromString("698dd0b8d0c299f080559a1cffc7fe029479a408");
70
71 private RefList<Ref> packed;
72
73 private RefList<Ref> loose;
74
75 private RefList<Ref> resolved;
76
77 @Before
78 public void setUp() throws Exception {
79 packed = RefList.emptyList();
80 loose = RefList.emptyList();
81 resolved = RefList.emptyList();
82 }
83
84 @Test
85 public void testEmpty_NoPrefix1() {
86 RefMap map = new RefMap("", packed, loose, resolved);
87 assertTrue(map.isEmpty());
88 assertEquals(0, map.size());
89 assertTrue(map.isEmpty());
90
91 assertFalse(map.entrySet().iterator().hasNext());
92 assertFalse(map.keySet().iterator().hasNext());
93 assertFalse(map.containsKey("a"));
94 assertNull(map.get("a"));
95 }
96
97 @Test
98 public void testEmpty_NoPrefix2() {
99 RefMap map = new RefMap();
100 assertTrue(map.isEmpty());
101 assertEquals(0, map.size());
102 assertTrue(map.isEmpty());
103
104 assertFalse(map.entrySet().iterator().hasNext());
105 assertFalse(map.keySet().iterator().hasNext());
106 assertFalse(map.containsKey("a"));
107 assertNull(map.get("a"));
108 }
109
110 @Test
111 public void testNotEmpty_NoPrefix() {
112 final Ref master = newRef("refs/heads/master", ID_ONE);
113 packed = toList(master);
114
115 RefMap map = new RefMap("", packed, loose, resolved);
116 assertFalse(map.isEmpty());
117 assertEquals(1, map.size());
118 assertFalse(map.isEmpty());
119 assertSame(master, map.values().iterator().next());
120 }
121
122 @Test
123 public void testEmpty_WithPrefix() {
124 final Ref master = newRef("refs/heads/master", ID_ONE);
125 packed = toList(master);
126
127 RefMap map = new RefMap("refs/tags/", packed, loose, resolved);
128 assertTrue(map.isEmpty());
129 assertEquals(0, map.size());
130 assertTrue(map.isEmpty());
131
132 assertFalse(map.entrySet().iterator().hasNext());
133 assertFalse(map.keySet().iterator().hasNext());
134 }
135
136 @Test
137 public void testNotEmpty_WithPrefix() {
138 final Ref master = newRef("refs/heads/master", ID_ONE);
139 packed = toList(master);
140
141 RefMap map = new RefMap("refs/heads/", packed, loose, resolved);
142 assertFalse(map.isEmpty());
143 assertEquals(1, map.size());
144 assertFalse(map.isEmpty());
145 assertSame(master, map.values().iterator().next());
146 }
147
148 @Test
149 public void testClear() {
150 final Ref master = newRef("refs/heads/master", ID_ONE);
151 loose = toList(master);
152
153 RefMap map = new RefMap("", packed, loose, resolved);
154 assertSame(master, map.get("refs/heads/master"));
155
156 map.clear();
157 assertNull(map.get("refs/heads/master"));
158 assertTrue(map.isEmpty());
159 assertEquals(0, map.size());
160 }
161
162 @Test
163 public void testIterator_RefusesRemove() {
164 final Ref master = newRef("refs/heads/master", ID_ONE);
165 loose = toList(master);
166
167 RefMap map = new RefMap("", packed, loose, resolved);
168 Iterator<Ref> itr = map.values().iterator();
169 assertTrue(itr.hasNext());
170 assertSame(master, itr.next());
171 try {
172 itr.remove();
173 fail("iterator allowed remove");
174 } catch (UnsupportedOperationException err) {
175
176 }
177 }
178
179 @Test
180 public void testIterator_FailsAtEnd() {
181 final Ref master = newRef("refs/heads/master", ID_ONE);
182 loose = toList(master);
183
184 RefMap map = new RefMap("", packed, loose, resolved);
185 Iterator<Ref> itr = map.values().iterator();
186 assertTrue(itr.hasNext());
187 assertSame(master, itr.next());
188 try {
189 itr.next();
190 fail("iterator allowed next");
191 } catch (NoSuchElementException err) {
192
193 }
194 }
195
196 @Test
197 public void testIterator_MissingUnresolvedSymbolicRefIsBug() {
198 final Ref master = newRef("refs/heads/master", ID_ONE);
199 final Ref headR = newRef("HEAD", master);
200
201 loose = toList(master);
202
203 resolved = toList(headR);
204
205 RefMap map = new RefMap("", packed, loose, resolved);
206 Iterator<Ref> itr = map.values().iterator();
207 try {
208 itr.hasNext();
209 fail("iterator did not catch bad input");
210 } catch (IllegalStateException err) {
211
212 }
213 }
214
215 @Test
216 public void testMerge_HeadMaster() {
217 final Ref master = newRef("refs/heads/master", ID_ONE);
218 final Ref headU = newRef("HEAD", "refs/heads/master");
219 final Ref headR = newRef("HEAD", master);
220
221 loose = toList(headU, master);
222 resolved = toList(headR);
223
224 RefMap map = new RefMap("", packed, loose, resolved);
225 assertEquals(2, map.size());
226 assertFalse(map.isEmpty());
227 assertTrue(map.containsKey("refs/heads/master"));
228 assertSame(master, map.get("refs/heads/master"));
229
230
231 assertSame(headR, map.get("HEAD"));
232
233 Iterator<Ref> itr = map.values().iterator();
234 assertTrue(itr.hasNext());
235 assertSame(headR, itr.next());
236 assertTrue(itr.hasNext());
237 assertSame(master, itr.next());
238 assertFalse(itr.hasNext());
239 }
240
241 @Test
242 public void testMerge_PackedLooseLoose() {
243 final Ref refA = newRef("A", ID_ONE);
244 final Ref refB_ONE = newRef("B", ID_ONE);
245 final Ref refB_TWO = newRef("B", ID_TWO);
246 final Ref refc = newRef("c", ID_ONE);
247
248 packed = toList(refA, refB_ONE);
249 loose = toList(refB_TWO, refc);
250
251 RefMap map = new RefMap("", packed, loose, resolved);
252 assertEquals(3, map.size());
253 assertFalse(map.isEmpty());
254 assertTrue(map.containsKey(refA.getName()));
255 assertSame(refA, map.get(refA.getName()));
256
257
258 assertSame(refB_TWO, map.get(refB_ONE.getName()));
259
260 Iterator<Ref> itr = map.values().iterator();
261 assertTrue(itr.hasNext());
262 assertSame(refA, itr.next());
263 assertTrue(itr.hasNext());
264 assertSame(refB_TWO, itr.next());
265 assertTrue(itr.hasNext());
266 assertSame(refc, itr.next());
267 assertFalse(itr.hasNext());
268 }
269
270 @Test
271 public void testMerge_WithPrefix() {
272 final Ref a = newRef("refs/heads/A", ID_ONE);
273 final Ref b = newRef("refs/heads/foo/bar/B", ID_TWO);
274 final Ref c = newRef("refs/heads/foo/rab/C", ID_TWO);
275 final Ref g = newRef("refs/heads/g", ID_ONE);
276 packed = toList(a, b, c, g);
277
278 RefMap map = new RefMap("refs/heads/foo/", packed, loose, resolved);
279 assertEquals(2, map.size());
280
281 assertSame(b, map.get("bar/B"));
282 assertSame(c, map.get("rab/C"));
283 assertNull(map.get("refs/heads/foo/bar/B"));
284 assertNull(map.get("refs/heads/A"));
285
286 assertTrue(map.containsKey("bar/B"));
287 assertTrue(map.containsKey("rab/C"));
288 assertFalse(map.containsKey("refs/heads/foo/bar/B"));
289 assertFalse(map.containsKey("refs/heads/A"));
290
291 Iterator<Map.Entry<String, Ref>> itr = map.entrySet().iterator();
292 Map.Entry<String, Ref> ent;
293 assertTrue(itr.hasNext());
294 ent = itr.next();
295 assertEquals("bar/B", ent.getKey());
296 assertSame(b, ent.getValue());
297 assertTrue(itr.hasNext());
298 ent = itr.next();
299 assertEquals("rab/C", ent.getKey());
300 assertSame(c, ent.getValue());
301 assertFalse(itr.hasNext());
302 }
303
304 @Test
305 public void testPut_KeyMustMatchName_NoPrefix() {
306 final Ref refA = newRef("refs/heads/A", ID_ONE);
307 RefMap map = new RefMap("", packed, loose, resolved);
308 try {
309 map.put("FOO", refA);
310 fail("map accepted invalid key/value pair");
311 } catch (IllegalArgumentException err) {
312
313 }
314 }
315
316 @Test
317 public void testPut_KeyMustMatchName_WithPrefix() {
318 final Ref refA = newRef("refs/heads/A", ID_ONE);
319 RefMap map = new RefMap("refs/heads/", packed, loose, resolved);
320 try {
321 map.put("FOO", refA);
322 fail("map accepted invalid key/value pair");
323 } catch (IllegalArgumentException err) {
324
325 }
326 }
327
328 @Test
329 public void testPut_NoPrefix() {
330 final Ref refA_one = newRef("refs/heads/A", ID_ONE);
331 final Ref refA_two = newRef("refs/heads/A", ID_TWO);
332
333 packed = toList(refA_one);
334
335 RefMap map = new RefMap("", packed, loose, resolved);
336 assertSame(refA_one, map.get(refA_one.getName()));
337 assertSame(refA_one, map.put(refA_one.getName(), refA_two));
338
339
340 assertSame(refA_two, map.get(refA_one.getName()));
341 assertSame(refA_one, packed.get(0));
342 assertEquals(0, loose.size());
343
344 assertSame(refA_two, map.put(refA_one.getName(), refA_one));
345 assertSame(refA_one, map.get(refA_one.getName()));
346 }
347
348 @Test
349 public void testPut_WithPrefix() {
350 final Ref refA_one = newRef("refs/heads/A", ID_ONE);
351 final Ref refA_two = newRef("refs/heads/A", ID_TWO);
352
353 packed = toList(refA_one);
354
355 RefMap map = new RefMap("refs/heads/", packed, loose, resolved);
356 assertSame(refA_one, map.get("A"));
357 assertSame(refA_one, map.put("A", refA_two));
358
359
360 assertSame(refA_two, map.get("A"));
361 assertSame(refA_one, packed.get(0));
362 assertEquals(0, loose.size());
363
364 assertSame(refA_two, map.put("A", refA_one));
365 assertSame(refA_one, map.get("A"));
366 }
367
368 @Test
369 public void testPut_CollapseResolved() {
370 final Ref master = newRef("refs/heads/master", ID_ONE);
371 final Ref headU = newRef("HEAD", "refs/heads/master");
372 final Ref headR = newRef("HEAD", master);
373 final Ref a = newRef("refs/heads/A", ID_ONE);
374
375 loose = toList(headU, master);
376 resolved = toList(headR);
377
378 RefMap map = new RefMap("", packed, loose, resolved);
379 assertNull(map.put(a.getName(), a));
380 assertSame(a, map.get(a.getName()));
381 assertSame(headR, map.get("HEAD"));
382 }
383
384 @Test
385 public void testRemove() {
386 final Ref master = newRef("refs/heads/master", ID_ONE);
387 final Ref headU = newRef("HEAD", "refs/heads/master");
388 final Ref headR = newRef("HEAD", master);
389
390 packed = toList(master);
391 loose = toList(headU, master);
392 resolved = toList(headR);
393
394 RefMap map = new RefMap("", packed, loose, resolved);
395 assertNull(map.remove("not.a.reference"));
396
397 assertSame(master, map.remove("refs/heads/master"));
398 assertNull(map.get("refs/heads/master"));
399
400 assertSame(headR, map.remove("HEAD"));
401 assertNull(map.get("HEAD"));
402
403 assertTrue(map.isEmpty());
404 }
405
406 @Test
407 public void testToString_NoPrefix() {
408 final Ref a = newRef("refs/heads/A", ID_ONE);
409 final Ref b = newRef("refs/heads/B", ID_TWO);
410
411 packed = toList(a, b);
412
413 StringBuilder exp = new StringBuilder();
414 exp.append("[");
415 exp.append(a.toString());
416 exp.append(", ");
417 exp.append(b.toString());
418 exp.append("]");
419
420 RefMap map = new RefMap("", packed, loose, resolved);
421 assertEquals(exp.toString(), map.toString());
422 }
423
424 @Test
425 public void testToString_WithPrefix() {
426 final Ref a = newRef("refs/heads/A", ID_ONE);
427 final Ref b = newRef("refs/heads/foo/B", ID_TWO);
428 final Ref c = newRef("refs/heads/foo/C", ID_TWO);
429 final Ref g = newRef("refs/heads/g", ID_ONE);
430
431 packed = toList(a, b, c, g);
432
433 StringBuilder exp = new StringBuilder();
434 exp.append("[");
435 exp.append(b.toString());
436 exp.append(", ");
437 exp.append(c.toString());
438 exp.append("]");
439
440 RefMap map = new RefMap("refs/heads/foo/", packed, loose, resolved);
441 assertEquals(exp.toString(), map.toString());
442 }
443
444 @Test
445 public void testEntryType() {
446 final Ref a = newRef("refs/heads/A", ID_ONE);
447 final Ref b = newRef("refs/heads/B", ID_TWO);
448
449 packed = toList(a, b);
450
451 RefMap map = new RefMap("refs/heads/", packed, loose, resolved);
452 Iterator<Map.Entry<String, Ref>> itr = map.entrySet().iterator();
453 Map.Entry<String, Ref> ent_a = itr.next();
454 Map.Entry<String, Ref> ent_b = itr.next();
455
456 assertEquals(ent_a.hashCode(), "A".hashCode());
457 assertEquals(ent_a, ent_a);
458 assertFalse(ent_a.equals(ent_b));
459
460 assertEquals(a.toString(), ent_a.toString());
461 }
462
463 @Test
464 public void testEntryTypeSet() {
465 final Ref refA_one = newRef("refs/heads/A", ID_ONE);
466 final Ref refA_two = newRef("refs/heads/A", ID_TWO);
467
468 packed = toList(refA_one);
469
470 RefMap map = new RefMap("refs/heads/", packed, loose, resolved);
471 assertSame(refA_one, map.get("A"));
472
473 Map.Entry<String, Ref> ent = map.entrySet().iterator().next();
474 assertEquals("A", ent.getKey());
475 assertSame(refA_one, ent.getValue());
476
477 assertSame(refA_one, ent.setValue(refA_two));
478 assertSame(refA_two, ent.getValue());
479 assertSame(refA_two, map.get("A"));
480 assertEquals(1, map.size());
481 }
482
483 private static RefList<Ref> toList(Ref... refs) {
484 RefList.Builder<Ref> b = new RefList.Builder<>(refs.length);
485 b.addAll(refs, 0, refs.length);
486 return b.toRefList();
487 }
488
489 private static Ref newRef(String name, String dst) {
490 return newRef(name,
491 new ObjectIdRef.Unpeeled(Ref.Storage.NEW, dst, null));
492 }
493
494 private static Ref newRef(String name, Ref dst) {
495 return new SymbolicRef(name, dst);
496 }
497
498 private static Ref newRef(String name, ObjectId id) {
499 return new ObjectIdRef.Unpeeled(Ref.Storage.LOOSE, name, id);
500 }
501 }