/* * 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 static org.inferred.freebuilder.processor.util.feature.GuavaLibrary.GUAVA; import static org.junit.Assume.assumeTrue; 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.Collections; import java.util.Comparator; import java.util.List; import java.util.SortedSet; import java.util.stream.Stream; import javax.tools.JavaFileObject; /** * Partial set of tests of {@link SortedSetPropertyFactory}. Tests specific to the mutateX methods * generated in Java 8+ are in {@link SortedSetMutateMethodTest}. Tests common to unsorted tests can * be found in {@link SetPropertyTest} and {@link SetMutateMethodTest}. */ @RunWith(Parameterized.class) @UseParametersRunnerFactory(ParameterizedBehaviorTestFactory.class) public class SortedSetPropertyTest { @Parameters(name = "{0}") public static List<FeatureSet> parameters() { return FeatureSets.ALL; } @Rule public final ExpectedException thrown = ExpectedException.none(); @Shared public BehaviorTester behaviorTester; private final FeatureSet features; private static final JavaFileObject 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("}") .build(); public SortedSetPropertyTest(FeatureSet features) { this.features = features; } public static final Comparator<String> NATURAL_ORDER = Ordering.natural().onResultOf(Integer::parseInt); public static final Comparator<String> EXPLICIT_DEFAULT_ORDER = String::compareTo; @Test public void testDefaultOrder() { behaviorTester .with(new Processor(features)) .with(SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("DataType value = new DataType.Builder()") .addLine(" .addItems(\"11\", \"3\", \"222\")") .addLine(" .build();") .addLine("assertThat(value.items()).containsExactly(\"11\", \"222\", \"3\").inOrder();") .build()) .runTest(); } @Test public void testNullOrder() { behaviorTester .with(new Processor(features)) .with(SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("DataType value = new DataType.Builder()") .addLine(" .setComparatorForItems(null)") .addLine(" .addItems(\"11\", \"3\", \"222\")") .addLine(" .build();") .addLine("assertThat(value.items()).containsExactly(\"11\", \"222\", \"3\").inOrder();") .build()) .runTest(); } @Test public void testReverseOrder() { behaviorTester .with(new Processor(features)) .with(SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("DataType value = new DataType.Builder()") .addLine(" .setComparatorForItems(%s.reverseOrder())", Collections.class) .addLine(" .addItems(\"11\", \"3\", \"222\")") .addLine(" .build();") .addLine("assertThat(value.items()).containsExactly(\"3\", \"222\", \"11\").inOrder();") .build()) .runTest(); } @Test public void testNaturalOrder() { behaviorTester .with(new Processor(features)) .with(SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("DataType value = new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .addItems(\"11\", \"3\", \"222\")") .addLine(" .build();") .addLine("assertThat(value.items()).containsExactly(\"3\", \"11\", \"222\").inOrder();") .build()) .runTest(); } @Test public void testBuilderGetter() { behaviorTester .with(new Processor(features)) .with(SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("DataType.Builder builder = new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .addItems(\"11\", \"3\", \"222\");") .addLine("assertThat(builder.items())") .addLine(" .containsExactly(\"3\", \"11\", \"222\").inOrder();") .build()) .runTest(); } @Test public void testGetterComparator() { behaviorTester .with(new Processor(features)) .with(SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("DataType value = new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .addItems(\"11\", \"3\", \"222\")") .addLine(" .build();") .addLine("assertThat(value.items().comparator()).isEqualTo(NATURAL_ORDER);") .build()) .runTest(); } @Test public void testBuilderGetterComparator() { behaviorTester .with(new Processor(features)) .with(SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("DataType.Builder builder = new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .addItems(\"11\", \"3\", \"222\");") .addLine("assertThat(builder.items().comparator()).isEqualTo(NATURAL_ORDER);") .build()) .runTest(); } @Test public void testMergeFromReusesImmutableSetInstanceWhenComparatorsBothNull() { assumeGuavaAvailable(); behaviorTester .with(new Processor(features)) .with(SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("DataType value = new DataType.Builder()") .addLine(" .setComparatorForItems(null)") .addLine(" .addItems(\"11\", \"3\", \"222\")") .addLine(" .build();") .addLine("DataType copy = new DataType.Builder()") .addLine(" .setComparatorForItems(null)") .addLine(" .mergeFrom(value)") .addLine(" .build();") .addLine("assertThat(copy.items()).isSameAs(value.items());") .build()) .runTest(); } @Test public void testMergeFromReusesImmutableSetInstanceWhenComparatorUnset() { assumeGuavaAvailable(); behaviorTester .with(new Processor(features)) .with(SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("DataType value = new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .addItems(\"11\", \"3\", \"222\")") .addLine(" .build();") .addLine("DataType copy = new DataType.Builder()") .addLine(" .mergeFrom(value)") .addLine(" .build();") .addLine("assertThat(copy.items()).isSameAs(value.items());") .build()) .runTest(); } @Test public void testMergeFromReusesImmutableSetInstanceWhenComparatorsMatch() { assumeGuavaAvailable(); behaviorTester .with(new Processor(features)) .with(SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("DataType value = new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .addItems(\"11\", \"3\", \"222\")") .addLine(" .build();") .addLine("DataType copy = new DataType.Builder()") .addLine(" .setComparatorForItems(NATURAL_ORDER)") .addLine(" .mergeFrom(value)") .addLine(" .build();") .addLine("assertThat(copy.items()).isSameAs(value.items());") .build()) .runTest(); } @Test public void testMergeFromDoesNotReuseImmutableSetInstanceWhenComparatorsDoNotMatch() { behaviorTester .with(new Processor(features)) .with(SORTED_SET_PROPERTY_TYPE) .with(testBuilder() .addLine("DataType value = new DataType.Builder()") .addLine(" .setComparatorForItems(null)") .addLine(" .addItems(\"11\", \"3\", \"222\")") .addLine(" .build();") .addLine("DataType copy = new DataType.Builder()") .addLine(" .setComparatorForItems(EXPLICIT_DEFAULT_ORDER)") .addLine(" .mergeFrom(value)") .addLine(" .build();") .addLine("assertThat(copy.items()).isEqualTo(value.items());") .addLine("assertThat(copy.items()).isNotSameAs(value.items());") .build()) .runTest(); } private void assumeGuavaAvailable() { assumeTrue("Guava available", features.get(GUAVA).isAvailable()); } private static TestBuilder testBuilder() { return new TestBuilder() .addImport("com.example.DataType") .addStaticImport(SortedSetPropertyTest.class, "EXPLICIT_DEFAULT_ORDER") .addStaticImport(SortedSetPropertyTest.class, "NATURAL_ORDER") .addImport(Stream.class); } }