/* * Copyright 2016 Google Inc. All rights reserved. * * 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 org.inferred.freebuilder.processor; import com.google.common.base.Preconditions; import com.google.common.collect.Ordering; import org.inferred.freebuilder.FreeBuilder; import org.inferred.freebuilder.processor.util.feature.FeatureSet; import org.inferred.freebuilder.processor.util.testing.BehaviorTestRunner.Shared; import org.inferred.freebuilder.processor.util.testing.BehaviorTester; import org.inferred.freebuilder.processor.util.testing.ParameterizedBehaviorTestFactory; import org.inferred.freebuilder.processor.util.testing.SourceBuilder; import org.inferred.freebuilder.processor.util.testing.TestBuilder; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import org.junit.runners.Parameterized.UseParametersRunnerFactory; import java.util.Comparator; import java.util.List; import java.util.Set; import java.util.SortedSet; import java.util.stream.Stream; import javax.tools.JavaFileObject; /** * Partial set of tests of {@link SortedSetPropertyFactory}. Tests common to unsorted tests can be * found in {@link SetPropertyTest} and {@link SetMutateMethodTest}. */ @RunWith(Parameterized.class) @UseParametersRunnerFactory(ParameterizedBehaviorTestFactory.class) public class SortedSetMutateMethodTest { @Parameters(name = "{0}") public static List<FeatureSet> parameters() { return FeatureSets.WITH_LAMBDAS; } @Rule public final ExpectedException thrown = ExpectedException.none(); @Shared public BehaviorTester behaviorTester; private final FeatureSet features; private static final String FAILED_VALIDATION_MESSAGE = "Elements cannot start with a '0'"; private static final JavaFileObject VALIDATED_SORTED_SET_PROPERTY_TYPE = new SourceBuilder() .addLine("package com.example;") .addLine("@%s", FreeBuilder.class) .addLine("public abstract class DataType {") .addLine(" public abstract %s<String> items();", SortedSet.class) .addLine("") .addLine(" public static class Builder extends DataType_Builder {") .addLine(" @Override") .addLine(" public Builder setComparatorForItems(%s<? super String> comparator) {", Comparator.class) .addLine(" return super.setComparatorForItems(comparator);") .addLine(" }") .addLine("") .addLine(" @Override") .addLine(" public Builder addItems(String element) {") .addLine(" %s.checkArgument(!element.startsWith(\"0\"), \"%s\");", Preconditions.class, FAILED_VALIDATION_MESSAGE) .addLine(" return super.addItems(element);") .addLine(" }") .addLine(" }") .addLine("}") .build(); public SortedSetMutateMethodTest(FeatureSet features) { this.features = features; } public static final Comparator<String> NATURAL_ORDER = new Comparator<String>() { private final Comparator<String> delegate = Ordering.natural().onResultOf(Integer::parseInt); @Override public int compare(String o1, String o2) { return delegate.compare(o1, o2); } @Override public String toString() { return "'natural order'"; } }; @Test public void testGetsDataInOrder() { behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .addItems(\"11\", \"3\", \"222\")") .addLine(" .mutateItems(items -> {") .addLine(" assertThat(items).containsExactly(\"3\", \"11\", \"222\").inOrder();") .addLine(" });") .build()) .runTest(); } @Test public void testComparator() { behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .addItems(\"11\", \"3\", \"222\")") .addLine(" .mutateItems(items -> {") .addLine(" assertThat(items.comparator()).isEqualTo(NATURAL_ORDER);") .addLine(" });") .build()) .runTest(); } @Test public void testSubSet_contents() { behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .addItems(\"6\", \"11\", \"3\", \"222\", \"44\")") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.subSet(\"6\", \"44\");") .addLine(" assertThat(subset).containsExactly(\"6\", \"11\");") .addLine(" });") .build()) .runTest(); } @Test public void testHeadSet_contents() { behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .addItems(\"6\", \"11\", \"3\", \"222\", \"44\")") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.headSet(\"44\");") .addLine(" assertThat(subset).containsExactly(\"3\", \"6\", \"11\");") .addLine(" });") .build()) .runTest(); } @Test public void testTailSet_contents() { behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .addItems(\"6\", \"11\", \"3\", \"222\", \"44\")") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.tailSet(\"6\");") .addLine(" assertThat(subset).containsExactly(\"6\", \"11\", \"44\", \"222\");") .addLine(" });") .build()) .runTest(); } @Test public void testSubSet_validatesInsertedItems() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage(FAILED_VALIDATION_MESSAGE); behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.subSet(\"6\", \"44\");") .addLine(" subset.add(\"007\");") .addLine(" });") .build()) .runTest(); } @Test public void testSubSet_permitsInsertionAtBoundaries_defaultOrder() { behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("DataType value = new DataType.Builder()") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.subSet(\"44\", \"6\");") .addLine(" subset.add(\"44\");") .addLine(" subset.add(\"599999\");") .addLine(" })") .addLine(" .build();") .addLine("assertThat(value.items()).containsExactly(\"44\", \"599999\").inOrder();") .build()) .runTest(); } @Test public void testSubSet_permitsInsertionAtBoundaries_naturalOrder() { behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("DataType value = new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.subSet(\"6\", \"44\");") .addLine(" subset.add(\"43\");") .addLine(" subset.add(\"6\");") .addLine(" })") .addLine(" .build();") .addLine("assertThat(value.items()).containsExactly(\"6\", \"43\").inOrder();") .build()) .runTest(); } @Test public void testSubSet_deniesInsertionBelowLowerBound_defaultOrder() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("element must be at least 44 (got 4399)"); behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("new DataType.Builder()") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.subSet(\"44\", \"6\");") .addLine(" subset.add(\"4399\");") .addLine(" });") .build()) .runTest(); } @Test public void testSubSet_deniesInsertionBelowLowerBound_naturalOrder() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("element must be at least 6 (got 5) using comparator 'natural order'"); behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.subSet(\"6\", \"44\");") .addLine(" subset.add(\"5\");") .addLine(" });") .build()) .runTest(); } @Test public void testSubSet_deniesInsertionAtUpperBound_defaultOrder() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("element must be less than 6 (got 6)"); behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("new DataType.Builder()") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.subSet(\"44\", \"6\");") .addLine(" subset.add(\"6\");") .addLine(" });") .build()) .runTest(); } @Test public void testSubSet_deniesInsertionAtUpperBound_naturalOrder() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("element must be less than 44 (got 44) using comparator 'natural order'"); behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.subSet(\"6\", \"44\");") .addLine(" subset.add(\"44\");") .addLine(" });") .build()) .runTest(); } @Test public void testHeadSet_validatesInsertedItems() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage(FAILED_VALIDATION_MESSAGE); behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.headSet(\"44\");") .addLine(" subset.add(\"007\");") .addLine(" });") .build()) .runTest(); } @Test public void testHeadSet_permitsInsertionBelowUpperBound_defaultOrder() { behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("DataType value = new DataType.Builder()") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.headSet(\"6\");") .addLine(" subset.add(\"44\");") .addLine(" subset.add(\"599999\");") .addLine(" })") .addLine(" .build();") .addLine("assertThat(value.items()).containsExactly(\"44\", \"599999\").inOrder();") .build()) .runTest(); } @Test public void testHeadSet_permitsInsertionBelowUpperBound_naturalOrder() { behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("DataType value = new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.headSet(\"44\");") .addLine(" subset.add(\"43\");") .addLine(" subset.add(\"6\");") .addLine(" })") .addLine(" .build();") .addLine("assertThat(value.items()).containsExactly(\"6\", \"43\").inOrder();") .build()) .runTest(); } @Test public void testHeadSet_deniesInsertionAtUpperBound_defaultOrder() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("element must be less than 6 (got 6)"); behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("new DataType.Builder()") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.headSet(\"6\");") .addLine(" subset.add(\"6\");") .addLine(" });") .build()) .runTest(); } @Test public void testHeadSet_deniesInsertionAtUpperBound_naturalOrder() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("element must be less than 44 (got 44) using comparator 'natural order'"); behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.headSet(\"44\");") .addLine(" subset.add(\"44\");") .addLine(" });") .build()) .runTest(); } @Test public void testTailSet_validatesInsertedItems() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage(FAILED_VALIDATION_MESSAGE); behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.tailSet(\"6\");") .addLine(" subset.add(\"007\");") .addLine(" });") .build()) .runTest(); } @Test public void testTailSet_permitsInsertionAtLowerBound_defaultOrder() { behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("DataType value = new DataType.Builder()") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.tailSet(\"44\");") .addLine(" subset.add(\"44\");") .addLine(" subset.add(\"599999\");") .addLine(" })") .addLine(" .build();") .addLine("assertThat(value.items()).containsExactly(\"44\", \"599999\").inOrder();") .build()) .runTest(); } @Test public void testTailSet_permitsInsertionAtLowerBound_naturalOrder() { behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("DataType value = new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.tailSet(\"6\");") .addLine(" subset.add(\"43\");") .addLine(" subset.add(\"6\");") .addLine(" })") .addLine(" .build();") .addLine("assertThat(value.items()).containsExactly(\"6\", \"43\").inOrder();") .build()) .runTest(); } @Test public void testTailSet_deniesInsertionBelowLowerBound_defaultOrder() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("element must be at least 44 (got 4399)"); behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("new DataType.Builder()") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.tailSet(\"44\");") .addLine(" subset.add(\"4399\");") .addLine(" });") .build()) .runTest(); } @Test public void testTailSet_deniesInsertionBelowLowerBound_naturalOrder() { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("element must be at least 6 (got 5) using comparator 'natural order'"); behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .mutateItems(items -> {") .addLine(" Set<String> subset = items.tailSet(\"6\");") .addLine(" subset.add(\"5\");") .addLine(" });") .build()) .runTest(); } @Test public void testFirstAndLastMatch() { behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .addItems(\"6\", \"11\", \"3\", \"222\", \"44\")") .addLine(" .mutateItems(items -> {") .addLine(" assertThat(items.first()).isEqualTo(\"3\");") .addLine(" assertThat(items.last()).isEqualTo(\"222\");") .addLine(" });") .build()) .runTest(); } @Test public void testSubSet_firstAndLastMatch() { behaviorTester .with(new Processor(features)) .with(VALIDATED_SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .addItems(\"6\", \"11\", \"3\", \"222\", \"44\")") .addLine(" .mutateItems(items -> {") .addLine(" SortedSet<String> subset = items.subSet(\"6\", \"44\");") .addLine(" assertThat(subset.first()).isEqualTo(\"6\");") .addLine(" assertThat(subset.last()).isEqualTo(\"11\");") .addLine(" });") .build()) .runTest(); } private static TestBuilder testBuilder() { return new TestBuilder() .addImport("com.example.DataType") .addStaticImport(SortedSetMutateMethodTest.class, "NATURAL_ORDER") .addImport(Set.class) .addImport(SortedSet.class) .addImport(Stream.class); } }