1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.grouplens.grapht.context;
21
22 import org.grouplens.grapht.reflect.MockInjectionPoint;
23 import org.grouplens.grapht.solver.DependencySolver;
24 import org.grouplens.grapht.solver.InjectionContext;
25 import org.grouplens.grapht.reflect.Desire;
26 import org.grouplens.grapht.reflect.Desires;
27 import org.grouplens.grapht.reflect.MockSatisfaction;
28 import org.junit.Test;
29
30 import java.util.ArrayList;
31
32 import static org.hamcrest.CoreMatchers.notNullValue;
33 import static org.hamcrest.CoreMatchers.nullValue;
34 import static org.hamcrest.Matchers.*;
35 import static org.junit.Assert.assertThat;
36
37 public class ContextPatternTest {
38 @Test
39 public void testSingletonChainEmptyContextSuccess() throws Exception {
40
41 assertThat(ContextPattern.empty().append(ContextElements.matchAny()).matches(makeContext()),
42 notNullValue());
43 }
44
45 @Test
46 public void testAnyChainEmptyContextSuccess() throws Exception {
47
48 assertThat(ContextPattern.any().matches(makeContext()),
49 notNullValue());
50 }
51
52 @Test
53 public void testEmptyChainNonEmptyContextFailure() throws Exception {
54 assertThat(ContextPattern.empty().matches(makeContext(A.class)),
55 nullValue());
56 }
57
58 @Test
59 public void testSingleton() {
60
61
62 ContextPattern initial = ContextPattern.empty().append(ContextElements.matchAny());
63 assertThat(initial.append(A.class).matches(makeContext(A.class)),
64 notNullValue());
65
66 assertThat(initial.append(A.class).matches(makeContext(B.class)),
67 nullValue());
68
69 assertThat(initial.append(A.class).matches(makeContext()),
70 nullValue());
71
72 assertThat(initial.append(A.class).matches(makeContext(A.class, B.class)),
73 nullValue());
74
75 assertThat(initial.append(A.class).matches(makeContext(B.class, A.class)),
76 nullValue());
77
78 assertThat(initial.append(A.class).matches(makeContext(B.class, A.class)),
79 nullValue());
80
81 assertThat(initial.append(A.class).matches(makeContext(A.class, A.class)),
82 nullValue());
83 }
84
85 @Test
86 public void testAnyChainNonEmptyContextSuccess() throws Exception {
87 assertThat(ContextPattern.any().matches(makeContext(A.class)),
88 notNullValue());
89 assertThat(ContextPattern.any().matches(makeContext(A.class, B.class)),
90 notNullValue());
91 assertThat(ContextPattern.any().matches(makeContext(A.class, Ap.class)),
92 notNullValue());
93 assertThat(ContextPattern.any().matches(makeContext(A.class, B.class, C.class)),
94 notNullValue());
95 }
96
97 @Test
98 public void testSubsequenceEqualChainContextSuccess() throws Exception {
99
100 assertThat(ContextPattern.subsequence(A.class)
101 .matches(makeContext(A.class)),
102 notNullValue());
103 assertThat(ContextPattern.subsequence(A.class, B.class)
104 .matches(makeContext(A.class, B.class)),
105 notNullValue());
106 assertThat(ContextPattern.subsequence(A.class, B.class, C.class)
107 .matches(makeContext(A.class, B.class, C.class)),
108 notNullValue());
109 }
110
111 @Test
112 public void testSubstringChainSuccess() throws Exception {
113 assertThat(ContextPattern.subsequence(A.class)
114 .matches(makeContext(A.class, B.class, C.class)),
115 notNullValue());
116 assertThat(ContextPattern.subsequence(B.class)
117 .matches(makeContext(A.class, B.class, C.class)),
118 notNullValue());
119 assertThat(ContextPattern.subsequence(C.class)
120 .matches(makeContext(A.class, B.class, C.class)), notNullValue());
121
122 assertThat(ContextPattern.subsequence(A.class, B.class)
123 .matches(makeContext(A.class, B.class, C.class)),
124 notNullValue());
125 assertThat(ContextPattern.subsequence(B.class, C.class)
126 .matches(makeContext(A.class, B.class, C.class)), notNullValue());
127
128 assertThat(ContextPattern.subsequence(B.class, C.class)
129 .matches(makeContext(A.class, B.class, C.class, Ap.class)),
130 notNullValue());
131 }
132
133 @Test
134 public void testSubsequenceChainSuccess() throws Exception {
135 assertThat(ContextPattern.subsequence(A.class, C.class)
136 .matches(makeContext(A.class, B.class, C.class, Ap.class, Bp.class, Cp.class)),
137 notNullValue());
138 assertThat(ContextPattern.subsequence(A.class, Ap.class)
139 .matches(makeContext(A.class, B.class, C.class, Ap.class, Bp.class, Cp.class)),
140 notNullValue());
141 assertThat(ContextPattern.subsequence(A.class, Bp.class)
142 .matches(makeContext(A.class, B.class, C.class, Ap.class, Bp.class, Cp.class)),
143 notNullValue());
144 assertThat(ContextPattern.subsequence(A.class, C.class, Bp.class)
145 .matches(makeContext(A.class, B.class, C.class, Ap.class, Bp.class, Cp.class)),
146 notNullValue());
147 assertThat(ContextPattern.subsequence(A.class, B.class, Ap.class)
148 .matches(makeContext(A.class, B.class, C.class, Ap.class, Bp.class, Cp.class)),
149 notNullValue());
150 assertThat(ContextPattern.subsequence(B.class, Cp.class)
151 .matches(makeContext(A.class, B.class, C.class, Ap.class, Bp.class, Cp.class)),
152 notNullValue());
153 assertThat(ContextPattern.subsequence(A.class, Cp.class)
154 .matches(makeContext(A.class, B.class, C.class, Ap.class, Bp.class, Cp.class)),
155 notNullValue());
156 assertThat(ContextPattern.subsequence(C.class, Ap.class, Bp.class)
157 .matches(makeContext(A.class, B.class, C.class, Ap.class, Bp.class, Cp.class)),
158 notNullValue());
159 }
160
161 @Test
162 public void testMatcherInheritenceSuccess() throws Exception {
163 assertThat(ContextPattern.subsequence(A.class).matches(makeContext(Ap.class)), notNullValue());
164
165 assertThat(ContextPattern.subsequence(A.class, C.class).matches(makeContext(Ap.class, Cp.class)), notNullValue());
166 assertThat(ContextPattern.subsequence(A.class, C.class).matches(makeContext(A.class, Cp.class)), notNullValue());
167 assertThat(ContextPattern.subsequence(A.class, C.class).matches(makeContext(Ap.class, C.class)), notNullValue());
168 }
169
170 @Test
171 public void testNonSubsequenceFail() throws Exception {
172 assertThat(ContextPattern.subsequence(A.class).matches(makeContext(B.class)), nullValue());
173 assertThat(ContextPattern.subsequence(A.class, B.class).matches(makeContext(B.class, A.class)), nullValue());
174 assertThat(ContextPattern.subsequence(B.class, A.class, C.class).matches(makeContext(C.class, B.class, A.class)), nullValue());
175 assertThat(ContextPattern.subsequence(A.class, B.class, C.class).matches(makeContext(C.class, B.class, A.class)), nullValue());
176 }
177
178 @Test
179 public void testSuperstringFail() throws Exception {
180 assertThat(ContextPattern.subsequence(A.class, B.class).matches(makeContext(A.class)), nullValue());
181 assertThat(ContextPattern.subsequence(A.class, B.class, C.class).matches(makeContext(A.class, C.class)), nullValue());
182 assertThat(ContextPattern.subsequence(A.class, B.class, C.class).matches(makeContext(A.class, B.class)), nullValue());
183 }
184
185 @Test
186 public void testTailAnchoredMatch() {
187 ContextMatcher matcher = ContextPattern.any().append(A.class);
188 assertThat(matcher.matches(makeContext()),
189 nullValue());
190 assertThat(matcher.matches(makeContext(A.class)),
191 notNullValue());
192 assertThat(matcher.matches(makeContext(B.class, A.class)),
193 notNullValue());
194 assertThat(matcher.matches(makeContext(A.class, B.class)),
195 nullValue());
196 }
197
198 @Test
199 public void testAnchoredAndUnanchored() {
200 ContextMatcher matcher = ContextPattern.any()
201 .append(A.class)
202 .append(B.class)
203 .appendDotStar();
204 assertThat(matcher.matches(makeContext()),
205 nullValue());
206 assertThat(matcher.matches(makeContext(A.class, B.class)),
207 notNullValue());
208 assertThat(matcher.matches(makeContext(A.class, B.class, C.class)),
209 notNullValue());
210 assertThat(matcher.matches(makeContext(A.class, C.class, B.class)),
211 nullValue());
212 }
213
214 @Test
215 public void testOrderByCloseness() {
216 ContextPattern patA = ContextPattern.subsequence(A.class);
217 ContextPattern patB = ContextPattern.subsequence(B.class);
218 InjectionContext ctx1 = makeContext(A.class, B.class);
219
220 assertThat(patB.matches(ctx1), lessThan(patA.matches(ctx1)));
221
222 assertThat(patA.matches(ctx1),
223 allOf(lessThanOrEqualTo(patA.matches(ctx1)),
224 greaterThanOrEqualTo(patA.matches(ctx1))));
225 }
226
227 @Test
228 public void testOrderByLength() {
229 ContextPattern patShort = ContextPattern.subsequence(B.class);
230 ContextPattern patLong = ContextPattern.subsequence(A.class, B.class);
231 InjectionContext ctx1 = makeContext(A.class, B.class);
232
233 assertThat(patLong.matches(ctx1), lessThan(patShort.matches(ctx1)));
234
235 assertThat(patLong.matches(ctx1),
236 allOf(lessThanOrEqualTo(patLong.matches(ctx1)),
237 greaterThanOrEqualTo(patLong.matches(ctx1))));
238 }
239
240 @Test
241 public void testOrderByLengthAfterCloseness() {
242 ContextPattern patClose = ContextPattern.subsequence(C.class);
243 ContextPattern patFar = ContextPattern.subsequence(A.class, B.class);
244 InjectionContext ctx1 = makeContext(A.class, B.class, C.class);
245
246 assertThat(patClose.matches(ctx1), lessThan(patFar.matches(ctx1)));
247 }
248
249 @Test
250 public void testOrderByType() {
251 ContextPattern patStrict = ContextPattern.subsequence(Ap.class);
252 ContextPattern patLoose = ContextPattern.subsequence(A.class);
253 InjectionContext ctx1 = makeContext(Ap.class);
254
255 assertThat(patStrict.matches(ctx1),
256 lessThan(patLoose.matches(ctx1)));
257 }
258
259 @Test
260 public void testOrderByTypeLast() {
261 ContextPattern patStrict = ContextPattern.subsequence(Bp.class);
262 ContextPattern patLong = ContextPattern.subsequence(A.class, B.class);
263 InjectionContext ctx1 = makeContext(A.class, Bp.class);
264
265 assertThat(patLong.matches(ctx1),
266 lessThan(patStrict.matches(ctx1)));
267 }
268
269 @Test
270 public void testOrderSubsequenceBeforeOther() {
271 ContextPattern patAny = ContextPattern.any();
272 ContextPattern patLimited = ContextPattern.subsequence(B.class);
273 InjectionContext ctx1 = makeContext(A.class, B.class);
274
275 assertThat(patLimited.matches(ctx1), lessThan(patAny.matches(ctx1)));
276 }
277
278 private InjectionContext makeContext(Class<?>... types) {
279 InjectionContext context = DependencySolver.initialContext();
280 for (Class<?> type: types) {
281 MockSatisfaction sat = new MockSatisfaction(type, new ArrayList<Desire>());
282 context = context.extend(sat, new MockInjectionPoint(type, null, false));
283 }
284 return context;
285 }
286
287 private static class A {}
288 private static class B {}
289 private static class C {}
290
291 private static class Ap extends A {}
292 private static class Bp extends B {}
293 private static class Cp extends C {}
294 }