View Javadoc

1   package com.atlassian.vcache.internal.test;
2   
3   import org.hamcrest.Description;
4   import org.hamcrest.Factory;
5   import org.hamcrest.Matcher;
6   import org.hamcrest.TypeSafeMatcher;
7   
8   import java.util.Optional;
9   import java.util.concurrent.CompletableFuture;
10  import java.util.concurrent.CompletionStage;
11  
12  import static java.util.Objects.requireNonNull;
13  
14  /**
15   * Matcher for {@link CompletionStage}
16   *
17   * @param <T> the type of the result
18   */
19  public class CompletionStageSuccessful<T> extends TypeSafeMatcher<CompletionStage<T>> {
20      private final Optional<Matcher<T>> valueMatcher;
21  
22      public CompletionStageSuccessful(Optional<Matcher<T>> valueMatcher) {
23          this.valueMatcher = requireNonNull(valueMatcher);
24      }
25  
26      @Override
27      protected boolean matchesSafely(CompletionStage<T> stage) {
28          try {
29              final CompletableFuture<T> future = stage.toCompletableFuture();
30              return !future.isCompletedExceptionally()
31                      && (!valueMatcher.isPresent() || valueMatcher.get().matches(future.get()));
32          } catch (Exception e) {
33              return false;
34          }
35      }
36  
37      @Override
38      public void describeTo(Description description) {
39          if (valueMatcher.isPresent()) {
40              description.appendText("successful result which ");
41              description.appendDescriptionOf(valueMatcher.get());
42          } else {
43              description.appendText("successful result");
44          }
45      }
46  
47      @Override
48      protected void describeMismatchSafely(CompletionStage<T> stage, Description mismatchDescription) {
49          final CompletableFuture<T> future = stage.toCompletableFuture();
50  
51          if (future.isCompletedExceptionally()) {
52              mismatchDescription.appendText("isCompletedExceptionally() is true");
53          } else if (valueMatcher.isPresent()) {
54              try {
55                  mismatchDescription.appendText("result was " + future.get());
56              } catch (Exception e) {
57                  mismatchDescription.appendText("get() throws " + e);
58              }
59          }
60      }
61  
62      @Factory
63      public static <T> Matcher<CompletionStage<T>> successfulWith(Matcher<T> valueMatcher) {
64          return new CompletionStageSuccessful<>(Optional.of(valueMatcher));
65      }
66  
67      @Factory
68      public static <T> Matcher<CompletionStage<T>> successful() {
69          return new CompletionStageSuccessful<>(Optional.empty());
70      }
71  }