1 package org.junit.runner;
2
3 import java.io.Serializable;
4 import java.lang.annotation.Annotation;
5 import java.util.ArrayList;
6 import java.util.Arrays;
7 import java.util.Collection;
8 import java.util.concurrent.ConcurrentLinkedQueue;
9 import java.util.regex.Matcher;
10 import java.util.regex.Pattern;
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 public class Description implements Serializable {
31 private static final long serialVersionUID = 1L;
32
33 private static final Pattern METHOD_AND_CLASS_NAME_PATTERN = Pattern
34 .compile("([\\s\\S]*)\\((.*)\\)");
35
36
37
38
39
40
41
42
43
44 public static Description createSuiteDescription(String name, Annotation... annotations) {
45 return new Description(null, name, annotations);
46 }
47
48
49
50
51
52
53
54
55
56
57 public static Description createSuiteDescription(String name, Serializable uniqueId, Annotation... annotations) {
58 return new Description(null, name, uniqueId, annotations);
59 }
60
61
62
63
64
65
66
67
68
69
70
71
72 public static Description createTestDescription(String className, String name, Annotation... annotations) {
73 return new Description(null, formatDisplayName(name, className), annotations);
74 }
75
76
77
78
79
80
81
82
83
84
85 public static Description createTestDescription(Class<?> clazz, String name, Annotation... annotations) {
86 return new Description(clazz, formatDisplayName(name, clazz.getName()), annotations);
87 }
88
89
90
91
92
93
94
95
96
97
98 public static Description createTestDescription(Class<?> clazz, String name) {
99 return new Description(clazz, formatDisplayName(name, clazz.getName()));
100 }
101
102
103
104
105
106
107
108
109 public static Description createTestDescription(String className, String name, Serializable uniqueId) {
110 return new Description(null, formatDisplayName(name, className), uniqueId);
111 }
112
113 private static String formatDisplayName(String name, String className) {
114 return String.format("%s(%s)", name, className);
115 }
116
117
118
119
120
121
122
123 public static Description createSuiteDescription(Class<?> testClass) {
124 return new Description(testClass, testClass.getName(), testClass.getAnnotations());
125 }
126
127
128
129
130 public static final Description EMPTY = new Description(null, "No Tests");
131
132
133
134
135
136
137 public static final Description TEST_MECHANISM = new Description(null, "Test mechanism");
138
139
140
141
142
143
144 private final Collection<Description> fChildren = new ConcurrentLinkedQueue<Description>();
145 private final String fDisplayName;
146 private final Serializable fUniqueId;
147 private final Annotation[] fAnnotations;
148 private volatile Class<?> fTestClass;
149
150 private Description(Class<?> clazz, String displayName, Annotation... annotations) {
151 this(clazz, displayName, displayName, annotations);
152 }
153
154 private Description(Class<?> testClass, String displayName, Serializable uniqueId, Annotation... annotations) {
155 if ((displayName == null) || (displayName.length() == 0)) {
156 throw new IllegalArgumentException(
157 "The display name must not be empty.");
158 }
159 if ((uniqueId == null)) {
160 throw new IllegalArgumentException(
161 "The unique id must not be null.");
162 }
163 this.fTestClass = testClass;
164 this.fDisplayName = displayName;
165 this.fUniqueId = uniqueId;
166 this.fAnnotations = annotations;
167 }
168
169
170
171
172 public String getDisplayName() {
173 return fDisplayName;
174 }
175
176
177
178
179
180
181 public void addChild(Description description) {
182 fChildren.add(description);
183 }
184
185
186
187
188
189 public ArrayList<Description> getChildren() {
190 return new ArrayList<Description>(fChildren);
191 }
192
193
194
195
196 public boolean isSuite() {
197 return !isTest();
198 }
199
200
201
202
203 public boolean isTest() {
204 return fChildren.isEmpty();
205 }
206
207
208
209
210 public int testCount() {
211 if (isTest()) {
212 return 1;
213 }
214 int result = 0;
215 for (Description child : fChildren) {
216 result += child.testCount();
217 }
218 return result;
219 }
220
221 @Override
222 public int hashCode() {
223 return fUniqueId.hashCode();
224 }
225
226 @Override
227 public boolean equals(Object obj) {
228 if (!(obj instanceof Description)) {
229 return false;
230 }
231 Description d = (Description) obj;
232 return fUniqueId.equals(d.fUniqueId);
233 }
234
235 @Override
236 public String toString() {
237 return getDisplayName();
238 }
239
240
241
242
243 public boolean isEmpty() {
244 return equals(EMPTY);
245 }
246
247
248
249
250
251 public Description childlessCopy() {
252 return new Description(fTestClass, fDisplayName, fAnnotations);
253 }
254
255
256
257
258
259 public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
260 for (Annotation each : fAnnotations) {
261 if (each.annotationType().equals(annotationType)) {
262 return annotationType.cast(each);
263 }
264 }
265 return null;
266 }
267
268
269
270
271 public Collection<Annotation> getAnnotations() {
272 return Arrays.asList(fAnnotations);
273 }
274
275
276
277
278
279 public Class<?> getTestClass() {
280 if (fTestClass != null) {
281 return fTestClass;
282 }
283 String name = getClassName();
284 if (name == null) {
285 return null;
286 }
287 try {
288 fTestClass = Class.forName(name, false, getClass().getClassLoader());
289 return fTestClass;
290 } catch (ClassNotFoundException e) {
291 return null;
292 }
293 }
294
295
296
297
298
299 public String getClassName() {
300 return fTestClass != null ? fTestClass.getName() : methodAndClassNamePatternGroupOrDefault(2, toString());
301 }
302
303
304
305
306
307 public String getMethodName() {
308 return methodAndClassNamePatternGroupOrDefault(1, null);
309 }
310
311 private String methodAndClassNamePatternGroupOrDefault(int group,
312 String defaultString) {
313 Matcher matcher = METHOD_AND_CLASS_NAME_PATTERN.matcher(toString());
314 return matcher.matches() ? matcher.group(group) : defaultString;
315 }
316 }