001package org.junit.experimental.results;
002
003import org.hamcrest.BaseMatcher;
004import org.hamcrest.Description;
005import org.hamcrest.Matcher;
006import org.hamcrest.TypeSafeMatcher;
007
008/**
009 * Matchers on a PrintableResult, to enable JUnit self-tests.
010 * For example:
011 *
012 * <pre>
013 * assertThat(testResult(HasExpectedException.class), isSuccessful());
014 * </pre>
015 */
016public class ResultMatchers {
017
018    /**
019     * Do not instantiate.
020     * @deprecated will be private soon.
021     */
022    @Deprecated
023    public ResultMatchers() {
024    }
025
026    /**
027     * Matches if the tests are all successful
028     */
029    public static Matcher<PrintableResult> isSuccessful() {
030        return failureCountIs(0);
031    }
032
033    /**
034     * Matches if there are {@code count} failures
035     */
036    public static Matcher<PrintableResult> failureCountIs(final int count) {
037        return new TypeSafeMatcher<PrintableResult>() {
038            public void describeTo(Description description) {
039                description.appendText("has " + count + " failures");
040            }
041
042            @Override
043            public boolean matchesSafely(PrintableResult item) {
044                return item.failureCount() == count;
045            }
046        };
047    }
048
049    /**
050     * Matches if the result has exactly one failure, and it contains {@code string}
051     */
052    public static Matcher<Object> hasSingleFailureContaining(final String string) {
053        return new BaseMatcher<Object>() {
054            public boolean matches(Object item) {
055                return item.toString().contains(string) && failureCountIs(1).matches(item);
056            }
057
058            public void describeTo(Description description) {
059                description.appendText("has single failure containing " + string);
060            }
061        };
062    }
063
064    /**
065     * Matches if the result has exactly one failure matching the given matcher.
066     *
067     * @since 4.13
068     */
069    public static Matcher<PrintableResult> hasSingleFailureMatching(final Matcher<Throwable> matcher) {
070        return new TypeSafeMatcher<PrintableResult>() {
071            @Override
072            public boolean matchesSafely(PrintableResult item) {
073                return item.failureCount() == 1 && matcher.matches(item.failures().get(0).getException());
074            }
075
076            public void describeTo(Description description) {
077                description.appendText("has failure with exception matching ");
078                matcher.describeTo(description);
079            }
080        };
081    }
082
083    /**
084     * Matches if the result has one or more failures, and at least one of them
085     * contains {@code string}
086     */
087    public static Matcher<PrintableResult> hasFailureContaining(final String string) {
088        return new TypeSafeMatcher<PrintableResult>() {
089            @Override
090            public boolean matchesSafely(PrintableResult item) {
091                return item.failureCount() > 0 && item.toString().contains(string);
092            }
093
094            public void describeTo(Description description) {
095                description.appendText("has failure containing " + string);
096            }
097        };
098    }
099}