aboutsummaryrefslogtreecommitdiff
path: root/junit5/src/main/java/com/google/testing/junit/testparameterinjector/junit5/TestParameterInjectorExtension.java
diff options
context:
space:
mode:
Diffstat (limited to 'junit5/src/main/java/com/google/testing/junit/testparameterinjector/junit5/TestParameterInjectorExtension.java')
-rw-r--r--junit5/src/main/java/com/google/testing/junit/testparameterinjector/junit5/TestParameterInjectorExtension.java140
1 files changed, 140 insertions, 0 deletions
diff --git a/junit5/src/main/java/com/google/testing/junit/testparameterinjector/junit5/TestParameterInjectorExtension.java b/junit5/src/main/java/com/google/testing/junit/testparameterinjector/junit5/TestParameterInjectorExtension.java
new file mode 100644
index 0000000..6d6aa51
--- /dev/null
+++ b/junit5/src/main/java/com/google/testing/junit/testparameterinjector/junit5/TestParameterInjectorExtension.java
@@ -0,0 +1,140 @@
+/*
+ * 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.junit5;
+
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.Iterables.getOnlyElement;
+
+import com.google.auto.value.AutoValue;
+import com.google.auto.value.extension.memoized.Memoized;
+import com.google.common.collect.ImmutableList;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.extension.Extension;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolver;
+import org.junit.jupiter.api.extension.TestInstancePostProcessor;
+import org.junit.jupiter.api.extension.TestTemplateInvocationContext;
+import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider;
+
+/** Implements the TestParameterInjector logic for JUnit5 (Jupiter). */
+class TestParameterInjectorExtension implements TestTemplateInvocationContextProvider {
+
+ private static final TestMethodProcessorList testMethodProcessors =
+ TestMethodProcessorList.createNewParameterizedProcessors();
+
+ @Override
+ public boolean supportsTestTemplate(ExtensionContext context) {
+ return true;
+ }
+
+ @Override
+ public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(
+ ExtensionContext extensionContext) {
+ validateTestMethodAndConstructor(
+ extensionContext.getRequiredTestMethod(), extensionContext.getRequiredTestClass());
+ List<TestInfo> testInfos =
+ testMethodProcessors.calculateTestInfos(
+ extensionContext.getRequiredTestMethod(), extensionContext.getRequiredTestClass());
+
+ return testInfos.stream().map(CustomInvocationContext::of);
+ }
+
+ private void validateTestMethodAndConstructor(Method testMethod, Class<?> testClass) {
+ checkState(
+ testClass.getDeclaredConstructors().length == 1,
+ "Only a single constructor is allowed, but found %s in %s",
+ testClass.getDeclaredConstructors().length,
+ testClass.getSimpleName());
+ Constructor<?> constructor =
+ getOnlyElement(ImmutableList.copyOf(testClass.getDeclaredConstructors()));
+
+ testMethodProcessors.validateConstructor(constructor).assertValid();
+
+ testMethodProcessors.validateTestMethod(testMethod, testClass).assertValid();
+
+ checkState(
+ testMethod.getAnnotation(TestParameterInjectorTest.class) != null,
+ "Each test method handled by this extension should be annotated with"
+ + " @TestParameterInjectorTest");
+ }
+
+ @AutoValue
+ abstract static class CustomInvocationContext implements TestTemplateInvocationContext {
+
+ abstract TestInfo testInfo();
+
+ @Memoized
+ List<Object> getConstructorParameters() {
+ Constructor<?> constructor =
+ getOnlyElement(ImmutableList.copyOf(testInfo().getTestClass().getDeclaredConstructors()));
+
+ return testMethodProcessors.getConstructorParameters(constructor, testInfo());
+ }
+
+ @Memoized
+ List<Object> getTestMethodParameters() {
+ return testMethodProcessors.getTestMethodParameters(testInfo());
+ }
+
+ static CustomInvocationContext of(TestInfo testInfo) {
+ return new AutoValue_TestParameterInjectorExtension_CustomInvocationContext(testInfo);
+ }
+
+ @Override
+ public String getDisplayName(int invocationIndex) {
+ return testInfo().getName();
+ }
+
+ @Override
+ public List<Extension> getAdditionalExtensions() {
+ return ImmutableList.of(new CustomAdditionalExtension());
+ }
+
+ class CustomAdditionalExtension implements ParameterResolver, TestInstancePostProcessor {
+
+ @Override
+ public boolean supportsParameter(
+ ParameterContext parameterContext, ExtensionContext extensionContext) {
+ if (parameterContext.getDeclaringExecutable() instanceof Constructor) {
+ return true;
+ } else {
+ return parameterContext
+ .getDeclaringExecutable()
+ .isAnnotationPresent(TestParameterInjectorTest.class);
+ }
+ }
+
+ @Override
+ public Object resolveParameter(
+ ParameterContext parameterContext, ExtensionContext extensionContext) {
+ if (parameterContext.getDeclaringExecutable() instanceof Constructor) {
+ return getConstructorParameters().get(parameterContext.getIndex());
+ } else {
+ return getTestMethodParameters().get(parameterContext.getIndex());
+ }
+ }
+
+ @Override
+ public void postProcessTestInstance(Object testInstance, ExtensionContext extensionContext)
+ throws Exception {
+ testMethodProcessors.postProcessTestInstance(testInstance, testInfo());
+ }
+ }
+ }
+}