1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect;
18
19 import static com.google.common.collect.BoundType.CLOSED;
20 import static com.google.common.collect.BoundType.OPEN;
21 import static com.google.common.collect.DiscreteDomain.integers;
22 import static com.google.common.testing.SerializableTester.reserializeAndAssert;
23 import static java.util.Arrays.asList;
24
25 import com.google.common.annotations.GwtCompatible;
26 import com.google.common.base.Predicate;
27 import com.google.common.collect.testing.Helpers;
28 import com.google.common.testing.EqualsTester;
29
30 import junit.framework.TestCase;
31
32 import java.util.Arrays;
33 import java.util.Collections;
34 import java.util.List;
35 import java.util.NoSuchElementException;
36
37
38
39
40
41
42 @GwtCompatible
43 public class RangeTest extends TestCase {
44 public void testOpen() {
45 Range<Integer> range = Range.open(4, 8);
46 checkContains(range);
47 assertTrue(range.hasLowerBound());
48 assertEquals(4, (int) range.lowerEndpoint());
49 assertEquals(OPEN, range.lowerBoundType());
50 assertTrue(range.hasUpperBound());
51 assertEquals(8, (int) range.upperEndpoint());
52 assertEquals(OPEN, range.upperBoundType());
53 assertFalse(range.isEmpty());
54 assertEquals("(4\u20258)", range.toString());
55 reserializeAndAssert(range);
56 }
57
58 public void testOpen_invalid() {
59 try {
60 Range.open(4, 3);
61 fail();
62 } catch (IllegalArgumentException expected) {
63 }
64 try {
65 Range.open(3, 3);
66 fail();
67 } catch (IllegalArgumentException expected) {
68 }
69 }
70
71 public void testClosed() {
72 Range<Integer> range = Range.closed(5, 7);
73 checkContains(range);
74 assertTrue(range.hasLowerBound());
75 assertEquals(5, (int) range.lowerEndpoint());
76 assertEquals(CLOSED, range.lowerBoundType());
77 assertTrue(range.hasUpperBound());
78 assertEquals(7, (int) range.upperEndpoint());
79 assertEquals(CLOSED, range.upperBoundType());
80 assertFalse(range.isEmpty());
81 assertEquals("[5\u20257]", range.toString());
82 reserializeAndAssert(range);
83 }
84
85 public void testClosed_invalid() {
86 try {
87 Range.closed(4, 3);
88 fail();
89 } catch (IllegalArgumentException expected) {
90 }
91 }
92
93 public void testOpenClosed() {
94 Range<Integer> range = Range.openClosed(4, 7);
95 checkContains(range);
96 assertTrue(range.hasLowerBound());
97 assertEquals(4, (int) range.lowerEndpoint());
98 assertEquals(OPEN, range.lowerBoundType());
99 assertTrue(range.hasUpperBound());
100 assertEquals(7, (int) range.upperEndpoint());
101 assertEquals(CLOSED, range.upperBoundType());
102 assertFalse(range.isEmpty());
103 assertEquals("(4\u20257]", range.toString());
104 reserializeAndAssert(range);
105 }
106
107 public void testClosedOpen() {
108 Range<Integer> range = Range.closedOpen(5, 8);
109 checkContains(range);
110 assertTrue(range.hasLowerBound());
111 assertEquals(5, (int) range.lowerEndpoint());
112 assertEquals(CLOSED, range.lowerBoundType());
113 assertTrue(range.hasUpperBound());
114 assertEquals(8, (int) range.upperEndpoint());
115 assertEquals(OPEN, range.upperBoundType());
116 assertFalse(range.isEmpty());
117 assertEquals("[5\u20258)", range.toString());
118 reserializeAndAssert(range);
119 }
120
121 public void testIsConnected() {
122 assertTrue(Range.closed(3, 5).isConnected(Range.open(5, 6)));
123 assertTrue(Range.closed(3, 5).isConnected(Range.openClosed(5, 5)));
124 assertTrue(Range.open(3, 5).isConnected(Range.closed(5, 6)));
125 assertTrue(Range.closed(3, 7).isConnected(Range.open(6, 8)));
126 assertTrue(Range.open(3, 7).isConnected(Range.closed(5, 6)));
127 assertFalse(Range.closed(3, 5).isConnected(Range.closed(7, 8)));
128 assertFalse(Range.closed(3, 5).isConnected(Range.closedOpen(7, 7)));
129 }
130
131 private static void checkContains(Range<Integer> range) {
132 assertFalse(range.contains(4));
133 assertTrue(range.contains(5));
134 assertTrue(range.contains(7));
135 assertFalse(range.contains(8));
136 }
137
138 public void testSingleton() {
139 Range<Integer> range = Range.closed(4, 4);
140 assertFalse(range.contains(3));
141 assertTrue(range.contains(4));
142 assertFalse(range.contains(5));
143 assertTrue(range.hasLowerBound());
144 assertEquals(4, (int) range.lowerEndpoint());
145 assertEquals(CLOSED, range.lowerBoundType());
146 assertTrue(range.hasUpperBound());
147 assertEquals(4, (int) range.upperEndpoint());
148 assertEquals(CLOSED, range.upperBoundType());
149 assertFalse(range.isEmpty());
150 assertEquals("[4\u20254]", range.toString());
151 reserializeAndAssert(range);
152 }
153
154 public void testEmpty1() {
155 Range<Integer> range = Range.closedOpen(4, 4);
156 assertFalse(range.contains(3));
157 assertFalse(range.contains(4));
158 assertFalse(range.contains(5));
159 assertTrue(range.hasLowerBound());
160 assertEquals(4, (int) range.lowerEndpoint());
161 assertEquals(CLOSED, range.lowerBoundType());
162 assertTrue(range.hasUpperBound());
163 assertEquals(4, (int) range.upperEndpoint());
164 assertEquals(OPEN, range.upperBoundType());
165 assertTrue(range.isEmpty());
166 assertEquals("[4\u20254)", range.toString());
167 reserializeAndAssert(range);
168 }
169
170 public void testEmpty2() {
171 Range<Integer> range = Range.openClosed(4, 4);
172 assertFalse(range.contains(3));
173 assertFalse(range.contains(4));
174 assertFalse(range.contains(5));
175 assertTrue(range.hasLowerBound());
176 assertEquals(4, (int) range.lowerEndpoint());
177 assertEquals(OPEN, range.lowerBoundType());
178 assertTrue(range.hasUpperBound());
179 assertEquals(4, (int) range.upperEndpoint());
180 assertEquals(CLOSED, range.upperBoundType());
181 assertTrue(range.isEmpty());
182 assertEquals("(4\u20254]", range.toString());
183 reserializeAndAssert(range);
184 }
185
186 public void testLessThan() {
187 Range<Integer> range = Range.lessThan(5);
188 assertTrue(range.contains(Integer.MIN_VALUE));
189 assertTrue(range.contains(4));
190 assertFalse(range.contains(5));
191 assertUnboundedBelow(range);
192 assertTrue(range.hasUpperBound());
193 assertEquals(5, (int) range.upperEndpoint());
194 assertEquals(OPEN, range.upperBoundType());
195 assertFalse(range.isEmpty());
196 assertEquals("(-\u221e\u20255)", range.toString());
197 reserializeAndAssert(range);
198 }
199
200 public void testGreaterThan() {
201 Range<Integer> range = Range.greaterThan(5);
202 assertFalse(range.contains(5));
203 assertTrue(range.contains(6));
204 assertTrue(range.contains(Integer.MAX_VALUE));
205 assertTrue(range.hasLowerBound());
206 assertEquals(5, (int) range.lowerEndpoint());
207 assertEquals(OPEN, range.lowerBoundType());
208 assertUnboundedAbove(range);
209 assertFalse(range.isEmpty());
210 assertEquals("(5\u2025+\u221e)", range.toString());
211 reserializeAndAssert(range);
212 }
213
214 public void testAtLeast() {
215 Range<Integer> range = Range.atLeast(6);
216 assertFalse(range.contains(5));
217 assertTrue(range.contains(6));
218 assertTrue(range.contains(Integer.MAX_VALUE));
219 assertTrue(range.hasLowerBound());
220 assertEquals(6, (int) range.lowerEndpoint());
221 assertEquals(CLOSED, range.lowerBoundType());
222 assertUnboundedAbove(range);
223 assertFalse(range.isEmpty());
224 assertEquals("[6\u2025+\u221e)", range.toString());
225 reserializeAndAssert(range);
226 }
227
228 public void testAtMost() {
229 Range<Integer> range = Range.atMost(4);
230 assertTrue(range.contains(Integer.MIN_VALUE));
231 assertTrue(range.contains(4));
232 assertFalse(range.contains(5));
233 assertUnboundedBelow(range);
234 assertTrue(range.hasUpperBound());
235 assertEquals(4, (int) range.upperEndpoint());
236 assertEquals(CLOSED, range.upperBoundType());
237 assertFalse(range.isEmpty());
238 assertEquals("(-\u221e\u20254]", range.toString());
239 reserializeAndAssert(range);
240 }
241
242 public void testAll() {
243 Range<Integer> range = Range.all();
244 assertTrue(range.contains(Integer.MIN_VALUE));
245 assertTrue(range.contains(Integer.MAX_VALUE));
246 assertUnboundedBelow(range);
247 assertUnboundedAbove(range);
248 assertFalse(range.isEmpty());
249 assertEquals("(-\u221e\u2025+\u221e)", range.toString());
250 assertSame(range, reserializeAndAssert(range));
251 assertSame(range, Range.all());
252 }
253
254 private static void assertUnboundedBelow(Range<Integer> range) {
255 assertFalse(range.hasLowerBound());
256 try {
257 range.lowerEndpoint();
258 fail();
259 } catch (IllegalStateException expected) {
260 }
261 try {
262 range.lowerBoundType();
263 fail();
264 } catch (IllegalStateException expected) {
265 }
266 }
267
268 private static void assertUnboundedAbove(Range<Integer> range) {
269 assertFalse(range.hasUpperBound());
270 try {
271 range.upperEndpoint();
272 fail();
273 } catch (IllegalStateException expected) {
274 }
275 try {
276 range.upperBoundType();
277 fail();
278 } catch (IllegalStateException expected) {
279 }
280 }
281
282 public void testOrderingCuts() {
283 Cut<Integer> a = Range.lessThan(0).lowerBound;
284 Cut<Integer> b = Range.atLeast(0).lowerBound;
285 Cut<Integer> c = Range.greaterThan(0).lowerBound;
286 Cut<Integer> d = Range.atLeast(1).lowerBound;
287 Cut<Integer> e = Range.greaterThan(1).lowerBound;
288 Cut<Integer> f = Range.greaterThan(1).upperBound;
289
290 Helpers.testCompareToAndEquals(ImmutableList.of(a, b, c, d, e, f));
291 }
292
293 public void testContainsAll() {
294 Range<Integer> range = Range.closed(3, 5);
295 assertTrue(range.containsAll(asList(3, 3, 4, 5)));
296 assertFalse(range.containsAll(asList(3, 3, 4, 5, 6)));
297
298
299
300 assertTrue(range.containsAll(ImmutableSortedSet.of(3, 3, 4, 5)));
301 assertTrue(range.containsAll(ImmutableSortedSet.of(3)));
302 assertTrue(range.containsAll(ImmutableSortedSet.<Integer>of()));
303 assertFalse(range.containsAll(ImmutableSortedSet.of(3, 3, 4, 5, 6)));
304
305 assertTrue(Range.openClosed(3, 3).containsAll(
306 Collections.<Integer>emptySet()));
307 }
308
309 public void testEncloses_open() {
310 Range<Integer> range = Range.open(2, 5);
311 assertTrue(range.encloses(range));
312 assertTrue(range.encloses(Range.open(2, 4)));
313 assertTrue(range.encloses(Range.open(3, 5)));
314 assertTrue(range.encloses(Range.closed(3, 4)));
315
316 assertFalse(range.encloses(Range.openClosed(2, 5)));
317 assertFalse(range.encloses(Range.closedOpen(2, 5)));
318 assertFalse(range.encloses(Range.closed(1, 4)));
319 assertFalse(range.encloses(Range.closed(3, 6)));
320 assertFalse(range.encloses(Range.greaterThan(3)));
321 assertFalse(range.encloses(Range.lessThan(3)));
322 assertFalse(range.encloses(Range.atLeast(3)));
323 assertFalse(range.encloses(Range.atMost(3)));
324 assertFalse(range.encloses(Range.<Integer>all()));
325 }
326
327 public void testEncloses_closed() {
328 Range<Integer> range = Range.closed(2, 5);
329 assertTrue(range.encloses(range));
330 assertTrue(range.encloses(Range.open(2, 5)));
331 assertTrue(range.encloses(Range.openClosed(2, 5)));
332 assertTrue(range.encloses(Range.closedOpen(2, 5)));
333 assertTrue(range.encloses(Range.closed(3, 5)));
334 assertTrue(range.encloses(Range.closed(2, 4)));
335
336 assertFalse(range.encloses(Range.open(1, 6)));
337 assertFalse(range.encloses(Range.greaterThan(3)));
338 assertFalse(range.encloses(Range.lessThan(3)));
339 assertFalse(range.encloses(Range.atLeast(3)));
340 assertFalse(range.encloses(Range.atMost(3)));
341 assertFalse(range.encloses(Range.<Integer>all()));
342 }
343
344 public void testIntersection_empty() {
345 Range<Integer> range = Range.closedOpen(3, 3);
346 assertEquals(range, range.intersection(range));
347
348 try {
349 range.intersection(Range.open(3, 5));
350 fail();
351 } catch (IllegalArgumentException expected) {
352 }
353 try {
354 range.intersection(Range.closed(0, 2));
355 fail();
356 } catch (IllegalArgumentException expected) {
357 }
358 }
359
360 public void testIntersection_deFactoEmpty() {
361 Range<Integer> range = Range.open(3, 4);
362 assertEquals(range, range.intersection(range));
363
364 assertEquals(Range.openClosed(3, 3),
365 range.intersection(Range.atMost(3)));
366 assertEquals(Range.closedOpen(4, 4),
367 range.intersection(Range.atLeast(4)));
368
369 try {
370 range.intersection(Range.lessThan(3));
371 fail();
372 } catch (IllegalArgumentException expected) {
373 }
374 try {
375 range.intersection(Range.greaterThan(4));
376 fail();
377 } catch (IllegalArgumentException expected) {
378 }
379
380 range = Range.closed(3, 4);
381 assertEquals(Range.openClosed(4, 4),
382 range.intersection(Range.greaterThan(4)));
383 }
384
385 public void testIntersection_singleton() {
386 Range<Integer> range = Range.closed(3, 3);
387 assertEquals(range, range.intersection(range));
388
389 assertEquals(range, range.intersection(Range.atMost(4)));
390 assertEquals(range, range.intersection(Range.atMost(3)));
391 assertEquals(range, range.intersection(Range.atLeast(3)));
392 assertEquals(range, range.intersection(Range.atLeast(2)));
393
394 assertEquals(Range.closedOpen(3, 3),
395 range.intersection(Range.lessThan(3)));
396 assertEquals(Range.openClosed(3, 3),
397 range.intersection(Range.greaterThan(3)));
398
399 try {
400 range.intersection(Range.atLeast(4));
401 fail();
402 } catch (IllegalArgumentException expected) {
403 }
404 try {
405 range.intersection(Range.atMost(2));
406 fail();
407 } catch (IllegalArgumentException expected) {
408 }
409 }
410
411 public void testIntersection_general() {
412 Range<Integer> range = Range.closed(4, 8);
413
414
415 try {
416 range.intersection(Range.closed(0, 2));
417 fail();
418 } catch (IllegalArgumentException expected) {
419 }
420
421
422 assertEquals(Range.closedOpen(4, 4),
423 range.intersection(Range.closedOpen(2, 4)));
424
425
426 assertEquals(Range.closed(4, 6), range.intersection(Range.closed(2, 6)));
427
428
429 assertEquals(Range.closed(4, 6), range.intersection(Range.closed(4, 6)));
430
431
432 assertEquals(Range.closed(5, 7), range.intersection(Range.closed(5, 7)));
433
434
435 assertEquals(Range.closed(6, 8), range.intersection(Range.closed(6, 8)));
436
437
438 assertEquals(range, range.intersection(range));
439
440
441 assertEquals(range, range.intersection(Range.closed(4, 10)));
442
443
444 assertEquals(range, range.intersection(Range.closed(2, 8)));
445
446
447 assertEquals(range, range.intersection(Range.closed(2, 10)));
448
449
450 assertEquals(Range.closed(6, 8), range.intersection(Range.closed(6, 10)));
451
452
453 assertEquals(Range.openClosed(8, 8),
454 range.intersection(Range.openClosed(8, 10)));
455
456
457 try {
458 range.intersection(Range.closed(10, 12));
459 fail();
460 } catch (IllegalArgumentException expected) {
461 }
462 }
463
464 public void testSpan_general() {
465 Range<Integer> range = Range.closed(4, 8);
466
467
468 assertEquals(Range.closed(0, 8), range.span(Range.closed(0, 2)));
469 assertEquals(Range.atMost(8), range.span(Range.atMost(2)));
470
471
472 assertEquals(Range.closed(2, 8), range.span(Range.closedOpen(2, 4)));
473 assertEquals(Range.atMost(8), range.span(Range.lessThan(4)));
474
475
476 assertEquals(Range.closed(2, 8), range.span(Range.closed(2, 6)));
477 assertEquals(Range.atMost(8), range.span(Range.atMost(6)));
478
479
480 assertEquals(range, range.span(Range.closed(4, 6)));
481
482
483 assertEquals(range, range.span(Range.closed(5, 7)));
484
485
486 assertEquals(range, range.span(Range.closed(6, 8)));
487
488
489 assertEquals(range, range.span(range));
490
491
492 assertEquals(Range.closed(4, 10), range.span(Range.closed(4, 10)));
493 assertEquals(Range.atLeast(4), range.span(Range.atLeast(4)));
494
495
496 assertEquals(Range.closed(2, 8), range.span(Range.closed(2, 8)));
497 assertEquals(Range.atMost(8), range.span(Range.atMost(8)));
498
499
500 assertEquals(Range.closed(2, 10), range.span(Range.closed(2, 10)));
501 assertEquals(Range.<Integer>all(), range.span(Range.<Integer>all()));
502
503
504 assertEquals(Range.closed(4, 10), range.span(Range.closed(6, 10)));
505 assertEquals(Range.atLeast(4), range.span(Range.atLeast(6)));
506
507
508 assertEquals(Range.closed(4, 10), range.span(Range.openClosed(8, 10)));
509 assertEquals(Range.atLeast(4), range.span(Range.greaterThan(8)));
510
511
512 assertEquals(Range.closed(4, 12), range.span(Range.closed(10, 12)));
513 assertEquals(Range.atLeast(4), range.span(Range.atLeast(10)));
514 }
515
516 public void testApply() {
517 Predicate<Integer> predicate = Range.closed(2, 3);
518 assertFalse(predicate.apply(1));
519 assertTrue(predicate.apply(2));
520 assertTrue(predicate.apply(3));
521 assertFalse(predicate.apply(4));
522 }
523
524 public void testEquals() {
525 new EqualsTester()
526 .addEqualityGroup(Range.open(1, 5),
527 Range.range(1, OPEN, 5, OPEN))
528 .addEqualityGroup(Range.greaterThan(2), Range.greaterThan(2))
529 .addEqualityGroup(Range.all(), Range.all())
530 .addEqualityGroup("Phil")
531 .testEquals();
532 }
533
534 public void testLegacyComparable() {
535 Range<LegacyComparable> range
536 = Range.closed(LegacyComparable.X, LegacyComparable.Y);
537 }
538
539 static final DiscreteDomain<Integer> UNBOUNDED_DOMAIN =
540 new DiscreteDomain<Integer>() {
541 @Override public Integer next(Integer value) {
542 return integers().next(value);
543 }
544
545 @Override public Integer previous(Integer value) {
546 return integers().previous(value);
547 }
548
549 @Override public long distance(Integer start, Integer end) {
550 return integers().distance(start, end);
551 }
552 };
553
554 public void testCanonical() {
555 assertEquals(Range.closedOpen(1, 5),
556 Range.closed(1, 4).canonical(integers()));
557 assertEquals(Range.closedOpen(1, 5),
558 Range.open(0, 5).canonical(integers()));
559 assertEquals(Range.closedOpen(1, 5),
560 Range.closedOpen(1, 5).canonical(integers()));
561 assertEquals(Range.closedOpen(1, 5),
562 Range.openClosed(0, 4).canonical(integers()));
563
564 assertEquals(Range.closedOpen(Integer.MIN_VALUE, 0),
565 Range.closedOpen(Integer.MIN_VALUE, 0).canonical(integers()));
566
567 assertEquals(Range.closedOpen(Integer.MIN_VALUE, 0),
568 Range.lessThan(0).canonical(integers()));
569 assertEquals(Range.closedOpen(Integer.MIN_VALUE, 1),
570 Range.atMost(0).canonical(integers()));
571 assertEquals(Range.atLeast(0), Range.atLeast(0).canonical(integers()));
572 assertEquals(Range.atLeast(1), Range.greaterThan(0).canonical(integers()));
573
574 assertEquals(Range.atLeast(Integer.MIN_VALUE), Range.<Integer>all().canonical(integers()));
575 }
576
577 public void testCanonical_unboundedDomain() {
578 assertEquals(Range.lessThan(0), Range.lessThan(0).canonical(UNBOUNDED_DOMAIN));
579 assertEquals(Range.lessThan(1), Range.atMost(0).canonical(UNBOUNDED_DOMAIN));
580 assertEquals(Range.atLeast(0), Range.atLeast(0).canonical(UNBOUNDED_DOMAIN));
581 assertEquals(Range.atLeast(1), Range.greaterThan(0).canonical(UNBOUNDED_DOMAIN));
582
583 assertEquals(Range.all(), Range.<Integer>all().canonical(UNBOUNDED_DOMAIN));
584 }
585
586 public void testEncloseAll() {
587 assertEquals(Range.closed(0, 0), Range.encloseAll(Arrays.asList(0)));
588 assertEquals(Range.closed(-3, 5), Range.encloseAll(Arrays.asList(5, -3)));
589 assertEquals(Range.closed(-3, 5), Range.encloseAll(Arrays.asList(1, 2, 2, 2, 5, -3, 0, -1)));
590 }
591
592 public void testEncloseAll_empty() {
593 try {
594 Range.encloseAll(ImmutableSet.<Integer>of());
595 fail();
596 } catch (NoSuchElementException expected) {}
597 }
598
599 public void testEncloseAll_nullValue() {
600 List<Integer> nullFirst = Lists.newArrayList(null, 0);
601 try {
602 Range.encloseAll(nullFirst);
603 fail();
604 } catch (NullPointerException expected) {}
605 List<Integer> nullNotFirst = Lists.newArrayList(0, null);
606 try {
607 Range.encloseAll(nullNotFirst);
608 fail();
609 } catch (NullPointerException expected) {}
610 }
611
612 public void testEquivalentFactories() {
613 new EqualsTester()
614 .addEqualityGroup(Range.all())
615 .addEqualityGroup(
616 Range.atLeast(1),
617 Range.downTo(1, CLOSED))
618 .addEqualityGroup(
619 Range.greaterThan(1),
620 Range.downTo(1, OPEN))
621 .addEqualityGroup(
622 Range.atMost(7),
623 Range.upTo(7, CLOSED))
624 .addEqualityGroup(
625 Range.lessThan(7),
626 Range.upTo(7, OPEN))
627 .addEqualityGroup(
628 Range.open(1, 7),
629 Range.range(1, OPEN, 7, OPEN))
630 .addEqualityGroup(
631 Range.openClosed(1, 7),
632 Range.range(1, OPEN, 7, CLOSED))
633 .addEqualityGroup(
634 Range.closed(1, 7),
635 Range.range(1, CLOSED, 7, CLOSED))
636 .addEqualityGroup(
637 Range.closedOpen(1, 7),
638 Range.range(1, CLOSED, 7, OPEN))
639 .testEquals();
640 }
641 }