diff options
Diffstat (limited to 'junit4/src/main/java/org/junit/experimental/theories/internal')
3 files changed, 309 insertions, 0 deletions
diff --git a/junit4/src/main/java/org/junit/experimental/theories/internal/AllMembersSupplier.java b/junit4/src/main/java/org/junit/experimental/theories/internal/AllMembersSupplier.java new file mode 100644 index 0000000..615cc3e --- /dev/null +++ b/junit4/src/main/java/org/junit/experimental/theories/internal/AllMembersSupplier.java @@ -0,0 +1,127 @@ +/** + * + */ +package org.junit.experimental.theories.internal; + +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; + +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.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 fMethod; + + private MethodParameterValue(FrameworkMethod dataPointMethod) { + fMethod= dataPointMethod; + } + + @Override + public Object getValue() throws CouldNotGenerateValueException { + try { + return fMethod.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 e) { + throw new CouldNotGenerateValueException(); + // do nothing, just look for more values + } + } + + @Override + public String getDescription() throws CouldNotGenerateValueException { + return fMethod.getName(); + } + } + + private final TestClass fClass; + + /** + * Constructs a new supplier for {@code type} + */ + public AllMembersSupplier(TestClass type) { + fClass= type; + } + + @Override + public List<PotentialAssignment> getValueSources(ParameterSignature sig) { + List<PotentialAssignment> list= new ArrayList<PotentialAssignment>(); + + addFields(sig, list); + addSinglePointMethods(sig, list); + addMultiPointMethods(list); + + return list; + } + + private void addMultiPointMethods(List<PotentialAssignment> list) { + for (FrameworkMethod dataPointsMethod : fClass + .getAnnotatedMethods(DataPoints.class)) + try { + addArrayValues(dataPointsMethod.getName(), list, dataPointsMethod.invokeExplosively(null)); + } catch (Throwable e) { + // ignore and move on + } + } + + @SuppressWarnings("deprecation") + private void addSinglePointMethods(ParameterSignature sig, + List<PotentialAssignment> list) { + for (FrameworkMethod dataPointMethod : fClass + .getAnnotatedMethods(DataPoint.class)) { + Class<?> type= sig.getType(); + if ((dataPointMethod.producesType(type))) + list.add(new MethodParameterValue(dataPointMethod)); + } + } + + private void addFields(ParameterSignature sig, + List<PotentialAssignment> list) { + for (final Field field : fClass.getJavaClass().getFields()) { + if (Modifier.isStatic(field.getModifiers())) { + Class<?> type= field.getType(); + if (sig.canAcceptArrayType(type) + && field.getAnnotation(DataPoints.class) != null) { + addArrayValues(field.getName(), list, getStaticFieldValue(field)); + } else if (sig.canAcceptType(type) + && field.getAnnotation(DataPoint.class) != null) { + list.add(PotentialAssignment + .forValue(field.getName(), getStaticFieldValue(field))); + } + } + } + } + + private void addArrayValues(String name, List<PotentialAssignment> list, Object array) { + for (int i= 0; i < Array.getLength(array); i++) + list.add(PotentialAssignment.forValue(name + "[" + i + "]", Array.get(array, i))); + } + + 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"); + } + } +}
\ No newline at end of file diff --git a/junit4/src/main/java/org/junit/experimental/theories/internal/Assignments.java b/junit4/src/main/java/org/junit/experimental/theories/internal/Assignments.java new file mode 100644 index 0000000..bd94f00 --- /dev/null +++ b/junit4/src/main/java/org/junit/experimental/theories/internal/Assignments.java @@ -0,0 +1,133 @@ +/** + * + */ +package org.junit.experimental.theories.internal; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import org.junit.experimental.theories.ParameterSignature; +import org.junit.experimental.theories.ParameterSupplier; +import org.junit.experimental.theories.ParametersSuppliedBy; +import org.junit.experimental.theories.PotentialAssignment; +import org.junit.experimental.theories.PotentialAssignment.CouldNotGenerateValueException; +import org.junit.runners.model.TestClass; + +/** + * A potentially incomplete list of value assignments for a method's formal + * parameters + */ +public class Assignments { + private List<PotentialAssignment> fAssigned; + + private final List<ParameterSignature> fUnassigned; + + private final TestClass fClass; + + private Assignments(List<PotentialAssignment> assigned, + List<ParameterSignature> unassigned, TestClass testClass) { + fUnassigned= unassigned; + fAssigned= assigned; + fClass= testClass; + } + + /** + * Returns a new assignment list for {@code testMethod}, with no params + * assigned. + */ + public static Assignments allUnassigned(Method testMethod, + TestClass testClass) throws Exception { + List<ParameterSignature> signatures; + signatures= ParameterSignature.signatures(testClass + .getOnlyConstructor()); + signatures.addAll(ParameterSignature.signatures(testMethod)); + return new Assignments(new ArrayList<PotentialAssignment>(), + signatures, testClass); + } + + public boolean isComplete() { + return fUnassigned.size() == 0; + } + + public ParameterSignature nextUnassigned() { + return fUnassigned.get(0); + } + + public Assignments assignNext(PotentialAssignment source) { + List<PotentialAssignment> assigned= new ArrayList<PotentialAssignment>( + fAssigned); + assigned.add(source); + + return new Assignments(assigned, fUnassigned.subList(1, fUnassigned + .size()), fClass); + } + + public Object[] getActualValues(int start, int stop, boolean nullsOk) + throws CouldNotGenerateValueException { + Object[] values= new Object[stop - start]; + for (int i= start; i < stop; i++) { + Object value= fAssigned.get(i).getValue(); + if (value == null && !nullsOk) + throw new CouldNotGenerateValueException(); + values[i - start]= value; + } + return values; + } + + public List<PotentialAssignment> potentialsForNextUnassigned() + throws InstantiationException, IllegalAccessException { + ParameterSignature unassigned= nextUnassigned(); + return getSupplier(unassigned).getValueSources(unassigned); + } + + public ParameterSupplier getSupplier(ParameterSignature unassigned) + throws InstantiationException, IllegalAccessException { + ParameterSupplier supplier= getAnnotatedSupplier(unassigned); + if (supplier != null) + return supplier; + + return new AllMembersSupplier(fClass); + } + + public ParameterSupplier getAnnotatedSupplier(ParameterSignature unassigned) + throws InstantiationException, IllegalAccessException { + ParametersSuppliedBy annotation= unassigned + .findDeepAnnotation(ParametersSuppliedBy.class); + if (annotation == null) + return null; + return annotation.value().newInstance(); + } + + public Object[] getConstructorArguments(boolean nullsOk) + throws CouldNotGenerateValueException { + return getActualValues(0, getConstructorParameterCount(), nullsOk); + } + + public Object[] getMethodArguments(boolean nullsOk) + throws CouldNotGenerateValueException { + return getActualValues(getConstructorParameterCount(), + fAssigned.size(), nullsOk); + } + + public Object[] getAllArguments(boolean nullsOk) + throws CouldNotGenerateValueException { + return getActualValues(0, fAssigned.size(), nullsOk); + } + + private int getConstructorParameterCount() { + List<ParameterSignature> signatures= ParameterSignature + .signatures(fClass.getOnlyConstructor()); + int constructorParameterCount= signatures.size(); + return constructorParameterCount; + } + + public Object[] getArgumentStrings(boolean nullsOk) + throws CouldNotGenerateValueException { + Object[] values= new Object[fAssigned.size()]; + for (int i= 0; i < values.length; i++) { + values[i]= fAssigned.get(i).getDescription(); + } + return values; + } +}
\ No newline at end of file diff --git a/junit4/src/main/java/org/junit/experimental/theories/internal/ParameterizedAssertionError.java b/junit4/src/main/java/org/junit/experimental/theories/internal/ParameterizedAssertionError.java new file mode 100644 index 0000000..285bc3a --- /dev/null +++ b/junit4/src/main/java/org/junit/experimental/theories/internal/ParameterizedAssertionError.java @@ -0,0 +1,49 @@ +/** + * + */ +package org.junit.experimental.theories.internal; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; + + +public class ParameterizedAssertionError extends RuntimeException { + private static final long serialVersionUID = 1L; + + public ParameterizedAssertionError(Throwable targetException, + String methodName, Object... params) { + super(String.format("%s(%s)", methodName, join(", ", params)), + targetException); + } + + @Override public boolean equals(Object obj) { + return toString().equals(obj.toString()); + } + + public static String join(String delimiter, Object... params) { + return join(delimiter, Arrays.asList(params)); + } + + public static String join(String delimiter, + Collection<Object> values) { + StringBuffer buffer = new StringBuffer(); + Iterator<Object> iter = values.iterator(); + while (iter.hasNext()) { + Object next = iter.next(); + buffer.append(stringValueOf(next)); + if (iter.hasNext()) { + buffer.append(delimiter); + } + } + return buffer.toString(); + } + + private static String stringValueOf(Object next) { + try { + return String.valueOf(next); + } catch (Throwable e) { + return "[toString failed]"; + } + } +}
\ No newline at end of file |