Skip to content

Commit c7b1880

Browse files
author
David Saff
committed
Merge pull request #651 from pimterry/datapoint-result-reuse-#638
Fixes for #637, making theory parameters assignment more consistent across sources
2 parents e012e06 + c60d087 commit c7b1880

File tree

6 files changed

+214
-86
lines changed

6 files changed

+214
-86
lines changed

src/main/java/org/junit/experimental/theories/ParameterSignature.java

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,35 @@
55
import java.lang.reflect.Method;
66
import java.util.ArrayList;
77
import java.util.Arrays;
8+
import java.util.Collections;
9+
import java.util.HashMap;
810
import java.util.List;
11+
import java.util.Map;
912

1013
public class ParameterSignature {
14+
15+
private static final Map<Class<?>, Class<?>> CONVERTABLE_TYPES_MAP = buildConvertableTypesMap();
16+
17+
private static Map<Class<?>, Class<?>> buildConvertableTypesMap() {
18+
Map<Class<?>, Class<?>> map = new HashMap<Class<?>, Class<?>>();
19+
20+
putSymmetrically(map, boolean.class, Boolean.class);
21+
putSymmetrically(map, byte.class, Byte.class);
22+
putSymmetrically(map, short.class, Short.class);
23+
putSymmetrically(map, char.class, Character.class);
24+
putSymmetrically(map, int.class, Integer.class);
25+
putSymmetrically(map, long.class, Long.class);
26+
putSymmetrically(map, float.class, Float.class);
27+
putSymmetrically(map, double.class, Double.class);
28+
29+
return Collections.unmodifiableMap(map);
30+
}
31+
32+
private static <T> void putSymmetrically(Map<T, T> map, T a, T b) {
33+
map.put(a, b);
34+
map.put(b, a);
35+
}
36+
1137
public static ArrayList<ParameterSignature> signatures(Method method) {
1238
return signatures(method.getParameterTypes(), method
1339
.getParameterAnnotations());
@@ -42,7 +68,23 @@ public boolean canAcceptValue(Object candidate) {
4268
}
4369

4470
public boolean canAcceptType(Class<?> candidate) {
45-
return type.isAssignableFrom(candidate);
71+
return type.isAssignableFrom(candidate) ||
72+
isAssignableViaTypeConversion(type, candidate);
73+
}
74+
75+
public boolean canPotentiallyAcceptType(Class<?> candidate) {
76+
return candidate.isAssignableFrom(type) ||
77+
isAssignableViaTypeConversion(candidate, type) ||
78+
canAcceptType(candidate);
79+
}
80+
81+
private boolean isAssignableViaTypeConversion(Class<?> targetType, Class<?> candidate) {
82+
if (CONVERTABLE_TYPES_MAP.containsKey(candidate)) {
83+
Class<?> wrapperClass = CONVERTABLE_TYPES_MAP.get(candidate);
84+
return targetType.isAssignableFrom(wrapperClass);
85+
} else {
86+
return false;
87+
}
4688
}
4789

4890
public Class<?> getType() {
@@ -53,10 +95,6 @@ public List<Annotation> getAnnotations() {
5395
return Arrays.asList(annotations);
5496
}
5597

56-
public boolean canAcceptArrayType(Class<?> type) {
57-
return type.isArray() && canAcceptType(type.getComponentType());
58-
}
59-
6098
public boolean hasAnnotation(Class<? extends Annotation> type) {
6199
return getAnnotation(type) != null;
62100
}

src/main/java/org/junit/experimental/theories/internal/AllMembersSupplier.java

Lines changed: 24 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,13 @@ public Object getValue() throws CouldNotGenerateValueException {
4040
throw new CouldNotGenerateValueException();
4141
// do nothing, just look for more values
4242
}
43-
}
44-
43+
}
44+
4545
@Override
4646
public String getDescription() throws CouldNotGenerateValueException {
4747
return fMethod.getName();
4848
}
49-
}
50-
49+
}
5150
private final TestClass fClass;
5251

