aboutsummaryrefslogtreecommitdiff
path: root/src/test/java/com/google
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java/com/google')
-rw-r--r--src/test/java/com/google/testing/junit/testparameterinjector/ParameterValueParsingTest.java136
-rw-r--r--src/test/java/com/google/testing/junit/testparameterinjector/PluggableTestRunnerTest.java74
-rw-r--r--src/test/java/com/google/testing/junit/testparameterinjector/TestInfoTest.java249
-rw-r--r--src/test/java/com/google/testing/junit/testparameterinjector/TestParameterAnnotationMethodProcessorTest.java1077
-rw-r--r--src/test/java/com/google/testing/junit/testparameterinjector/TestParameterTest.java211
-rw-r--r--src/test/java/com/google/testing/junit/testparameterinjector/TestParametersMethodProcessorTest.java474
6 files changed, 2221 insertions, 0 deletions
diff --git a/src/test/java/com/google/testing/junit/testparameterinjector/ParameterValueParsingTest.java b/src/test/java/com/google/testing/junit/testparameterinjector/ParameterValueParsingTest.java
new file mode 100644
index 0000000..0f19466
--- /dev/null
+++ b/src/test/java/com/google/testing/junit/testparameterinjector/ParameterValueParsingTest.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2021 Google Inc.
+ *
+ * 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.testing.junit.testparameterinjector;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.protobuf.ByteString;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(TestParameterInjector.class)
+public class ParameterValueParsingTest {
+
+ @Test
+ public void parseEnum_success() throws Exception {
+ Enum<?> result = ParameterValueParsing.parseEnum("BBB", TestEnum.class);
+
+ assertThat(result).isEqualTo(TestEnum.BBB);
+ }
+
+ @Test
+ @TestParameters({
+ "{yamlString: '{a: b, c: 15}', valid: true}",
+ "{yamlString: '{a: b c: 15', valid: false}",
+ "{yamlString: 'a: b c: 15', valid: false}",
+ })
+ @Ignore("b/195657808 @TestParameters is not supported on Android")
+ public void isValidYamlString_success(String yamlString, boolean valid) throws Exception {
+ boolean result = ParameterValueParsing.isValidYamlString(yamlString);
+
+ assertThat(result).isEqualTo(valid);
+ }
+
+ enum ParseYamlValueToJavaTypeCases {
+ STRING_TO_STRING(
+ /* yamlString= */ "abc", /* javaClass= */ String.class, /* expectedResult= */ "abc"),
+ BOOLEAN_TO_STRING(
+ /* yamlString= */ "true", /* javaClass= */ String.class, /* expectedResult= */ "true"),
+ INT_TO_STRING(
+ /* yamlString= */ "123", /* javaClass= */ String.class, /* expectedResult= */ "123"),
+ LONG_TO_STRING(
+ /* yamlString= */ "442147483648",
+ /* javaClass= */ String.class,
+ /* expectedResult= */ "442147483648"),
+ DOUBLE_TO_STRING(
+ /* yamlString= */ "1.23", /* javaClass= */ String.class, /* expectedResult= */ "1.23"),
+
+ BOOLEAN_TO_BOOLEAN(
+ /* yamlString= */ "true", /* javaClass= */ Boolean.class, /* expectedResult= */ true),
+
+ INT_TO_INT(/* yamlString= */ "123", /* javaClass= */ int.class, /* expectedResult= */ 123),
+
+ LONG_TO_LONG(
+ /* yamlString= */ "442147483648",
+ /* javaClass= */ long.class,
+ /* expectedResult= */ 442147483648L),
+ INT_TO_LONG(/* yamlString= */ "123", /* javaClass= */ Long.class, /* expectedResult= */ 123L),
+
+ DOUBLE_TO_DOUBLE(
+ /* yamlString= */ "1.23", /* javaClass= */ Double.class, /* expectedResult= */ 1.23),
+ INT_TO_DOUBLE(
+ /* yamlString= */ "123", /* javaClass= */ Double.class, /* expectedResult= */ 123.0),
+ LONG_TO_DOUBLE(
+ /* yamlString= */ "442147483648",
+ /* javaClass= */ Double.class,
+ /* expectedResult= */ 442147483648.0),
+
+ DOUBLE_TO_FLOAT(
+ /* yamlString= */ "1.23", /* javaClass= */ Float.class, /* expectedResult= */ 1.23F),
+ INT_TO_FLOAT(/* yamlString= */ "123", /* javaClass= */ Float.class, /* expectedResult= */ 123F),
+
+ STRING_TO_ENUM(
+ /* yamlString= */ "AAA",
+ /* javaClass= */ TestEnum.class,
+ /* expectedResult= */ TestEnum.AAA),
+
+ STRING_TO_BYTES(
+ /* yamlString= */ "data",
+ /* javaClass= */ byte[].class,
+ /* expectedResult= */ "data".getBytes()),
+
+ BYTES_TO_BYTES(
+ /* yamlString= */ "!!binary 'ZGF0YQ=='",
+ /* javaClass= */ byte[].class,
+ /* expectedResult= */ "data".getBytes()),
+
+ STRING_TO_BYTESTRING(
+ /* yamlString= */ "'data'",
+ /* javaClass= */ ByteString.class,
+ /* expectedResult= */ ByteString.copyFromUtf8("data")),
+
+ BINARY_TO_BYTESTRING(
+ /* yamlString= */ "!!binary 'ZGF0YQ=='",
+ /* javaClass= */ ByteString.class,
+ /* expectedResult= */ ByteString.copyFromUtf8("data"));
+
+ final String yamlString;
+ final Class<?> javaClass;
+ final Object expectedResult;
+
+ ParseYamlValueToJavaTypeCases(String yamlString, Class<?> javaClass, Object expectedResult) {
+ this.yamlString = yamlString;
+ this.javaClass = javaClass;
+ this.expectedResult = expectedResult;
+ }
+ }
+
+ @Test
+ public void parseYamlStringToJavaType_success(
+ @TestParameter ParseYamlValueToJavaTypeCases parseYamlValueToJavaTypeCases) throws Exception {
+ Object result =
+ ParameterValueParsing.parseYamlStringToJavaType(
+ parseYamlValueToJavaTypeCases.yamlString, parseYamlValueToJavaTypeCases.javaClass);
+
+ assertThat(result).isEqualTo(parseYamlValueToJavaTypeCases.expectedResult);
+ }
+
+ private enum TestEnum {
+ AAA,
+ BBB;
+ }
+}
diff --git a/src/test/java/com/google/testing/junit/testparameterinjector/PluggableTestRunnerTest.java b/src/test/java/com/google/testing/junit/testparameterinjector/PluggableTestRunnerTest.java
new file mode 100644
index 0000000..686b152
--- /dev/null
+++ b/src/test/java/com/google/testing/junit/testparameterinjector/PluggableTestRunnerTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2021 Google Inc.
+ *
+ * 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.testing.junit.testparameterinjector;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.MethodRule;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+
+@RunWith(JUnit4.class)
+public class PluggableTestRunnerTest {
+
+ private static int ruleInvocationCount = 0;
+
+ public static class TestAndMethodRule implements MethodRule, TestRule {
+
+ @Override
+ public Statement apply(Statement base, Description description) {
+ ruleInvocationCount++;
+ return base;
+ }
+
+ @Override
+ public Statement apply(Statement base, FrameworkMethod method, Object target) {
+ ruleInvocationCount++;
+ return base;
+ }
+ }
+
+ @RunWith(PluggableTestRunner.class)
+ public static class PluggableTestRunnerTestClass {
+
+ @Rule public TestAndMethodRule rule = new TestAndMethodRule();
+
+ @Test
+ public void test() {
+ // no-op
+ }
+ }
+
+ @Test
+ public void ruleThatIsBothTestRuleAndMethodRuleIsInvokedOnceOnly() throws Exception {
+ PluggableTestRunner.run(
+ new PluggableTestRunner(PluggableTestRunnerTestClass.class) {
+ @Override
+ protected List<TestMethodProcessor> createTestMethodProcessorList() {
+ return ImmutableList.of();
+ }
+ });
+
+ assertThat(ruleInvocationCount).isEqualTo(1);
+ }
+}
diff --git a/src/test/java/com/google/testing/junit/testparameterinjector/TestInfoTest.java b/src/test/java/com/google/testing/junit/testparameterinjector/TestInfoTest.java
new file mode 100644
index 0000000..ae817f6
--- /dev/null
+++ b/src/test/java/com/google/testing/junit/testparameterinjector/TestInfoTest.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2021 Google Inc.
+ *
+ * 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.testing.junit.testparameterinjector;
+
+import static com.google.common.truth.Truth.assertThat;
+import static java.util.stream.Collectors.toList;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.truth.IterableSubject;
+import com.google.testing.junit.testparameterinjector.TestInfo.TestInfoParameter;
+import java.util.List;
+import java.util.stream.IntStream;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class TestInfoTest {
+
+ @Test
+ public void shortenNamesIfNecessary_emptyTestInfos() throws Exception {
+ ImmutableList<TestInfo> result = TestInfo.shortenNamesIfNecessary(ImmutableList.of());
+
+ assertThat(result).isEmpty();
+ }
+
+ @Test
+ public void shortenNamesIfNecessary_noParameters() throws Exception {
+ ImmutableList<TestInfo> givenTestInfos = ImmutableList.of(fakeTestInfo());
+
+ ImmutableList<TestInfo> result = TestInfo.shortenNamesIfNecessary(givenTestInfos);
+
+ assertThat(result).containsExactlyElementsIn(givenTestInfos).inOrder();
+ }
+
+ @Test
+ public void shortenNamesIfNecessary_veryLongTestMethodName_noParameters() throws Exception {
+ ImmutableList<TestInfo> givenTestInfos =
+ ImmutableList.of(
+ TestInfo.createWithoutParameters(
+ getClass()
+ .getMethod(
+ "unusedMethodThatHasAVeryLongNameForTest000000000000000000000000000000000"
+ + "000000000000000000000000000000000000000000000000000000000000000000"
+ + "000000000000000000000000000000000000000000000000000000000000000000"
+ + "000000000000000000000000"),
+ /* annotations= */ ImmutableList.of()));
+
+ ImmutableList<TestInfo> result = TestInfo.shortenNamesIfNecessary(givenTestInfos);
+
+ assertThat(result).containsExactlyElementsIn(givenTestInfos).inOrder();
+ }
+
+ @Test
+ public void shortenNamesIfNecessary_noShorteningNeeded() throws Exception {
+ ImmutableList<TestInfo> givenTestInfos =
+ ImmutableList.of(
+ fakeTestInfo(
+ TestInfoParameter.create(
+ /* name= */ "short", /* value= */ 1, /* indexInValueSource= */ 1),
+ TestInfoParameter.create(
+ /* name= */ "shorter", /* value= */ null, /* indexInValueSource= */ 3)),
+ fakeTestInfo(
+ TestInfoParameter.create(
+ /* name= */ "short", /* value= */ 1, /* indexInValueSource= */ 1),
+ TestInfoParameter.create(
+ /* name= */ "shortest", /* value= */ 20, /* indexInValueSource= */ 0)));
+
+ ImmutableList<TestInfo> result = TestInfo.shortenNamesIfNecessary(givenTestInfos);
+
+ assertThat(result).containsExactlyElementsIn(givenTestInfos).inOrder();
+ }
+
+ @Test
+ public void shortenNamesIfNecessary_singleParameterTooLong_twoParameters() throws Exception {
+ ImmutableList<TestInfo> result =
+ TestInfo.shortenNamesIfNecessary(
+ ImmutableList.of(
+ fakeTestInfo(
+ TestInfoParameter.create(
+ /* name= */ "short", /* value= */ 1, /* indexInValueSource= */ 0),
+ TestInfoParameter.create(
+ /* name= */ "shorter", /* value= */ null, /* indexInValueSource= */ 0)),
+ fakeTestInfo(
+ TestInfoParameter.create(
+ /* name= */ "short", /* value= */ 1, /* indexInValueSource= */ 0),
+ TestInfoParameter.create(
+ /* name= */ "very long parameter name for test"
+ + " 00000000000000000000000000000000000000000000000000000000"
+ + "000000000000000000000000000000000000000000000000000000000"
+ + "0000000000000000000000000000000000000000000000",
+ /* value= */ 20,
+ /* indexInValueSource= */ 1))));
+
+ assertThatTestNamesOf(result)
+ .containsExactly(
+ "toLowerCase[short,1.shorter]",
+ "toLowerCase[short,2.very long parameter name for test "
+ + "0000000000000000000000000000000000000000000000000000...]")
+ .inOrder();
+ }
+
+ @Test
+ public void shortenNamesIfNecessary_singleParameterTooLong_onlyParameter() throws Exception {
+ ImmutableList<TestInfo> result =
+ TestInfo.shortenNamesIfNecessary(
+ ImmutableList.of(
+ fakeTestInfo(
+ TestInfoParameter.create(
+ /* name= */ "shorter", /* value= */ null, /* indexInValueSource= */ 0)),
+ fakeTestInfo(
+ TestInfoParameter.create(
+ /* name= */ "very long parameter name for test"
+ + " 00000000000000000000000000000000000000000000000000000000"
+ + "000000000000000000000000000000000000000000000000000000000"
+ + "0000000000000000000000000000000000000000000000",
+ /* value= */ 20,
+ /* indexInValueSource= */ 1))));
+
+ assertThatTestNamesOf(result)
+ .containsExactly(
+ "toLowerCase[1.shorter]",
+ "toLowerCase[2.very long parameter name for test"
+ + " 000000000000000000000000000000000000000000000000000000000000...]")
+ .inOrder();
+ }
+
+ @Test
+ public void shortenNamesIfNecessary_tooManyParameters() throws Exception {
+ TestInfo testInfoWithManyParams =
+ fakeTestInfo(
+ IntStream.range(0, 50)
+ .mapToObj(
+ i ->
+ TestInfoParameter.create(
+ /* name= */ "short", /* value= */ i, /* indexInValueSource= */ i))
+ .toArray(TestInfoParameter[]::new));
+
+ ImmutableList<TestInfo> result =
+ TestInfo.shortenNamesIfNecessary(ImmutableList.of(testInfoWithManyParams));
+
+ assertThatTestNamesOf(result)
+ .containsExactly(
+ "toLowerCase[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,"
+ + "27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50]");
+ }
+
+ @Test
+ public void deduplicateTestNames_noDuplicates() throws Exception {
+ ImmutableList<TestInfo> givenTestInfos =
+ ImmutableList.of(
+ fakeTestInfo(
+ TestInfoParameter.create(
+ /* name= */ "aaa", /* value= */ 1, /* indexInValueSource= */ 1),
+ TestInfoParameter.create(
+ /* name= */ "bbb", /* value= */ null, /* indexInValueSource= */ 3)),
+ fakeTestInfo(
+ TestInfoParameter.create(
+ /* name= */ "aaa", /* value= */ 1, /* indexInValueSource= */ 1),
+ TestInfoParameter.create(
+ /* name= */ "ccc", /* value= */ 1, /* indexInValueSource= */ 0)));
+
+ ImmutableList<TestInfo> result = TestInfo.deduplicateTestNames(givenTestInfos);
+
+ assertThat(result).containsExactlyElementsIn(givenTestInfos).inOrder();
+ }
+
+ @Test
+ public void deduplicateTestNames_duplicateParameterNamesWithDifferentTypes() throws Exception {
+ ImmutableList<TestInfo> result =
+ TestInfo.deduplicateTestNames(
+ ImmutableList.of(
+ fakeTestInfo(
+ TestInfoParameter.create(
+ /* name= */ "aaa", /* value= */ 1, /* indexInValueSource= */ 1),
+ TestInfoParameter.create(
+ /* name= */ "null", /* value= */ null, /* indexInValueSource= */ 3)),
+ fakeTestInfo(
+ TestInfoParameter.create(
+ /* name= */ "aaa", /* value= */ 1, /* indexInValueSource= */ 1),
+ TestInfoParameter.create(
+ /* name= */ "null", /* value= */ "null", /* indexInValueSource= */ 0)),
+ fakeTestInfo(
+ TestInfoParameter.create(
+ /* name= */ "aaa", /* value= */ 1, /* indexInValueSource= */ 1),
+ TestInfoParameter.create(
+ /* name= */ "bbb", /* value= */ "b", /* indexInValueSource= */ 0))));
+
+ assertThatTestNamesOf(result)
+ .containsExactly(
+ "toLowerCase[aaa,null (null reference)]",
+ "toLowerCase[aaa,null (String)]",
+ "toLowerCase[aaa,bbb]")
+ .inOrder();
+ }
+
+ @Test
+ public void deduplicateTestNames_duplicateParameterNamesWithSameTypes() throws Exception {
+ ImmutableList<TestInfo> result =
+ TestInfo.deduplicateTestNames(
+ ImmutableList.of(
+ fakeTestInfo(
+ TestInfoParameter.create(
+ /* name= */ "aaa", /* value= */ 1, /* indexInValueSource= */ 0),
+ TestInfoParameter.create(
+ /* name= */ "bbb", /* value= */ 1, /* indexInValueSource= */ 0)),
+ fakeTestInfo(
+ TestInfoParameter.create(
+ /* name= */ "aaa", /* value= */ 1, /* indexInValueSource= */ 0),
+ TestInfoParameter.create(
+ /* name= */ "bbb", /* value= */ 1, /* indexInValueSource= */ 1)),
+ fakeTestInfo(
+ TestInfoParameter.create(
+ /* name= */ "aaa", /* value= */ 1, /* indexInValueSource= */ 0),
+ TestInfoParameter.create(
+ /* name= */ "ccc", /* value= */ "b", /* indexInValueSource= */ 2))));
+
+ assertThatTestNamesOf(result)
+ .containsExactly(
+ "toLowerCase[1.aaa,1.bbb]", "toLowerCase[1.aaa,2.bbb]", "toLowerCase[1.aaa,3.ccc]")
+ .inOrder();
+ }
+
+ private static TestInfo fakeTestInfo(TestInfoParameter... parameters)
+ throws NoSuchMethodException {
+ return TestInfo.createWithoutParameters(
+ String.class.getMethod("toLowerCase"), /* annotations= */ ImmutableList.of())
+ .withExtraParameters(ImmutableList.copyOf(parameters));
+ }
+
+ private static IterableSubject assertThatTestNamesOf(List<TestInfo> result) {
+ return assertThat(result.stream().map(TestInfo::getName).collect(toList()));
+ }
+
+ public void
+ unusedMethodThatHasAVeryLongNameForTest000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000() {}
+}
diff --git a/src/test/java/com/google/testing/junit/testparameterinjector/TestParameterAnnotationMethodProcessorTest.java b/src/test/java/com/google/testing/junit/testparameterinjector/TestParameterAnnotationMethodProcessorTest.java
new file mode 100644
index 0000000..51a328d
--- /dev/null
+++ b/src/test/java/com/google/testing/junit/testparameterinjector/TestParameterAnnotationMethodProcessorTest.java
@@ -0,0 +1,1077 @@
+/*
+ * Copyright 2021 Google Inc.
+ *
+ * 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.testing.junit.testparameterinjector;
+
+import static com.google.common.collect.ImmutableList.toImmutableList;
+import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.truth.Truth.assertThat;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.fail;
+
+import com.google.common.collect.ImmutableList;
+import com.google.testing.junit.testparameterinjector.TestParameter.TestParameterValuesProvider;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Function;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+import org.junit.runner.RunWith;
+import org.junit.runner.notification.Failure;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.junit.runners.model.TestClass;
+
+/**
+ * Test class to test the PluggableTestRunner test harness works with {@link
+ * TestParameterAnnotation}s.
+ */
+@RunWith(Parameterized.class)
+public class TestParameterAnnotationMethodProcessorTest {
+
+ @Retention(RUNTIME)
+ @interface ClassTestResult {
+ Result value();
+ }
+
+ enum Result {
+ /**
+ * A successful test run is expected in both for
+ * TestParameterAnnotationMethodProcessor#forAllAnnotationPlacements and
+ * TestParameterAnnotationMethodProcessor#onlyForFieldsAndParameters.
+ */
+ SUCCESS_ALWAYS,
+ SUCCESS_FOR_ALL_PLACEMENTS_ONLY,
+ FAILURE,
+ }
+
+ public enum TestEnum {
+ UNDEFINED,
+ ONE,
+ TWO,
+ THREE,
+ FOUR,
+ FIVE
+ }
+
+ @Retention(RUNTIME)
+ @TestParameterAnnotation
+ public @interface EnumParameter {
+ TestEnum[] value() default {};
+ }
+
+ @ClassTestResult(Result.SUCCESS_ALWAYS)
+ public static class SingleAnnotationClass {
+
+ private static List<TestEnum> testedParameters;
+
+ @EnumParameter({TestEnum.ONE, TestEnum.TWO, TestEnum.THREE})
+ TestEnum enumParameter;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ public void test() {
+ testedParameters.add(enumParameter);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters).containsExactly(TestEnum.ONE, TestEnum.TWO, TestEnum.THREE);
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_ALWAYS)
+ public static class MultipleAllEnumValuesAnnotationClass {
+
+ private static List<String> testedParameters;
+
+ @TestParameter TestEnum enumParameter1;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ public void test(@TestParameter TestEnum enumParameter2) {
+ testedParameters.add(enumParameter1 + ":" + enumParameter2);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters).hasSize(TestEnum.values().length * TestEnum.values().length);
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_FOR_ALL_PLACEMENTS_ONLY)
+ public static class SingleParameterAnnotationClass {
+
+ private static List<TestEnum> testedParameters;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ @EnumParameter({TestEnum.ONE, TestEnum.TWO, TestEnum.THREE})
+ public void test(TestEnum enumParameter) {
+ testedParameters.add(enumParameter);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters).containsExactly(TestEnum.ONE, TestEnum.TWO, TestEnum.THREE);
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_ALWAYS)
+ public static class SingleAnnotatedParameterAnnotationClass {
+
+ private static List<TestEnum> testedParameters;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ public void test(
+ @EnumParameter({TestEnum.ONE, TestEnum.TWO, TestEnum.THREE}) TestEnum enumParameter) {
+ testedParameters.add(enumParameter);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters).containsExactly(TestEnum.ONE, TestEnum.TWO, TestEnum.THREE);
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_ALWAYS)
+ public static class AnnotatedSuperclassParameter {
+
+ private static List<Object> testedParameters;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ public void test(
+ @EnumParameter({TestEnum.ONE, TestEnum.TWO, TestEnum.THREE}) Object enumParameter) {
+ testedParameters.add(enumParameter);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters).containsExactly(TestEnum.ONE, TestEnum.TWO, TestEnum.THREE);
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_ALWAYS)
+ public static class DuplicatedAnnotatedParameterAnnotationClass {
+
+ private static List<ImmutableList<TestEnum>> testedParameters;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ public void test(
+ @EnumParameter({TestEnum.ONE, TestEnum.TWO, TestEnum.THREE}) TestEnum enumParameter,
+ @EnumParameter({TestEnum.FOUR, TestEnum.FIVE}) TestEnum enumParameter2) {
+ testedParameters.add(ImmutableList.of(enumParameter, enumParameter2));
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters)
+ .containsExactly(
+ ImmutableList.of(TestEnum.ONE, TestEnum.FOUR),
+ ImmutableList.of(TestEnum.ONE, TestEnum.FIVE),
+ ImmutableList.of(TestEnum.TWO, TestEnum.FOUR),
+ ImmutableList.of(TestEnum.TWO, TestEnum.FIVE),
+ ImmutableList.of(TestEnum.THREE, TestEnum.FOUR),
+ ImmutableList.of(TestEnum.THREE, TestEnum.FIVE));
+ }
+ }
+
+ @ClassTestResult(Result.FAILURE)
+ public static class SingleAnnotatedParameterAnnotationClassWithMissingValue {
+
+ private static List<TestEnum> testedParameters;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ public void test(@EnumParameter TestEnum enumParameter) {
+ testedParameters.add(enumParameter);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters).containsExactly(TestEnum.ONE, TestEnum.TWO, TestEnum.THREE);
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_FOR_ALL_PLACEMENTS_ONLY)
+ public static class MultipleAnnotationTestClass {
+
+ private static List<TestEnum> testedParameters;
+
+ @EnumParameter({TestEnum.ONE, TestEnum.TWO})
+ TestEnum enumParameter;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ @EnumParameter({TestEnum.THREE})
+ public void parameterized() {
+ testedParameters.add(enumParameter);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters).containsExactly(TestEnum.THREE);
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_ALWAYS)
+ public static class TooLongTestNamesShortened {
+
+ @Rule public TestName testName = new TestName();
+
+ private static List<String> allTestNames;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ allTestNames = new ArrayList<>();
+ }
+
+ @Test
+ public void test1(
+ @TestParameter({
+ "ABC",
+ "This is a very long string (240 characters) that would normally cause Sponge+Tin to"
+ + " exceed the filename limit of 255 characters."
+ + " ==========================================================================="
+ + "==================================="
+ })
+ String testString) {
+ allTestNames.add(testName.getMethodName());
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(allTestNames)
+ .containsExactly(
+ "test1[1.ABC]",
+ "test1[2.This is a very long string (240 characters) that would normally cause"
+ + " Sponge+Tin to exceed the...]");
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_ALWAYS)
+ public static class DuplicateTestNames {
+
+ @Rule public TestName testName = new TestName();
+
+ private static List<String> allTestNames;
+ private static List<Object> allTestParameterValues;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ allTestNames = new ArrayList<>();
+ allTestParameterValues = new ArrayList<>();
+ }
+
+ @Test
+ public void test1(@TestParameter({"ABC", "ABC"}) String testString) {
+ allTestNames.add(testName.getMethodName());
+ allTestParameterValues.add(testString);
+ }
+
+ private static final class Test2Provider implements TestParameterValuesProvider {
+ @Override
+ public List<Object> provideValues() {
+ return newArrayList(123, "123", "null", null);
+ }
+ }
+
+ @Test
+ public void test2(@TestParameter(valuesProvider = Test2Provider.class) Object testObject) {
+ allTestNames.add(testName.getMethodName());
+ allTestParameterValues.add(testObject);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(allTestNames)
+ .containsExactly(
+ "test1[1.ABC]",
+ "test1[2.ABC]",
+ "test2[123 (Integer)]",
+ "test2[123 (String)]",
+ "test2[null (String)]",
+ "test2[null (null reference)]");
+ assertThat(allTestParameterValues).containsExactly("ABC", "ABC", 123, "123", "null", null);
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_ALWAYS)
+ public static class DuplicateFieldAnnotationTestClass {
+
+ private static List<String> testedParameters;
+
+ @TestParameter({"foo", "bar"})
+ String stringParameter;
+
+ @TestParameter({"baz", "qux"})
+ String stringParameter2;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ public void test() {
+ testedParameters.add(stringParameter + ":" + stringParameter2);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters).containsExactly("foo:baz", "foo:qux", "bar:baz", "bar:qux");
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_ALWAYS)
+ public static class DuplicateIdenticalFieldAnnotationTestClass {
+
+ private static List<String> testedParameters;
+
+ @TestParameter({"foo", "bar"})
+ String stringParameter;
+
+ @TestParameter({"foo", "bar"})
+ String stringParameter2;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ public void test() {
+ testedParameters.add(stringParameter + ":" + stringParameter2);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters).containsExactly("foo:foo", "foo:bar", "bar:foo", "bar:bar");
+ }
+ }
+
+ @ClassTestResult(Result.FAILURE)
+ public static class ErrorDuplicateFieldAnnotationTestClass {
+
+ @EnumParameter({TestEnum.ONE, TestEnum.TWO})
+ TestEnum parameter1;
+
+ @EnumParameter({TestEnum.THREE, TestEnum.FOUR})
+ TestEnum parameter2;
+
+ @Test
+ @EnumParameter(TestEnum.FIVE)
+ public void test() {}
+ }
+
+ @ClassTestResult(Result.FAILURE)
+ public static class ErrorDuplicateFieldAndClassAnnotationTestClass {
+
+ @EnumParameter({TestEnum.ONE, TestEnum.TWO})
+ TestEnum parameter;
+
+ @EnumParameter(TestEnum.FIVE)
+ public ErrorDuplicateFieldAndClassAnnotationTestClass() {}
+
+ @Test
+ public void test() {}
+ }
+
+ @ClassTestResult(Result.SUCCESS_ALWAYS)
+ public static class SingleAnnotationTestClassWithAnnotation {
+
+ private static List<TestEnum> testedParameters;
+
+ @EnumParameter({TestEnum.ONE, TestEnum.TWO, TestEnum.THREE})
+ TestEnum enumParameter;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ public void test() {
+ testedParameters.add(enumParameter);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters).containsExactly(TestEnum.ONE, TestEnum.TWO, TestEnum.THREE);
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_ALWAYS)
+ public static class MultipleAnnotationTestClassWithAnnotation {
+
+ private static List<String> testedParameters;
+
+ @EnumParameter({TestEnum.ONE, TestEnum.TWO, TestEnum.THREE})
+ TestEnum enumParameter;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ public void parameterized(@TestParameter({"foo", "bar"}) String stringParameter) {
+ testedParameters.add(stringParameter + ":" + enumParameter);
+ }
+
+ @Test
+ public void nonParameterized() {
+ testedParameters.add("none:" + enumParameter);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters)
+ .containsExactly(
+ "none:ONE",
+ "none:TWO",
+ "none:THREE",
+ "foo:ONE",
+ "foo:TWO",
+ "foo:THREE",
+ "bar:ONE",
+ "bar:TWO",
+ "bar:THREE");
+ }
+ }
+
+ public abstract static class BaseClassWithAnnotations {
+ @Rule public TestName testName = new TestName();
+
+ static List<String> allTestNames;
+
+ @TestParameter boolean boolInBase;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ allTestNames = new ArrayList<>();
+ }
+
+ @Before
+ public void setUp() {
+ assertThat(allTestNames).doesNotContain(testName.getMethodName());
+ }
+
+ @After
+ public void tearDown() {
+ assertThat(allTestNames).contains(testName.getMethodName());
+ }
+
+ @Test
+ public void testInBase(@TestParameter({"ONE", "TWO"}) TestEnum enumInBase) {
+ allTestNames.add(testName.getMethodName());
+ }
+
+ @Test
+ public abstract void abstractTestInBase();
+
+ @Test
+ public void overridableTestInBase() {
+ throw new UnsupportedOperationException("Expected the base class to override this");
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_ALWAYS)
+ public static class AnnotationInheritedFromBaseClass extends BaseClassWithAnnotations {
+
+ @TestParameter boolean boolInChild;
+
+ @Test
+ public void testInChild(@TestParameter({"TWO", "THREE"}) TestEnum enumInChild) {
+ allTestNames.add(testName.getMethodName());
+ }
+
+ @Override
+ public void abstractTestInBase() {
+ allTestNames.add(testName.getMethodName());
+ }
+
+ @Override
+ public void overridableTestInBase() {
+ allTestNames.add(testName.getMethodName());
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(allTestNames)
+ .containsExactly(
+ "testInBase[boolInChild=false,boolInBase=false,ONE]",
+ "testInBase[boolInChild=false,boolInBase=false,TWO]",
+ "testInBase[boolInChild=false,boolInBase=true,ONE]",
+ "testInBase[boolInChild=false,boolInBase=true,TWO]",
+ "testInBase[boolInChild=true,boolInBase=false,ONE]",
+ "testInBase[boolInChild=true,boolInBase=false,TWO]",
+ "testInBase[boolInChild=true,boolInBase=true,ONE]",
+ "testInBase[boolInChild=true,boolInBase=true,TWO]",
+ "testInChild[boolInChild=false,boolInBase=false,TWO]",
+ "testInChild[boolInChild=false,boolInBase=false,THREE]",
+ "testInChild[boolInChild=false,boolInBase=true,TWO]",
+ "testInChild[boolInChild=false,boolInBase=true,THREE]",
+ "testInChild[boolInChild=true,boolInBase=false,TWO]",
+ "testInChild[boolInChild=true,boolInBase=false,THREE]",
+ "testInChild[boolInChild=true,boolInBase=true,TWO]",
+ "testInChild[boolInChild=true,boolInBase=true,THREE]",
+ "abstractTestInBase[boolInChild=false,boolInBase=false]",
+ "abstractTestInBase[boolInChild=false,boolInBase=true]",
+ "abstractTestInBase[boolInChild=true,boolInBase=false]",
+ "abstractTestInBase[boolInChild=true,boolInBase=true]",
+ "overridableTestInBase[boolInChild=false,boolInBase=false]",
+ "overridableTestInBase[boolInChild=false,boolInBase=true]",
+ "overridableTestInBase[boolInChild=true,boolInBase=false]",
+ "overridableTestInBase[boolInChild=true,boolInBase=true]");
+ }
+ }
+
+ @Retention(RUNTIME)
+ @TestParameterAnnotation(validator = TestEnumValidator.class, processor = TestEnumProcessor.class)
+ public @interface EnumEvaluatorParameter {
+ TestEnum[] value() default {};
+ }
+
+ public static class TestEnumValidator implements TestParameterValidator {
+
+ @Override
+ public boolean shouldSkip(Context context) {
+ return context.has(EnumEvaluatorParameter.class, TestEnum.THREE);
+ }
+ }
+
+ public static class TestEnumProcessor implements TestParameterProcessor {
+
+ static List<Object> beforeCalls = new ArrayList<>();
+ static List<Object> afterCalls = new ArrayList<>();
+
+ static void init() {
+ beforeCalls.clear();
+ afterCalls.clear();
+ }
+
+ static TestEnum currentValue;
+
+ @Override
+ public void before(Object testParameterValue) {
+ beforeCalls.add(testParameterValue);
+ currentValue = (TestEnum) testParameterValue;
+ }
+
+ @Override
+ public void after(Object testParameterValue) {
+ afterCalls.add(testParameterValue);
+ currentValue = null;
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_ALWAYS)
+ public static class MethodEvaluatorClass {
+
+ private static List<TestEnum> testedParameters;
+
+ @Test
+ public void test(
+ @EnumEvaluatorParameter({TestEnum.ONE, TestEnum.TWO, TestEnum.THREE}) TestEnum value) {
+ if (value == TestEnum.THREE) {
+ fail();
+ } else {
+ testedParameters.add(value);
+ }
+ }
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @BeforeClass
+ public static void init() {
+ TestEnumProcessor.init();
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters).containsExactly(TestEnum.ONE, TestEnum.TWO);
+ assertThat(TestEnumProcessor.beforeCalls).containsExactly(TestEnum.ONE, TestEnum.TWO);
+ assertThat(TestEnumProcessor.afterCalls).containsExactly(TestEnum.ONE, TestEnum.TWO);
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_ALWAYS)
+ public static class FieldEvaluatorClass {
+
+ private static List<TestEnum> testedParameters;
+
+ @EnumEvaluatorParameter({TestEnum.ONE, TestEnum.TWO, TestEnum.THREE})
+ TestEnum value;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ public void test() {
+ if (value == TestEnum.THREE) {
+ fail();
+ } else {
+ testedParameters.add(value);
+ }
+ }
+
+ @BeforeClass
+ public static void init() {
+ TestEnumProcessor.init();
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters).containsExactly(TestEnum.ONE, TestEnum.TWO);
+ assertThat(TestEnumProcessor.beforeCalls).containsExactly(TestEnum.ONE, TestEnum.TWO);
+ assertThat(TestEnumProcessor.afterCalls).containsExactly(TestEnum.ONE, TestEnum.TWO);
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_FOR_ALL_PLACEMENTS_ONLY)
+ @EnumEvaluatorParameter({TestEnum.ONE, TestEnum.TWO, TestEnum.THREE})
+ public static class ClassEvaluatorClass {
+
+ private static List<TestEnum> testedParameters;
+
+ public ClassEvaluatorClass() {}
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ public void test() {
+ if (TestEnumProcessor.currentValue == TestEnum.THREE) {
+ fail();
+ } else {
+ testedParameters.add(TestEnumProcessor.currentValue);
+ }
+ }
+
+ @BeforeClass
+ public static void init() {
+ TestEnumProcessor.init();
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters).containsExactly(TestEnum.ONE, TestEnum.TWO);
+ assertThat(TestEnumProcessor.beforeCalls).containsExactly(TestEnum.ONE, TestEnum.TWO);
+ assertThat(TestEnumProcessor.afterCalls).containsExactly(TestEnum.ONE, TestEnum.TWO);
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_ALWAYS)
+ public static class ConstructorClass {
+
+ private static List<TestEnum> testedParameters;
+ final TestEnum enumParameter;
+
+ public ConstructorClass(
+ @EnumParameter({TestEnum.ONE, TestEnum.TWO, TestEnum.THREE}) TestEnum enumParameter) {
+ this.enumParameter = enumParameter;
+ }
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ public void test() {
+ testedParameters.add(enumParameter);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters).containsExactly(TestEnum.ONE, TestEnum.TWO, TestEnum.THREE);
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_FOR_ALL_PLACEMENTS_ONLY)
+ public static class MethodFieldOverrideClass {
+
+ private static List<TestEnum> testedParameters;
+
+ @EnumParameter({TestEnum.ONE, TestEnum.TWO})
+ TestEnum enumParameter;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ @EnumParameter({TestEnum.ONE, TestEnum.TWO, TestEnum.THREE})
+ public void test() {
+ testedParameters.add(enumParameter);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters).containsExactly(TestEnum.ONE, TestEnum.TWO, TestEnum.THREE);
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_FOR_ALL_PLACEMENTS_ONLY)
+ @EnumEvaluatorParameter({TestEnum.ONE})
+ public static class MethodClassOverrideClass {
+
+ private static List<TestEnum> testedParameters;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ @EnumEvaluatorParameter({TestEnum.ONE, TestEnum.TWO, TestEnum.THREE})
+ public void test() {
+ testedParameters.add(TestEnumProcessor.currentValue);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters).containsExactly(TestEnum.ONE, TestEnum.TWO);
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_FOR_ALL_PLACEMENTS_ONLY)
+ public static class ErrorDuplicatedConstructorMethodAnnotation {
+
+ private static List<String> testedParameters;
+ final TestEnum enumParameter;
+
+ @EnumParameter({TestEnum.ONE, TestEnum.TWO, TestEnum.THREE})
+ public ErrorDuplicatedConstructorMethodAnnotation(TestEnum enumParameter) {
+ this.enumParameter = enumParameter;
+ }
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ @EnumParameter({TestEnum.ONE, TestEnum.TWO})
+ public void test(TestEnum otherParameter) {
+ testedParameters.add(enumParameter + ":" + otherParameter);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters)
+ .containsExactly("ONE:ONE", "ONE:TWO", "TWO:ONE", "TWO:TWO", "THREE:ONE", "THREE:TWO");
+ }
+ }
+
+ @ClassTestResult(Result.FAILURE)
+ @EnumParameter({TestEnum.ONE, TestEnum.TWO, TestEnum.THREE})
+ public static class ErrorDuplicatedClassFieldAnnotation {
+
+ private static List<TestEnum> testedParameters;
+
+ @EnumParameter({TestEnum.ONE, TestEnum.TWO})
+ TestEnum enumParameter;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ public void test() {
+ testedParameters.add(enumParameter);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters).containsExactly(TestEnum.ONE, TestEnum.TWO);
+ }
+ }
+
+ @ClassTestResult(Result.FAILURE)
+ public static class ErrorNonStaticProviderClass {
+
+ @Test
+ public void test(@TestParameter(valuesProvider = NonStaticProvider.class) int i) {}
+
+ @SuppressWarnings("ClassCanBeStatic")
+ class NonStaticProvider implements TestParameterValuesProvider {
+ @Override
+ public List<?> provideValues() {
+ return ImmutableList.of();
+ }
+ }
+ }
+
+ public enum EnumA {
+ A1,
+ A2
+ }
+
+ public enum EnumB {
+ B1,
+ B2
+ }
+
+ public enum EnumC {
+ C1,
+ C2,
+ C3
+ }
+
+ @Retention(RUNTIME)
+ @TestParameterAnnotation(validator = TestBaseValidatorValidator.class)
+ public @interface EnumAParameter {
+ EnumA[] value() default {EnumA.A1, EnumA.A2};
+ }
+
+ @Retention(RUNTIME)
+ @TestParameterAnnotation(validator = TestBaseValidatorValidator.class)
+ public @interface EnumBParameter {
+ EnumB[] value() default {EnumB.B1, EnumB.B2};
+ }
+
+ @Retention(RUNTIME)
+ @TestParameterAnnotation(validator = TestBaseValidatorValidator.class)
+ public @interface EnumCParameter {
+ EnumC[] value() default {EnumC.C1, EnumC.C2, EnumC.C3};
+ }
+
+ public static class TestBaseValidatorValidator extends BaseTestParameterValidator {
+
+ @Override
+ protected List<List<Class<? extends Annotation>>> getIndependentParameters(Context context) {
+ return ImmutableList.of(
+ ImmutableList.of(EnumAParameter.class, EnumBParameter.class, EnumCParameter.class));
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_ALWAYS)
+ public static class IndependentAnnotation {
+
+ @EnumAParameter EnumA enumA;
+ @EnumBParameter EnumB enumB;
+ @EnumCParameter EnumC enumC;
+
+ private static List<List<Object>> testedParameters;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ public void test() {
+ testedParameters.add(ImmutableList.of(enumA, enumB, enumC));
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ // Only 3 tests should have been sufficient to cover all cases.
+ assertThat(testedParameters).hasSize(3);
+ assertAllEnumsAreIncluded(EnumA.values());
+ assertAllEnumsAreIncluded(EnumB.values());
+ assertAllEnumsAreIncluded(EnumC.values());
+ }
+
+ private static <T extends Enum<T>> void assertAllEnumsAreIncluded(Enum<T>[] values) {
+ Set<Enum<T>> enumSet = new HashSet<>(Arrays.asList(values));
+ for (List<Object> enumList : testedParameters) {
+ enumSet.removeAll(enumList);
+ }
+ assertThat(enumSet).isEmpty();
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_ALWAYS)
+ public static class TestNamesTest {
+
+ @Rule public TestName name = new TestName();
+
+ @TestParameter("8")
+ long fieldParam;
+
+ @Test
+ public void withPrimitives(
+ @TestParameter("true") boolean param1, @TestParameter("2") int param2) {
+ assertThat(name.getMethodName())
+ .isEqualTo("withPrimitives[fieldParam=8,param1=true,param2=2]");
+ }
+
+ @Test
+ public void withString(@TestParameter("AAA") String param1) {
+ assertThat(name.getMethodName()).isEqualTo("withString[fieldParam=8,AAA]");
+ }
+
+ @Test
+ public void withEnum(@EnumParameter(TestEnum.TWO) TestEnum param1) {
+ assertThat(name.getMethodName()).isEqualTo("withEnum[fieldParam=8,TWO]");
+ }
+ }
+
+ @ClassTestResult(Result.SUCCESS_ALWAYS)
+ public static class MethodNameContainsOrderedParameterNames {
+
+ @Rule public TestName name = new TestName();
+
+ @Test
+ public void pretest(@TestParameter({"a", "b"}) String foo) {}
+
+ @Test
+ public void test(
+ @EnumParameter({TestEnum.ONE, TestEnum.TWO}) TestEnum e, @TestParameter({"c"}) String foo) {
+ assertThat(name.getMethodName()).isEqualTo("test[" + e.name() + "," + foo + "]");
+ }
+ }
+
+ @Parameters(name = "{0}:{2}")
+ public static Collection<Object[]> parameters() {
+ return Arrays.stream(TestParameterAnnotationMethodProcessorTest.class.getClasses())
+ .filter(cls -> cls.isAnnotationPresent(ClassTestResult.class))
+ .map(
+ cls ->
+ new Object[] {
+ cls.getSimpleName(), cls, cls.getAnnotation(ClassTestResult.class).value()
+ })
+ .collect(toImmutableList());
+ }
+
+ private final Class<?> testClass;
+ private final Result result;
+
+ public TestParameterAnnotationMethodProcessorTest(
+ String name, Class<?> testClass, Result result) {
+ this.testClass = testClass;
+ this.result = result;
+ }
+
+ @Test
+ @Ignore("b/195657808 @TestParameters is not supported on Android")
+ public void test() throws Exception {
+ List<Failure> failures;
+ switch (result) {
+ case SUCCESS_ALWAYS:
+ failures =
+ PluggableTestRunner.run(
+ newTestRunnerWithParameterizedSupport(
+ TestParameterAnnotationMethodProcessor::forAllAnnotationPlacements));
+ assertThat(failures).isEmpty();
+
+ failures =
+ PluggableTestRunner.run(
+ newTestRunnerWithParameterizedSupport(
+ TestParameterAnnotationMethodProcessor::onlyForFieldsAndParameters));
+ assertThat(failures).isEmpty();
+ break;
+
+ case SUCCESS_FOR_ALL_PLACEMENTS_ONLY:
+ failures =
+ PluggableTestRunner.run(
+ newTestRunnerWithParameterizedSupport(
+ TestParameterAnnotationMethodProcessor::forAllAnnotationPlacements));
+ assertThat(failures).isEmpty();
+
+ assertThrows(
+ IllegalStateException.class,
+ () ->
+ PluggableTestRunner.run(
+ newTestRunnerWithParameterizedSupport(
+ TestParameterAnnotationMethodProcessor::onlyForFieldsAndParameters)));
+ break;
+
+ case FAILURE:
+ assertThrows(
+ IllegalStateException.class,
+ () ->
+ PluggableTestRunner.run(
+ newTestRunnerWithParameterizedSupport(
+ TestParameterAnnotationMethodProcessor::forAllAnnotationPlacements)));
+ assertThrows(
+ IllegalStateException.class,
+ () ->
+ PluggableTestRunner.run(
+ newTestRunnerWithParameterizedSupport(
+ TestParameterAnnotationMethodProcessor::onlyForFieldsAndParameters)));
+ break;
+ }
+ }
+
+ private PluggableTestRunner newTestRunnerWithParameterizedSupport(
+ Function<TestClass, TestMethodProcessor> processor) throws Exception {
+ return new PluggableTestRunner(testClass) {
+ @Override
+ protected List<TestMethodProcessor> createTestMethodProcessorList() {
+ return ImmutableList.of(processor.apply(getTestClass()));
+ }
+ };
+ }
+}
diff --git a/src/test/java/com/google/testing/junit/testparameterinjector/TestParameterTest.java b/src/test/java/com/google/testing/junit/testparameterinjector/TestParameterTest.java
new file mode 100644
index 0000000..b16d5e1
--- /dev/null
+++ b/src/test/java/com/google/testing/junit/testparameterinjector/TestParameterTest.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2021 Google Inc.
+ *
+ * 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.testing.junit.testparameterinjector;
+
+import static com.google.common.collect.ImmutableList.toImmutableList;
+import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.google.common.base.CharMatcher;
+import com.google.testing.junit.testparameterinjector.TestParameter.TestParameterValuesProvider;
+import java.lang.annotation.Retention;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runner.notification.Failure;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/** Test class to test the @TestParameter's value provider. */
+@RunWith(Parameterized.class)
+public class TestParameterTest {
+
+ @Retention(RUNTIME)
+ @interface RunAsTest {}
+
+ public enum TestEnum {
+ ONE,
+ TWO,
+ THREE,
+ }
+
+ @RunAsTest
+ public static class AnnotatedField {
+ private static List<TestEnum> testedParameters;
+
+ @TestParameter TestEnum enumParameter;
+
+ @BeforeClass
+ public static void initializeStaticFields() {
+ assertWithMessage("Expecting this class to be run only once").that(testedParameters).isNull();
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ public void test() {
+ testedParameters.add(enumParameter);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters).containsExactly(TestEnum.ONE, TestEnum.TWO, TestEnum.THREE);
+ }
+ }
+
+ @RunAsTest
+ public static class AnnotatedConstructorParameter {
+ private static List<TestEnum> testedParameters;
+
+ private final TestEnum enumParameter;
+
+ public AnnotatedConstructorParameter(@TestParameter TestEnum enumParameter) {
+ this.enumParameter = enumParameter;
+ }
+
+ @BeforeClass
+ public static void initializeStaticFields() {
+ assertWithMessage("Expecting this class to be run only once").that(testedParameters).isNull();
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ public void test() {
+ testedParameters.add(enumParameter);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters).containsExactly(TestEnum.ONE, TestEnum.TWO, TestEnum.THREE);
+ }
+ }
+
+ @RunAsTest
+ public static class MultipleAnnotatedParameters {
+ private static List<String> testedParameters;
+
+ @BeforeClass
+ public static void initializeStaticFields() {
+ assertWithMessage("Expecting this class to be run only once").that(testedParameters).isNull();
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ public void test(
+ @TestParameter TestEnum enumParameterA,
+ @TestParameter({"TWO", "THREE"}) TestEnum enumParameterB,
+ @TestParameter({"!!binary 'ZGF0YQ=='", "data2"}) byte[] bytes) {
+ testedParameters.add(
+ String.format("%s:%s:%s", enumParameterA, enumParameterB, new String(bytes)));
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters)
+ .containsExactly(
+ "ONE:TWO:data",
+ "ONE:THREE:data",
+ "TWO:TWO:data",
+ "TWO:THREE:data",
+ "THREE:TWO:data",
+ "THREE:THREE:data",
+ "ONE:TWO:data2",
+ "ONE:THREE:data2",
+ "TWO:TWO:data2",
+ "TWO:THREE:data2",
+ "THREE:TWO:data2",
+ "THREE:THREE:data2");
+ }
+ }
+
+ @RunAsTest
+ public static class WithValuesProvider {
+ private static List<Object> testedParameters;
+
+ @BeforeClass
+ public static void initializeStaticFields() {
+ assertWithMessage("Expecting this class to be run only once").that(testedParameters).isNull();
+ testedParameters = new ArrayList<>();
+ }
+
+ @Test
+ public void stringTest(
+ @TestParameter(valuesProvider = TestStringProvider.class) String string) {
+ testedParameters.add(string);
+ }
+
+ @Test
+ public void charMatcherTest(
+ @TestParameter(valuesProvider = CharMatcherProvider.class) CharMatcher charMatcher) {
+ testedParameters.add(charMatcher);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testedParameters)
+ .containsExactly(
+ "A", "B", null, CharMatcher.any(), CharMatcher.ascii(), CharMatcher.whitespace());
+ }
+
+ private static final class TestStringProvider implements TestParameterValuesProvider {
+ @Override
+ public List<String> provideValues() {
+ return newArrayList("A", "B", null);
+ }
+ }
+
+ private static final class CharMatcherProvider implements TestParameterValuesProvider {
+ @Override
+ public List<CharMatcher> provideValues() {
+ return newArrayList(CharMatcher.any(), CharMatcher.ascii(), CharMatcher.whitespace());
+ }
+ }
+ }
+
+ @Parameters(name = "{0}")
+ public static Collection<Object[]> parameters() {
+ return Arrays.stream(TestParameterTest.class.getClasses())
+ .filter(cls -> cls.isAnnotationPresent(RunAsTest.class))
+ .map(cls -> new Object[] {cls.getSimpleName(), cls})
+ .collect(toImmutableList());
+ }
+
+ private final Class<?> testClass;
+
+ public TestParameterTest(String name, Class<?> testClass) {
+ this.testClass = testClass;
+ }
+
+ @Test
+ public void test() throws Exception {
+ List<Failure> failures =
+ PluggableTestRunner.run(
+ new PluggableTestRunner(testClass) {
+ @Override
+ protected List<TestMethodProcessor> createTestMethodProcessorList() {
+ return TestMethodProcessors.createNewParameterizedProcessorsWithLegacyFeatures(
+ getTestClass());
+ }
+ });
+
+ assertThat(failures).isEmpty();
+ }
+}
diff --git a/src/test/java/com/google/testing/junit/testparameterinjector/TestParametersMethodProcessorTest.java b/src/test/java/com/google/testing/junit/testparameterinjector/TestParametersMethodProcessorTest.java
new file mode 100644
index 0000000..b27ce7a
--- /dev/null
+++ b/src/test/java/com/google/testing/junit/testparameterinjector/TestParametersMethodProcessorTest.java
@@ -0,0 +1,474 @@
+/*
+ * Copyright 2021 Google Inc.
+ *
+ * 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.testing.junit.testparameterinjector;
+
+import static com.google.common.collect.ImmutableList.toImmutableList;
+import static com.google.common.truth.Truth.assertThat;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.google.common.collect.ImmutableList;
+import com.google.testing.junit.testparameterinjector.TestParameters.TestParametersValues;
+import com.google.testing.junit.testparameterinjector.TestParameters.TestParametersValuesProvider;
+import java.lang.annotation.Retention;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+import org.junit.runner.RunWith;
+import org.junit.runner.notification.Failure;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+@Ignore("b/195657808 @TestParameters is not supported on Android")
+public class TestParametersMethodProcessorTest {
+
+ @Retention(RUNTIME)
+ @interface RunAsTest {}
+
+ public enum TestEnum {
+ ONE,
+ TWO,
+ THREE;
+ }
+
+ @RunAsTest
+ public static class SimpleMethodAnnotation {
+ @Rule public TestName testName = new TestName();
+
+ private static Map<String, String> testNameToStringifiedParametersMap;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testNameToStringifiedParametersMap = new LinkedHashMap<>();
+ }
+
+ @Test
+ @TestParameters({
+ "{testEnum: ONE, testLong: 11, testBoolean: false, testString: ABC}",
+ "{testEnum: TWO,\ntestLong: 22,\ntestBoolean: true,\r\n\r\n testString: 'DEF'}",
+ "{testEnum: null, testLong: 33, testBoolean: false, testString: null}",
+ })
+ @Ignore("b/195657808 @TestParameters is not supported on Android")
+ public void test(TestEnum testEnum, long testLong, boolean testBoolean, String testString) {
+ testNameToStringifiedParametersMap.put(
+ testName.getMethodName(),
+ String.format("%s,%s,%s,%s", testEnum, testLong, testBoolean, testString));
+ }
+
+ @Test
+ @TestParameters({
+ "{testString: ABC}",
+ "{testString: 'This is a very long string (240 characters) that would normally cause"
+ + " Sponge+Tin to exceed the filename limit of 255 characters."
+ + " ================================================================================="
+ + "=============='}"
+ })
+ @Ignore("b/195657808 @TestParameters is not supported on Android")
+ public void test2_withLongNames(String testString) {
+ testNameToStringifiedParametersMap.put(testName.getMethodName(), testString);
+ }
+
+ @Test
+ @TestParameters({
+ "{testEnums: [ONE, TWO, THREE], testLongs: [11, 4], testBooleans: [false, true],"
+ + " testStrings: [ABC, '123']}",
+ "{testEnums: [TWO],\ntestLongs: [22],\ntestBooleans: [true],\r\n\r\n testStrings: ['DEF']}",
+ "{testEnums: [], testLongs: [], testBooleans: [], testStrings: []}",
+ })
+ @Ignore("b/195657808 @TestParameters is not supported on Android")
+ public void test3_withRepeatedParams(
+ List<TestEnum> testEnums,
+ List<Long> testLongs,
+ List<Boolean> testBooleans,
+ List<String> testStrings) {
+ testNameToStringifiedParametersMap.put(
+ testName.getMethodName(),
+ String.format("%s,%s,%s,%s", testEnums, testLongs, testBooleans, testStrings));
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testNameToStringifiedParametersMap)
+ .containsExactly(
+ "test[{testEnum: ONE, testLong: 11, testBoolean: false, testString: ABC}]",
+ "ONE,11,false,ABC",
+ "test[{testEnum: TWO, testLong: 22, testBoolean: true, testString: 'DEF'}]",
+ "TWO,22,true,DEF",
+ "test[{testEnum: null, testLong: 33, testBoolean: false, testString: null}]",
+ "null,33,false,null",
+ "test2_withLongNames[1.{testString: ABC}]",
+ "ABC",
+ "test2_withLongNames[2.{testString: 'This is a very long string (240 characters)"
+ + " that would normally cause Sponge+Tin...]",
+ "This is a very long string (240 characters) that would normally cause Sponge+Tin to"
+ + " exceed the filename limit of 255 characters."
+ + " ================================================================================="
+ + "==============",
+ "test3_withRepeatedParams[1.{testEnums: [ONE, TWO, THREE], testLongs: [11, 4],"
+ + " testBooleans: [false, true], testStrings: [...]",
+ "[ONE, TWO, THREE],[11, 4],[false, true],[ABC, 123]",
+ "test3_withRepeatedParams[2.{testEnums: [TWO], testLongs: [22], testBooleans: [true],"
+ + " testStrings: ['DEF']}]",
+ "[TWO],[22],[true],[DEF]",
+ "test3_withRepeatedParams[3.{testEnums: [], testLongs: [], testBooleans: [],"
+ + " testStrings: []}]",
+ "[],[],[],[]");
+ }
+ }
+
+ @RunAsTest
+ public static class SimpleConstructorAnnotation {
+
+ @Rule public TestName testName = new TestName();
+
+ private static Map<String, String> testNameToStringifiedParametersMap;
+
+ private final TestEnum testEnum;
+ private final long testLong;
+ private final boolean testBoolean;
+ private final String testString;
+
+ @TestParameters({
+ "{testEnum: ONE, testLong: 11, testBoolean: false, testString: ABC}",
+ "{testEnum: TWO, testLong: 22, testBoolean: true, testString: DEF}",
+ "{testEnum: null, testLong: 33, testBoolean: false, testString: null}",
+ })
+ public SimpleConstructorAnnotation(
+ TestEnum testEnum, long testLong, boolean testBoolean, String testString) {
+ this.testEnum = testEnum;
+ this.testLong = testLong;
+ this.testBoolean = testBoolean;
+ this.testString = testString;
+ }
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testNameToStringifiedParametersMap = new LinkedHashMap<>();
+ }
+
+ @Test
+ public void test1() {
+ testNameToStringifiedParametersMap.put(
+ testName.getMethodName(),
+ String.format("%s,%s,%s,%s", testEnum, testLong, testBoolean, testString));
+ }
+
+ @Test
+ public void test2() {
+ testNameToStringifiedParametersMap.put(
+ testName.getMethodName(),
+ String.format("%s,%s,%s,%s", testEnum, testLong, testBoolean, testString));
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testNameToStringifiedParametersMap)
+ .containsExactly(
+ "test1[{testEnum: ONE, testLong: 11, testBoolean: false, testString: ABC}]",
+ "ONE,11,false,ABC",
+ "test1[{testEnum: TWO, testLong: 22, testBoolean: true, testString: DEF}]",
+ "TWO,22,true,DEF",
+ "test1[{testEnum: null, testLong: 33, testBoolean: false, testString: null}]",
+ "null,33,false,null",
+ "test2[{testEnum: ONE, testLong: 11, testBoolean: false, testString: ABC}]",
+ "ONE,11,false,ABC",
+ "test2[{testEnum: TWO, testLong: 22, testBoolean: true, testString: DEF}]",
+ "TWO,22,true,DEF",
+ "test2[{testEnum: null, testLong: 33, testBoolean: false, testString: null}]",
+ "null,33,false,null");
+ }
+ }
+
+ @RunAsTest
+ public static class ConstructorAnnotationWithProvider {
+
+ @Rule public TestName testName = new TestName();
+
+ private static Map<String, TestEnum> testNameToParameterMap;
+
+ private final TestEnum testEnum;
+
+ @TestParameters(valuesProvider = TestEnumValuesProvider.class)
+ public ConstructorAnnotationWithProvider(TestEnum testEnum) {
+ this.testEnum = testEnum;
+ }
+
+ @BeforeClass
+ public static void resetStaticState() {
+ testNameToParameterMap = new LinkedHashMap<>();
+ }
+
+ @Test
+ public void test1() {
+ testNameToParameterMap.put(testName.getMethodName(), testEnum);
+ }
+
+ @Test
+ public void test2() {
+ testNameToParameterMap.put(testName.getMethodName(), testEnum);
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(testNameToParameterMap)
+ .containsExactly(
+ "test1[one]", TestEnum.ONE,
+ "test1[two]", TestEnum.TWO,
+ "test1[null-case]", null,
+ "test2[one]", TestEnum.ONE,
+ "test2[two]", TestEnum.TWO,
+ "test2[null-case]", null);
+ }
+
+ private static final class TestEnumValuesProvider implements TestParametersValuesProvider {
+ @Override
+ public List<TestParametersValues> provideValues() {
+ return ImmutableList.of(
+ TestParametersValues.builder()
+ .name("one")
+ .addParameter("testEnum", TestEnum.ONE)
+ .build(),
+ TestParametersValues.builder()
+ .name("two")
+ .addParameter("testEnum", TestEnum.TWO)
+ .build(),
+ TestParametersValues.builder()
+ .name("null-case")
+ .addParameter("testEnum", null)
+ .build());
+ }
+ }
+ }
+
+ public abstract static class BaseClassWithMethodAnnotation {
+ @Rule public TestName testName = new TestName();
+
+ static List<String> allTestNames;
+
+ @BeforeClass
+ public static void resetStaticState() {
+ allTestNames = new ArrayList<>();
+ }
+
+ @Before
+ public void setUp() {
+ assertThat(allTestNames).doesNotContain(testName.getMethodName());
+ }
+
+ @After
+ public void tearDown() {
+ assertThat(allTestNames).contains(testName.getMethodName());
+ }
+
+ @Test
+ @TestParameters({"{testEnum: ONE}", "{testEnum: TWO}"})
+ public void testInBase(TestEnum testEnum) {
+ allTestNames.add(testName.getMethodName());
+ }
+ }
+
+ @RunAsTest
+ public static class AnnotationInheritedFromBaseClass extends BaseClassWithMethodAnnotation {
+
+ @Test
+ @TestParameters({"{testEnum: TWO}", "{testEnum: THREE}"})
+ public void testInChild(TestEnum testEnum) {
+ allTestNames.add(testName.getMethodName());
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(allTestNames)
+ .containsExactly(
+ "testInBase[{testEnum: ONE}]",
+ "testInBase[{testEnum: TWO}]",
+ "testInChild[{testEnum: TWO}]",
+ "testInChild[{testEnum: THREE}]");
+ }
+ }
+
+ @RunAsTest
+ public static class MixedWithTestParameterMethodAnnotation {
+ @Rule public TestName testName = new TestName();
+
+ private static List<String> allTestNames;
+ private static List<String> testNamesThatInvokedBefore;
+ private static List<String> testNamesThatInvokedAfter;
+
+ @TestParameters({"{testEnum: ONE}", "{testEnum: TWO}"})
+ public MixedWithTestParameterMethodAnnotation(TestEnum testEnum) {}
+
+ @BeforeClass
+ public static void resetStaticState() {
+ allTestNames = new ArrayList<>();
+ testNamesThatInvokedBefore = new ArrayList<>();
+ testNamesThatInvokedAfter = new ArrayList<>();
+ }
+
+ @Before
+ public void setUp() {
+ assertThat(allTestNames).doesNotContain(testName.getMethodName());
+ testNamesThatInvokedBefore.add(testName.getMethodName());
+ }
+
+ @After
+ public void tearDown() {
+ assertThat(allTestNames).contains(testName.getMethodName());
+ testNamesThatInvokedAfter.add(testName.getMethodName());
+ }
+
+ @Test
+ public void test1(@TestParameter TestEnum testEnum) {
+ assertThat(testNamesThatInvokedBefore).contains(testName.getMethodName());
+ allTestNames.add(testName.getMethodName());
+ }
+
+ @Test
+ @TestParameters({"{testString: ABC}", "{testString: DEF}"})
+ public void test2(String testString) {
+ allTestNames.add(testName.getMethodName());
+ }
+
+ @Test
+ @TestParameters({
+ "{testString: ABC}",
+ "{testString: 'This is a very long string (240 characters) that would normally cause"
+ + " Sponge+Tin to exceed the filename limit of 255 characters."
+ + " ================================================================================="
+ + "=============='}"
+ })
+ public void test3_withLongNames(String testString) {
+ allTestNames.add(testName.getMethodName());
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(allTestNames)
+ .containsExactly(
+ "test1[{testEnum: ONE},ONE]",
+ "test1[{testEnum: ONE},TWO]",
+ "test1[{testEnum: ONE},THREE]",
+ "test1[{testEnum: TWO},ONE]",
+ "test1[{testEnum: TWO},TWO]",
+ "test1[{testEnum: TWO},THREE]",
+ "test2[{testEnum: ONE},{testString: ABC}]",
+ "test2[{testEnum: ONE},{testString: DEF}]",
+ "test2[{testEnum: TWO},{testString: ABC}]",
+ "test2[{testEnum: TWO},{testString: DEF}]",
+ "test3_withLongNames[{testEnum: ONE},1.{testString: ABC}]",
+ "test3_withLongNames[{testEnum: ONE},2.{testString: 'This is a very long string"
+ + " (240 characters) that would normally caus...]",
+ "test3_withLongNames[{testEnum: TWO},1.{testString: ABC}]",
+ "test3_withLongNames[{testEnum: TWO},2.{testString: 'This is a very long string"
+ + " (240 characters) that would normally caus...]");
+
+ assertThat(testNamesThatInvokedBefore).containsExactlyElementsIn(allTestNames).inOrder();
+ assertThat(testNamesThatInvokedAfter).containsExactlyElementsIn(allTestNames).inOrder();
+ }
+ }
+
+ @RunAsTest
+ public static class MixedWithTestParameterFieldAnnotation {
+ @Rule public TestName testName = new TestName();
+
+ private static List<String> allTestNames;
+
+ @TestParameter TestEnum testEnumA;
+
+ @TestParameters({"{testEnumB: ONE}", "{testEnumB: TWO}"})
+ public MixedWithTestParameterFieldAnnotation(TestEnum testEnumB) {}
+
+ @BeforeClass
+ public static void resetStaticState() {
+ allTestNames = new ArrayList<>();
+ }
+
+ @Before
+ public void setUp() {
+ assertThat(allTestNames).doesNotContain(testName.getMethodName());
+ }
+
+ @After
+ public void tearDown() {
+ assertThat(allTestNames).contains(testName.getMethodName());
+ }
+
+ @Test
+ @TestParameters({"{testString: ABC}", "{testString: DEF}"})
+ @Ignore("b/195657808 @TestParameters is not supported on Android")
+ public void test1(String testString) {
+ allTestNames.add(testName.getMethodName());
+ }
+
+ @AfterClass
+ public static void completedAllParameterizedTests() {
+ assertThat(allTestNames)
+ .containsExactly(
+ "test1[{testEnumB: ONE},{testString: ABC},ONE]",
+ "test1[{testEnumB: ONE},{testString: ABC},TWO]",
+ "test1[{testEnumB: ONE},{testString: ABC},THREE]",
+ "test1[{testEnumB: ONE},{testString: DEF},ONE]",
+ "test1[{testEnumB: ONE},{testString: DEF},TWO]",
+ "test1[{testEnumB: ONE},{testString: DEF},THREE]",
+ "test1[{testEnumB: TWO},{testString: ABC},ONE]",
+ "test1[{testEnumB: TWO},{testString: ABC},TWO]",
+ "test1[{testEnumB: TWO},{testString: ABC},THREE]",
+ "test1[{testEnumB: TWO},{testString: DEF},ONE]",
+ "test1[{testEnumB: TWO},{testString: DEF},TWO]",
+ "test1[{testEnumB: TWO},{testString: DEF},THREE]");
+ }
+ }
+
+ @Parameters(name = "{0}")
+ public static Collection<Object[]> parameters() {
+ return Arrays.stream(TestParametersMethodProcessorTest.class.getClasses())
+ .filter(cls -> cls.isAnnotationPresent(RunAsTest.class))
+ .map(cls -> new Object[] {cls.getSimpleName(), cls})
+ .collect(toImmutableList());
+ }
+
+ private final Class<?> testClass;
+
+ public TestParametersMethodProcessorTest(String name, Class<?> testClass) {
+ this.testClass = testClass;
+ }
+
+ @Test
+ public void test() throws Exception {
+ List<Failure> failures = PluggableTestRunner.run(newTestRunner());
+ assertThat(failures).isEmpty();
+ }
+
+ private PluggableTestRunner newTestRunner() throws Exception {
+ return new PluggableTestRunner(testClass) {
+ @Override
+ protected List<TestMethodProcessor> createTestMethodProcessorList() {
+ return TestMethodProcessors.createNewParameterizedProcessorsWithLegacyFeatures(
+ getTestClass());
+ }
+ };
+ }
+}