1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.callbackparams.junit4;
18
19 import java.lang.reflect.InvocationTargetException;
20 import java.lang.reflect.Method;
21 import java.util.ArrayList;
22 import java.util.List;
23 import org.callbackparams.combine.reflect.CallbackRecordsFactory;
24 import org.junit.runner.Description;
25 import org.junit.runner.notification.RunNotifier;
26 import org.junit.runners.BlockJUnit4ClassRunner;
27 import org.junit.runners.ParentRunner;
28 import org.junit.runners.model.FrameworkMethod;
29 import org.junit.runners.model.InitializationError;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 public class EnumRunner extends ParentRunner<BlockJUnit4ClassRunner> {
53
54 private final List<BlockJUnit4ClassRunner> children;
55
56 public EnumRunner(Class<? extends Enum> testClass)
57 throws InitializationError {
58 super(testClass);
59 Object[] enumValues = getValues(testClass);
60 this.children = new ArrayList<BlockJUnit4ClassRunner>(enumValues.length);
61 for (Object testInstance : enumValues) {
62 this.children.add(new SingleEnumValueRunner(testClass, testInstance));
63 }
64 }
65
66 private Object[] getValues(Class<? extends Enum> testClass) {
67 try {
68 Method valuesMethod = CallbackRecordsFactory
69 .valuesMethodFor(testClass);
70 try {
71 valuesMethod.setAccessible(true);
72 } catch (SecurityException ignoreAndContinueAnyway) {}
73 return (Object[]) valuesMethod.invoke(null);
74
75 } catch (NoSuchMethodException ex) {
76 throw new Error("When using EnumRunner for a non-enum class, the "
77 + "class must have a method 'values()' that provides the "
78 + "test instances!", ex);
79 } catch (IllegalAccessException ex) {
80 throw new Error(ex);
81 } catch (InvocationTargetException ite) {
82 throw new Error(ite.getTargetException());
83 }
84 }
85
86 @Override
87 protected List<BlockJUnit4ClassRunner> getChildren() {
88 return this.children;
89 }
90
91 @Override
92 protected Description describeChild(BlockJUnit4ClassRunner child) {
93 return child.getDescription();
94 }
95
96 @Override
97 protected void runChild(
98 BlockJUnit4ClassRunner child, RunNotifier notifier) {
99 child.run(notifier);
100 }
101
102 private static class SingleEnumValueRunner
103 extends BlockJUnit4ClassRunner {
104
105 private final Object testValue;
106
107 public SingleEnumValueRunner(Class<?> testClass, Object testValue)
108 throws InitializationError {
109 super(testClass);
110 this.testValue = testValue;
111 }
112
113 @Override
114 protected Object createTest() {
115 return testValue;
116 }
117
118 @Override
119 protected String testName(FrameworkMethod method) {
120 return super.testName(method) + '[' + testValue + ']';
121 }
122
123 @Override
124
125
126
127 protected void collectInitializationErrors(List<Throwable> errors) {
128 validateInstanceMethods(errors);
129 }
130 }
131 }