5352
/**
@@ -71,60 +70,48 @@ public List<PotentialAssignment> getValueSources(ParameterSignature sig) {
7170

7271
private void addMultiPointMethods(ParameterSignature sig, List<PotentialAssignment> list) {
7372
for (FrameworkMethod dataPointsMethod : getDataPointsMethods(sig)) {
74-
try {
75-
addMultiPointArrayValues(sig, dataPointsMethod.getName(), list, dataPointsMethod.invokeExplosively(null));
76-
} catch (Throwable e) {
77-
// ignore and move on
73+
Class<?> returnType = dataPointsMethod.getReturnType();
74+
75+
if (returnType.isArray() && sig.canPotentiallyAcceptType(returnType.getComponentType())) {
76+
try {
77+
addArrayValues(sig, dataPointsMethod.getName(), list, dataPointsMethod.invokeExplosively(null));
78+
} catch (Throwable e) {
79+
// ignore and move on
80+
}
7881
}
7982
}
8083
}
8184

82-
private void addSinglePointMethods(ParameterSignature sig,
83-
List<PotentialAssignment> list) {
85+
private void addSinglePointMethods(ParameterSignature sig, List<PotentialAssignment> list) {
8486
for (FrameworkMethod dataPointMethod : getSingleDataPointMethods(sig)) {
8587
if (sig.canAcceptType(dataPointMethod.getType())) {
8688
list.add(new MethodParameterValue(dataPointMethod));
8789
}
8890
}
8991
}
9092

91-
private void addMultiPointFields(ParameterSignature sig,
92-
List<PotentialAssignment> list) {
93+
private void addMultiPointFields(ParameterSignature sig, List<PotentialAssignment> list) {
9394
for (final Field field : getDataPointsFields(sig)) {
94-
Class<?> type = field.getType();
95-
if (sig.canAcceptArrayType(type)) {
96-
try {
97-
addArrayValues(field.getName(), list, getStaticFieldValue(field));
98-
} catch (Throwable e) {
99-
// ignore and move on
100-
}
101-
}
95+
addArrayValues(sig, field.getName(), list, getStaticFieldValue(field));
10296
}
103-
}
97+
}
10498

105-
private void addSinglePointFields(ParameterSignature sig,
106-
List<PotentialAssignment> list) {
99+
private void addSinglePointFields(ParameterSignature sig, List<PotentialAssignment> list) {
107100
for (final Field field : getSingleDataPointFields(sig)) {
108-
Class<?> type = field.getType();
109-
if (sig.canAcceptType(type)) {
110-
list.add(PotentialAssignment.forValue(field.getName(), getStaticFieldValue(field)));
101+
Object value = getStaticFieldValue(field);
102+
103+
if (sig.canAcceptValue(value)) {
104+
list.add(PotentialAssignment.forValue(field.getName(), value));
111105
}
112106
}
113107
}
114108

115-
private void addArrayValues(String name, List<PotentialAssignment> list, Object array) {
116-
for (int i = 0; i < Array.getLength(array); i++) {
117-
list.add(PotentialAssignment.forValue(name + "[" + i + "]", Array.get(array, i)));
118-
}
119-
}
120-
121-
private void addMultiPointArrayValues(ParameterSignature sig, String name, List<PotentialAssignment> list,
122-
Object array) throws Throwable {
109+
private void addArrayValues(ParameterSignature sig, String name, List<PotentialAssignment> list, Object array) {
123110
for (int i = 0; i < Array.getLength(array); i++) {
124-
if (!sig.canAcceptValue(Array.get(array, i))) {
125-
return;
111+
Object value = Array.get(array, i);
112+
if (sig.canAcceptValue(value)) {
113+
list.add(PotentialAssignment.forValue(name + "[" + i + "]", value));
126114
}
127-
list.add(PotentialAssignment.forValue(name + "[" + i + "]", Array.get(array, i)));
128115
}
129116
}
130117

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,42 @@
11
package org.junit.tests.experimental.theories;
22

3+
import static org.junit.tests.experimental.theories.TheoryTestUtils.runTheoryClass;
34
import org.junit.Assert;
45
import org.junit.Assume;
56
import org.junit.Test;
67
import org.junit.experimental.theories.DataPoint;
78
import org.junit.experimental.theories.Theories;
89
import org.junit.experimental.theories.Theory;
9-
import org.junit.runner.JUnitCore;
10-
import org.junit.runner.Request;
1110
import org.junit.runner.Result;
1211
import org.junit.runner.RunWith;
13-
import org.junit.runner.Runner;
1412
import org.junit.runners.model.InitializationError;
1513

1614
@RunWith(Theories.class)
1715
public class AssumingInTheoriesTest {
1816

19-
@Test
20-
public void noTheoryAnnotationMeansAssumeShouldIgnore() {
21-
Assume.assumeTrue(false);
22-
}
23-
24-
@Test
25-
public void theoryMeansOnlyAssumeShouldFail() throws InitializationError {
26-
JUnitCore junitRunner = new JUnitCore();
27-
Runner theoryRunner = new Theories(TheoryWithNoUnassumedParameters.class);
28-
Request request = Request.runner(theoryRunner);
29-
Result result = junitRunner.run(request);
30-
Assert.assertEquals(1, result.getFailureCount());
31-
}
32-
33-
/**
34-
* Simple class that SHOULD fail because no parameters are met.
35-
*/
36-
public static class TheoryWithNoUnassumedParameters {
37-
38-
@DataPoint
39-
public final static boolean FALSE = false;
40-
41-
@Theory
42-
public void theoryWithNoUnassumedParameters(boolean value) {
43-
Assume.assumeTrue(value);
44-
}
45-
}
17+
@Test
18+
public void noTheoryAnnotationMeansAssumeShouldIgnore() {
19+
Assume.assumeTrue(false);
20+
}
21+
22+
@Test
23+
public void theoryMeansOnlyAssumeShouldFail() throws InitializationError {
24+
Result result = runTheoryClass(TheoryWithNoUnassumedParameters.class);
25+
Assert.assertEquals(1, result.getFailureCount());
26+
}
27+
28+
/**
29+
* Simple class that SHOULD fail because no parameters are met.
30+
*/
31+
public static class TheoryWithNoUnassumedParameters {
32+
33+
@DataPoint
34+
public final static boolean FALSE = false;
35+
36+
@Theory
37+
public void theoryWithNoUnassumedParameters(boolean value) {
38+
Assume.assumeTrue(value);
39+
}
40+
}
4641

