/** * Copyright (C) 2009-2013 FoundationDB, LLC * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.foundationdb.sql.optimizer.rule.range; import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import static com.foundationdb.sql.optimizer.rule.range.TUtils.exclusive; import static com.foundationdb.sql.optimizer.rule.range.TUtils.inclusive; import static com.foundationdb.sql.optimizer.rule.range.TUtils.nullExclusive; import static com.foundationdb.sql.optimizer.rule.range.TUtils.nullInclusive; import static com.foundationdb.sql.optimizer.rule.range.TUtils.segment; import static com.foundationdb.util.AssertUtils.assertCollectionEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; public final class RangeSegmentTest { @Test public void sacEmptyList() { List<RangeSegment> original = Collections.emptyList(); sacAndCheck(original, Collections.<RangeSegment>emptyList()); } @Test public void sacUnchanged() { List<RangeSegment> original = Arrays.asList( segment(nullExclusive("apple"), exclusive("apple")), segment(exclusive("apple"), exclusive("orange")), segment(exclusive("orange"), RangeEndpoint.UPPER_WILD) ); List<RangeSegment> copy = new ArrayList<>(original); sacAndCheck(original, copy); } @Test public void sacSortNoCombine() { List<RangeSegment> original = Arrays.asList( segment(exclusive("apple"), exclusive("orange")), segment(exclusive("orange"), RangeEndpoint.UPPER_WILD), segment(nullExclusive("apple"), exclusive("apple")) ); sacAndCheck( original, segment(nullExclusive("apple"), exclusive("apple")), segment(exclusive("apple"), exclusive("orange")), segment(exclusive("orange"), RangeEndpoint.UPPER_WILD) ); } @Test public void sacCombineInclusiveInclusive() { List<RangeSegment> original = Arrays.asList( segment(exclusive("aardvark"), inclusive("apple")), segment(inclusive("apple"), inclusive("orange")) ); sacAndCheck( original, segment(exclusive("aardvark"), inclusive("orange")) ); } @Test public void sacCombineInclusiveExclusive() { List<RangeSegment> original = Arrays.asList( segment(exclusive("aardvark"), inclusive("apple")), segment(exclusive("apple"), inclusive("orange")) ); sacAndCheck( original, segment(exclusive("aardvark"), inclusive("orange")) ); } @Test public void sacCombineExclusiveExclusive() { List<RangeSegment> original = Arrays.asList( segment(exclusive("aardvark"), exclusive("apple")), segment(exclusive("apple"), inclusive("orange")) ); sacAndCheck( original, segment(exclusive("aardvark"), exclusive("apple")), segment(exclusive("apple"), inclusive("orange")) ); } @Test public void sacCombineExclusiveInclusive() { List<RangeSegment> original = Arrays.asList( segment(exclusive("aardvark"), exclusive("apple")), segment(inclusive("apple"), inclusive("orange")) ); sacAndCheck( original, segment(exclusive("aardvark"), inclusive("orange")) ); } @Test public void sacCombineStartExclusiveInclusiveNulls() { List<RangeSegment> original = Arrays.asList( segment(nullExclusive("apple"), exclusive("apple")), segment(nullInclusive("banana"), inclusive("banana")) ); sacAndCheck( original, segment(nullInclusive("banana"), inclusive("banana")) ); } @Test public void sacCombineStartInclusiveExclusiveNulls() { List<RangeSegment> original = Arrays.asList( segment(nullInclusive("apple"), exclusive("apple")), segment(nullExclusive("banana"), inclusive("banana")) ); sacAndCheck( original, segment(nullInclusive("banana"), inclusive("banana")) ); } @Test public void sacCombineStartExclusiveInclusiveStrings() { List<RangeSegment> original = Arrays.asList( segment(exclusive("apple"), exclusive("banana")), segment(inclusive("apple"), inclusive("mango")) ); sacAndCheck( original, segment(inclusive("apple"), inclusive("mango")) ); } @Test public void sacCombineStartInclusiveExclusiveStrings() { List<RangeSegment> original = Arrays.asList( segment(inclusive("apple"), exclusive("banana")), segment(exclusive("apple"), inclusive("mango")) ); sacAndCheck( original, segment(inclusive("apple"), inclusive("mango")) ); } @Test public void sacCombineEndExclusiveInclusiveStrings() { List<RangeSegment> original = Arrays.asList( segment(exclusive("apple"), exclusive("mango")), segment(inclusive("banana"), inclusive("mango")) ); sacAndCheck( original, segment(exclusive("apple"), inclusive("mango")) ); } @Test public void sacCombineEndInclusiveExclusiveStrings() { List<RangeSegment> original = Arrays.asList( segment(exclusive("apple"), inclusive("mango")), segment(inclusive("banana"), exclusive("mango")) ); sacAndCheck( original, segment(exclusive("apple"), inclusive("mango")) ); } @Test public void sacSubset() { List<RangeSegment> original = Arrays.asList( segment(exclusive("apple"), exclusive("zebra")), segment(inclusive("cactus"), inclusive("person")) ); sacAndCheck( original, segment(exclusive("apple"), exclusive("zebra")) ); } @Test public void sacOverlapNoWilds() { List<RangeSegment> original = Arrays.asList( segment(exclusive("apple"), exclusive("person")), segment(inclusive("cactus"), inclusive("zebra")) ); sacAndCheck( original, segment(exclusive("apple"), inclusive("zebra")) ); } @Test public void sacOverlapWildStart() { List<RangeSegment> original = Arrays.asList( segment(exclusive("apple"), exclusive("person")), segment(nullExclusive("zebra"), inclusive("zebra")) ); sacAndCheck( original, segment(nullExclusive("zebra"), inclusive("zebra")) ); } @Test public void sacOverlapWildEnd() { List<RangeSegment> original = Arrays.asList( segment(inclusive("aardvark"), RangeEndpoint.UPPER_WILD), segment(exclusive("apple"), exclusive("person")) ); sacAndCheck( original, segment(inclusive("aardvark"), RangeEndpoint.UPPER_WILD) ); } @Test public void sacKeepStartAndEndInclusivity() { List<RangeSegment> original = Arrays.asList( segment(inclusive("aardvark"), inclusive("person")), segment(inclusive("cat"), inclusive("zebra")) ); sacAndCheck( original, segment(inclusive("aardvark"), inclusive("zebra")) ); } @Test public void sacKeepStartExclusivity() { List<RangeSegment> original = Arrays.asList( segment(exclusive("aardvark"), inclusive("person")), segment(inclusive("cat"), inclusive("zebra")) ); sacAndCheck( original, segment(exclusive("aardvark"), inclusive("zebra")) ); } @Test public void sacKeepEndExclusivity() { List<RangeSegment> original = Arrays.asList( segment(inclusive("aardvark"), inclusive("person")), segment(inclusive("cat"), exclusive("zebra")) ); sacAndCheck( original, segment(inclusive("aardvark"), exclusive("zebra")) ); } @Test public void sacIncomparableTypesForSorting() { List<RangeSegment> original = Arrays.asList( segment(inclusive("aardvark"), inclusive("person")), segment(inclusive(1L), exclusive("zebra")) ); List<RangeSegment> copy = new ArrayList<>(original); List<RangeSegment> sorted = RangeSegment.sortAndCombine(copy); assertCollectionEquals(original, copy); assertNull("sorted list should be null", sorted); } @Test public void sacIncomparableTypesForMerging() { List<RangeSegment> original = Arrays.asList( segment(inclusive("aardvark"), inclusive(1L)), segment(inclusive("cat"), exclusive(1L)) ); List<RangeSegment> copy = new ArrayList<>(original); List<RangeSegment> sorted = RangeSegment.sortAndCombine(copy); assertCollectionEquals(original, copy); assertNull("sorted list should be null", sorted); } @Test(expected = IllegalArgumentException.class) public void startIsNull() { segment(null, inclusive(1)); } @Test(expected = IllegalArgumentException.class) public void endIsNull() { segment(inclusive(1), null); } /** * checks sortAndCombine (aka sac) by sac'ing (a copy of) the given list, asserting that what comes out * is the same instance, and checking it for equality against a list created from the given expected RangeSegments. * @param list the list to sac-and-check * @param expectedList the expected RangeSegments */ private static void sacAndCheck(List<? extends RangeSegment> list, List<? extends RangeSegment> expectedList) { List<RangeSegment> copy = new ArrayList<>(list); List<RangeSegment> sorted = RangeSegment.sortAndCombine(copy); assertSame(copy, sorted); assertCollectionEquals(expectedList, new ArrayList<>(sorted)); } private static void sacAndCheck(List<RangeSegment> list, RangeSegment first, RangeSegment... expecteds) { List<RangeSegment> expectedsList = new ArrayList<>(); expectedsList.add(first); Collections.addAll(expectedsList, expecteds); sacAndCheck(list, expectedsList); } }