View Javadoc
1   /*
2    * Copyright (c) 2006 JMockit developers
3    * This file is subject to the terms of the MIT license (see LICENSE.txt).
4    */
5   package mockit.internal.expectations.argumentMatching;
6   
7   import edu.umd.cs.findbugs.annotations.NonNull;
8   import edu.umd.cs.findbugs.annotations.Nullable;
9   
10  import mockit.internal.reflection.FieldReflection;
11  
12  import org.hamcrest.Description;
13  import org.hamcrest.Matcher;
14  import org.hamcrest.StringDescription;
15  import org.hamcrest.core.Is;
16  import org.hamcrest.core.IsEqual;
17  import org.hamcrest.core.IsNot;
18  import org.hamcrest.core.IsSame;
19  
20  /**
21   * Adapts the <code>org.hamcrest.Matcher</code> interface to {@link ArgumentMatcher}.
22   */
23  public final class HamcrestAdapter implements ArgumentMatcher<HamcrestAdapter> {
24      @NonNull
25      private final Matcher<?> hamcrestMatcher;
26  
27      public HamcrestAdapter(@NonNull Matcher<?> matcher) {
28          hamcrestMatcher = matcher;
29      }
30  
31      @Override
32      public boolean same(@NonNull HamcrestAdapter other) {
33          return hamcrestMatcher == other.hamcrestMatcher;
34      }
35  
36      @Override
37      public boolean matches(@Nullable Object argValue) {
38          return hamcrestMatcher.matches(argValue);
39      }
40  
41      @Override
42      public void writeMismatchPhrase(@NonNull ArgumentMismatch argumentMismatch) {
43          Description strDescription = new StringDescription();
44          hamcrestMatcher.describeTo(strDescription);
45          argumentMismatch.append(strDescription.toString());
46      }
47  
48      @Nullable
49      public Object getInnerValue() {
50          Object innermostMatcher = getInnermostMatcher();
51          return getArgumentValueFromMatcherIfAvailable(innermostMatcher);
52      }
53  
54      @NonNull
55      private Object getInnermostMatcher() {
56          Matcher<?> innerMatcher = hamcrestMatcher;
57  
58          while (innerMatcher instanceof Is || innerMatcher instanceof IsNot) {
59              innerMatcher = FieldReflection.getField(innerMatcher.getClass(), Matcher.class, innerMatcher);
60          }
61  
62          assert innerMatcher != null;
63          return innerMatcher;
64      }
65  
66      @Nullable
67      private static Object getArgumentValueFromMatcherIfAvailable(@NonNull Object argMatcher) {
68          if (argMatcher instanceof IsEqual || argMatcher instanceof IsSame
69                  || "org.hamcrest.number.OrderingComparison".equals(argMatcher.getClass().getName())) {
70              return FieldReflection.getField(argMatcher.getClass(), Object.class, argMatcher);
71          }
72  
73          return null;
74      }
75  }