org.junit.experimental.theories.internal.AllMembersSupplier Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of junit Show documentation
Show all versions of junit Show documentation
JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck.
package org.junit.experimental.theories.internal;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.junit.Assume;
import org.junit.experimental.theories.DataPoint;
import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.ParameterSignature;
import org.junit.experimental.theories.ParameterSupplier;
import org.junit.experimental.theories.PotentialAssignment;
import org.junit.runners.model.FrameworkField;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.TestClass;
/**
* Supplies Theory parameters based on all public members of the target class.
*/
public class AllMembersSupplier extends ParameterSupplier {
static class MethodParameterValue extends PotentialAssignment {
private final FrameworkMethod method;
private MethodParameterValue(FrameworkMethod dataPointMethod) {
method = dataPointMethod;
}
@Override
public Object getValue() throws CouldNotGenerateValueException {
try {
return method.invokeExplosively(null);
} catch (IllegalArgumentException e) {
throw new RuntimeException(
"unexpected: argument length is checked");
} catch (IllegalAccessException e) {
throw new RuntimeException(
"unexpected: getMethods returned an inaccessible method");
} catch (Throwable throwable) {
DataPoint annotation = method.getAnnotation(DataPoint.class);
Assume.assumeTrue(annotation == null || !isAssignableToAnyOf(annotation.ignoredExceptions(), throwable));
throw new CouldNotGenerateValueException(throwable);
}
}
@Override
public String getDescription() throws CouldNotGenerateValueException {
return method.getName();
}
}
private final TestClass clazz;
/**
* Constructs a new supplier for {@code type}
*/
public AllMembersSupplier(TestClass type) {
clazz = type;
}
@Override
public List getValueSources(ParameterSignature sig) throws Throwable {
List list = new ArrayList();
addSinglePointFields(sig, list);
addMultiPointFields(sig, list);
addSinglePointMethods(sig, list);
addMultiPointMethods(sig, list);
return list;
}
private void addMultiPointMethods(ParameterSignature sig, List list) throws Throwable {
for (FrameworkMethod dataPointsMethod : getDataPointsMethods(sig)) {
Class returnType = dataPointsMethod.getReturnType();
if ((returnType.isArray() && sig.canPotentiallyAcceptType(returnType.getComponentType())) ||
Iterable.class.isAssignableFrom(returnType)) {
try {
addDataPointsValues(returnType, sig, dataPointsMethod.getName(), list,
dataPointsMethod.invokeExplosively(null));
} catch (Throwable throwable) {
DataPoints annotation = dataPointsMethod.getAnnotation(DataPoints.class);
if (annotation != null && isAssignableToAnyOf(annotation.ignoredExceptions(), throwable)) {
return;
} else {
throw throwable;
}
}
}
}
}
private void addSinglePointMethods(ParameterSignature sig, List list) {
for (FrameworkMethod dataPointMethod : getSingleDataPointMethods(sig)) {
if (sig.canAcceptType(dataPointMethod.getType())) {
list.add(new MethodParameterValue(dataPointMethod));
}
}
}
private void addMultiPointFields(ParameterSignature sig, List list) {
for (final Field field : getDataPointsFields(sig)) {
Class type = field.getType();
addDataPointsValues(type, sig, field.getName(), list, getStaticFieldValue(field));
}
}
private void addSinglePointFields(ParameterSignature sig, List list) {
for (final Field field : getSingleDataPointFields(sig)) {
Object value = getStaticFieldValue(field);
if (sig.canAcceptValue(value)) {
list.add(PotentialAssignment.forValue(field.getName(), value));
}
}
}
private void addDataPointsValues(Class type, ParameterSignature sig, String name,
List list, Object value) {
if (type.isArray()) {
addArrayValues(sig, name, list, value);
}
else if (Iterable.class.isAssignableFrom(type)) {
addIterableValues(sig, name, list, (Iterable) value);
}
}
private void addArrayValues(ParameterSignature sig, String name, List list, Object array) {
for (int i = 0; i < Array.getLength(array); i++) {
Object value = Array.get(array, i);
if (sig.canAcceptValue(value)) {
list.add(PotentialAssignment.forValue(name + "[" + i + "]", value));
}
}
}
private void addIterableValues(ParameterSignature sig, String name, List list, Iterable iterable) {
Iterator iterator = iterable.iterator();
int i = 0;
while (iterator.hasNext()) {
Object value = iterator.next();
if (sig.canAcceptValue(value)) {
list.add(PotentialAssignment.forValue(name + "[" + i + "]", value));
}
i += 1;
}
}
private Object getStaticFieldValue(final Field field) {
try {
return field.get(null);
} catch (IllegalArgumentException e) {
throw new RuntimeException(
"unexpected: field from getClass doesn't exist on object");
} catch (IllegalAccessException e) {
throw new RuntimeException(
"unexpected: getFields returned an inaccessible field");
}
}
private static boolean isAssignableToAnyOf(Class[] typeArray, Object target) {
for (Class type : typeArray) {
if (type.isAssignableFrom(target.getClass())) {
return true;
}
}
return false;
}
protected Collection getDataPointsMethods(ParameterSignature sig) {
return clazz.getAnnotatedMethods(DataPoints.class);
}
protected Collection getSingleDataPointFields(ParameterSignature sig) {
List fields = clazz.getAnnotatedFields(DataPoint.class);
Collection validFields = new ArrayList();
for (FrameworkField frameworkField : fields) {
validFields.add(frameworkField.getField());
}
return validFields;
}
protected Collection getDataPointsFields(ParameterSignature sig) {
List fields = clazz.getAnnotatedFields(DataPoints.class);
Collection validFields = new ArrayList();
for (FrameworkField frameworkField : fields) {
validFields.add(frameworkField.getField());
}
return validFields;
}
protected Collection getSingleDataPointMethods(ParameterSignature sig) {
return clazz.getAnnotatedMethods(DataPoint.class);
}
}