• 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 
23 import java.util.List;
24 import java.util.NavigableMap;
25 
26 /**
27  * Tests for {@link TreeRangeSet}.
28  *
29  * @author Louis Wasserman
30  * @author Chris Povirk
31  */
32 @GwtIncompatible("TreeRangeSet")
33 public class TreeRangeSetTest extends AbstractRangeSetTest {
34   // TODO(cpovirk): test all of these with the ranges added in the reverse order
35 
36   private static final ImmutableList<Range<Integer>> QUERY_RANGES;
37 
38   private static final int MIN_BOUND = -1;
39   private static final int MAX_BOUND = 1;
40 
41   static {
42     ImmutableList.Builder<Range<Integer>> queryBuilder = ImmutableList.builder();
43 
all()44     queryBuilder.add(Range.<Integer>all());
45 
46     for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
47       for (BoundType boundType : BoundType.values()) {
Range.upTo(i, boundType)48         queryBuilder.add(Range.upTo(i, boundType));
Range.downTo(i, boundType)49         queryBuilder.add(Range.downTo(i, boundType));
50       }
Range.singleton(i)51       queryBuilder.add(Range.singleton(i));
Range.openClosed(i, i)52       queryBuilder.add(Range.openClosed(i, i));
Range.closedOpen(i, i)53       queryBuilder.add(Range.closedOpen(i, i));
54 
55       for (BoundType lowerBoundType : BoundType.values()) {
56         for (int j = i + 1; j <= MAX_BOUND; j++) {
57           for (BoundType upperBoundType : BoundType.values()) {
Range.range(i, lowerBoundType, j, upperBoundType)58             queryBuilder.add(Range.range(i, lowerBoundType, j, upperBoundType));
59           }
60         }
61       }
62     }
63     QUERY_RANGES = queryBuilder.build();
64   }
65 
testViewAgainstExpected(RangeSet<Integer> expected, RangeSet<Integer> view)66   void testViewAgainstExpected(RangeSet<Integer> expected, RangeSet<Integer> view) {
67     assertEquals(expected, view);
68     assertEquals(expected.asRanges(), view.asRanges());
69     assertEquals(expected.isEmpty(), view.isEmpty());
70 
71     if (!expected.isEmpty()) {
72       assertEquals(expected.span(), view.span());
73     }
74 
75     for (int i = MIN_BOUND - 1; i <= MAX_BOUND + 1; i++) {
76       assertEquals(expected.contains(i), view.contains(i));
77       assertEquals(expected.rangeContaining(i), view.rangeContaining(i));
78     }
79     testEnclosing(view);
80     if (view instanceof TreeRangeSet) {
81       testRangesByLowerBounds((TreeRangeSet<Integer>) view, expected.asRanges());
82     }
83   }
84 
85   private static final ImmutableList<Cut<Integer>> CUTS_TO_TEST;
86 
87   static {
88     List<Cut<Integer>> cutsToTest = Lists.newArrayList();
89     for (int i = MIN_BOUND - 1; i <= MAX_BOUND + 1; i++) {
Cut.belowValue(i)90       cutsToTest.add(Cut.belowValue(i));
Cut.aboveValue(i)91       cutsToTest.add(Cut.aboveValue(i));
92     }
aboveAll()93     cutsToTest.add(Cut.<Integer>aboveAll());
belowAll()94     cutsToTest.add(Cut.<Integer>belowAll());
95     CUTS_TO_TEST = ImmutableList.copyOf(cutsToTest);
96   }
97 
testRangesByLowerBounds( TreeRangeSet<Integer> rangeSet, Iterable<Range<Integer>> expectedRanges)98   private void testRangesByLowerBounds(
99       TreeRangeSet<Integer> rangeSet, Iterable<Range<Integer>> expectedRanges) {
100     NavigableMap<Cut<Integer>, Range<Integer>> expectedRangesByLowerBound = Maps.newTreeMap();
101     for (Range<Integer> range : expectedRanges) {
102       expectedRangesByLowerBound.put(range.lowerBound, range);
103     }
104 
105     NavigableMap<Cut<Integer>, Range<Integer>> rangesByLowerBound = rangeSet.rangesByLowerBound;
106     testNavigationAgainstExpected(expectedRangesByLowerBound, rangesByLowerBound, CUTS_TO_TEST);
107   }
108 
testNavigationAgainstExpected( NavigableMap<K, V> expected, NavigableMap<K, V> navigableMap, Iterable<K> keysToTest)109   <K, V> void testNavigationAgainstExpected(
110       NavigableMap<K, V> expected, NavigableMap<K, V> navigableMap, Iterable<K> keysToTest) {
111     for (K key : keysToTest) {
112       assertEquals(expected.lowerEntry(key), navigableMap.lowerEntry(key));
113       assertEquals(expected.floorEntry(key), navigableMap.floorEntry(key));
114       assertEquals(expected.ceilingEntry(key), navigableMap.ceilingEntry(key));
115       assertEquals(expected.higherEntry(key), navigableMap.higherEntry(key));
116       for (boolean inclusive : new boolean[] {false, true}) {
117         assertThat(navigableMap.headMap(key, inclusive).entrySet())
118             .has().exactlyAs(expected.headMap(key, inclusive).entrySet()).inOrder();
119         assertThat(navigableMap.tailMap(key, inclusive).entrySet())
120             .has().exactlyAs(expected.tailMap(key, inclusive).entrySet()).inOrder();
121         assertThat(navigableMap.headMap(key, inclusive).descendingMap().entrySet())
122             .has().exactlyAs(expected.headMap(key, inclusive).descendingMap().entrySet()).inOrder();
123         assertThat(navigableMap.tailMap(key, inclusive).descendingMap().entrySet())
124             .has().exactlyAs(expected.tailMap(key, inclusive).descendingMap().entrySet()).inOrder();
125       }
126     }
127   }
128 
testEnclosing(RangeSet<Integer> rangeSet)129   public void testEnclosing(RangeSet<Integer> rangeSet) {
130     for (Range<Integer> query : QUERY_RANGES) {
131       boolean expectEnclose = false;
132       for (Range<Integer> expectedRange : rangeSet.asRanges()) {
133         if (expectedRange.encloses(query)) {
134           expectEnclose = true;
135           break;
136         }
137       }
138 
139       assertEquals(rangeSet + " was incorrect on encloses(" + query + ")", expectEnclose,
140           rangeSet.encloses(query));
141     }
142   }
143 
testAllSingleRangesComplementAgainstRemove()144   public void testAllSingleRangesComplementAgainstRemove() {
145     for (Range<Integer> range : QUERY_RANGES) {
146       TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
147       rangeSet.add(range);
148 
149       TreeRangeSet<Integer> complement = TreeRangeSet.create();
150       complement.add(Range.<Integer>all());
151       complement.remove(range);
152 
153       assertEquals(complement, rangeSet.complement());
154       assertThat(rangeSet.complement().asRanges())
155           .has().exactlyAs(complement.asRanges()).inOrder();
156     }
157   }
158 
testInvariantsEmpty()159   public void testInvariantsEmpty() {
160     testInvariants(TreeRangeSet.create());
161   }
162 
testAllSingleRangesEnclosing()163   public void testAllSingleRangesEnclosing() {
164     for (Range<Integer> range : QUERY_RANGES) {
165       TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
166       rangeSet.add(range);
167       testEnclosing(rangeSet);
168       testEnclosing(rangeSet.complement());
169     }
170   }
171 
testAllTwoRangesEnclosing()172   public void testAllTwoRangesEnclosing() {
173     for (Range<Integer> range1 : QUERY_RANGES) {
174       for (Range<Integer> range2 : QUERY_RANGES) {
175         TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
176         rangeSet.add(range1);
177         rangeSet.add(range2);
178         testEnclosing(rangeSet);
179         testEnclosing(rangeSet.complement());
180       }
181     }
182   }
183 
testCreateCopy()184   public void testCreateCopy() {
185     for (Range<Integer> range1 : QUERY_RANGES) {
186       for (Range<Integer> range2 : QUERY_RANGES) {
187         TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
188         rangeSet.add(range1);
189         rangeSet.add(range2);
190 
191         assertEquals(rangeSet, TreeRangeSet.create(rangeSet));
192       }
193     }
194   }
195 
expectedSubRangeSet( RangeSet<Integer> rangeSet, Range<Integer> subRange)196   private RangeSet<Integer> expectedSubRangeSet(
197       RangeSet<Integer> rangeSet, Range<Integer> subRange) {
198     RangeSet<Integer> expected = TreeRangeSet.create();
199     for (Range<Integer> range : rangeSet.asRanges()) {
200       if (range.isConnected(subRange)) {
201         expected.add(range.intersection(subRange));
202       }
203     }
204     return expected;
205   }
206 
expectedComplement(RangeSet<Integer> rangeSet)207   private RangeSet<Integer> expectedComplement(RangeSet<Integer> rangeSet) {
208     RangeSet<Integer> expected = TreeRangeSet.create();
209     expected.add(Range.<Integer>all());
210     expected.removeAll(rangeSet);
211     return expected;
212   }
213 
testSubRangeSet()214   public void testSubRangeSet() {
215     for (Range<Integer> range1 : QUERY_RANGES) {
216       for (Range<Integer> range2 : QUERY_RANGES) {
217         TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
218         rangeSet.add(range1);
219         rangeSet.add(range2);
220         for (Range<Integer> subRange : QUERY_RANGES) {
221           testViewAgainstExpected(
222               expectedSubRangeSet(rangeSet, subRange), rangeSet.subRangeSet(subRange));
223         }
224       }
225     }
226   }
227 
testComplement()228   public void testComplement() {
229     for (Range<Integer> range1 : QUERY_RANGES) {
230       for (Range<Integer> range2 : QUERY_RANGES) {
231         TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
232         rangeSet.add(range1);
233         rangeSet.add(range2);
234         testViewAgainstExpected(expectedComplement(rangeSet), rangeSet.complement());
235       }
236     }
237   }
238 
testSubRangeSetOfComplement()239   public void testSubRangeSetOfComplement() {
240     for (Range<Integer> range1 : QUERY_RANGES) {
241       for (Range<Integer> range2 : QUERY_RANGES) {
242         TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
243         rangeSet.add(range1);
244         rangeSet.add(range2);
245         for (Range<Integer> subRange : QUERY_RANGES) {
246           testViewAgainstExpected(
247               expectedSubRangeSet(expectedComplement(rangeSet), subRange),
248               rangeSet.complement().subRangeSet(subRange));
249         }
250       }
251     }
252   }
253 
testComplementOfSubRangeSet()254   public void testComplementOfSubRangeSet() {
255     for (Range<Integer> range1 : QUERY_RANGES) {
256       for (Range<Integer> range2 : QUERY_RANGES) {
257         TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
258         rangeSet.add(range1);
259         rangeSet.add(range2);
260         for (Range<Integer> subRange : QUERY_RANGES) {
261           testViewAgainstExpected(
262               expectedComplement(expectedSubRangeSet(rangeSet, subRange)),
263               rangeSet.subRangeSet(subRange).complement());
264         }
265       }
266     }
267   }
268 
testRangesByUpperBound()269   public void testRangesByUpperBound() {
270     for (Range<Integer> range1 : QUERY_RANGES) {
271       for (Range<Integer> range2 : QUERY_RANGES) {
272         TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
273         rangeSet.add(range1);
274         rangeSet.add(range2);
275 
276         NavigableMap<Cut<Integer>, Range<Integer>> expectedRangesByUpperBound = Maps.newTreeMap();
277         for (Range<Integer> range : rangeSet.asRanges()) {
278           expectedRangesByUpperBound.put(range.upperBound, range);
279         }
280         testNavigationAgainstExpected(expectedRangesByUpperBound,
281             new TreeRangeSet.RangesByUpperBound<Integer>(rangeSet.rangesByLowerBound),
282             CUTS_TO_TEST);
283       }
284     }
285   }
286 
testMergesConnectedWithOverlap()287   public void testMergesConnectedWithOverlap() {
288     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
289     rangeSet.add(Range.closed(1, 4));
290     rangeSet.add(Range.open(2, 6));
291     testInvariants(rangeSet);
292     assertThat(rangeSet.asRanges()).has().item(Range.closedOpen(1, 6));
293     assertThat(rangeSet.complement().asRanges())
294         .has().exactly(Range.lessThan(1), Range.atLeast(6)).inOrder();
295   }
296 
testMergesConnectedDisjoint()297   public void testMergesConnectedDisjoint() {
298     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
299     rangeSet.add(Range.closed(1, 4));
300     rangeSet.add(Range.open(4, 6));
301     testInvariants(rangeSet);
302     assertThat(rangeSet.asRanges()).has().item(Range.closedOpen(1, 6));
303     assertThat(rangeSet.complement().asRanges())
304         .has().exactly(Range.lessThan(1), Range.atLeast(6)).inOrder();
305   }
306 
testIgnoresSmallerSharingNoBound()307   public void testIgnoresSmallerSharingNoBound() {
308     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
309     rangeSet.add(Range.closed(1, 6));
310     rangeSet.add(Range.open(2, 4));
311     testInvariants(rangeSet);
312     assertThat(rangeSet.asRanges()).has().item(Range.closed(1, 6));
313     assertThat(rangeSet.complement().asRanges())
314         .has().exactly(Range.lessThan(1), Range.greaterThan(6)).inOrder();
315   }
316 
testIgnoresSmallerSharingLowerBound()317   public void testIgnoresSmallerSharingLowerBound() {
318     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
319     rangeSet.add(Range.closed(1, 6));
320     rangeSet.add(Range.closed(1, 4));
321     testInvariants(rangeSet);
322     assertThat(rangeSet.asRanges()).has().item(Range.closed(1, 6));
323     assertThat(rangeSet.complement().asRanges())
324         .has().exactly(Range.lessThan(1), Range.greaterThan(6)).inOrder();
325   }
326 
testIgnoresSmallerSharingUpperBound()327   public void testIgnoresSmallerSharingUpperBound() {
328     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
329     rangeSet.add(Range.closed(1, 6));
330     rangeSet.add(Range.closed(3, 6));
331     testInvariants(rangeSet);
332     assertThat(rangeSet.asRanges()).has().item(Range.closed(1, 6));
333     assertThat(rangeSet.complement().asRanges())
334         .has().exactly(Range.lessThan(1), Range.greaterThan(6)).inOrder();
335   }
336 
testIgnoresEqual()337   public void testIgnoresEqual() {
338     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
339     rangeSet.add(Range.closed(1, 6));
340     rangeSet.add(Range.closed(1, 6));
341     testInvariants(rangeSet);
342     assertThat(rangeSet.asRanges()).has().item(Range.closed(1, 6));
343     assertThat(rangeSet.complement().asRanges())
344         .has().exactly(Range.lessThan(1), Range.greaterThan(6)).inOrder();
345   }
346 
testExtendSameLowerBound()347   public void testExtendSameLowerBound() {
348     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
349     rangeSet.add(Range.closed(1, 4));
350     rangeSet.add(Range.closed(1, 6));
351     testInvariants(rangeSet);
352     assertThat(rangeSet.asRanges()).has().item(Range.closed(1, 6));
353     assertThat(rangeSet.complement().asRanges())
354         .has().exactly(Range.lessThan(1), Range.greaterThan(6)).inOrder();
355   }
356 
testExtendSameUpperBound()357   public void testExtendSameUpperBound() {
358     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
359     rangeSet.add(Range.closed(3, 6));
360     rangeSet.add(Range.closed(1, 6));
361     testInvariants(rangeSet);
362     assertThat(rangeSet.asRanges()).has().item(Range.closed(1, 6));
363     assertThat(rangeSet.complement().asRanges())
364         .has().exactly(Range.lessThan(1), Range.greaterThan(6)).inOrder();
365   }
366 
testExtendBothDirections()367   public void testExtendBothDirections() {
368     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
369     rangeSet.add(Range.closed(3, 4));
370     rangeSet.add(Range.closed(1, 6));
371     testInvariants(rangeSet);
372     assertThat(rangeSet.asRanges()).has().item(Range.closed(1, 6));
373     assertThat(rangeSet.complement().asRanges())
374         .has().exactly(Range.lessThan(1), Range.greaterThan(6)).inOrder();
375   }
376 
testAddEmpty()377   public void testAddEmpty() {
378     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
379     rangeSet.add(Range.closedOpen(3, 3));
380     testInvariants(rangeSet);
381     assertThat(rangeSet.asRanges()).isEmpty();
382     assertThat(rangeSet.complement().asRanges()).has().exactly(Range.<Integer>all()).inOrder();
383   }
384 
testFillHoleExactly()385   public void testFillHoleExactly() {
386     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
387     rangeSet.add(Range.closedOpen(1, 3));
388     rangeSet.add(Range.closedOpen(4, 6));
389     rangeSet.add(Range.closedOpen(3, 4));
390     testInvariants(rangeSet);
391     assertThat(rangeSet.asRanges()).has().item(Range.closedOpen(1, 6));
392     assertThat(rangeSet.complement().asRanges())
393         .has().exactly(Range.lessThan(1), Range.atLeast(6)).inOrder();
394   }
395 
testFillHoleWithOverlap()396   public void testFillHoleWithOverlap() {
397     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
398     rangeSet.add(Range.closedOpen(1, 3));
399     rangeSet.add(Range.closedOpen(4, 6));
400     rangeSet.add(Range.closedOpen(2, 5));
401     testInvariants(rangeSet);
402     assertThat(rangeSet.asRanges()).has().item(Range.closedOpen(1, 6));
403     assertThat(rangeSet.complement().asRanges())
404         .has().exactly(Range.lessThan(1), Range.atLeast(6)).inOrder();
405   }
406 
testAddManyPairs()407   public void testAddManyPairs() {
408     for (int aLow = 0; aLow < 6; aLow++) {
409       for (int aHigh = 0; aHigh < 6; aHigh++) {
410         for (BoundType aLowType : BoundType.values()) {
411           for (BoundType aHighType : BoundType.values()) {
412             if ((aLow == aHigh && aLowType == OPEN && aHighType == OPEN) || aLow > aHigh) {
413               continue;
414             }
415             for (int bLow = 0; bLow < 6; bLow++) {
416               for (int bHigh = 0; bHigh < 6; bHigh++) {
417                 for (BoundType bLowType : BoundType.values()) {
418                   for (BoundType bHighType : BoundType.values()) {
419                     if ((bLow == bHigh && bLowType == OPEN && bHighType == OPEN) || bLow > bHigh) {
420                       continue;
421                     }
422                     doPairTest(range(aLow, aLowType, aHigh, aHighType),
423                         range(bLow, bLowType, bHigh, bHighType));
424                   }
425                 }
426               }
427             }
428           }
429         }
430       }
431     }
432   }
433 
doPairTest(Range<Integer> a, Range<Integer> b)434   private static void doPairTest(Range<Integer> a, Range<Integer> b) {
435     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
436     rangeSet.add(a);
437     rangeSet.add(b);
438     if (a.isEmpty() && b.isEmpty()) {
439       assertThat(rangeSet.asRanges()).isEmpty();
440     } else if (a.isEmpty()) {
441       assertThat(rangeSet.asRanges()).has().item(b);
442     } else if (b.isEmpty()) {
443       assertThat(rangeSet.asRanges()).has().item(a);
444     } else if (a.isConnected(b)) {
445       assertThat(rangeSet.asRanges()).has().exactly(a.span(b)).inOrder();
446     } else {
447       if (a.lowerEndpoint() < b.lowerEndpoint()) {
448         assertThat(rangeSet.asRanges()).has().exactly(a, b).inOrder();
449       } else {
450         assertThat(rangeSet.asRanges()).has().exactly(b, a).inOrder();
451       }
452     }
453   }
454 
testRemoveEmpty()455   public void testRemoveEmpty() {
456     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
457     rangeSet.add(Range.closed(1, 6));
458     rangeSet.remove(Range.closedOpen(3, 3));
459     testInvariants(rangeSet);
460     assertThat(rangeSet.asRanges()).has().item(Range.closed(1, 6));
461     assertThat(rangeSet.complement().asRanges())
462         .has().exactly(Range.lessThan(1), Range.greaterThan(6)).inOrder();
463   }
464 
testRemovePartSharingLowerBound()465   public void testRemovePartSharingLowerBound() {
466     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
467     rangeSet.add(Range.closed(3, 5));
468     rangeSet.remove(Range.closedOpen(3, 5));
469     testInvariants(rangeSet);
470     assertThat(rangeSet.asRanges()).has().item(Range.singleton(5));
471     assertThat(rangeSet.complement().asRanges())
472         .has().exactly(Range.lessThan(5), Range.greaterThan(5)).inOrder();
473   }
474 
testRemovePartSharingUpperBound()475   public void testRemovePartSharingUpperBound() {
476     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
477     rangeSet.add(Range.closed(3, 5));
478     rangeSet.remove(Range.openClosed(3, 5));
479     testInvariants(rangeSet);
480     assertThat(rangeSet.asRanges()).has().item(Range.singleton(3));
481     assertThat(rangeSet.complement().asRanges())
482         .has().exactly(Range.lessThan(3), Range.greaterThan(3)).inOrder();
483   }
484 
testRemoveMiddle()485   public void testRemoveMiddle() {
486     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
487     rangeSet.add(Range.atMost(6));
488     rangeSet.remove(Range.closedOpen(3, 4));
489     testInvariants(rangeSet);
490     assertThat(rangeSet.asRanges()).has().exactly(Range.lessThan(3), Range.closed(4, 6)).inOrder();
491     assertThat(rangeSet.complement().asRanges())
492         .has().exactly(Range.closedOpen(3, 4), Range.greaterThan(6)).inOrder();
493   }
494 
testRemoveNoOverlap()495   public void testRemoveNoOverlap() {
496     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
497     rangeSet.add(Range.closed(3, 6));
498     rangeSet.remove(Range.closedOpen(1, 3));
499     testInvariants(rangeSet);
500     assertThat(rangeSet.asRanges()).has().exactly(Range.closed(3, 6)).inOrder();
501   }
502 
testRemovePartFromBelowLowerBound()503   public void testRemovePartFromBelowLowerBound() {
504     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
505     rangeSet.add(Range.closed(3, 6));
506     rangeSet.remove(Range.closed(1, 3));
507     testInvariants(rangeSet);
508     assertThat(rangeSet.asRanges()).has().exactly(Range.openClosed(3, 6)).inOrder();
509   }
510 
testRemovePartFromAboveUpperBound()511   public void testRemovePartFromAboveUpperBound() {
512     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
513     rangeSet.add(Range.closed(3, 6));
514     rangeSet.remove(Range.closed(6, 9));
515     testInvariants(rangeSet);
516     assertThat(rangeSet.asRanges()).has().exactly(Range.closedOpen(3, 6)).inOrder();
517   }
518 
testRemoveExact()519   public void testRemoveExact() {
520     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
521     rangeSet.add(Range.closed(3, 6));
522     rangeSet.remove(Range.closed(3, 6));
523     testInvariants(rangeSet);
524     assertThat(rangeSet.asRanges()).isEmpty();
525   }
526 
testRemoveAllFromBelowLowerBound()527   public void testRemoveAllFromBelowLowerBound() {
528     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
529     rangeSet.add(Range.closed(3, 6));
530     rangeSet.remove(Range.closed(2, 6));
531     testInvariants(rangeSet);
532     assertThat(rangeSet.asRanges()).isEmpty();
533   }
534 
testRemoveAllFromAboveUpperBound()535   public void testRemoveAllFromAboveUpperBound() {
536     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
537     rangeSet.add(Range.closed(3, 6));
538     rangeSet.remove(Range.closed(3, 7));
539     testInvariants(rangeSet);
540     assertThat(rangeSet.asRanges()).isEmpty();
541   }
542 
testRemoveAllExtendingBothDirections()543   public void testRemoveAllExtendingBothDirections() {
544     TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
545     rangeSet.add(Range.closed(3, 6));
546     rangeSet.remove(Range.closed(2, 7));
547     testInvariants(rangeSet);
548     assertThat(rangeSet.asRanges()).isEmpty();
549   }
550 
testRangeContaining1()551   public void testRangeContaining1() {
552     RangeSet<Integer> rangeSet = TreeRangeSet.create();
553     rangeSet.add(Range.closed(3, 10));
554     assertEquals(Range.closed(3, 10), rangeSet.rangeContaining(5));
555     assertTrue(rangeSet.contains(5));
556     assertNull(rangeSet.rangeContaining(1));
557     assertFalse(rangeSet.contains(1));
558   }
559 
testRangeContaining2()560   public void testRangeContaining2() {
561     RangeSet<Integer> rangeSet = TreeRangeSet.create();
562     rangeSet.add(Range.closed(3, 10));
563     rangeSet.remove(Range.open(5, 7));
564     assertEquals(Range.closed(3, 5), rangeSet.rangeContaining(5));
565     assertTrue(rangeSet.contains(5));
566     assertEquals(Range.closed(7, 10), rangeSet.rangeContaining(8));
567     assertTrue(rangeSet.contains(8));
568     assertNull(rangeSet.rangeContaining(6));
569     assertFalse(rangeSet.contains(6));
570   }
571 }
572