• 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"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 
15 package com.google.common.collect;
16 
17 import static com.google.common.collect.BoundType.OPEN;
18 import static com.google.common.collect.Range.range;
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import com.google.common.annotations.GwtIncompatible;
22 import com.google.common.testing.SerializableTester;
23 import java.util.Arrays;
24 import java.util.List;
25 import java.util.NavigableMap;
26 
27 /**
28  * Tests for {@link TreeRangeSet}.
29  *
30  * @author Louis Wasserman
31  * @author Chris Povirk
32  */
33 @GwtIncompatible // TreeRangeSet
34 public class TreeRangeSetTest extends AbstractRangeSetTest {
35   // TODO(cpovirk): test all of these with the ranges added in the reverse order
36 
37   private static final ImmutableList<Range<Integer>> QUERY_RANGES;
38 
39   private static final int MIN_BOUND = -1;
40   private static final int MAX_BOUND = 1;
41 
42   static {
43     ImmutableList.Builder<Range<Integer>> queryBuilder = ImmutableList.builder();
44 
all()45     queryBuilder.add(Range.<Integer>all());
46 
47     for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
48       for (BoundType boundType : BoundType.values()) {
Range.upTo(i, boundType)49         queryBuilder.add(Range.upTo(i, boundType));
Range.downTo(i, boundType)50         queryBuilder.add(Range.downTo(i, boundType));
51       }
Range.singleton(i)52       queryBuilder.add(Range.singleton(i));
Range.openClosed(i, i)53       queryBuilder.add(Range.openClosed(i, i));
Range.closedOpen(i, i)54       queryBuilder.add(Range.closedOpen(i, i));
55 
56       for (BoundType lowerBoundType : BoundType.values()) {
57         for (int j = i + 1; j <= MAX_BOUND; j++) {
58           for (BoundType upperBoundType : BoundType.values()) {
Range.range(i, lowerBoundType, j, upperBoundType)59             queryBuilder.add(Range.range(i, lowerBoundType, j, upperBoundType));
60           }
61         }
62       }
63     }
64     QUERY_RANGES = queryBuilder.build();
65   }
66 
testViewAgainstExpected(RangeSet<Integer> expected, RangeSet<Integer> view)67   void testViewAgainstExpected(RangeSet<Integer> expected, RangeSet<Integer> view) {
68     assertEquals(expected, view);
69     assertEquals(expected.asRanges(), view.asRanges());
70     assertEquals(expected.isEmpty(), view.isEmpty());
71 
72     if (!expected.isEmpty()) {
73       assertEquals(expected.span(), view.span());
74     }
75 
76     for (int i = MIN_BOUND - 1; i <= MAX_BOUND + 1; i++) {
77       assertEquals(expected.contains(i), view.contains(i));
78       assertEquals(expected.rangeContaining(i), view.rangeContaining(i));
79     }
80     testEnclosing(view);
81     if (view instanceof TreeRangeSet) {
82       testRangesByLowerBounds((TreeRangeSet<Integer>) view, expected.asRanges());
83     }
84   }
85 
86   private static final ImmutableList<Cut<Integer>> CUTS_TO_TEST;
87 
88   static {
89     List<Cut<Integer>> cutsToTest = Lists.newArrayList();
90     for (int i = MIN_BOUND - 1; i <= MAX_BOUND + 1; i++) {
Cut.belowValue(i)91       cutsToTest.add(Cut.belowValue(i));
Cut.aboveValue(i)92       cutsToTest.add(Cut.aboveValue(i));
93     }
aboveAll()94     cutsToTest.add(Cut.<Integer>aboveAll());
belowAll()95     cutsToTest.add(Cut.<Integer>belowAll());
96     CUTS_TO_TEST = ImmutableList.copyOf(cutsToTest);
97   }
98 
testRangesByLowerBounds( TreeRangeSet<Integer> rangeSet, Iterable<Range<Integer>> expectedRanges)99   private void testRangesByLowerBounds(
100       TreeRangeSet<Integer> rangeSet, Iterable<Range<Integer>> expectedRanges) {
101     NavigableMap<Cut<Integer>, Range<Integer>> expectedRangesByLowerBound = Maps.newTreeMap();
102     for (Range<Integer> range : expectedRanges) {
103       expectedRangesByLowerBound.put(range.lowerBound, range);
104     }
105 
106     NavigableMap<Cut<Integer>, Range<Integer>> rangesByLowerBound = rangeSet.rangesByLowerBound;
107     testNavigationAgainstExpected(expectedRangesByLowerBound, rangesByLowerBound, CUTS_TO_TEST);
108   }
109 
testNavigationAgainstExpected( NavigableMap<K, V> expected, NavigableMap<K, V> navigableMap, Iterable<K> keysToTest)110   <K, V> void testNavigationAgainstExpected(
111       NavigableMap<K, V> expected, NavigableMap<K, V> navigableMap, Iterable<K> keysToTest) {
112     for (K key : keysToTest) {
113       assertEquals(expected.lowerEntry(key), navigableMap.lowerEntry(key));
114       assertEquals(expected.floorEntry(key), navigableMap.floorEntry(key));
115       assertEquals(expected.ceilingEntry(key), navigableMap.ceilingEntry(key));
116       assertEquals(expected.higherEntry(key), navigableMap.higherEntry(key));
117       for (boolean inclusive : new boolean[] {false, true}) {
118         assertThat(navigableMap.headMap(key, inclusive).entrySet())
119             .containsExactlyElementsIn(expected.headMap(key, inclusive).entrySet())
120             .inOrder();
121         assertThat(navigableMap.tailMap(key, inclusive).entrySet())
122             .containsExactlyElementsIn(expected.tailMap(key, inclusive).entrySet())
123             .inOrder();
124         assertThat(navigableMap.headMap(key, inclusive).descendingMap().entrySet())
125             .containsExactlyElementsIn(expected.headMap(key, inclusive).descendingMap().entrySet())
126             .inOrder();
127         assertThat(navigableMap.tailMap(key, inclusive).descendingMap().entrySet())
128             .containsExactlyElementsIn(expected.tailMap(key, inclusive).descendingMap().entrySet())
129             .inOrder();
130       }
131     }
132   }
133 
testIntersects(RangeSet<Integer> rangeSet)134   public void testIntersects(RangeSet<Integer> rangeSet) {
135     for (Range<Integer> query : QUERY_RANGES) {
136       boolean expectIntersect = false;
137       for (Range<Integer> expectedRange : rangeSet.asRanges()) {
138         if (expectedRange.isConnected(query) && !expectedRange.intersection(query).isEmpty()) {
139           expectIntersect = true;
140           break;
141         }
142       }
143       assertEquals(
144           rangeSet + " was incorrect on intersects(" + query + ")",
145           expectIntersect,
146           rangeSet.intersects(query));
147     }
148   }
149 
testEnclosing(RangeSet<Integer> rangeSet)150   public void testEnclosing(RangeSet<Integer> rangeSet) {
151     assertTrue(rangeSet.enclosesAll(ImmutableList.<Range<Integer>>of()));
152     for (Range<Integer> query : QUERY_RANGES) {
153       boolean expectEnclose = false;
154       for (Range<Integer> expectedRange : rangeSet.asRanges()) {
155         if (expectedRange.encloses(query)) {
156           expectEnclose = true;
157           break;
158         }
159       }
160 
161       assertEquals(
162           rangeSet + " was incorrect on encloses(" + query + ")",
163           expectEnclose,
164           rangeSet.encloses(query));
165       assertEquals(
166           rangeSet + " was incorrect on enclosesAll([" + query + "])",
167           expectEnclose,
168           rangeSet.enclosesAll(ImmutableList.of(query)));
169     }
170   }
171 
testAllSingleRangesComplementAgainstRemove()172   public void testAllSingleRangesComplementAgainstRemove() {
173     for (Range<Integer> range : QUERY_RANGES) {
174       TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
175       rangeSet.add(range);
176 
177       TreeRangeSet<Integer> complement = TreeRangeSet.create();
178       complement.add(Range.<Integer>all());
179       complement.remove(range);
180 
181       assertEquals(complement, rangeSet.complement());
182       assertThat(rangeSet.complement().asRanges())
183           .containsExactlyElementsIn(complement.asRanges())
184           .inOrder();
185     }
186   }
187 
testInvariantsEmpty()188   public void testInvariantsEmpty() {
189     testInvariants(TreeRangeSet.create());
190   }
191 
testEmptyIntersecting()192   public void testEmptyIntersecting() {
193     testIntersects(TreeRangeSet.<Integer>create());
194     testIntersects(TreeRangeSet.<Integer>create().complement());
195   }
196 
testAllSingleRangesIntersecting()197   public void testAllSingleRangesIntersecting() {
198     for (Range<Integer> range : QUERY_RANGES) {
199       TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
200       rangeSet.add(range);
201       testIntersects(rangeSet);
202       testIntersects(rangeSet.complement());
203     }
204   }
205 
testAllTwoRangesIntersecting()206   public void testAllTwoRangesIntersecting() {
207     for (Range<Integer> range1 : QUERY_RANGES) {
208       for (Range<Integer> range2 : QUERY_RANGES) {
209         TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
210         rangeSet.add(range1);
211         rangeSet.add(range2);
212         testIntersects(rangeSet);
213         testIntersects(rangeSet.complement());
214       }
215     }
216   }
217 
testEmptyEnclosing()218   public void testEmptyEnclosing() {
219     testEnclosing(TreeRangeSet.<Integer>create());
220     testEnclosing(TreeRangeSet.<Integer>create().complement());
221   }
222 
testAllSingleRangesEnclosing()223   public void testAllSingleRangesEnclosing() {
224     for (Range<Integer> range : QUERY_RANGES) {
225       TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
226       rangeSet.add(range);
227       testEnclosing(rangeSet);
228       testEnclosing(rangeSet.complement());
229     }
230   }
231 
testAllTwoRangesEnclosing()232   public void testAllTwoRangesEnclosing() {
233     for (Range<Integer> range1 : QUERY_RANGES) {
234       for (Range<Integer> range2 : QUERY_RANGES) {
235         TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
236         rangeSet.add(range1);
237         rangeSet.add(range2);
238         testEnclosing(rangeSet);
239         testEnclosing(rangeSet.complement());
240       }
241     }
242   }
243 
testCreateCopy()244   public void testCreateCopy() {
245     for (Range<Integer> range1 : QUERY_RANGES) {
246       for (Range<Integer> range2 : QUERY_RANGES) {
247         TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
248         rangeSet.add(range1);
249         rangeSet.add(range2);
250 
251         assertEquals(rangeSet, TreeRangeSet.create(rangeSet));
252       }
253     }
254   }
255 
expectedSubRangeSet( RangeSet<Integer> rangeSet, Range<Integer> subRange)256   private RangeSet<Integer> expectedSubRangeSet(
257       RangeSet<Integer> rangeSet, Range<Integer> subRange) {
258     RangeSet<Integer> expected = TreeRangeSet.create();
259     for (Range<Integer> range : rangeSet.asRanges()) {
260       if (range.isConnected(subRange)) {
261         expected.add(range.intersection(subRange));
262       }
263     }
264     return expected;
265   }
266 
expectedComplement(RangeSet<Integer> rangeSet)267   private RangeSet<Integer> expectedComplement(RangeSet<Integer> rangeSet) {
268     RangeSet<Integer> expected = TreeRangeSet.create();
269     expected.add(Range.<Integer>all());
270     expected.removeAll(rangeSet);
271     return expected;
272   }
273 
274 
testSubRangeSet()275   public void testSubRangeSet() {
276     for (Range<Integer> range1 : QUERY_RANGES) {
277       for (Range<Integer> range2 : QUERY_RANGES) {
278         TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
279         rangeSet.add(range1);
280         rangeSet.add(range2);
281         for (Range<Integer> subRange : QUERY_RANGES) {
282           testViewAgainstExpected(
283               expectedSubRangeSet(rangeSet, subRange), rangeSet.subRangeSet(subRange));
284         }
285       }
286     }
287   }
288 
testSubRangeSetAdd()289   public void testSubRangeSetAdd() {
290     TreeRangeSet<Integer> set = TreeRangeSet.create();
291     Range<Integer> range = Range.closedOpen(0, 5);
292     set.subRangeSet(range).add(range);
293   }
294 
testSubRangeSetReplaceAdd()295   public void testSubRangeSetReplaceAdd() {
296     TreeRangeSet<Integer> set = TreeRangeSet.create();
297     Range<Integer> range = Range.closedOpen(0, 5);
298     set.add(range);
299     set.subRangeSet(range).add(range);
300   }
301 
testComplement()302   public void testComplement() {
303     for (Range<Integer> range1 : QUERY_RANGES) {
304       for (Range<Integer> range2 : QUERY_RANGES) {
305         TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
306         rangeSet.add(range1);
307         rangeSet.add(range2);
308         testViewAgainstExpected(expectedComplement(rangeSet), rangeSet.complement());
309       }
310     }
311   }
312 
313 
testSubRangeSetOfComplement()314   public void testSubRangeSetOfComplement() {
315     for (Range<Integer> range1 : QUERY_RANGES) {
316       for (Range<Integer> range2 : QUERY_RANGES) {
317         TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
318         rangeSet.add(range1);
319         rangeSet.add(range2);
320         for (Range<Integer> subRange : QUERY_RANGES) {
321           testViewAgainstExpected(
322               expectedSubRangeSet(expectedComplement(rangeSet), subRange),
323               rangeSet.complement().subRangeSet(subRange));
324         }
325       }
326     }
327   }
328 
329 
testComplementOfSubRangeSet()330   public void testComplementOfSubRangeSet() {
331     for (Range<Integer> range1 : QUERY_RANGES) {
332       for (Range<Integer> range2 : QUERY_RANGES) {
333         TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
334         rangeSet.add(range1);
335         rangeSet.add(range2);
336         for (Range<Integer> subRange : QUERY_RANGES) {
337           testViewAgainstExpected(
338               expectedComplement(expectedSubRangeSet(rangeSet, subRange)),
339               rangeSet.subRangeSet(subRange).complement());
340         }
341       }
342     }
343   }
344 
testRangesByUpperBound()345   public void testRangesByUpperBound() {
346     for (Range<Integer> range1 : QUERY_RANGES) {
347       for (Range<Integer> range2 : QUERY_RANGES) {
348         TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
349         rangeSet.add(range1);
350         rangeSet.add(range2);
351 
352         NavigableMap<Cut<Integer>, Range<Integer>> expectedRangesByUpperBound = Maps.newTreeMap();
353         for (Range<Integer> range : rangeSet.asRanges()) {
354           expectedRangesByUpperBound.put(range.upperBound, range);
355         }
356         testNavigationAgainstExpected(
357             expectedRangesByUpperBound,
358             new TreeRangeSet.RangesByUpperBound<Integer>(rangeSet.rangesByLowerBound),
359             CUTS_TO_TEST);
360       }
361     }
362   }
363 
testMergesConnectedWithOverlap()364   public void testMergesConnectedWithOverlap() {
365     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
366     rangeSet.add(Range.closed(1, 4));
367     rangeSet.add(Range.open(2, 6));
368     testInvariants(rangeSet);
369     assertThat(rangeSet.asRanges()).contains(Range.closedOpen(1, 6));
370     assertThat(rangeSet.complement().asRanges())
371         .containsExactly(Range.lessThan(1), Range.atLeast(6))
372         .inOrder();
373   }
374 
testMergesConnectedDisjoint()375   public void testMergesConnectedDisjoint() {
376     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
377     rangeSet.add(Range.closed(1, 4));
378     rangeSet.add(Range.open(4, 6));
379     testInvariants(rangeSet);
380     assertThat(rangeSet.asRanges()).contains(Range.closedOpen(1, 6));
381     assertThat(rangeSet.complement().asRanges())
382         .containsExactly(Range.lessThan(1), Range.atLeast(6))
383         .inOrder();
384   }
385 
testIgnoresSmallerSharingNoBound()386   public void testIgnoresSmallerSharingNoBound() {
387     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
388     rangeSet.add(Range.closed(1, 6));
389     rangeSet.add(Range.open(2, 4));
390     testInvariants(rangeSet);
391     assertThat(rangeSet.asRanges()).contains(Range.closed(1, 6));
392     assertThat(rangeSet.complement().asRanges())
393         .containsExactly(Range.lessThan(1), Range.greaterThan(6))
394         .inOrder();
395   }
396 
testIgnoresSmallerSharingLowerBound()397   public void testIgnoresSmallerSharingLowerBound() {
398     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
399     rangeSet.add(Range.closed(1, 6));
400     rangeSet.add(Range.closed(1, 4));
401     testInvariants(rangeSet);
402     assertThat(rangeSet.asRanges()).contains(Range.closed(1, 6));
403     assertThat(rangeSet.complement().asRanges())
404         .containsExactly(Range.lessThan(1), Range.greaterThan(6))
405         .inOrder();
406   }
407 
testIgnoresSmallerSharingUpperBound()408   public void testIgnoresSmallerSharingUpperBound() {
409     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
410     rangeSet.add(Range.closed(1, 6));
411     rangeSet.add(Range.closed(3, 6));
412     testInvariants(rangeSet);
413     assertThat(rangeSet.asRanges()).contains(Range.closed(1, 6));
414     assertThat(rangeSet.complement().asRanges())
415         .containsExactly(Range.lessThan(1), Range.greaterThan(6))
416         .inOrder();
417   }
418 
testIgnoresEqual()419   public void testIgnoresEqual() {
420     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
421     rangeSet.add(Range.closed(1, 6));
422     rangeSet.add(Range.closed(1, 6));
423     testInvariants(rangeSet);
424     assertThat(rangeSet.asRanges()).contains(Range.closed(1, 6));
425     assertThat(rangeSet.complement().asRanges())
426         .containsExactly(Range.lessThan(1), Range.greaterThan(6))
427         .inOrder();
428   }
429 
testExtendSameLowerBound()430   public void testExtendSameLowerBound() {
431     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
432     rangeSet.add(Range.closed(1, 4));
433     rangeSet.add(Range.closed(1, 6));
434     testInvariants(rangeSet);
435     assertThat(rangeSet.asRanges()).contains(Range.closed(1, 6));
436     assertThat(rangeSet.complement().asRanges())
437         .containsExactly(Range.lessThan(1), Range.greaterThan(6))
438         .inOrder();
439   }
440 
testExtendSameUpperBound()441   public void testExtendSameUpperBound() {
442     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
443     rangeSet.add(Range.closed(3, 6));
444     rangeSet.add(Range.closed(1, 6));
445     testInvariants(rangeSet);
446     assertThat(rangeSet.asRanges()).contains(Range.closed(1, 6));
447     assertThat(rangeSet.complement().asRanges())
448         .containsExactly(Range.lessThan(1), Range.greaterThan(6))
449         .inOrder();
450   }
451 
testExtendBothDirections()452   public void testExtendBothDirections() {
453     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
454     rangeSet.add(Range.closed(3, 4));
455     rangeSet.add(Range.closed(1, 6));
456     testInvariants(rangeSet);
457     assertThat(rangeSet.asRanges()).contains(Range.closed(1, 6));
458     assertThat(rangeSet.complement().asRanges())
459         .containsExactly(Range.lessThan(1), Range.greaterThan(6))
460         .inOrder();
461   }
462 
testAddEmpty()463   public void testAddEmpty() {
464     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
465     rangeSet.add(Range.closedOpen(3, 3));
466     testInvariants(rangeSet);
467     assertThat(rangeSet.asRanges()).isEmpty();
468     assertThat(rangeSet.complement().asRanges()).containsExactly(Range.<Integer>all());
469   }
470 
testFillHoleExactly()471   public void testFillHoleExactly() {
472     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
473     rangeSet.add(Range.closedOpen(1, 3));
474     rangeSet.add(Range.closedOpen(4, 6));
475     rangeSet.add(Range.closedOpen(3, 4));
476     testInvariants(rangeSet);
477     assertThat(rangeSet.asRanges()).contains(Range.closedOpen(1, 6));
478     assertThat(rangeSet.complement().asRanges())
479         .containsExactly(Range.lessThan(1), Range.atLeast(6))
480         .inOrder();
481   }
482 
testFillHoleWithOverlap()483   public void testFillHoleWithOverlap() {
484     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
485     rangeSet.add(Range.closedOpen(1, 3));
486     rangeSet.add(Range.closedOpen(4, 6));
487     rangeSet.add(Range.closedOpen(2, 5));
488     testInvariants(rangeSet);
489     assertThat(rangeSet.asRanges()).contains(Range.closedOpen(1, 6));
490     assertThat(rangeSet.complement().asRanges())
491         .containsExactly(Range.lessThan(1), Range.atLeast(6))
492         .inOrder();
493   }
494 
testAddManyPairs()495   public void testAddManyPairs() {
496     for (int aLow = 0; aLow < 6; aLow++) {
497       for (int aHigh = 0; aHigh < 6; aHigh++) {
498         for (BoundType aLowType : BoundType.values()) {
499           for (BoundType aHighType : BoundType.values()) {
500             if ((aLow == aHigh && aLowType == OPEN && aHighType == OPEN) || aLow > aHigh) {
501               continue;
502             }
503             for (int bLow = 0; bLow < 6; bLow++) {
504               for (int bHigh = 0; bHigh < 6; bHigh++) {
505                 for (BoundType bLowType : BoundType.values()) {
506                   for (BoundType bHighType : BoundType.values()) {
507                     if ((bLow == bHigh && bLowType == OPEN && bHighType == OPEN) || bLow > bHigh) {
508                       continue;
509                     }
510                     doPairTest(
511                         range(aLow, aLowType, aHigh, aHighType),
512                         range(bLow, bLowType, bHigh, bHighType));
513                   }
514                 }
515               }
516             }
517           }
518         }
519       }
520     }
521   }
522 
doPairTest(Range<Integer> a, Range<Integer> b)523   private static void doPairTest(Range<Integer> a, Range<Integer> b) {
524     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
525     rangeSet.add(a);
526     rangeSet.add(b);
527     if (a.isEmpty() && b.isEmpty()) {
528       assertThat(rangeSet.asRanges()).isEmpty();
529     } else if (a.isEmpty()) {
530       assertThat(rangeSet.asRanges()).contains(b);
531     } else if (b.isEmpty()) {
532       assertThat(rangeSet.asRanges()).contains(a);
533     } else if (a.isConnected(b)) {
534       assertThat(rangeSet.asRanges()).containsExactly(a.span(b));
535     } else {
536       if (a.lowerEndpoint() < b.lowerEndpoint()) {
537         assertThat(rangeSet.asRanges()).containsExactly(a, b).inOrder();
538       } else {
539         assertThat(rangeSet.asRanges()).containsExactly(b, a).inOrder();
540       }
541     }
542   }
543 
testRemoveEmpty()544   public void testRemoveEmpty() {
545     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
546     rangeSet.add(Range.closed(1, 6));
547     rangeSet.remove(Range.closedOpen(3, 3));
548     testInvariants(rangeSet);
549     assertThat(rangeSet.asRanges()).contains(Range.closed(1, 6));
550     assertThat(rangeSet.complement().asRanges())
551         .containsExactly(Range.lessThan(1), Range.greaterThan(6))
552         .inOrder();
553   }
554 
testRemovePartSharingLowerBound()555   public void testRemovePartSharingLowerBound() {
556     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
557     rangeSet.add(Range.closed(3, 5));
558     rangeSet.remove(Range.closedOpen(3, 5));
559     testInvariants(rangeSet);
560     assertThat(rangeSet.asRanges()).contains(Range.singleton(5));
561     assertThat(rangeSet.complement().asRanges())
562         .containsExactly(Range.lessThan(5), Range.greaterThan(5))
563         .inOrder();
564   }
565 
testRemovePartSharingUpperBound()566   public void testRemovePartSharingUpperBound() {
567     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
568     rangeSet.add(Range.closed(3, 5));
569     rangeSet.remove(Range.openClosed(3, 5));
570     testInvariants(rangeSet);
571     assertThat(rangeSet.asRanges()).contains(Range.singleton(3));
572     assertThat(rangeSet.complement().asRanges())
573         .containsExactly(Range.lessThan(3), Range.greaterThan(3))
574         .inOrder();
575   }
576 
testRemoveMiddle()577   public void testRemoveMiddle() {
578     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
579     rangeSet.add(Range.atMost(6));
580     rangeSet.remove(Range.closedOpen(3, 4));
581     testInvariants(rangeSet);
582     assertThat(rangeSet.asRanges())
583         .containsExactly(Range.lessThan(3), Range.closed(4, 6))
584         .inOrder();
585     assertThat(rangeSet.complement().asRanges())
586         .containsExactly(Range.closedOpen(3, 4), Range.greaterThan(6))
587         .inOrder();
588   }
589 
testRemoveNoOverlap()590   public void testRemoveNoOverlap() {
591     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
592     rangeSet.add(Range.closed(3, 6));
593     rangeSet.remove(Range.closedOpen(1, 3));
594     testInvariants(rangeSet);
595     assertThat(rangeSet.asRanges()).containsExactly(Range.closed(3, 6));
596   }
597 
testRemovePartFromBelowLowerBound()598   public void testRemovePartFromBelowLowerBound() {
599     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
600     rangeSet.add(Range.closed(3, 6));
601     rangeSet.remove(Range.closed(1, 3));
602     testInvariants(rangeSet);
603     assertThat(rangeSet.asRanges()).containsExactly(Range.openClosed(3, 6));
604   }
605 
testRemovePartFromAboveUpperBound()606   public void testRemovePartFromAboveUpperBound() {
607     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
608     rangeSet.add(Range.closed(3, 6));
609     rangeSet.remove(Range.closed(6, 9));
610     testInvariants(rangeSet);
611     assertThat(rangeSet.asRanges()).containsExactly(Range.closedOpen(3, 6));
612   }
613 
testRemoveExact()614   public void testRemoveExact() {
615     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
616     rangeSet.add(Range.closed(3, 6));
617     rangeSet.remove(Range.closed(3, 6));
618     testInvariants(rangeSet);
619     assertThat(rangeSet.asRanges()).isEmpty();
620   }
621 
testRemoveAllFromBelowLowerBound()622   public void testRemoveAllFromBelowLowerBound() {
623     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
624     rangeSet.add(Range.closed(3, 6));
625     rangeSet.remove(Range.closed(2, 6));
626     testInvariants(rangeSet);
627     assertThat(rangeSet.asRanges()).isEmpty();
628   }
629 
testRemoveAllFromAboveUpperBound()630   public void testRemoveAllFromAboveUpperBound() {
631     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
632     rangeSet.add(Range.closed(3, 6));
633     rangeSet.remove(Range.closed(3, 7));
634     testInvariants(rangeSet);
635     assertThat(rangeSet.asRanges()).isEmpty();
636   }
637 
testRemoveAllExtendingBothDirections()638   public void testRemoveAllExtendingBothDirections() {
639     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
640     rangeSet.add(Range.closed(3, 6));
641     rangeSet.remove(Range.closed(2, 7));
642     testInvariants(rangeSet);
643     assertThat(rangeSet.asRanges()).isEmpty();
644   }
645 
testRangeContaining1()646   public void testRangeContaining1() {
647     RangeSet<Integer> rangeSet = TreeRangeSet.create();
648     rangeSet.add(Range.closed(3, 10));
649     assertEquals(Range.closed(3, 10), rangeSet.rangeContaining(5));
650     assertTrue(rangeSet.contains(5));
651     assertNull(rangeSet.rangeContaining(1));
652     assertFalse(rangeSet.contains(1));
653   }
654 
testRangeContaining2()655   public void testRangeContaining2() {
656     RangeSet<Integer> rangeSet = TreeRangeSet.create();
657     rangeSet.add(Range.closed(3, 10));
658     rangeSet.remove(Range.open(5, 7));
659     assertEquals(Range.closed(3, 5), rangeSet.rangeContaining(5));
660     assertTrue(rangeSet.contains(5));
661     assertEquals(Range.closed(7, 10), rangeSet.rangeContaining(8));
662     assertTrue(rangeSet.contains(8));
663     assertNull(rangeSet.rangeContaining(6));
664     assertFalse(rangeSet.contains(6));
665   }
666 
testAddAll()667   public void testAddAll() {
668     RangeSet<Integer> rangeSet = TreeRangeSet.create();
669     rangeSet.add(Range.closed(3, 10));
670     rangeSet.addAll(Arrays.asList(Range.open(1, 3), Range.closed(5, 8), Range.closed(9, 11)));
671     assertThat(rangeSet.asRanges()).containsExactly(Range.openClosed(1, 11)).inOrder();
672   }
673 
testRemoveAll()674   public void testRemoveAll() {
675     RangeSet<Integer> rangeSet = TreeRangeSet.create();
676     rangeSet.add(Range.closed(3, 10));
677     rangeSet.removeAll(Arrays.asList(Range.open(1, 3), Range.closed(5, 8), Range.closed(9, 11)));
678     assertThat(rangeSet.asRanges())
679         .containsExactly(Range.closedOpen(3, 5), Range.open(8, 9))
680         .inOrder();
681   }
682 
683   @GwtIncompatible // SerializableTester
testSerialization()684   public void testSerialization() {
685     RangeSet<Integer> rangeSet = TreeRangeSet.create();
686     rangeSet.add(Range.closed(3, 10));
687     rangeSet.remove(Range.open(5, 7));
688     SerializableTester.reserializeAndAssert(rangeSet);
689   }
690 }
691