• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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 
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.collect.testing.features.CollectionFeature.ALLOWS_NULL_QUERIES;
23 import static com.google.common.collect.testing.features.CollectionFeature.KNOWN_ORDER;
24 import static com.google.common.collect.testing.features.CollectionFeature.NON_STANDARD_TOSTRING;
25 import static com.google.common.collect.testing.features.CollectionFeature.RESTRICTS_ELEMENTS;
26 import static com.google.common.collect.testing.testers.NavigableSetNavigationTester.getHoleMethods;
27 import static com.google.common.testing.SerializableTester.reserialize;
28 import static com.google.common.testing.SerializableTester.reserializeAndAssert;
29 import static com.google.common.truth.Truth.assertThat;
30 
31 import com.google.common.annotations.GwtCompatible;
32 import com.google.common.annotations.GwtIncompatible;
33 import com.google.common.collect.testing.NavigableSetTestSuiteBuilder;
34 import com.google.common.collect.testing.features.CollectionSize;
35 import com.google.common.collect.testing.google.SetGenerators.ContiguousSetDescendingGenerator;
36 import com.google.common.collect.testing.google.SetGenerators.ContiguousSetGenerator;
37 import com.google.common.collect.testing.google.SetGenerators.ContiguousSetHeadsetGenerator;
38 import com.google.common.collect.testing.google.SetGenerators.ContiguousSetSubsetGenerator;
39 import com.google.common.collect.testing.google.SetGenerators.ContiguousSetTailsetGenerator;
40 import com.google.common.testing.EqualsTester;
41 import java.util.Collection;
42 import java.util.Set;
43 import junit.framework.Test;
44 import junit.framework.TestCase;
45 import junit.framework.TestSuite;
46 
47 /**
48  * @author Gregory Kick
49  */
50 @GwtCompatible(emulated = true)
51 public class ContiguousSetTest extends TestCase {
52   private static final DiscreteDomain<Integer> NOT_EQUAL_TO_INTEGERS =
53       new DiscreteDomain<Integer>() {
54         @Override
55         public Integer next(Integer value) {
56           return integers().next(value);
57         }
58 
59         @Override
60         public Integer previous(Integer value) {
61           return integers().previous(value);
62         }
63 
64         @Override
65         public long distance(Integer start, Integer end) {
66           return integers().distance(start, end);
67         }
68 
69         @Override
70         public Integer minValue() {
71           return integers().minValue();
72         }
73 
74         @Override
75         public Integer maxValue() {
76           return integers().maxValue();
77         }
78       };
79 
testInvalidIntRange()80   public void testInvalidIntRange() {
81     try {
82       ContiguousSet.closed(2, 1);
83       fail();
84     } catch (IllegalArgumentException expected) {
85     }
86     try {
87       ContiguousSet.closedOpen(2, 1);
88       fail();
89     } catch (IllegalArgumentException expected) {
90     }
91   }
92 
testInvalidLongRange()93   public void testInvalidLongRange() {
94     try {
95       ContiguousSet.closed(2L, 1L);
96       fail();
97     } catch (IllegalArgumentException expected) {
98     }
99     try {
100       ContiguousSet.closedOpen(2L, 1L);
101       fail();
102     } catch (IllegalArgumentException expected) {
103     }
104   }
105 
testEquals()106   public void testEquals() {
107     new EqualsTester()
108         .addEqualityGroup(
109             ContiguousSet.create(Range.closed(1, 3), integers()),
110             ContiguousSet.closed(1, 3),
111             ContiguousSet.create(Range.closedOpen(1, 4), integers()),
112             ContiguousSet.closedOpen(1, 4),
113             ContiguousSet.create(Range.openClosed(0, 3), integers()),
114             ContiguousSet.create(Range.open(0, 4), integers()),
115             ContiguousSet.create(Range.closed(1, 3), NOT_EQUAL_TO_INTEGERS),
116             ContiguousSet.create(Range.closedOpen(1, 4), NOT_EQUAL_TO_INTEGERS),
117             ContiguousSet.create(Range.openClosed(0, 3), NOT_EQUAL_TO_INTEGERS),
118             ContiguousSet.create(Range.open(0, 4), NOT_EQUAL_TO_INTEGERS),
119             ImmutableSortedSet.of(1, 2, 3))
120         .addEqualityGroup(
121             ContiguousSet.create(Range.closedOpen(1, 1), integers()),
122             ContiguousSet.closedOpen(1, 1),
123             ContiguousSet.closedOpen(Integer.MIN_VALUE, Integer.MIN_VALUE),
124             ImmutableSortedSet.of(),
125             ImmutableSet.of())
126         .testEquals();
127     // not testing hashCode for these because it takes forever to compute
128     assertEquals(
129         ContiguousSet.closed(Integer.MIN_VALUE, Integer.MAX_VALUE),
130         ContiguousSet.create(Range.<Integer>all(), integers()));
131     assertEquals(
132         ContiguousSet.closed(Integer.MIN_VALUE, Integer.MAX_VALUE),
133         ContiguousSet.create(Range.atLeast(Integer.MIN_VALUE), integers()));
134     assertEquals(
135         ContiguousSet.closed(Integer.MIN_VALUE, Integer.MAX_VALUE),
136         ContiguousSet.create(Range.atMost(Integer.MAX_VALUE), integers()));
137   }
138 
139   @GwtIncompatible // SerializableTester
testSerialization()140   public void testSerialization() {
141     ContiguousSet<Integer> empty = ContiguousSet.create(Range.closedOpen(1, 1), integers());
142     assertTrue(empty instanceof EmptyContiguousSet);
143     reserializeAndAssert(empty);
144 
145     ContiguousSet<Integer> regular = ContiguousSet.create(Range.closed(1, 3), integers());
146     assertTrue(regular instanceof RegularContiguousSet);
147     reserializeAndAssert(regular);
148 
149     /*
150      * Make sure that we're using RegularContiguousSet.SerializedForm and not
151      * ImmutableSet.SerializedForm, which would be enormous.
152      */
153     ContiguousSet<Integer> enormous = ContiguousSet.create(Range.<Integer>all(), integers());
154     assertTrue(enormous instanceof RegularContiguousSet);
155     // We can't use reserializeAndAssert because it calls hashCode, which is enormously slow.
156     ContiguousSet<Integer> enormousReserialized = reserialize(enormous);
157     assertEquals(enormous, enormousReserialized);
158   }
159 
160   private static final DiscreteDomain<Integer> UNBOUNDED_THROWING_DOMAIN =
161       new DiscreteDomain<Integer>() {
162         @Override
163         public Integer next(Integer value) {
164           throw new AssertionError();
165         }
166 
167         @Override
168         public Integer previous(Integer value) {
169           throw new AssertionError();
170         }
171 
172         @Override
173         public long distance(Integer start, Integer end) {
174           throw new AssertionError();
175         }
176       };
177 
testCreate_noMin()178   public void testCreate_noMin() {
179     Range<Integer> range = Range.lessThan(0);
180     try {
181       ContiguousSet.create(range, UNBOUNDED_THROWING_DOMAIN);
182       fail();
183     } catch (IllegalArgumentException expected) {
184     }
185   }
186 
testCreate_noMax()187   public void testCreate_noMax() {
188     Range<Integer> range = Range.greaterThan(0);
189     try {
190       ContiguousSet.create(range, UNBOUNDED_THROWING_DOMAIN);
191       fail();
192     } catch (IllegalArgumentException expected) {
193     }
194   }
195 
testCreate_empty()196   public void testCreate_empty() {
197     assertEquals(ImmutableSet.of(), ContiguousSet.create(Range.closedOpen(1, 1), integers()));
198     assertEquals(ImmutableSet.of(), ContiguousSet.closedOpen(1, 1));
199     assertEquals(ImmutableSet.of(), ContiguousSet.create(Range.openClosed(5, 5), integers()));
200     assertEquals(
201         ImmutableSet.of(), ContiguousSet.create(Range.lessThan(Integer.MIN_VALUE), integers()));
202     assertEquals(
203         ImmutableSet.of(), ContiguousSet.create(Range.greaterThan(Integer.MAX_VALUE), integers()));
204   }
205 
testHeadSet()206   public void testHeadSet() {
207     ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
208     assertThat(set.headSet(1)).isEmpty();
209     assertThat(set.headSet(2)).containsExactly(1).inOrder();
210     assertThat(set.headSet(3)).containsExactly(1, 2).inOrder();
211     assertThat(set.headSet(4)).containsExactly(1, 2, 3).inOrder();
212     assertThat(set.headSet(Integer.MAX_VALUE)).containsExactly(1, 2, 3).inOrder();
213     assertThat(set.headSet(1, true)).containsExactly(1).inOrder();
214     assertThat(set.headSet(2, true)).containsExactly(1, 2).inOrder();
215     assertThat(set.headSet(3, true)).containsExactly(1, 2, 3).inOrder();
216     assertThat(set.headSet(4, true)).containsExactly(1, 2, 3).inOrder();
217     assertThat(set.headSet(Integer.MAX_VALUE, true)).containsExactly(1, 2, 3).inOrder();
218   }
219 
testHeadSet_tooSmall()220   public void testHeadSet_tooSmall() {
221     assertThat(ContiguousSet.create(Range.closed(1, 3), integers()).headSet(0)).isEmpty();
222   }
223 
testTailSet()224   public void testTailSet() {
225     ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
226     assertThat(set.tailSet(Integer.MIN_VALUE)).containsExactly(1, 2, 3).inOrder();
227     assertThat(set.tailSet(1)).containsExactly(1, 2, 3).inOrder();
228     assertThat(set.tailSet(2)).containsExactly(2, 3).inOrder();
229     assertThat(set.tailSet(3)).containsExactly(3).inOrder();
230     assertThat(set.tailSet(Integer.MIN_VALUE, false)).containsExactly(1, 2, 3).inOrder();
231     assertThat(set.tailSet(1, false)).containsExactly(2, 3).inOrder();
232     assertThat(set.tailSet(2, false)).containsExactly(3).inOrder();
233     assertThat(set.tailSet(3, false)).isEmpty();
234   }
235 
testTailSet_tooLarge()236   public void testTailSet_tooLarge() {
237     assertThat(ContiguousSet.create(Range.closed(1, 3), integers()).tailSet(4)).isEmpty();
238   }
239 
testSubSet()240   public void testSubSet() {
241     ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
242     assertThat(set.subSet(1, 4)).containsExactly(1, 2, 3).inOrder();
243     assertThat(set.subSet(2, 4)).containsExactly(2, 3).inOrder();
244     assertThat(set.subSet(3, 4)).containsExactly(3).inOrder();
245     assertThat(set.subSet(3, 3)).isEmpty();
246     assertThat(set.subSet(2, 3)).containsExactly(2).inOrder();
247     assertThat(set.subSet(1, 3)).containsExactly(1, 2).inOrder();
248     assertThat(set.subSet(1, 2)).containsExactly(1).inOrder();
249     assertThat(set.subSet(2, 2)).isEmpty();
250     assertThat(set.subSet(Integer.MIN_VALUE, Integer.MAX_VALUE)).containsExactly(1, 2, 3).inOrder();
251     assertThat(set.subSet(1, true, 3, true)).containsExactly(1, 2, 3).inOrder();
252     assertThat(set.subSet(1, false, 3, true)).containsExactly(2, 3).inOrder();
253     assertThat(set.subSet(1, true, 3, false)).containsExactly(1, 2).inOrder();
254     assertThat(set.subSet(1, false, 3, false)).containsExactly(2).inOrder();
255   }
256 
testSubSet_outOfOrder()257   public void testSubSet_outOfOrder() {
258     ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
259     try {
260       set.subSet(3, 2);
261       fail();
262     } catch (IllegalArgumentException expected) {
263     }
264   }
265 
testSubSet_tooLarge()266   public void testSubSet_tooLarge() {
267     assertThat(ContiguousSet.create(Range.closed(1, 3), integers()).subSet(4, 6)).isEmpty();
268   }
269 
testSubSet_tooSmall()270   public void testSubSet_tooSmall() {
271     assertThat(ContiguousSet.create(Range.closed(1, 3), integers()).subSet(-1, 0)).isEmpty();
272   }
273 
testFirst()274   public void testFirst() {
275     assertEquals(1, ContiguousSet.create(Range.closed(1, 3), integers()).first().intValue());
276     assertEquals(1, ContiguousSet.create(Range.open(0, 4), integers()).first().intValue());
277     assertEquals(
278         Integer.MIN_VALUE,
279         ContiguousSet.create(Range.<Integer>all(), integers()).first().intValue());
280   }
281 
testLast()282   public void testLast() {
283     assertEquals(3, ContiguousSet.create(Range.closed(1, 3), integers()).last().intValue());
284     assertEquals(3, ContiguousSet.create(Range.open(0, 4), integers()).last().intValue());
285     assertEquals(
286         Integer.MAX_VALUE,
287         ContiguousSet.create(Range.<Integer>all(), integers()).last().intValue());
288   }
289 
testContains()290   public void testContains() {
291     ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
292     assertFalse(set.contains(0));
293     assertTrue(set.contains(1));
294     assertTrue(set.contains(2));
295     assertTrue(set.contains(3));
296     assertFalse(set.contains(4));
297     set = ContiguousSet.create(Range.open(0, 4), integers());
298     assertFalse(set.contains(0));
299     assertTrue(set.contains(1));
300     assertTrue(set.contains(2));
301     assertTrue(set.contains(3));
302     assertFalse(set.contains(4));
303     assertFalse(set.contains((Object) "blah"));
304   }
305 
testContainsAll()306   public void testContainsAll() {
307     ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
308     for (Set<Integer> subset : Sets.powerSet(ImmutableSet.of(1, 2, 3))) {
309       assertTrue(set.containsAll(subset));
310     }
311     for (Set<Integer> subset : Sets.powerSet(ImmutableSet.of(1, 2, 3))) {
312       assertFalse(set.containsAll(Sets.union(subset, ImmutableSet.of(9))));
313     }
314     assertFalse(set.containsAll((Collection<?>) ImmutableSet.of("blah")));
315   }
316 
testRange()317   public void testRange() {
318     assertEquals(Range.closed(1, 3), ContiguousSet.create(Range.closed(1, 3), integers()).range());
319     assertEquals(Range.closed(1, 3), ContiguousSet.closed(1, 3).range());
320     assertEquals(
321         Range.closed(1, 3), ContiguousSet.create(Range.closedOpen(1, 4), integers()).range());
322     assertEquals(Range.closed(1, 3), ContiguousSet.closedOpen(1, 4).range());
323     assertEquals(Range.closed(1, 3), ContiguousSet.create(Range.open(0, 4), integers()).range());
324     assertEquals(
325         Range.closed(1, 3), ContiguousSet.create(Range.openClosed(0, 3), integers()).range());
326 
327     assertEquals(
328         Range.openClosed(0, 3),
329         ContiguousSet.create(Range.closed(1, 3), integers()).range(OPEN, CLOSED));
330     assertEquals(
331         Range.openClosed(0, 3),
332         ContiguousSet.create(Range.closedOpen(1, 4), integers()).range(OPEN, CLOSED));
333     assertEquals(
334         Range.openClosed(0, 3),
335         ContiguousSet.create(Range.open(0, 4), integers()).range(OPEN, CLOSED));
336     assertEquals(
337         Range.openClosed(0, 3),
338         ContiguousSet.create(Range.openClosed(0, 3), integers()).range(OPEN, CLOSED));
339 
340     assertEquals(
341         Range.open(0, 4), ContiguousSet.create(Range.closed(1, 3), integers()).range(OPEN, OPEN));
342     assertEquals(
343         Range.open(0, 4),
344         ContiguousSet.create(Range.closedOpen(1, 4), integers()).range(OPEN, OPEN));
345     assertEquals(
346         Range.open(0, 4), ContiguousSet.create(Range.open(0, 4), integers()).range(OPEN, OPEN));
347     assertEquals(
348         Range.open(0, 4),
349         ContiguousSet.create(Range.openClosed(0, 3), integers()).range(OPEN, OPEN));
350 
351     assertEquals(
352         Range.closedOpen(1, 4),
353         ContiguousSet.create(Range.closed(1, 3), integers()).range(CLOSED, OPEN));
354     assertEquals(
355         Range.closedOpen(1, 4),
356         ContiguousSet.create(Range.closedOpen(1, 4), integers()).range(CLOSED, OPEN));
357     assertEquals(
358         Range.closedOpen(1, 4),
359         ContiguousSet.create(Range.open(0, 4), integers()).range(CLOSED, OPEN));
360     assertEquals(
361         Range.closedOpen(1, 4),
362         ContiguousSet.create(Range.openClosed(0, 3), integers()).range(CLOSED, OPEN));
363   }
364 
testRange_unboundedRange()365   public void testRange_unboundedRange() {
366     assertEquals(
367         Range.closed(Integer.MIN_VALUE, Integer.MAX_VALUE),
368         ContiguousSet.create(Range.<Integer>all(), integers()).range());
369     assertEquals(
370         Range.atLeast(Integer.MIN_VALUE),
371         ContiguousSet.create(Range.<Integer>all(), integers()).range(CLOSED, OPEN));
372     assertEquals(
373         Range.all(), ContiguousSet.create(Range.<Integer>all(), integers()).range(OPEN, OPEN));
374     assertEquals(
375         Range.atMost(Integer.MAX_VALUE),
376         ContiguousSet.create(Range.<Integer>all(), integers()).range(OPEN, CLOSED));
377   }
378 
testIntersection_empty()379   public void testIntersection_empty() {
380     ContiguousSet<Integer> set = ContiguousSet.closed(1, 3);
381     ContiguousSet<Integer> emptySet = ContiguousSet.closedOpen(2, 2);
382     assertEquals(ImmutableSet.of(), set.intersection(emptySet));
383     assertEquals(ImmutableSet.of(), emptySet.intersection(set));
384     assertEquals(
385         ImmutableSet.of(),
386         ContiguousSet.create(Range.closed(-5, -1), integers())
387             .intersection(ContiguousSet.create(Range.open(3, 64), integers())));
388   }
389 
testIntersection()390   public void testIntersection() {
391     ContiguousSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
392     assertEquals(
393         ImmutableSet.of(1, 2, 3),
394         ContiguousSet.create(Range.open(-1, 4), integers()).intersection(set));
395     assertEquals(
396         ImmutableSet.of(1, 2, 3),
397         set.intersection(ContiguousSet.create(Range.open(-1, 4), integers())));
398     assertEquals(
399         ImmutableSet.of(3), set.intersection(ContiguousSet.create(Range.closed(3, 5), integers())));
400   }
401 
testAsList()402   public void testAsList() {
403     ImmutableList<Integer> list = ContiguousSet.create(Range.closed(1, 3), integers()).asList();
404     for (int i = 0; i < 3; i++) {
405       assertEquals(i + 1, list.get(i).intValue());
406     }
407     assertEquals(ImmutableList.of(1, 2, 3), ImmutableList.copyOf(list.iterator()));
408     assertEquals(ImmutableList.of(1, 2, 3), ImmutableList.copyOf(list.toArray(new Integer[0])));
409   }
410 
411   @GwtIncompatible // suite
412   public static class BuiltTests extends TestCase {
suite()413     public static Test suite() {
414       TestSuite suite = new TestSuite();
415 
416       suite.addTest(
417           NavigableSetTestSuiteBuilder.using(new ContiguousSetGenerator())
418               .named("Range.asSet")
419               .withFeatures(
420                   CollectionSize.ANY,
421                   KNOWN_ORDER,
422                   ALLOWS_NULL_QUERIES,
423                   NON_STANDARD_TOSTRING,
424                   RESTRICTS_ELEMENTS)
425               .suppressing(getHoleMethods())
426               .createTestSuite());
427 
428       suite.addTest(
429           NavigableSetTestSuiteBuilder.using(new ContiguousSetHeadsetGenerator())
430               .named("Range.asSet, headset")
431               .withFeatures(
432                   CollectionSize.ANY,
433                   KNOWN_ORDER,
434                   ALLOWS_NULL_QUERIES,
435                   NON_STANDARD_TOSTRING,
436                   RESTRICTS_ELEMENTS)
437               .suppressing(getHoleMethods())
438               .createTestSuite());
439 
440       suite.addTest(
441           NavigableSetTestSuiteBuilder.using(new ContiguousSetTailsetGenerator())
442               .named("Range.asSet, tailset")
443               .withFeatures(
444                   CollectionSize.ANY,
445                   KNOWN_ORDER,
446                   ALLOWS_NULL_QUERIES,
447                   NON_STANDARD_TOSTRING,
448                   RESTRICTS_ELEMENTS)
449               .suppressing(getHoleMethods())
450               .createTestSuite());
451 
452       suite.addTest(
453           NavigableSetTestSuiteBuilder.using(new ContiguousSetSubsetGenerator())
454               .named("Range.asSet, subset")
455               .withFeatures(
456                   CollectionSize.ANY,
457                   KNOWN_ORDER,
458                   ALLOWS_NULL_QUERIES,
459                   NON_STANDARD_TOSTRING,
460                   RESTRICTS_ELEMENTS)
461               .suppressing(getHoleMethods())
462               .createTestSuite());
463 
464       suite.addTest(
465           NavigableSetTestSuiteBuilder.using(new ContiguousSetDescendingGenerator())
466               .named("Range.asSet.descendingSet")
467               .withFeatures(
468                   CollectionSize.ANY,
469                   KNOWN_ORDER,
470                   ALLOWS_NULL_QUERIES,
471                   NON_STANDARD_TOSTRING,
472                   RESTRICTS_ELEMENTS)
473               .suppressing(getHoleMethods())
474               .createTestSuite());
475 
476       return suite;
477     }
478   }
479 }
480