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