/* * Copyright (C) 2011 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ package com.google.common.collect; import static com.google.common.collect.BoundType.OPEN; import static com.google.common.collect.Ranges.range; import static org.junit.contrib.truth.Truth.ASSERT; import com.google.common.annotations.GwtIncompatible; /** * Tests for {@link TreeRangeSet}. * * @author Louis Wasserman * @author Chris Povirk */ @GwtIncompatible("TreeRangeSet") public class TreeRangeSetTest extends AbstractRangeSetTest { // TODO(cpovirk): test all of these with the ranges added in the reverse order public void testMergesConnectedWithOverlap() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(1, 4)); rangeSet.add(Ranges.open(2, 6)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(Ranges.closedOpen(1, 6)); ASSERT.that(rangeSet.complement().asRanges()).hasContentsInOrder(Ranges.lessThan(1), Ranges.atLeast(6)); } public void testMergesConnectedDisjoint() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(1, 4)); rangeSet.add(Ranges.open(4, 6)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(Ranges.closedOpen(1, 6)); ASSERT.that(rangeSet.complement().asRanges()).hasContentsInOrder(Ranges.lessThan(1), Ranges.atLeast(6)); } public void testIgnoresSmallerSharingNoBound() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(1, 6)); rangeSet.add(Ranges.open(2, 4)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(Ranges.closed(1, 6)); ASSERT.that(rangeSet.complement().asRanges()).hasContentsInOrder(Ranges.lessThan(1), Ranges.greaterThan(6)); } public void testIgnoresSmallerSharingLowerBound() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(1, 6)); rangeSet.add(Ranges.closed(1, 4)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(Ranges.closed(1, 6)); ASSERT.that(rangeSet.complement().asRanges()).hasContentsInOrder(Ranges.lessThan(1), Ranges.greaterThan(6)); } public void testIgnoresSmallerSharingUpperBound() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(1, 6)); rangeSet.add(Ranges.closed(3, 6)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(Ranges.closed(1, 6)); ASSERT.that(rangeSet.complement().asRanges()).hasContentsInOrder(Ranges.lessThan(1), Ranges.greaterThan(6)); } public void testIgnoresEqual() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(1, 6)); rangeSet.add(Ranges.closed(1, 6)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(Ranges.closed(1, 6)); ASSERT.that(rangeSet.complement().asRanges()).hasContentsInOrder(Ranges.lessThan(1), Ranges.greaterThan(6)); } public void testExtendSameLowerBound() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(1, 4)); rangeSet.add(Ranges.closed(1, 6)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(Ranges.closed(1, 6)); ASSERT.that(rangeSet.complement().asRanges()).hasContentsInOrder(Ranges.lessThan(1), Ranges.greaterThan(6)); } public void testExtendSameUpperBound() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(3, 6)); rangeSet.add(Ranges.closed(1, 6)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(Ranges.closed(1, 6)); ASSERT.that(rangeSet.complement().asRanges()).hasContentsInOrder(Ranges.lessThan(1), Ranges.greaterThan(6)); } public void testExtendBothDirections() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(3, 4)); rangeSet.add(Ranges.closed(1, 6)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(Ranges.closed(1, 6)); ASSERT.that(rangeSet.complement().asRanges()).hasContentsInOrder(Ranges.lessThan(1), Ranges.greaterThan(6)); } public void testAddEmpty() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closedOpen(3, 3)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).isEmpty(); ASSERT.that(rangeSet.complement().asRanges()).hasContentsInOrder(Ranges.<Integer>all()); } public void testFillHoleExactly() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closedOpen(1, 3)); rangeSet.add(Ranges.closedOpen(4, 6)); rangeSet.add(Ranges.closedOpen(3, 4)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(Ranges.closedOpen(1, 6)); ASSERT.that(rangeSet.complement().asRanges()).hasContentsInOrder(Ranges.lessThan(1), Ranges.atLeast(6)); } public void testFillHoleWithOverlap() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closedOpen(1, 3)); rangeSet.add(Ranges.closedOpen(4, 6)); rangeSet.add(Ranges.closedOpen(2, 5)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(Ranges.closedOpen(1, 6)); ASSERT.that(rangeSet.complement().asRanges()).hasContentsInOrder(Ranges.lessThan(1), Ranges.atLeast(6)); } public void testAddManyPairs() { for (int aLow = 0; aLow < 6; aLow++) { for (int aHigh = 0; aHigh < 6; aHigh++) { for (BoundType aLowType : BoundType.values()) { for (BoundType aHighType : BoundType.values()) { if ((aLow == aHigh && aLowType == OPEN && aHighType == OPEN) || aLow > aHigh) { continue; } for (int bLow = 0; bLow < 6; bLow++) { for (int bHigh = 0; bHigh < 6; bHigh++) { for (BoundType bLowType : BoundType.values()) { for (BoundType bHighType : BoundType.values()) { if ((bLow == bHigh && bLowType == OPEN && bHighType == OPEN) || bLow > bHigh) { continue; } doPairTest(range(aLow, aLowType, aHigh, aHighType), range(bLow, bLowType, bHigh, bHighType)); } } } } } } } } } private static void doPairTest(Range<Integer> a, Range<Integer> b) { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(a); rangeSet.add(b); if (a.isEmpty() && b.isEmpty()) { ASSERT.that(rangeSet.asRanges()).isEmpty(); } else if (a.isEmpty()) { ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(b); } else if (b.isEmpty()) { ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(a); } else if (a.isConnected(b)) { ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(a.span(b)); } else { if (a.lowerEndpoint() < b.lowerEndpoint()) { ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(a, b); } else { ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(b, a); } } } public void testRemoveEmpty() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(1, 6)); rangeSet.remove(Ranges.closedOpen(3, 3)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(Ranges.closed(1, 6)); ASSERT.that(rangeSet.complement().asRanges()).hasContentsInOrder(Ranges.lessThan(1), Ranges.greaterThan(6)); } public void testRemovePartSharingLowerBound() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(3, 5)); rangeSet.remove(Ranges.closedOpen(3, 5)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(Ranges.singleton(5)); ASSERT.that(rangeSet.complement().asRanges()).hasContentsInOrder(Ranges.lessThan(5), Ranges.greaterThan(5)); } public void testRemovePartSharingUpperBound() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(3, 5)); rangeSet.remove(Ranges.openClosed(3, 5)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(Ranges.singleton(3)); ASSERT.that(rangeSet.complement().asRanges()).hasContentsInOrder(Ranges.lessThan(3), Ranges.greaterThan(3)); } public void testRemoveMiddle() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.atMost(6)); rangeSet.remove(Ranges.closedOpen(3, 4)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(Ranges.lessThan(3), Ranges.closed(4, 6)); ASSERT.that(rangeSet.complement().asRanges()).hasContentsInOrder(Ranges.closedOpen(3, 4), Ranges.greaterThan(6)); } public void testRemoveNoOverlap() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(3, 6)); rangeSet.remove(Ranges.closedOpen(1, 3)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(Ranges.closed(3, 6)); } public void testRemovePartFromBelowLowerBound() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(3, 6)); rangeSet.remove(Ranges.closed(1, 3)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(Ranges.openClosed(3, 6)); } public void testRemovePartFromAboveUpperBound() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(3, 6)); rangeSet.remove(Ranges.closed(6, 9)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).hasContentsInOrder(Ranges.closedOpen(3, 6)); } public void testRemoveExact() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(3, 6)); rangeSet.remove(Ranges.closed(3, 6)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).isEmpty(); } public void testRemoveAllFromBelowLowerBound() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(3, 6)); rangeSet.remove(Ranges.closed(2, 6)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).isEmpty(); } public void testRemoveAllFromAboveUpperBound() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(3, 6)); rangeSet.remove(Ranges.closed(3, 7)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).isEmpty(); } public void testRemoveAllExtendingBothDirections() { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(3, 6)); rangeSet.remove(Ranges.closed(2, 7)); testInvariants(rangeSet); ASSERT.that(rangeSet.asRanges()).isEmpty(); } public void testRangeContaining1() { RangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(3, 10)); assertEquals(Ranges.closed(3, 10), rangeSet.rangeContaining(5)); assertTrue(rangeSet.contains(5)); assertNull(rangeSet.rangeContaining(1)); assertFalse(rangeSet.contains(1)); } public void testRangeContaining2() { RangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Ranges.closed(3, 10)); rangeSet.remove(Ranges.open(5, 7)); assertEquals(Ranges.closed(3, 5), rangeSet.rangeContaining(5)); assertTrue(rangeSet.contains(5)); assertEquals(Ranges.closed(7, 10), rangeSet.rangeContaining(8)); assertTrue(rangeSet.contains(8)); assertNull(rangeSet.rangeContaining(6)); assertFalse(rangeSet.contains(6)); } }