1/*
2 * Copyright (C) 2008 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.google.common.collect;
18
19import static com.google.common.collect.BoundType.CLOSED;
20import static com.google.common.collect.BoundType.OPEN;
21import static com.google.common.collect.DiscreteDomain.integers;
22import static com.google.common.testing.SerializableTester.reserializeAndAssert;
23import static java.util.Arrays.asList;
24
25import com.google.common.annotations.GwtCompatible;
26import com.google.common.base.Predicate;
27import com.google.common.collect.testing.Helpers;
28import com.google.common.testing.EqualsTester;
29
30import junit.framework.TestCase;
31
32import java.util.Arrays;
33import java.util.Collections;
34import java.util.List;
35import java.util.NoSuchElementException;
36
37/**
38 * Unit test for {@link Range}.
39 *
40 * @author Kevin Bourrillion
41 */
42@GwtCompatible
43public 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    // We happen to know that natural-order sorted sets use a different code
299    // path, so we test that separately
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    // separate below
415    try {
416      range.intersection(Range.closed(0, 2));
417      fail();
418    } catch (IllegalArgumentException expected) {
419    }
420
421    // adjacent below
422    assertEquals(Range.closedOpen(4, 4),
423        range.intersection(Range.closedOpen(2, 4)));
424
425    // overlap below
426    assertEquals(Range.closed(4, 6), range.intersection(Range.closed(2, 6)));
427
428    // enclosed with same start
429    assertEquals(Range.closed(4, 6), range.intersection(Range.closed(4, 6)));
430
431    // enclosed, interior
432    assertEquals(Range.closed(5, 7), range.intersection(Range.closed(5, 7)));
433
434    // enclosed with same end
435    assertEquals(Range.closed(6, 8), range.intersection(Range.closed(6, 8)));
436
437    // equal
438    assertEquals(range, range.intersection(range));
439
440    // enclosing with same start
441    assertEquals(range, range.intersection(Range.closed(4, 10)));
442
443    // enclosing with same end
444    assertEquals(range, range.intersection(Range.closed(2, 8)));
445
446    // enclosing, exterior
447    assertEquals(range, range.intersection(Range.closed(2, 10)));
448
449    // overlap above
450    assertEquals(Range.closed(6, 8), range.intersection(Range.closed(6, 10)));
451
452    // adjacent above
453    assertEquals(Range.openClosed(8, 8),
454        range.intersection(Range.openClosed(8, 10)));
455
456    // separate above
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    // separate below
468    assertEquals(Range.closed(0, 8), range.span(Range.closed(0, 2)));
469    assertEquals(Range.atMost(8), range.span(Range.atMost(2)));
470
471    // adjacent below
472    assertEquals(Range.closed(2, 8), range.span(Range.closedOpen(2, 4)));
473    assertEquals(Range.atMost(8), range.span(Range.lessThan(4)));
474
475    // overlap below
476    assertEquals(Range.closed(2, 8), range.span(Range.closed(2, 6)));
477    assertEquals(Range.atMost(8), range.span(Range.atMost(6)));
478
479    // enclosed with same start
480    assertEquals(range, range.span(Range.closed(4, 6)));
481
482    // enclosed, interior
483    assertEquals(range, range.span(Range.closed(5, 7)));
484
485    // enclosed with same end
486    assertEquals(range, range.span(Range.closed(6, 8)));
487
488    // equal
489    assertEquals(range, range.span(range));
490
491    // enclosing with same start
492    assertEquals(Range.closed(4, 10), range.span(Range.closed(4, 10)));
493    assertEquals(Range.atLeast(4), range.span(Range.atLeast(4)));
494
495    // enclosing with same end
496    assertEquals(Range.closed(2, 8), range.span(Range.closed(2, 8)));
497    assertEquals(Range.atMost(8), range.span(Range.atMost(8)));
498
499    // enclosing, exterior
500    assertEquals(Range.closed(2, 10), range.span(Range.closed(2, 10)));
501    assertEquals(Range.<Integer>all(), range.span(Range.<Integer>all()));
502
503    // overlap above
504    assertEquals(Range.closed(4, 10), range.span(Range.closed(6, 10)));
505    assertEquals(Range.atLeast(4), range.span(Range.atLeast(6)));
506
507    // adjacent above
508    assertEquals(Range.closed(4, 10), range.span(Range.openClosed(8, 10)));
509    assertEquals(Range.atLeast(4), range.span(Range.greaterThan(8)));
510
511    // separate above
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}
642