aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java')
-rw-r--r--src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java143
1 files changed, 143 insertions, 0 deletions
diff --git a/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java b/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java
new file mode 100644
index 0000000..1c49f84
--- /dev/null
+++ b/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java
@@ -0,0 +1,143 @@
+package org.junit.runners.parameterized;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.util.List;
+
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.model.FrameworkField;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.Statement;
+
+/**
+ * A {@link BlockJUnit4ClassRunner} with parameters support. Parameters can be
+ * injected via constructor or into annotated fields.
+ */
+public class BlockJUnit4ClassRunnerWithParameters extends
+ BlockJUnit4ClassRunner {
+ private final Object[] parameters;
+
+ private final String name;
+
+ public BlockJUnit4ClassRunnerWithParameters(TestWithParameters test)
+ throws InitializationError {
+ super(test.getTestClass().getJavaClass());
+ parameters = test.getParameters().toArray(
+ new Object[test.getParameters().size()]);
+ name = test.getName();
+ }
+
+ @Override
+ public Object createTest() throws Exception {
+ if (fieldsAreAnnotated()) {
+ return createTestUsingFieldInjection();
+ } else {
+ return createTestUsingConstructorInjection();
+ }
+ }
+
+ private Object createTestUsingConstructorInjection() throws Exception {
+ return getTestClass().getOnlyConstructor().newInstance(parameters);
+ }
+
+ private Object createTestUsingFieldInjection() throws Exception {
+ List<FrameworkField> annotatedFieldsByParameter = getAnnotatedFieldsByParameter();
+ if (annotatedFieldsByParameter.size() != parameters.length) {
+ throw new Exception(
+ "Wrong number of parameters and @Parameter fields."
+ + " @Parameter fields counted: "
+ + annotatedFieldsByParameter.size()
+ + ", available parameters: " + parameters.length
+ + ".");
+ }
+ Object testClassInstance = getTestClass().getJavaClass().newInstance();
+ for (FrameworkField each : annotatedFieldsByParameter) {
+ Field field = each.getField();
+ Parameter annotation = field.getAnnotation(Parameter.class);
+ int index = annotation.value();
+ try {
+ field.set(testClassInstance, parameters[index]);
+ } catch (IllegalArgumentException iare) {
+ throw new Exception(getTestClass().getName()
+ + ": Trying to set " + field.getName()
+ + " with the value " + parameters[index]
+ + " that is not the right type ("
+ + parameters[index].getClass().getSimpleName()
+ + " instead of " + field.getType().getSimpleName()
+ + ").", iare);
+ }
+ }
+ return testClassInstance;
+ }
+
+ @Override
+ protected String getName() {
+ return name;
+ }
+
+ @Override
+ protected String testName(FrameworkMethod method) {
+ return method.getName() + getName();
+ }
+
+ @Override
+ protected void validateConstructor(List<Throwable> errors) {
+ validateOnlyOneConstructor(errors);
+ if (fieldsAreAnnotated()) {
+ validateZeroArgConstructor(errors);
+ }
+ }
+
+ @Override
+ protected void validateFields(List<Throwable> errors) {
+ super.validateFields(errors);
+ if (fieldsAreAnnotated()) {
+ List<FrameworkField> annotatedFieldsByParameter = getAnnotatedFieldsByParameter();
+ int[] usedIndices = new int[annotatedFieldsByParameter.size()];
+ for (FrameworkField each : annotatedFieldsByParameter) {
+ int index = each.getField().getAnnotation(Parameter.class)
+ .value();
+ if (index < 0 || index > annotatedFieldsByParameter.size() - 1) {
+ errors.add(new Exception("Invalid @Parameter value: "
+ + index + ". @Parameter fields counted: "
+ + annotatedFieldsByParameter.size()
+ + ". Please use an index between 0 and "
+ + (annotatedFieldsByParameter.size() - 1) + "."));
+ } else {
+ usedIndices[index]++;
+ }
+ }
+ for (int index = 0; index < usedIndices.length; index++) {
+ int numberOfUse = usedIndices[index];
+ if (numberOfUse == 0) {
+ errors.add(new Exception("@Parameter(" + index
+ + ") is never used."));
+ } else if (numberOfUse > 1) {
+ errors.add(new Exception("@Parameter(" + index
+ + ") is used more than once (" + numberOfUse + ")."));
+ }
+ }
+ }
+ }
+
+ @Override
+ protected Statement classBlock(RunNotifier notifier) {
+ return childrenInvoker(notifier);
+ }
+
+ @Override
+ protected Annotation[] getRunnerAnnotations() {
+ return new Annotation[0];
+ }
+
+ private List<FrameworkField> getAnnotatedFieldsByParameter() {
+ return getTestClass().getAnnotatedFields(Parameter.class);
+ }
+
+ private boolean fieldsAreAnnotated() {
+ return !getAnnotatedFieldsByParameter().isEmpty();
+ }
+}