View Javadoc
1   package io.atlassian.fugue.hamcrest;
2   
3   import io.atlassian.fugue.Try;
4   import org.hamcrest.Description;
5   import org.hamcrest.Matcher;
6   import org.hamcrest.Matchers;
7   import org.hamcrest.TypeSafeMatcher;
8   
9   import static io.atlassian.fugue.Unit.Unit;
10  import static java.util.Objects.requireNonNull;
11  
12  /**
13   * @since 4.7.0
14   */
15  public final class TryMatchers {
16  
17    private TryMatchers() {
18      throw new UnsupportedOperationException();
19    }
20  
21    public static Matcher<Try<?>> isFailure(Matcher<? super Exception> subMatcher) {
22      return new FailureMatcher(requireNonNull(subMatcher, "subMatcher"));
23    }
24  
25    public static Matcher<Try<?>> isFailure() {
26      return new FailureMatcher(Matchers.any(Exception.class));
27    }
28  
29    public static <A> Matcher<Try<A>> isSuccessful(Matcher<? super A> subMatcher) {
30      return new SuccessfulMatcher<>(requireNonNull(subMatcher, "subMatcher"));
31    }
32  
33    private static class FailureMatcher extends TypeSafeMatcher<Try<?>> {
34      private final Matcher<? super Exception> subMatcher;
35  
36      private FailureMatcher(Matcher<? super Exception> subMatcher) {
37        this.subMatcher = subMatcher;
38      }
39  
40      @Override protected boolean matchesSafely(Try<?> actual) {
41        return actual.toEither().left().exists(subMatcher::matches);
42      }
43  
44      @Override public void describeTo(Description description) {
45        description.appendText("failure that ");
46        subMatcher.describeTo(description);
47      }
48  
49      @Override protected void describeMismatchSafely(Try<?> actual, Description mismatchDescription) {
50        actual.fold(left -> {
51          mismatchDescription.appendText("was failure that ");
52          subMatcher.describeMismatch(left, mismatchDescription);
53          return Unit();
54        }, right -> {
55          mismatchDescription.appendText("was successful");
56          return Unit();
57        });
58      }
59    }
60  
61    private static class SuccessfulMatcher<A> extends TypeSafeMatcher<Try<A>> {
62  
63      private final Matcher<? super A> subMatcher;
64  
65      private SuccessfulMatcher(Matcher<? super A> subMatcher) {
66        this.subMatcher = subMatcher;
67      }
68  
69      @Override protected boolean matchesSafely(Try<A> actual) {
70        return actual.toEither().right().exists(subMatcher::matches);
71      }
72  
73      @Override public void describeTo(Description description) {
74        description.appendText("successful that ");
75        subMatcher.describeTo(description);
76      }
77  
78      @Override protected void describeMismatchSafely(Try<A> actual, Description mismatchDescription) {
79        actual.fold(left -> {
80          mismatchDescription.appendText("was failure");
81          return Unit();
82        }, right -> {
83          mismatchDescription.appendText("was successful that ");
84          subMatcher.describeMismatch(right, mismatchDescription);
85          return Unit();
86        });
87      }
88    }
89  }