aboutsummaryrefslogtreecommitdiff
path: root/src/test/java/com/google/testing/junit/testparameterinjector/TestParameterAnnotationMethodProcessorTest.java
diff options
context:
space:
mode:
authorJonathan Scott <scottjonathan@google.com>2021-08-05 16:56:21 +0100
committerJonathan Scott <scottjonathan@google.com>2021-08-05 18:09:49 +0100
commitb51cebd6ba9ca7f524418ed3b2d9b2540308b8d7 (patch)
tree13a630d6c68439dc4dd20f07df2657da81189de9 /src/test/java/com/google/testing/junit/testparameterinjector/TestParameterAnnotationMethodProcessorTest.java
parentd515d44bc91c3e4747c0469fe2ad0ee38cd97804 (diff)
downloadTestParameterInjector-b51cebd6ba9ca7f524418ed3b2d9b2540308b8d7.tar.gz
Import TestParameterInjector.
Test: atest TestParameterInjectorTest Change-Id: I4eee53057041be2223ae133c2d2cf1d14fa752d0
Diffstat (limited to 'src/test/java/com/google/testing/junit/testparameterinjector/TestParameterAnnotationMethodProcessorTest.java')
-rw-r--r--src/test/java/com/google/testing/junit/testparameterinjector/TestParameterAnnotationMethodProcessorTest.java1077
1 files changed, 1077 insertions, 0 deletions
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()));
+ }
+ };
+ }
+}