001    package org.junit.experimental.results;
002    
003    import org.hamcrest.BaseMatcher;
004    import org.hamcrest.Description;
005    import org.hamcrest.Matcher;
006    import 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     */
016    public 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    }