1 | // License: GPL. For details, see LICENSE file.
|
---|
2 | package org.openstreetmap.josm.testutils;
|
---|
3 |
|
---|
4 | import org.hamcrest.Description;
|
---|
5 | import org.hamcrest.Factory;
|
---|
6 | import org.hamcrest.Matcher;
|
---|
7 | import org.hamcrest.TypeSafeMatcher;
|
---|
8 |
|
---|
9 | /**
|
---|
10 | * Matches the root cause of a {@code Throwable}.
|
---|
11 | * This has been rejected from JUnit developers (see https://github.com/junit-team/junit4/pull/778),
|
---|
12 | * But this is really useful, thanks to pimterry for implementing it.
|
---|
13 | *
|
---|
14 | * @param <T> Throwable type
|
---|
15 | * @see <a href="https://github.com/junit-team/junit4/pull/778">Github pull request</a>
|
---|
16 | */
|
---|
17 | public class ThrowableRootCauseMatcher<T extends Throwable> extends TypeSafeMatcher<T> {
|
---|
18 |
|
---|
19 | private final Matcher<T> fMatcher;
|
---|
20 |
|
---|
21 | /**
|
---|
22 | * Constructs a new {@code ThrowableRootCauseMatcher}.
|
---|
23 | * @param matcher matcher
|
---|
24 | */
|
---|
25 | public ThrowableRootCauseMatcher(Matcher<T> matcher) {
|
---|
26 | fMatcher = matcher;
|
---|
27 | }
|
---|
28 |
|
---|
29 | @Override
|
---|
30 | public void describeTo(Description description) {
|
---|
31 | description.appendText("exception with cause ");
|
---|
32 | description.appendDescriptionOf(fMatcher);
|
---|
33 | }
|
---|
34 |
|
---|
35 | @Override
|
---|
36 | protected boolean matchesSafely(T item) {
|
---|
37 | Throwable exception = item;
|
---|
38 | while (exception.getCause() != null) {
|
---|
39 | exception = exception.getCause();
|
---|
40 | }
|
---|
41 | return fMatcher.matches(exception);
|
---|
42 | }
|
---|
43 |
|
---|
44 | @Override
|
---|
45 | protected void describeMismatchSafely(T item, Description description) {
|
---|
46 | description.appendText("cause ");
|
---|
47 | fMatcher.describeMismatch(item.getCause(), description);
|
---|
48 | }
|
---|
49 |
|
---|
50 | /**
|
---|
51 | * Returns a new {@code ThrowableRootCauseMatcher} instance.
|
---|
52 | * @param <T> Throwable type
|
---|
53 | * @param matcher matcher
|
---|
54 | * @return new {@code ThrowableRootCauseMatcher} instance
|
---|
55 | */
|
---|
56 | @Factory
|
---|
57 | public static <T extends Throwable> Matcher<T> hasRootCause(final Matcher<T> matcher) {
|
---|
58 | return new ThrowableRootCauseMatcher<>(matcher);
|
---|
59 | }
|
---|
60 | }
|
---|