4742
}

src/test/java/org/junit/tests/experimental/theories/ParameterSignatureTest.java

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static org.hamcrest.CoreMatchers.isA;
44
import static org.junit.Assert.assertEquals;
55
import static org.junit.Assert.assertThat;
6+
import static org.junit.Assert.assertTrue;
67
import static org.junit.Assume.assumeTrue;
78

89
import java.lang.annotation.Annotation;
@@ -40,17 +41,52 @@ public void getType(Method method, int index) {
4041
.signatures(method).get(index).getType());
4142
}
4243

43-
public void foo(@TestedOn(ints = {1, 2, 3})
44-
int x) {
44+
public void foo(@TestedOn(ints = {1, 2, 3}) int x) {
4545
}
4646

4747
@Test
4848
public void getAnnotations() throws SecurityException,
4949
NoSuchMethodException {
50-
Method method = ParameterSignatureTest.class.getMethod("foo", int.class);
50+
Method method = getClass().getMethod("foo", int.class);
5151
List<Annotation> annotations = ParameterSignature.signatures(method)
5252
.get(0).getAnnotations();
5353
assertThat(annotations,
5454
CoreMatchers.<TestedOn>hasItem(isA(TestedOn.class)));
5555
}
56+
57+
public void intMethod(int param) {
58+
}
59+
60+
public void integerMethod(Integer param) {
61+
}
62+
63+
public void numberMethod(Number param) {
64+
}
65+
66+
@Test
67+
public void primitiveTypesShouldBeAcceptedAsWrapperTypes() throws Exception {
68+
List<ParameterSignature> signatures = ParameterSignature
69+
.signatures(getClass().getMethod("integerMethod", Integer.class));
70+
ParameterSignature integerSignature = signatures.get(0);
71+
72+
assertTrue(integerSignature.canAcceptType(int.class));
73+
}
74+
75+
@Test
76+
public void primitiveTypesShouldBeAcceptedAsWrapperTypeAssignables() throws Exception {
77+
List<ParameterSignature> signatures = ParameterSignature
78+
.signatures(getClass().getMethod("numberMethod", Number.class));
79+
ParameterSignature numberSignature = signatures.get(0);
80+
81+
assertTrue(numberSignature.canAcceptType(int.class));
82+
}
83+
84+
@Test
85+
public void wrapperTypesShouldBeAcceptedAsPrimitiveTypes() throws Exception {
86+
List<ParameterSignature> signatures = ParameterSignature
87+
.signatures(getClass().getMethod("intMethod", int.class));
88+
ParameterSignature intSignature = signatures.get(0);
89+
90+
assertTrue(intSignature.canAcceptType(Integer.class));
91+
}
5692
}

src/test/java/org/junit/tests/experimental/theories/TheoryTestUtils.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@
44
import java.util.List;
55

66
import org.junit.experimental.theories.PotentialAssignment;
7+
import org.junit.experimental.theories.Theories;
78
import org.junit.experimental.theories.internal.Assignments;
9+
import org.junit.runner.JUnitCore;
10+
import org.junit.runner.Request;
11+
import org.junit.runner.Result;
12+
import org.junit.runner.Runner;
13+
import org.junit.runners.model.InitializationError;
814
import org.junit.runners.model.TestClass;
915

1016
public final class TheoryTestUtils {
@@ -17,5 +23,11 @@ public static List<PotentialAssignment> potentialAssignments(Method method)
1723
new TestClass(method.getDeclaringClass()))
1824
.potentialsForNextUnassigned();
1925
}
26+
27+
public static Result runTheoryClass(Class<?> testClass) throws InitializationError {
28+
Runner theoryRunner = new Theories(testClass);
29+
Request request = Request.runner(theoryRunner);
30+
return new JUnitCore().run(request);
31+
}
2032

2133
}

0 commit comments

Comments
 (0)