aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/junit/internal/builders/AnnotatedBuilder.java
diff options
context:
space:
mode:
authorPaul Duffin <paulduffin@google.com>2016-12-14 11:49:43 +0000
committerPaul Duffin <paulduffin@google.com>2016-12-20 15:52:52 +0000
commitaeb93fc33cae3aadbb9b46083350ad2dc9aea645 (patch)
treeb316db7dee11d1aeee3510562e036fd41705b8b5 /src/main/java/org/junit/internal/builders/AnnotatedBuilder.java
parent26401927b83770db45f00706ccc589955644c6c2 (diff)
downloadjunit-aeb93fc33cae3aadbb9b46083350ad2dc9aea645.tar.gz
Upgrade to JUnit 4.12
The license has changed from Common Public License v1.0 to Eclipse Public License v1.0. This will not compile as it is because it is intended to be built against Hamcrest 1.3 or later but it is being built against Hamcrest 1.1. A follow on patch will fix the compilation errors so that it builds against Hamcrest 1.1. That allows Hamcrest to be upgraded separately. The patch can be reverted once Hamcrest has been upgraded. There are also some Android specific issues that will also be fixed in follow on patches. Bug: 33613916 Test: make checkbuild Change-Id: Ic2c983a030399e3ace1a14927cb143fbd8307b4f
Diffstat (limited to 'src/main/java/org/junit/internal/builders/AnnotatedBuilder.java')
-rw-r--r--src/main/java/org/junit/internal/builders/AnnotatedBuilder.java143
1 files changed, 107 insertions, 36 deletions
diff --git a/src/main/java/org/junit/internal/builders/AnnotatedBuilder.java b/src/main/java/org/junit/internal/builders/AnnotatedBuilder.java
index 8ed9ca7..04d7a68 100644
--- a/src/main/java/org/junit/internal/builders/AnnotatedBuilder.java
+++ b/src/main/java/org/junit/internal/builders/AnnotatedBuilder.java
@@ -1,6 +1,3 @@
-/**
- *
- */
package org.junit.internal.builders;
import org.junit.runner.RunWith;
@@ -8,38 +5,112 @@ import org.junit.runner.Runner;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.RunnerBuilder;
+import java.lang.reflect.Modifier;
+
+
+/**
+ * The {@code AnnotatedBuilder} is a strategy for constructing runners for test class that have been annotated with the
+ * {@code @RunWith} annotation. All tests within this class will be executed using the runner that was specified within
+ * the annotation.
+ * <p>
+ * If a runner supports inner member classes, the member classes will inherit the runner from the enclosing class, e.g.:
+ * <pre>
+ * &#064;RunWith(MyRunner.class)
+ * public class MyTest {
+ * // some tests might go here
+ *
+ * public class MyMemberClass {
+ * &#064;Test
+ * public void thisTestRunsWith_MyRunner() {
+ * // some test logic
+ * }
+ *
+ * // some more tests might go here
+ * }
+ *
+ * &#064;RunWith(AnotherRunner.class)
+ * public class AnotherMemberClass {
+ * // some tests might go here
+ *
+ * public class DeepInnerClass {
+ * &#064;Test
+ * public void thisTestRunsWith_AnotherRunner() {
+ * // some test logic
+ * }
+ * }
+ *
+ * public class DeepInheritedClass extends SuperTest {
+ * &#064;Test
+ * public void thisTestRunsWith_SuperRunner() {
+ * // some test logic
+ * }
+ * }
+ * }
+ * }
+ *
+ * &#064;RunWith(SuperRunner.class)
+ * public class SuperTest {
+ * // some tests might go here
+ * }
+ * </pre>
+ * The key points to note here are:
+ * <ul>
+ * <li>If there is no RunWith annotation, no runner will be created.</li>
+ * <li>The resolve step is inside-out, e.g. the closest RunWith annotation wins</li>
+ * <li>RunWith annotations are inherited and work as if the class was annotated itself.</li>
+ * <li>The default JUnit runner does not support inner member classes,
+ * so this is only valid for custom runners that support inner member classes.</li>
+ * <li>Custom runners with support for inner classes may or may not support RunWith annotations for member
+ * classes. Please refer to the custom runner documentation.</li>
+ * </ul>
+ *
+ * @see org.junit.runners.model.RunnerBuilder
+ * @see org.junit.runner.RunWith
+ * @since 4.0
+ */
public class AnnotatedBuilder extends RunnerBuilder {
- private static final String CONSTRUCTOR_ERROR_FORMAT= "Custom runner class %s should have a public constructor with signature %s(Class testClass)";
-
- private RunnerBuilder fSuiteBuilder;
-
- public AnnotatedBuilder(RunnerBuilder suiteBuilder) {
- fSuiteBuilder= suiteBuilder;
- }
-
- @Override
- public Runner runnerForClass(Class<?> testClass) throws Exception {
- RunWith annotation= testClass.getAnnotation(RunWith.class);
- if (annotation != null)
- return buildRunner(annotation.value(), testClass);
- return null;
- }
-
- public Runner buildRunner(Class<? extends Runner> runnerClass,
- Class<?> testClass) throws Exception {
- try {
- return runnerClass.getConstructor(Class.class).newInstance(
- new Object[] { testClass });
- } catch (NoSuchMethodException e) {
- try {
- return runnerClass.getConstructor(Class.class,
- RunnerBuilder.class).newInstance(
- new Object[] { testClass, fSuiteBuilder });
- } catch (NoSuchMethodException e2) {
- String simpleName= runnerClass.getSimpleName();
- throw new InitializationError(String.format(
- CONSTRUCTOR_ERROR_FORMAT, simpleName, simpleName));
- }
- }
- }
+ private static final String CONSTRUCTOR_ERROR_FORMAT = "Custom runner class %s should have a public constructor with signature %s(Class testClass)";
+
+ private final RunnerBuilder suiteBuilder;
+
+ public AnnotatedBuilder(RunnerBuilder suiteBuilder) {
+ this.suiteBuilder = suiteBuilder;
+ }
+
+ @Override
+ public Runner runnerForClass(Class<?> testClass) throws Exception {
+ for (Class<?> currentTestClass = testClass; currentTestClass != null;
+ currentTestClass = getEnclosingClassForNonStaticMemberClass(currentTestClass)) {
+ RunWith annotation = currentTestClass.getAnnotation(RunWith.class);
+ if (annotation != null) {
+ return buildRunner(annotation.value(), testClass);
+ }
+ }
+
+ return null;
+ }
+
+ private Class<?> getEnclosingClassForNonStaticMemberClass(Class<?> currentTestClass) {
+ if (currentTestClass.isMemberClass() && !Modifier.isStatic(currentTestClass.getModifiers())) {
+ return currentTestClass.getEnclosingClass();
+ } else {
+ return null;
+ }
+ }
+
+ public Runner buildRunner(Class<? extends Runner> runnerClass,
+ Class<?> testClass) throws Exception {
+ try {
+ return runnerClass.getConstructor(Class.class).newInstance(testClass);
+ } catch (NoSuchMethodException e) {
+ try {
+ return runnerClass.getConstructor(Class.class,
+ RunnerBuilder.class).newInstance(testClass, suiteBuilder);
+ } catch (NoSuchMethodException e2) {
+ String simpleName = runnerClass.getSimpleName();
+ throw new InitializationError(String.format(
+ CONSTRUCTOR_ERROR_FORMAT, simpleName, simpleName));
+ }
+ }
+ }
} \ No newline at end of file