Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parameterized: added new @StaticParameter annotation #1381

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/main/java/org/junit/runners/Parameterized.java
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,27 @@ public class Parameterized extends Suite {
int value() default 0;
}

/**
* Annotation for fields of the test class which will be initialized by the
* method annotated by <code>StaticParameter</code>.
* It can be used to initialize static fields.
* Index range must start at 0.
* Default value is 0.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public static @interface StaticParameter {
/**
* Method that returns the index of the parameter in the array
* returned by the method annotated by <code>StaticParameter</code>.
* Index range must start at 0.
* Default value is 0.
*
* @return the index of the parameter.
*/
int value() default 0;
}

/**
* Add this annotation to your test class if you want to generate a special
* runner. You have to specify a {@link ParametersRunnerFactory} class that
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

import org.junit.runner.RunWith;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.StaticParameter;
import org.junit.runners.model.FrameworkField;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
Expand Down Expand Up @@ -55,14 +58,36 @@ private Object createTestUsingConstructorInjection() throws Exception {

private Object createTestUsingFieldInjection() throws Exception {
List<FrameworkField> annotatedFieldsByParameter = getAnnotatedFieldsByParameter();
if (annotatedFieldsByParameter.size() != parameters.length) {
List<FrameworkField> annotatedFieldsByStaticParameter = getAnnotatedFieldsByStaticParameter();

if (annotatedFieldsByParameter.size() + annotatedFieldsByStaticParameter.size() != parameters.length) {
throw new Exception(
"Wrong number of parameters and @Parameter fields."
+ " @Parameter fields counted: "
+ annotatedFieldsByParameter.size()
+ ", available parameters: " + parameters.length
+ ".");
}

// Static parameters
for (FrameworkField each : annotatedFieldsByStaticParameter) {
Field field = each.getField();
StaticParameter annotation = field.getAnnotation(StaticParameter.class);
int index = annotation.value();
try {
field.set(null, 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);
}
}

// Non-static parameters
Object testClassInstance = getTestClass().getJavaClass().newInstance();
for (FrameworkField each : annotatedFieldsByParameter) {
Field field = each.getField();
Expand Down Expand Up @@ -105,29 +130,50 @@ protected void validateConstructor(List<Throwable> errors) {
protected void validateFields(List<Throwable> errors) {
super.validateFields(errors);
if (getInjectionType() == InjectionType.FIELD) {
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()
List<FrameworkField> parametricFields = new ArrayList<FrameworkField>();
parametricFields.addAll(getAnnotatedFieldsByParameter());
parametricFields.addAll(getAnnotatedFieldsByStaticParameter());

int[] usedIndices = new int[parametricFields.size()];
for (FrameworkField each : parametricFields) {
int index = -1;
Field annotatedField = each.getField();
if (Modifier.isStatic(annotatedField.getModifiers())) {
StaticParameter staticParam = annotatedField.getAnnotation(StaticParameter.class);
if (staticParam == null) {
errors.add(new Exception("Invalid @Parameter annotation on the static field: "
+ annotatedField.getName() + ". It should be @StaticParameter."));
} else {
index = staticParam.value();
}

} else {
Parameter param = annotatedField.getAnnotation(Parameter.class);
if (param == null) {
errors.add(new Exception("Invalid @StaticParameter annotation on the field: "
+ annotatedField.getName() + ". It should be @Parameter."));
} else {
index = param.value();
}
}
if (index < 0 || index > parametricFields.size() - 1) {
errors.add(new Exception("Invalid @Parameter or @StaticParameter value: "
+ index + ". parametric fields counted: "
+ parametricFields.size()
+ ". Please use an index between 0 and "
+ (annotatedFieldsByParameter.size() - 1) + "."));
+ (parametricFields.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."));
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 + ")."));
errors.add(new Exception("Parameter " + index
+ " is used more than once (" + numberOfUse + ")."));
}
}
}
Expand All @@ -152,6 +198,10 @@ protected Annotation[] getRunnerAnnotations() {
return annotationsWithoutRunWith;
}

private List<FrameworkField> getAnnotatedFieldsByStaticParameter() {
return getTestClass().getAnnotatedFields(StaticParameter.class);
}

private List<FrameworkField> getAnnotatedFieldsByParameter() {
return getTestClass().getAnnotatedFields(Parameter.class);
}
Expand All @@ -165,6 +215,6 @@ private InjectionType getInjectionType() {
}

private boolean fieldsAreAnnotated() {
return !getAnnotatedFieldsByParameter().isEmpty();
return !getAnnotatedFieldsByParameter().isEmpty() || !getAnnotatedFieldsByStaticParameter().isEmpty();
}
}