MatcherGenericTypeExtractorTest.java revision 2637d96c202372854a7c71466ddcc6e90fc4fc53
1package org.mockito.internal.hamcrest;
2
3import org.hamcrest.BaseMatcher;
4import org.hamcrest.Description;
5import org.hamcrest.Matcher;
6import org.junit.Test;
7import org.mockitoutil.TestBase;
8
9import java.io.Serializable;
10import java.util.HashMap;
11
12import static junit.framework.TestCase.assertEquals;
13import static org.mockito.internal.hamcrest.MatcherGenericTypeExtractor.genericTypeOfMatcher;
14
15public class MatcherGenericTypeExtractorTest extends TestBase {
16
17    //traditional inner class for matcher
18    private class IntMatcher extends BaseMatcher<Integer> {
19        public boolean matches(Object o) {
20            return true;
21        }
22        public void describeTo(Description description) {}
23    }
24
25    //static class with matcher
26    private static class StaticIntMatcher extends BaseMatcher<Integer> {
27        public boolean matches(Object o) {
28            return true;
29        }
30        public void describeTo(Description description) {}
31    }
32
33    //static subclass
34    private static class StaticIntMatcherSubclass extends StaticIntMatcher {
35        public boolean matches(Object o) {
36            return true;
37        }
38        public void describeTo(Description description) {}
39    }
40
41    //non-generic
42    @SuppressWarnings("rawtypes")
43    private static class NonGenericMatcher extends BaseMatcher {
44        public boolean matches(Object o) {
45            return true;
46        }
47        public void describeTo(Description description) {}
48    }
49
50    //Matcher interface implementation (instead of the BaseMatcher)
51    private class IntMatcherFromInterface extends BaseMatcher<Integer> {
52        public boolean matches(Object o) {
53            return true;
54        }
55        public void describeMismatch(Object item, Description mismatchDescription) {}
56        public void describeTo(Description description) {}
57    }
58
59    //Static Matcher interface implementation (instead of the BaseMatcher)
60    private static class StaticIntMatcherFromInterface extends BaseMatcher<Integer> {
61        public boolean matches(Object o) {
62            return true;
63        }
64        public void describeMismatch(Object item, Description mismatchDescription) {}
65        public void describeTo(Description description) {}
66    }
67
68    //non-generic matcher implementing the interface
69    @SuppressWarnings("rawtypes")
70    private static class NonGenericMatcherFromInterface extends BaseMatcher {
71        public boolean matches(Object o) {
72            return true;
73        }
74        public void describeMismatch(Object item, Description mismatchDescription) {}
75        public void describeTo(Description description) {}
76    }
77
78    private interface IMatcher extends Matcher<Integer> {}
79
80    //non-generic matcher implementing the interface
81    private static class SubclassGenericMatcherFromInterface extends BaseMatcher<Integer> implements Serializable, Cloneable, IMatcher {
82        public boolean matches(Object o) {
83            return true;
84        }
85        public void describeMismatch(Object item, Description mismatchDescription) {}
86        public void describeTo(Description description) {}
87    }
88
89    //I refuse to comment on the sanity of this case
90    private static class InsaneEdgeCase extends SubclassGenericMatcherFromInterface {}
91
92    @Test
93    public void findsGenericType() {
94        assertEquals(Integer.class, genericTypeOfMatcher(IntMatcher.class));
95        assertEquals(Integer.class, genericTypeOfMatcher(StaticIntMatcher.class));
96        assertEquals(Integer.class, genericTypeOfMatcher(IntMatcherFromInterface.class));
97        assertEquals(Integer.class, genericTypeOfMatcher(StaticIntMatcherSubclass.class));
98        assertEquals(Integer.class, genericTypeOfMatcher(IntMatcherFromInterface.class));
99        assertEquals(Integer.class, genericTypeOfMatcher(StaticIntMatcherFromInterface.class));
100        assertEquals(Integer.class, genericTypeOfMatcher(SubclassGenericMatcherFromInterface.class));
101        assertEquals(Integer.class, genericTypeOfMatcher(InsaneEdgeCase.class));
102
103        assertEquals(Integer.class, genericTypeOfMatcher(new BaseMatcher<Integer>() {
104            public void describeTo(Description description) {
105            }
106
107            public boolean matches(Object o) {
108                return false;
109            }
110        }.getClass()));
111        assertEquals(Integer.class, genericTypeOfMatcher(new BaseMatcher<Integer>() {
112            public void describeTo(Description description) {
113            }
114
115            public boolean matches(Object o) {
116                return false;
117            }
118
119            public void describeMismatch(Object item, Description mismatchDescription) {
120            }
121        }.getClass()));
122
123        assertEquals(Object.class, genericTypeOfMatcher(Object.class));
124        assertEquals(Object.class, genericTypeOfMatcher(String.class));
125        assertEquals(Object.class, genericTypeOfMatcher(HashMap.class));
126        assertEquals(Object.class, genericTypeOfMatcher(new HashMap<String, String>() {
127        }.getClass()));
128        assertEquals(Object.class, genericTypeOfMatcher(NonGenericMatcher.class));
129        assertEquals(Object.class, genericTypeOfMatcher(NonGenericMatcherFromInterface.class));
130    }
131}
132