Version 4.4.3: fix 4.4.2
[nikiroo-utils.git] / src / be / nikiroo / utils / test / TestCase.java
1 package be.nikiroo.utils.test;
2
3 import java.io.File;
4 import java.util.Arrays;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.Map.Entry;
8
9 import be.nikiroo.utils.IOUtils;
10
11 /**
12 * A {@link TestCase} that can be run with {@link TestLauncher}.
13 *
14 * @author niki
15 */
16 abstract public class TestCase {
17 /**
18 * The type of {@link Exception} used to signal a failed assertion or a
19 * force-fail.
20 *
21 * @author niki
22 */
23 class AssertException extends Exception {
24 private static final long serialVersionUID = 1L;
25
26 public AssertException(String reason, Exception source) {
27 super(reason, source);
28 }
29
30 public AssertException(String reason) {
31 super(reason);
32 }
33 }
34
35 private String name;
36
37 /**
38 * Create a new {@link TestCase}.
39 *
40 * @param name
41 * the test name
42 */
43 public TestCase(String name) {
44 this.name = name;
45 }
46
47 /**
48 * This constructor can be used if you require a no-param constructor. In
49 * this case, you are allowed to set the name manually via
50 * {@link TestCase#setName}.
51 */
52 protected TestCase() {
53 this("no name");
54 }
55
56 /**
57 * Setup the test (called before the test is run).
58 *
59 * @throws Exception
60 * in case of error
61 */
62 public void setUp() throws Exception {
63 }
64
65 /**
66 * Tear-down the test (called when the test has been ran).
67 *
68 * @throws Exception
69 * in case of error
70 */
71 public void tearDown() throws Exception {
72 }
73
74 /**
75 * The test name.
76 *
77 * @return the name
78 */
79 public String getName() {
80 return name;
81 }
82
83 /**
84 * The test name.
85 *
86 * @param name
87 * the new name (internal use only)
88 *
89 * @return this (so we can chain and so we can initialize it in a member
90 * variable if this is an anonymous inner class)
91 */
92 protected TestCase setName(String name) {
93 this.name = name;
94 return this;
95 }
96
97 /**
98 * Actually do the test.
99 *
100 * @throws Exception
101 * in case of error
102 */
103 abstract public void test() throws Exception;
104
105 /**
106 * Force a failure.
107 *
108 * @throws AssertException
109 * every time
110 */
111 public void fail() throws AssertException {
112 fail(null);
113 }
114
115 /**
116 * Force a failure.
117 *
118 * @param reason
119 * the failure reason
120 *
121 * @throws AssertException
122 * every time
123 */
124 public void fail(String reason) throws AssertException {
125 fail(reason, null);
126 }
127
128 /**
129 * Force a failure.
130 *
131 * @param reason
132 * the failure reason
133 * @param e
134 * the exception that caused the failure (can be NULL)
135 *
136 * @throws AssertException
137 * every time
138 */
139 public void fail(String reason, Exception e) throws AssertException {
140 throw new AssertException("Failed!" + //
141 reason != null ? "\n" + reason : "", e);
142 }
143
144 /**
145 * Check that 2 {@link Object}s are equals.
146 *
147 * @param expected
148 * the expected value
149 * @param actual
150 * the actual value
151 *
152 * @throws AssertException
153 * in case they differ
154 */
155 public void assertEquals(Object expected, Object actual)
156 throws AssertException {
157 assertEquals(null, expected, actual);
158 }
159
160 /**
161 * Check that 2 {@link Object}s are equals.
162 *
163 * @param errorMessage
164 * the error message to display if they differ
165 * @param expected
166 * the expected value
167 * @param actual
168 * the actual value
169 *
170 * @throws AssertException
171 * in case they differ
172 */
173 public void assertEquals(String errorMessage, Object expected, Object actual)
174 throws AssertException {
175 if ((expected == null && actual != null)
176 || (expected != null && !expected.equals(actual))) {
177 if (errorMessage == null) {
178 throw new AssertException(generateAssertMessage(expected,
179 actual));
180 }
181
182 throw new AssertException(errorMessage, new AssertException(
183 generateAssertMessage(expected, actual)));
184 }
185 }
186
187 /**
188 * Check that 2 longs are equals.
189 *
190 * @param expected
191 * the expected value
192 * @param actual
193 * the actual value
194 *
195 * @throws AssertException
196 * in case they differ
197 */
198 public void assertEquals(long expected, long actual) throws AssertException {
199 assertEquals(Long.valueOf(expected), Long.valueOf(actual));
200 }
201
202 /**
203 * Check that 2 longs are equals.
204 *
205 * @param errorMessage
206 * the error message to display if they differ
207 * @param expected
208 * the expected value
209 * @param actual
210 * the actual value
211 *
212 * @throws AssertException
213 * in case they differ
214 */
215 public void assertEquals(String errorMessage, long expected, long actual)
216 throws AssertException {
217 assertEquals(errorMessage, Long.valueOf(expected), Long.valueOf(actual));
218 }
219
220 /**
221 * Check that 2 booleans are equals.
222 *
223 * @param expected
224 * the expected value
225 * @param actual
226 * the actual value
227 *
228 * @throws AssertException
229 * in case they differ
230 */
231 public void assertEquals(boolean expected, boolean actual)
232 throws AssertException {
233 assertEquals(Boolean.valueOf(expected), Boolean.valueOf(actual));
234 }
235
236 /**
237 * Check that 2 booleans are equals.
238 *
239 * @param errorMessage
240 * the error message to display if they differ
241 * @param expected
242 * the expected value
243 * @param actual
244 * the actual value
245 *
246 * @throws AssertException
247 * in case they differ
248 */
249 public void assertEquals(String errorMessage, boolean expected,
250 boolean actual) throws AssertException {
251 assertEquals(errorMessage, Boolean.valueOf(expected),
252 Boolean.valueOf(actual));
253 }
254
255 /**
256 * Check that 2 doubles are equals.
257 *
258 * @param expected
259 * the expected value
260 * @param actual
261 * the actual value
262 *
263 * @throws AssertException
264 * in case they differ
265 */
266 public void assertEquals(double expected, double actual)
267 throws AssertException {
268 assertEquals(Double.valueOf(expected), Double.valueOf(actual));
269 }
270
271 /**
272 * Check that 2 doubles are equals.
273 *
274 * @param errorMessage
275 * the error message to display if they differ
276 * @param expected
277 * the expected value
278 * @param actual
279 * the actual value
280 *
281 * @throws AssertException
282 * in case they differ
283 */
284 public void assertEquals(String errorMessage, double expected, double actual)
285 throws AssertException {
286 assertEquals(errorMessage, Double.valueOf(expected),
287 Double.valueOf(actual));
288 }
289
290 /**
291 * Check that 2 {@link List}s are equals.
292 *
293 * @param errorMessage
294 * the error message to display if they differ
295 * @param expected
296 * the expected value
297 * @param actual
298 * the actual value
299 *
300 * @throws AssertException
301 * in case they differ
302 */
303 public void assertEquals(List<?> expected, List<?> actual)
304 throws AssertException {
305 assertEquals("Assertion failed", expected, actual);
306 }
307
308 /**
309 * Check that 2 {@link List}s are equals.
310 *
311 * @param errorMessage
312 * the error message to display if they differ
313 * @param expected
314 * the expected value
315 * @param actual
316 * the actual value
317 *
318 * @throws AssertException
319 * in case they differ
320 */
321 public void assertEquals(String errorMessage, List<?> expected,
322 List<?> actual) throws AssertException {
323
324 if (expected.size() != actual.size()) {
325 assertEquals(errorMessage + ": not same number of items",
326 list(expected), list(actual));
327 }
328
329 int size = expected.size();
330 for (int i = 0; i < size; i++) {
331 assertEquals(errorMessage + ": item " + i
332 + " (0-based) is not correct", expected.get(i),
333 actual.get(i));
334 }
335 }
336
337 /**
338 * Check that 2 {@link File}s are equals, by doing a line-by-line
339 * comparison.
340 *
341 * @param expected
342 * the expected value
343 * @param actual
344 * the actual value
345 * @param errorMessage
346 * the error message to display if they differ
347 *
348 * @throws AssertException
349 * in case they differ
350 */
351 public void assertEquals(File expected, File actual) throws AssertException {
352 assertEquals(generateAssertMessage(expected, actual), expected, actual);
353 }
354
355 /**
356 * Check that 2 {@link File}s are equals, by doing a line-by-line
357 * comparison.
358 *
359 * @param errorMessage
360 * the error message to display if they differ
361 * @param expected
362 * the expected value
363 * @param actual
364 * the actual value
365 *
366 * @throws AssertException
367 * in case they differ
368 */
369 public void assertEquals(String errorMessage, File expected, File actual)
370 throws AssertException {
371 assertEquals(errorMessage, expected, actual, null);
372 }
373
374 /**
375 * Check that 2 {@link File}s are equals, by doing a line-by-line
376 * comparison.
377 *
378 * @param errorMessage
379 * the error message to display if they differ
380 * @param expected
381 * the expected value
382 * @param actual
383 * the actual value
384 * @param skipCompare
385 * skip the lines starting with some values for the given files
386 * (relative path from base directory in recursive mode)
387 *
388 * @throws AssertException
389 * in case they differ
390 */
391 public void assertEquals(String errorMessage, File expected, File actual,
392 Map<String, List<String>> skipCompare) throws AssertException {
393 assertEquals(errorMessage, expected, actual, skipCompare, null);
394 }
395
396 private void assertEquals(String errorMessage, File expected, File actual,
397 Map<String, List<String>> skipCompare, String removeFromName)
398 throws AssertException {
399
400 if (expected.isDirectory() || actual.isDirectory()) {
401 assertEquals(errorMessage + ": type mismatch: expected a "
402 + (expected.isDirectory() ? "directory" : "file")
403 + ", received a "
404 + (actual.isDirectory() ? "directory" : "file"),
405 expected.isDirectory(), actual.isDirectory());
406
407 List<String> expectedFiles = Arrays.asList(expected.list());
408 expectedFiles.sort(null);
409 List<String> actualFiles = Arrays.asList(actual.list());
410 actualFiles.sort(null);
411
412 assertEquals(errorMessage, expectedFiles, actualFiles);
413 for (int i = 0; i < actualFiles.size(); i++) {
414 File expectedFile = new File(expected, expectedFiles.get(i));
415 File actualFile = new File(actual, actualFiles.get(i));
416
417 assertEquals(errorMessage, expectedFile, actualFile,
418 skipCompare, expected.getAbsolutePath());
419 }
420 } else {
421 try {
422 List<String> expectedLines = Arrays.asList(IOUtils
423 .readSmallFile(expected).split("\n"));
424 List<String> resultLines = Arrays.asList(IOUtils.readSmallFile(
425 actual).split("\n"));
426
427 String name = expected.getAbsolutePath();
428 if (removeFromName != null && name.startsWith(removeFromName)) {
429 name = expected.getName()
430 + name.substring(removeFromName.length());
431 }
432
433 assertEquals(errorMessage + ": " + name
434 + ": the number of lines is not the same",
435 expectedLines.size(), resultLines.size());
436
437 for (int j = 0; j < expectedLines.size(); j++) {
438 String expectedLine = expectedLines.get(j);
439 String resultLine = resultLines.get(j);
440
441 boolean skip = false;
442 if (skipCompare != null) {
443 for (Entry<String, List<String>> skipThose : skipCompare
444 .entrySet()) {
445 for (String skipStart : skipThose.getValue()) {
446 if (name.endsWith(skipThose.getKey())
447 && expectedLine.startsWith(skipStart)
448 && resultLine.startsWith(skipStart)) {
449 skip = true;
450 }
451 }
452 }
453 }
454
455 if (skip) {
456 continue;
457 }
458
459 assertEquals(errorMessage + ": line " + (j + 1)
460 + " is not the same in file " + name, expectedLine,
461 resultLine);
462 }
463 } catch (Exception e) {
464 throw new AssertException(errorMessage, e);
465 }
466 }
467 }
468
469 /**
470 * Check that given {@link Object} is not NULL.
471 *
472 * @param errorMessage
473 * the error message to display if it is NULL
474 * @param actual
475 * the actual value
476 *
477 * @throws AssertException
478 * in case they differ
479 */
480 public void assertNotNull(String errorMessage, Object actual)
481 throws AssertException {
482 if (actual == null) {
483 String defaultReason = String.format("" //
484 + "Assertion failed!%n" //
485 + "Object should not have been NULL");
486
487 if (errorMessage == null) {
488 throw new AssertException(defaultReason);
489 }
490
491 throw new AssertException(errorMessage, new AssertException(
492 defaultReason));
493 }
494 }
495
496 /**
497 * Generate the default assert message for 2 different values that were
498 * supposed to be equals.
499 *
500 * @param expected
501 * the expected value
502 * @param actual
503 * the actual value
504 *
505 * @return the message
506 */
507 public static String generateAssertMessage(Object expected, Object actual) {
508 return String.format("" //
509 + "Assertion failed!%n" //
510 + "Expected value: [%s]%n" //
511 + "Actual value: [%s]", expected, actual);
512 }
513
514 private static String list(List<?> items) {
515 StringBuilder builder = new StringBuilder();
516 for (Object item : items) {
517 if (builder.length() == 0) {
518 builder.append(items.size() + " item(s): ");
519 } else {
520 builder.append(", ");
521 }
522
523 builder.append("" + item);
524
525 if (builder.length() > 60) {
526 builder.setLength(57);
527 builder.append("...");
528 break;
529 }
530 }
531
532 return builder.toString();
533 }
534 }