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