Skip to content

Commit 2c6c142

Browse files
committed
Added error validation to check that datapoints array fields are all static and public too, fixing #125
1 parent 3aca014 commit 2c6c142

File tree

2 files changed

+146
-33
lines changed

2 files changed

+146
-33
lines changed

Diff for: src/main/java/org/junit/experimental/theories/Theories.java

+19-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.lang.reflect.Field;
44
import java.lang.reflect.InvocationTargetException;
5+
import java.lang.reflect.Method;
56
import java.lang.reflect.Modifier;
67
import java.util.ArrayList;
78
import java.util.List;
@@ -26,13 +27,14 @@ public Theories(Class<?> klass) throws InitializationError {
2627
protected void collectInitializationErrors(List<Throwable> errors) {
2728
super.collectInitializationErrors(errors);
2829
validateDataPointFields(errors);
30+
validateDataPointMethods(errors);
2931
}
3032

3133
private void validateDataPointFields(List<Throwable> errors) {
3234
Field[] fields = getTestClass().getJavaClass().getDeclaredFields();
3335

3436
for (Field field : fields) {
35-
if (field.getAnnotation(DataPoint.class) == null) {
37+
if (field.getAnnotation(DataPoint.class) == null && field.getAnnotation(DataPoints.class) == null) {
3638
continue;
3739
}
3840
if (!Modifier.isStatic(field.getModifiers())) {
@@ -44,6 +46,22 @@ private void validateDataPointFields(List<Throwable> errors) {
4446
}
4547
}
4648

49+
private void validateDataPointMethods(List<Throwable> errors) {
50+
Method[] methods = getTestClass().getJavaClass().getDeclaredMethods();
51+
52+
for (Method method : methods) {
53+
if (method.getAnnotation(DataPoint.class) == null && method.getAnnotation(DataPoints.class) == null) {
54+
continue;
55+
}
56+
if (!Modifier.isStatic(method.getModifiers())) {
57+
errors.add(new Error("DataPoint method " + method.getName() + " must be static"));
58+
}
59+
if (!Modifier.isPublic(method.getModifiers())) {
60+
errors.add(new Error("DataPoint method " + method.getName() + " must be public"));
61+
}
62+
}
63+
}
64+
4765
@Override
4866
protected void validateConstructor(List<Throwable> errors) {
4967
validateOnlyOneConstructor(errors);

Diff for: src/test/java/org/junit/tests/experimental/theories/runner/UnsuccessfulWithDataPointFields.java

+127-32
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,26 @@
22

33
import static org.hamcrest.CoreMatchers.allOf;
44
import static org.hamcrest.CoreMatchers.is;
5+
import static org.junit.Assert.assertEquals;
6+
import static org.junit.Assert.assertNotNull;
57
import static org.junit.Assert.assertThat;
68
import static org.junit.experimental.results.PrintableResult.testResult;
79
import static org.junit.experimental.results.ResultMatchers.failureCountIs;
810
import static org.junit.experimental.results.ResultMatchers.hasFailureContaining;
911
import static org.junit.experimental.results.ResultMatchers.hasSingleFailureContaining;
10-
1112
import org.hamcrest.CoreMatchers;
1213
import org.junit.Test;
1314
import org.junit.experimental.results.PrintableResult;
1415
import org.junit.experimental.theories.DataPoint;
16+
import org.junit.experimental.theories.DataPoints;
1517
import org.junit.experimental.theories.Theories;
1618
import org.junit.experimental.theories.Theory;
1719
import org.junit.runner.RunWith;
1820
import org.junit.runners.model.TestClass;
1921

2022
public class UnsuccessfulWithDataPointFields {
2123
@RunWith(Theories.class)
22-
public static class HasATheory {
24+
public static class HasAFailingTheory {
2325
@DataPoint
2426
public static int ONE = 1;
2527

@@ -31,19 +33,19 @@ public void everythingIsZero(int x) {
3133

3234
@Test
3335
public void theoryClassMethodsShowUp() throws Exception {
34-
assertThat(new Theories(HasATheory.class).getDescription()
36+
assertThat(new Theories(HasAFailingTheory.class).getDescription()
3537
.getChildren().size(), is(1));
3638
}
3739

3840
@Test
3941
public void theoryAnnotationsAreRetained() throws Exception {
40-
assertThat(new TestClass(HasATheory.class).getAnnotatedMethods(
42+
assertThat(new TestClass(HasAFailingTheory.class).getAnnotatedMethods(
4143
Theory.class).size(), is(1));
4244
}
4345

4446
@Test
4547
public void canRunTheories() throws Exception {
46-
assertThat(testResult(HasATheory.class),
48+
assertThat(testResult(HasAFailingTheory.class),
4749
hasSingleFailureContaining("Expected"));
4850
}
4951

@@ -83,75 +85,168 @@ public void nullsUsedUnlessProhibited() throws Exception {
8385
assertThat(testResult(NullsOK.class),
8486
hasSingleFailureContaining("null"));
8587
}
86-
88+
8789
@RunWith(Theories.class)
88-
public static class DataPointsMustBeStatic {
90+
public static class TheoriesMustBePublic {
8991
@DataPoint
90-
public int THREE = 3;
92+
public static int THREE = 3;
9193

92-
@DataPoint
93-
public int FOUR = 4;
94+
@Theory
95+
void numbers(int x) {
96+
97+
}
98+
}
99+
100+
@Test
101+
public void theoriesMustBePublic() {
102+
assertThat(
103+
testResult(TheoriesMustBePublic.class),
104+
hasSingleFailureContaining("public"));
105+
}
94106

107+
@RunWith(Theories.class)
108+
public static class DataPointFieldsMustBeStatic {
109+
@DataPoint
110+
public int THREE = 3;
111+
112+
@DataPoints
113+
public int[] FOURS = new int[] { 4 };
114+
95115
@Theory
96116
public void numbers(int x) {
97117

98118
}
99119
}
100120

101121
@Test
102-
public void dataPointsMustBeStatic() {
122+
public void dataPointFieldsMustBeStatic() {
103123
assertThat(
104-
testResult(DataPointsMustBeStatic.class),
124+
testResult(DataPointFieldsMustBeStatic.class),
105125
CoreMatchers.<PrintableResult>both(failureCountIs(2))
106126
.and(
107127
hasFailureContaining("DataPoint field THREE must be static"))
108128
.and(
109-
hasFailureContaining("DataPoint field FOUR must be static")));
129+
hasFailureContaining("DataPoint field FOURS must be static")));
110130
}
111-
131+
112132
@RunWith(Theories.class)
113-
public static class TheoriesMustBePublic {
133+
public static class DataPointMethodsMustBeStatic {
114134
@DataPoint
115-
public static int THREE = 3;
135+
public int singleDataPointMethod() {
136+
return 1;
137+
}
138+
139+
@DataPoints
140+
public int[] dataPointArrayMethod() {
141+
return new int[] { 1, 2, 3 };
142+
}
116143

117144
@Theory
118-
void numbers(int x) {
119-
145+
public void numbers(int x) {
146+
120147
}
121148
}
122-
149+
123150
@Test
124-
public void theoriesMustBePublic() {
151+
public void dataPointMethodsMustBeStatic() {
125152
assertThat(
126-
testResult(TheoriesMustBePublic.class),
127-
hasSingleFailureContaining("public"));
153+
testResult(DataPointMethodsMustBeStatic.class),
154+
CoreMatchers.<PrintableResult>both(failureCountIs(2))
155+
.and(
156+
hasFailureContaining("DataPoint method singleDataPointMethod must be static"))
157+
.and(
158+
hasFailureContaining("DataPoint method dataPointArrayMethod must be static")));
128159
}
129160

130161
@RunWith(Theories.class)
131-
public static class DataPointsMustBePublic {
162+
public static class DataPointFieldsMustBePublic {
132163
@DataPoint
133164
static int THREE = 3;
165+
166+
@DataPoints
167+
static int[] THREES = new int[] { 3 };
134168

135169
@DataPoint
136170
protected static int FOUR = 4;
171+
172+
@DataPoints
173+
protected static int[] FOURS = new int[] { 4 };
137174

138-
@SuppressWarnings("unused")
139175
@DataPoint
140176
private static int FIVE = 5;
177+
178+
@DataPoints
179+
private static int[] FIVES = new int[] { 5 };
141180

142181
@Theory
143182
public void numbers(int x) {
144-
183+
145184
}
146185
}
147186

148187
@Test
149-
public void dataPointsMustBePublic() {
150-
assertThat(
151-
testResult(DataPointsMustBePublic.class),
152-
allOf(failureCountIs(3),
153-
hasFailureContaining("DataPoint field THREE must be public"),
154-
hasFailureContaining("DataPoint field FOUR must be public"),
155-
hasFailureContaining("DataPoint field FIVE must be public")));
188+
public void dataPointFieldsMustBePublic() {
189+
PrintableResult result = testResult(DataPointFieldsMustBePublic.class);
190+
assertEquals(6, result.failureCount());
191+
192+
assertThat(result,
193+
allOf(hasFailureContaining("DataPoint field THREE must be public"),
194+
hasFailureContaining("DataPoint field THREES must be public"),
195+
hasFailureContaining("DataPoint field FOUR must be public"),
196+
hasFailureContaining("DataPoint field FOURS must be public"),
197+
hasFailureContaining("DataPoint field FIVE must be public"),
198+
hasFailureContaining("DataPoint field FIVES must be public")));
199+
}
200+
201+
@RunWith(Theories.class)
202+
public static class DataPointMethodsMustBePublic {
203+
@DataPoint
204+
static int three() {
205+
return 3;
206+
}
207+
208+
@DataPoints
209+
static int[] threes() {
210+
return new int[] { 3 };
211+
}
212+
213+
@DataPoint
214+
protected static int four() {
215+
return 4;
216+
}
217+
218+
@DataPoints
219+
protected static int[] fours() {
220+
return new int[] { 4 };
221+
}
222+
223+
@DataPoint
224+
private static int five() {
225+
return 5;
226+
}
227+
228+
@DataPoints
229+
private static int[] fives() {
230+
return new int[] { 5 };
231+
}
232+
233+
@Theory
234+
public void numbers(int x) {
235+
236+
}
237+
}
238+
239+
@Test
240+
public void dataPointMethodsMustBePublic() {
241+
PrintableResult result = testResult(DataPointMethodsMustBePublic.class);
242+
assertEquals(6, result.failureCount());
243+
244+
assertThat(result,
245+
allOf(hasFailureContaining("DataPoint method three must be public"),
246+
hasFailureContaining("DataPoint method threes must be public"),
247+
hasFailureContaining("DataPoint method four must be public"),
248+
hasFailureContaining("DataPoint method fours must be public"),
249+
hasFailureContaining("DataPoint method five must be public"),
250+
hasFailureContaining("DataPoint method fives must be public")));
156251
}
157252
}

0 commit comments

Comments
 (0)