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