1 package org.junit.tests.experimental.rules;
2
3 import static org.hamcrest.CoreMatchers.containsString;
4 import static org.hamcrest.CoreMatchers.is;
5 import static org.junit.Assert.assertEquals;
6 import static org.junit.Assert.assertThat;
7 import static org.junit.Assert.assertTrue;
8 import static org.junit.Assert.fail;
9 import static org.junit.experimental.results.PrintableResult.testResult;
10 import static org.junit.experimental.results.ResultMatchers.hasSingleFailureContaining;
11 import static org.junit.experimental.results.ResultMatchers.isSuccessful;
12
13 import java.util.LinkedList;
14 import java.util.List;
15
16 import org.junit.After;
17 import org.junit.Assume;
18 import org.junit.Before;
19 import org.junit.Rule;
20 import org.junit.Test;
21 import org.junit.internal.AssumptionViolatedException;
22 import org.junit.rules.TestName;
23 import org.junit.rules.TestRule;
24 import org.junit.rules.TestWatcher;
25 import org.junit.runner.Description;
26 import org.junit.runner.JUnitCore;
27 import org.junit.runner.Result;
28 import org.junit.runners.model.FrameworkMethod;
29 import org.junit.runners.model.Statement;
30
31 public class TestRuleTest {
32 private static boolean wasRun;
33
34 public static class ExampleTest {
35 @Rule
36 public TestRule example = new TestRule() {
37 public Statement apply(final Statement base, Description description) {
38 return new Statement() {
39 @Override
40 public void evaluate() throws Throwable {
41 wasRun = true;
42 base.evaluate();
43 }
44
45 ;
46 };
47 }
48 };
49
50 @Test
51 public void nothing() {
52
53 }
54 }
55
56 @Test
57 public void ruleIsIntroducedAndEvaluated() {
58 wasRun = false;
59 JUnitCore.runClasses(ExampleTest.class);
60 assertTrue(wasRun);
61 }
62
63 public static class BothKindsOfRule implements TestRule, org.junit.rules.MethodRule {
64 public int applications = 0;
65
66 public Statement apply(Statement base, FrameworkMethod method,
67 Object target) {
68 applications++;
69 return base;
70 }
71
72 public Statement apply(Statement base, Description description) {
73 applications++;
74 return base;
75 }
76 }
77
78 public static class OneFieldTwoKindsOfRule {
79 @Rule
80 public BothKindsOfRule both = new BothKindsOfRule();
81
82 @Test
83 public void onlyOnce() {
84 assertEquals(1, both.applications);
85 }
86 }
87
88
89 @Test
90 public void onlyApplyOnceEvenIfImplementsBothInterfaces() {
91 assertTrue(JUnitCore.runClasses(OneFieldTwoKindsOfRule.class).wasSuccessful());
92 }
93
94 public static class SonOfExampleTest extends ExampleTest {
95
96 }
97
98 @Test
99 public void ruleIsIntroducedAndEvaluatedOnSubclass() {
100 wasRun = false;
101 JUnitCore.runClasses(SonOfExampleTest.class);
102 assertTrue(wasRun);
103 }
104
105 private static int runCount;
106
107 public static class MultipleRuleTest {
108 private static class Increment implements TestRule {
109 public Statement apply(final Statement base, Description description) {
110 return new Statement() {
111 @Override
112 public void evaluate() throws Throwable {
113 runCount++;
114 base.evaluate();
115 }
116
117 ;
118 };
119 }
120 }
121
122 @Rule
123 public TestRule incrementor1 = new Increment();
124
125 @Rule
126 public TestRule incrementor2 = new Increment();
127
128 @Test
129 public void nothing() {
130
131 }
132 }
133
134 @Test
135 public void multipleRulesAreRun() {
136 runCount = 0;
137 JUnitCore.runClasses(MultipleRuleTest.class);
138 assertEquals(2, runCount);
139 }
140
141 public static class NoRulesTest {
142 public int x;
143
144 @Test
145 public void nothing() {
146
147 }
148 }
149
150 @Test
151 public void ignoreNonRules() {
152 Result result = JUnitCore.runClasses(NoRulesTest.class);
153 assertEquals(0, result.getFailureCount());
154 }
155
156 private static String log;
157
158 public static class OnFailureTest {
159 @Rule
160 public TestRule watcher = new TestWatcher() {
161 @Override
162 protected void failed(Throwable e, Description description) {
163 log += description + " " + e.getClass().getSimpleName();
164 }
165 };
166
167 @Test
168 public void nothing() {
169 fail();
170 }
171 }
172
173 @Test
174 public void onFailure() {
175 log = "";
176 Result result = JUnitCore.runClasses(OnFailureTest.class);
177 assertEquals(String.format("nothing(%s) AssertionError", OnFailureTest.class.getName()), log);
178 assertEquals(1, result.getFailureCount());
179 }
180
181 public static class WatchmanTest {
182 private static String watchedLog;
183
184 @Rule
185 public TestRule watcher = new TestWatcher() {
186 @Override
187 protected void failed(Throwable e, Description description) {
188 watchedLog += description + " "
189 + e.getClass().getSimpleName() + "\n";
190 }
191
192 @Override
193 protected void succeeded(Description description) {
194 watchedLog += description + " " + "success!\n";
195 }
196 };
197
198 @Test
199 public void fails() {
200 fail();
201 }
202
203 @Test
204 public void succeeds() {
205 }
206 }
207
208 @Test
209 public void succeeded() {
210 WatchmanTest.watchedLog = "";
211 JUnitCore.runClasses(WatchmanTest.class);
212 assertThat(WatchmanTest.watchedLog, containsString(String.format("fails(%s) AssertionError", WatchmanTest.class.getName())));
213 assertThat(WatchmanTest.watchedLog, containsString(String.format("succeeds(%s) success!", WatchmanTest.class.getName())));
214 }
215
216 public static class BeforesAndAfters {
217 private static StringBuilder watchedLog = new StringBuilder();
218
219 @Before
220 public void before() {
221 watchedLog.append("before ");
222 }
223
224 @Rule
225 public TestRule watcher = new LoggingTestWatcher(watchedLog);
226
227 @After
228 public void after() {
229 watchedLog.append("after ");
230 }
231
232 @Test
233 public void succeeds() {
234 watchedLog.append("test ");
235 }
236 }
237
238 @Test
239 public void beforesAndAfters() {
240 BeforesAndAfters.watchedLog = new StringBuilder();
241 JUnitCore.runClasses(BeforesAndAfters.class);
242 assertThat(BeforesAndAfters.watchedLog.toString(),
243 is("starting before test after succeeded finished "));
244 }
245
246 public static class WrongTypedField {
247 @Rule
248 public int x = 5;
249
250 @Test
251 public void foo() {
252 }
253 }
254
255 @Test
256 public void validateWrongTypedField() {
257 assertThat(testResult(WrongTypedField.class),
258 hasSingleFailureContaining("must implement MethodRule"));
259 }
260
261 public static class SonOfWrongTypedField extends WrongTypedField {
262
263 }
264
265 @Test
266 public void validateWrongTypedFieldInSuperclass() {
267 assertThat(testResult(SonOfWrongTypedField.class),
268 hasSingleFailureContaining("must implement MethodRule"));
269 }
270
271 public static class PrivateRule {
272 @Rule
273 private TestRule rule = new TestName();
274
275 @Test
276 public void foo() {
277 }
278 }
279
280 @Test
281 public void validatePrivateRule() {
282 assertThat(testResult(PrivateRule.class),
283 hasSingleFailureContaining("must be public"));
284 }
285
286 public static class CustomTestName implements TestRule {
287 public String name = null;
288
289 public Statement apply(final Statement base, final Description description) {
290 return new Statement() {
291 @Override
292 public void evaluate() throws Throwable {
293 name = description.getMethodName();
294 base.evaluate();
295 }
296 };
297 }
298 }
299
300 public static class UsesCustomMethodRule {
301 @Rule
302 public CustomTestName counter = new CustomTestName();
303
304 @Test
305 public void foo() {
306 assertEquals("foo", counter.name);
307 }
308 }
309
310 @Test
311 public void useCustomMethodRule() {
312 assertThat(testResult(UsesCustomMethodRule.class), isSuccessful());
313 }
314
315 public static class MethodExampleTest {
316 private TestRule example = new TestRule() {
317 public Statement apply(final Statement base, Description description) {
318 return new Statement() {
319 @Override
320 public void evaluate() throws Throwable {
321 wasRun = true;
322 base.evaluate();
323 }
324
325 ;
326 };
327 }
328 };
329
330 @Rule
331 public TestRule getExample() {
332 return example;
333 }
334
335 @Test
336 public void nothing() {
337
338 }
339 }
340
341 @Test
342 public void methodRuleIsIntroducedAndEvaluated() {
343 wasRun = false;
344 JUnitCore.runClasses(MethodExampleTest.class);
345 assertTrue(wasRun);
346 }
347
348 public static class MethodBothKindsOfRule implements TestRule, org.junit.rules.MethodRule {
349 public int applications = 0;
350
351 public Statement apply(Statement base, FrameworkMethod method,
352 Object target) {
353 applications++;
354 return base;
355 }
356
357 public Statement apply(Statement base, Description description) {
358 applications++;
359 return base;
360 }
361 }
362
363 public static class MethodOneFieldTwoKindsOfRule {
364 private MethodBothKindsOfRule both = new MethodBothKindsOfRule();
365
366 @Rule
367 public MethodBothKindsOfRule getBoth() {
368 return both;
369 }
370
371 @Test
372 public void onlyOnce() {
373 assertEquals(1, both.applications);
374 }
375 }
376
377
378 @Test
379 public void methodOnlyApplyOnceEvenIfImplementsBothInterfaces() {
380 assertTrue(JUnitCore.runClasses(MethodOneFieldTwoKindsOfRule.class).wasSuccessful());
381 }
382
383 public static class MethodSonOfExampleTest extends MethodExampleTest {
384
385 }
386
387 @Test
388 public void methodRuleIsIntroducedAndEvaluatedOnSubclass() {
389 wasRun = false;
390 JUnitCore.runClasses(MethodSonOfExampleTest.class);
391 assertTrue(wasRun);
392 }
393
394
395
396 public static class MethodMultipleRuleTest {
397 private static class Increment implements TestRule {
398 public Statement apply(final Statement base, Description description) {
399 return new Statement() {
400 @Override
401 public void evaluate() throws Throwable {
402 runCount++;
403 base.evaluate();
404 }
405
406 ;
407 };
408 }
409 }
410
411 private TestRule incrementor1 = new Increment();
412
413 @Rule
414 public TestRule getIncrementor1() {
415 return incrementor1;
416 }
417
418 private TestRule incrementor2 = new Increment();
419
420 @Rule
421 public TestRule getIncrementor2() {
422 return incrementor2;
423 }
424
425 @Test
426 public void nothing() {
427
428 }
429 }
430
431 @Test
432 public void methodMultipleRulesAreRun() {
433 runCount = 0;
434 JUnitCore.runClasses(MethodMultipleRuleTest.class);
435 assertEquals(2, runCount);
436 }
437
438 public static class MethodNoRulesTest {
439 public int x;
440
441 @Test
442 public void nothing() {
443
444 }
445 }
446
447 @Test
448 public void methodIgnoreNonRules() {
449 Result result = JUnitCore.runClasses(MethodNoRulesTest.class);
450 assertEquals(0, result.getFailureCount());
451 }
452
453 public static class MethodOnFailureTest {
454 private TestRule watchman = new TestWatcher() {
455 @Override
456 protected void failed(Throwable e, Description description) {
457 log += description + " " + e.getClass().getSimpleName();
458 }
459 };
460
461 @Rule
462 public TestRule getWatchman() {
463 return watchman;
464 }
465
466 @Test
467 public void nothing() {
468 fail();
469 }
470 }
471
472 @Test
473 public void methodOnFailure() {
474 log = "";
475 Result result = JUnitCore.runClasses(MethodOnFailureTest.class);
476 assertEquals(String.format("nothing(%s) AssertionError", MethodOnFailureTest.class.getName()), log);
477 assertEquals(1, result.getFailureCount());
478 }
479
480 public static class MethodOnSkippedTest {
481 private TestRule watchman = new TestWatcher() {
482 @Override
483 protected void skipped(AssumptionViolatedException e, Description description) {
484 log += description + " " + e.getClass().getSimpleName();
485 }
486 };
487
488 @Rule
489 public TestRule getWatchman() {
490 return watchman;
491 }
492
493 @Test
494 public void nothing() {
495 Assume.assumeTrue(false);
496 }
497 }
498
499 @Test
500 public void methodOnSkipped() {
501 log = "";
502 Result result = JUnitCore.runClasses(MethodOnSkippedTest.class);
503 assertEquals(String.format("nothing(%s) AssumptionViolatedException", MethodOnSkippedTest.class.getName()), log);
504 assertEquals(0, result.getFailureCount());
505 assertEquals(1, result.getRunCount());
506 }
507
508 public static class MethodWatchmanTest {
509 @SuppressWarnings("unused")
510 private static String watchedLog;
511
512 private TestRule watchman = new TestWatcher() {
513 @Override
514 protected void failed(Throwable e, Description description) {
515 watchedLog += description + " "
516 + e.getClass().getSimpleName() + "\n";
517 }
518
519 @Override
520 protected void succeeded(Description description) {
521 watchedLog += description + " " + "success!\n";
522 }
523 };
524
525 @Rule
526 public TestRule getWatchman() {
527 return watchman;
528 }
529
530 @Test
531 public void fails() {
532 fail();
533 }
534
535 @Test
536 public void succeeds() {
537 }
538 }
539
540 @Test
541 public void methodSucceeded() {
542 WatchmanTest.watchedLog = "";
543 JUnitCore.runClasses(WatchmanTest.class);
544 assertThat(WatchmanTest.watchedLog, containsString(String.format("fails(%s) AssertionError", WatchmanTest.class.getName())));
545 assertThat(WatchmanTest.watchedLog, containsString(String.format("succeeds(%s) success!", WatchmanTest.class.getName())));
546 }
547
548 public static class MethodBeforesAndAfters {
549 private static String watchedLog;
550
551 @Before
552 public void before() {
553 watchedLog += "before ";
554 }
555
556 private TestRule watchman = new TestWatcher() {
557 @Override
558 protected void starting(Description d) {
559 watchedLog += "starting ";
560 }
561
562 @Override
563 protected void finished(Description d) {
564 watchedLog += "finished ";
565 }
566
567 @Override
568 protected void succeeded(Description d) {
569 watchedLog += "succeeded ";
570 }
571 };
572
573 @Rule
574 public TestRule getWatchman() {
575 return watchman;
576 }
577
578 @After
579 public void after() {
580 watchedLog += "after ";
581 }
582
583 @Test
584 public void succeeds() {
585 watchedLog += "test ";
586 }
587 }
588
589 @Test
590 public void methodBeforesAndAfters() {
591 MethodBeforesAndAfters.watchedLog = "";
592 JUnitCore.runClasses(MethodBeforesAndAfters.class);
593 assertThat(MethodBeforesAndAfters.watchedLog, is("starting before test after succeeded finished "));
594 }
595
596 public static class MethodWrongTypedField {
597 @Rule
598 public int getX() {
599 return 5;
600 }
601
602 @Test
603 public void foo() {
604 }
605 }
606
607 @Test
608 public void methodValidateWrongTypedField() {
609 assertThat(testResult(MethodWrongTypedField.class),
610 hasSingleFailureContaining("must return an implementation of MethodRule"));
611 }
612
613 public static class MethodSonOfWrongTypedField extends MethodWrongTypedField {
614
615 }
616
617 @Test
618 public void methodValidateWrongTypedFieldInSuperclass() {
619 assertThat(testResult(MethodSonOfWrongTypedField.class),
620 hasSingleFailureContaining("must return an implementation of MethodRule"));
621 }
622
623 public static class MethodPrivateRule {
624 @Rule
625 private TestRule getRule() {
626 return new TestName();
627 }
628
629 @Test
630 public void foo() {
631 }
632 }
633
634 @Test
635 public void methodValidatePrivateRule() {
636 assertThat(testResult(MethodPrivateRule.class),
637 hasSingleFailureContaining("must be public"));
638 }
639
640 public static class MethodUsesCustomMethodRule {
641 private CustomTestName counter = new CustomTestName();
642
643 @Rule
644 public CustomTestName getCounter() {
645 return counter;
646 }
647
648 @Test
649 public void foo() {
650 assertEquals("foo", counter.name);
651 }
652 }
653
654 @Test
655 public void methodUseCustomMethodRule() {
656 assertThat(testResult(MethodUsesCustomMethodRule.class), isSuccessful());
657 }
658
659 private static final List<String> orderList = new LinkedList<String>();
660
661 private static class OrderTestRule implements TestRule {
662 private String name;
663
664 public OrderTestRule(String name) {
665 this.name = name;
666 }
667
668 public Statement apply(final Statement base, final Description description) {
669 return new Statement() {
670 @Override
671 public void evaluate() throws Throwable {
672 orderList.add(name);
673 base.evaluate();
674 }
675 };
676 }
677 }
678
679 ;
680
681 public static class UsesFieldAndMethodRule {
682 @Rule
683 public OrderTestRule orderMethod() {
684 return new OrderTestRule("orderMethod");
685 }
686
687 @Rule
688 public OrderTestRule orderField = new OrderTestRule("orderField");
689
690 @Test
691 public void foo() {
692 assertEquals("orderField", orderList.get(0));
693 assertEquals("orderMethod", orderList.get(1));
694 }
695 }
696
697 @Test
698 public void usesFieldAndMethodRule() {
699 orderList.clear();
700 assertThat(testResult(UsesFieldAndMethodRule.class), isSuccessful());
701 }
702
703 public static class MultipleCallsTest implements TestRule {
704 public int applications = 0;
705
706 public Statement apply(Statement base, Description description) {
707 applications++;
708 return base;
709 }
710 }
711
712 public static class CallMethodOnlyOnceRule {
713 int countOfMethodCalls = 0;
714
715 private static class Dummy implements TestRule {
716 public Statement apply(final Statement base, Description description) {
717 return new Statement() {
718 @Override
719 public void evaluate() throws Throwable {
720 base.evaluate();
721 }
722
723 ;
724 };
725 }
726 }
727
728 @Rule
729 public Dummy both() {
730 countOfMethodCalls++;
731 return new Dummy();
732 }
733
734 @Test
735 public void onlyOnce() {
736 assertEquals(1, countOfMethodCalls);
737 }
738 }
739
740 @Test
741 public void testCallMethodOnlyOnceRule() {
742 assertTrue(JUnitCore.runClasses(CallMethodOnlyOnceRule.class).wasSuccessful());
743 }
744 }