1
2
3
4
5
6
7
8
9 package org.opendaylight.lispflowmapping.tools.junit;
10
11 import java.lang.reflect.Field;
12 import java.lang.reflect.InvocationTargetException;
13 import java.lang.reflect.Method;
14 import java.util.ArrayList;
15 import java.util.Arrays;
16 import java.util.HashSet;
17 import java.util.List;
18 import java.util.Set;
19
20 import org.hamcrest.BaseMatcher;
21 import org.hamcrest.Description;
22 import org.hamcrest.Matcher;
23 import org.hamcrest.TypeSafeMatcher;
24 import org.jmock.Expectations;
25 import org.jmock.Mockery;
26 import org.jmock.api.Action;
27 import org.jmock.api.Invocation;
28 import org.jmock.internal.InvocationExpectationBuilder;
29 import org.jmock.internal.ReturnDefaultValueAction;
30 import org.jmock.lib.concurrent.Synchroniser;
31 import org.jmock.lib.legacy.ClassImposteriser;
32 import org.jmock.syntax.ReceiverClause;
33 import org.junit.After;
34 import org.junit.Assert;
35 import org.junit.Before;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 public abstract class BaseExpectations extends Expectations {
40 protected Mockery context;
41 protected boolean showAllExpectations;
42 private final Synchroniser synchroniser = new Synchroniser();
43 protected static final Logger LOG = LoggerFactory.getLogger(BaseExpectations.class);
44
45 @Before
46 public void before() throws Exception {
47 context = new Mockery() {
48 {
49 setImposteriser(ClassImposteriser.INSTANCE);
50 setThreadingPolicy(synchroniser);
51
52 }
53 };
54 defaultAction = new ReturnDefaultValueAction(ClassImposteriser.INSTANCE);
55 }
56
57 @After
58 public void after() throws Exception {
59 context.assertIsSatisfied();
60 }
61
62
63
64 protected final void ret(Object result) {
65 will(returnValue(result));
66 }
67
68 protected final void rethrow(Throwable throwable) {
69 will(throwException(throwable));
70 }
71
72 protected final void retField(Object container, String fieldName) throws Exception {
73 will(new ReturnField(container, fieldName));
74 }
75
76 protected final void rets(Object... results) {
77 will(returnValues(results));
78 }
79
80 protected final <T> T wany(Class<T> type) {
81 return with(any(type));
82 }
83
84 protected final int wanyint() {
85 return with(any(int.class));
86 }
87
88 protected final long wanylong() {
89 return with(any(long.class));
90 }
91
92 protected final boolean wanybool() {
93 return with(any(boolean.class));
94 }
95
96 protected final <T> T wsame(T instance) {
97 return with(same(instance));
98 }
99
100 protected final <T> T weq(T instance) {
101 return with(equal(instance));
102 }
103
104 protected final short weq(short instance) {
105 return with(equal(instance));
106 }
107
108 protected final int weq(int instance) {
109 return with(equal(instance));
110 }
111
112 protected final long weq(long instance) {
113 return with(equal(instance));
114 }
115
116 protected final boolean weq(boolean instance) {
117 return with(equal(instance));
118 }
119
120 public static Action returnValues(Object... result) {
121 return new ActionSequenceValue(result);
122 }
123
124 protected void retMethod(final String methodName) {
125 will(new MethodAction(this, methodName));
126 }
127
128 private static class MethodAction implements Action {
129 private Object testInstance;
130 private String methodName;
131 private Method method;
132
133 public MethodAction(Object testInstance, String methodName) {
134 this.testInstance = testInstance;
135 this.methodName = methodName;
136 method = findMethod(testInstance.getClass());
137 Assert.assertNotNull("Cannot locate '" + methodName + "'", method);
138 }
139
140 private Method findMethod(Class<? extends Object> clazz) {
141 if (Object.class.equals(clazz)) {
142 return null;
143 }
144 try {
145 return clazz.getMethod(methodName, Invocation.class);
146 } catch (SecurityException e) {
147 LOG.debug("Catched SecurityException", e);
148 } catch (NoSuchMethodException e) {
149 LOG.debug("Catched NoSuchMethodException", e);
150 }
151
152 return findMethod(clazz.getSuperclass());
153 }
154
155 public void describeTo(Description arg0) {
156 arg0.appendText("running " + methodName);
157 }
158
159 public Object invoke(Invocation invocation) throws Throwable {
160 Exception e = null;
161 try {
162 return method.invoke(testInstance, invocation);
163 } catch (SecurityException se) {
164 e = se;
165 } catch (IllegalAccessException iae) {
166 e = iae;
167 } catch (InvocationTargetException ite) {
168 throw ite.getTargetException();
169 }
170 Assert.fail("Got " + e.getMessage() + " while trying to execute '" + methodName + "'");
171 return null;
172 }
173
174 }
175
176 private static class ActionSequenceValue implements Action {
177 private final Object[] values;
178 private int i = 0;
179
180 public ActionSequenceValue(Object... values) {
181 this.values = values;
182 }
183
184 public Object invoke(Invocation invocation) throws Throwable {
185 if (i < values.length) {
186 return values[i++];
187 }
188 throw new RuntimeException("no morCxtrmExpectationse actions available: " + invocation);
189 }
190
191 public void describeTo(Description description) {
192 description.appendText(", and then ").appendText(Arrays.toString(values));
193 }
194 }
195
196 protected static final class ReturnField implements Action {
197 private final Object container;
198 private final Field field;
199
200 public ReturnField(Object container, String fieldName) throws Exception {
201 this.container = container;
202 field = container.getClass().getDeclaredField(fieldName);
203 field.setAccessible(true);
204 }
205
206 public void describeTo(Description description) {
207 description.appendText("return " + container.getClass().getName() + "." + field.getName());
208 }
209
210 public Object invoke(Invocation invocation) throws Throwable {
211 return field.get(container);
212 }
213 }
214
215 public static class ValueSaverAction<T> extends BaseMatcher<T> implements Action {
216 private final String logMatch;
217 private final boolean logInvocation;
218 public T lastValue;
219 public final List<T> values = new ArrayList<T>();
220
221 public ValueSaverAction() {
222 this(null, false);
223 }
224
225 public ValueSaverAction(String logMatch, boolean logInvocation) {
226 this.logMatch = logMatch;
227 this.logInvocation = logInvocation;
228 }
229
230 @SuppressWarnings("unchecked")
231 public final boolean matches(Object arg) {
232 T value = (T) arg;
233 if (!validate(value)) {
234 return false;
235 }
236 lastValue = transformOnMatch(value);
237 values.add(lastValue);
238 boolean match = match(lastValue);
239 if (match && (logMatch != null)) {
240 LOG.trace("Match: " + logMatch + " " + value);
241 }
242 return match;
243 }
244
245 protected T onMatch(T value) {
246 return value;
247 }
248
249 protected boolean match(T lastValue2) {
250 return true;
251 }
252
253 protected boolean validate(T value) {
254 return true;
255 }
256
257 protected T transformOnMatch(T value) {
258 return value;
259 }
260
261 public void describeTo(Description arg0) {
262 }
263
264 public Object invoke(Invocation invocation) throws Throwable {
265 if (logInvocation) {
266 LOG.trace("Invoke: returning " + lastValue);
267 }
268 return lastValue;
269 }
270
271 @Override
272 public String toString() {
273 return "ValueSavers: " + values.toString();
274 }
275 }
276
277 @SafeVarargs
278 protected final static <T> Matcher<T[]> contains(final T... expected) {
279 return new BaseMatcher<T[]>() {
280 @SuppressWarnings("unchecked")
281 public boolean matches(Object actual) {
282 T[] arr = (T[]) actual;
283 if (arr.length != expected.length) {
284 return false;
285 }
286 for (T expectedInstance : expected) {
287 boolean found = false;
288 for (int j = 0; (j < arr.length) && !found; j++) {
289 found = (arr[j] == expectedInstance);
290 }
291 if (!found) {
292 return false;
293 }
294 }
295 return true;
296 }
297
298 public void describeTo(Description arg0) {
299 }
300 };
301 }
302
303 @SafeVarargs
304 protected final static <T> Matcher<T[]> sameArbitraryArray(final T... expectedArr) {
305 return new TypeSafeMatcher<T[]>() {
306 @Override
307 public boolean matchesSafely(T[] actualArr) {
308 Set<T> expected = new HashSet<T>();
309 for (T val : expectedArr) {
310 expected.add(val);
311 }
312 Set<T> actual = new HashSet<T>();
313 actual.addAll(Arrays.asList(actualArr));
314 return actual.equals(expected);
315 }
316
317 public void describeTo(Description description) {
318 description.appendText("Same arbitrary array as " + Arrays.toString(expectedArr));
319 }
320 };
321 }
322
323 @SafeVarargs
324 protected final static <T> Matcher<T[]> doseNotContain(final T... forbiddenValues) {
325 return new TypeSafeMatcher<T[]>() {
326 @Override
327 public boolean matchesSafely(T[] arr) {
328 for (T forbiddenInstance : forbiddenValues) {
329 for (T element : arr) {
330 if (element == forbiddenInstance) {
331 return false;
332 }
333 }
334 }
335 return true;
336 }
337
338 public void describeTo(Description description) {
339 }
340 };
341 }
342
343 public class StringArrayMatcher extends BaseMatcher<String[]> {
344 private final Object[] expected;
345
346
347
348
349
350 private StringArrayMatcher(Object... expected) {
351 this.expected = expected;
352 }
353
354 public boolean matches(Object item) {
355 if (!(item instanceof String[])) {
356 return false;
357 }
358 String[] actual = (String[]) item;
359 if (expected.length != actual.length) {
360 return false;
361 }
362 for (int i = 0; i < expected.length; i++) {
363 if ((expected[i] != null) && !expected[i].toString().equals(actual[i])) {
364 return false;
365 }
366 }
367 return true;
368 }
369
370 public void describeTo(Description description) {
371 description.appendText("String" + Arrays.toString(expected));
372 }
373 }
374
375
376
377
378
379 public final String[] wStrArr(Object... expected) {
380 return with(new StringArrayMatcher(expected));
381 }
382
383
384
385
386 private ReturnDefaultValueAction defaultAction;
387
388 protected InvocationExpectationBuilder getCurrentBuilder() {
389 try {
390 return currentBuilder();
391 } catch (IllegalStateException e) {
392 LOG.debug("Catched IllegalStateException", e);
393 return null;
394 }
395 }
396
397 private void addCurrentExpectation() {
398 context.addExpectation(currentBuilder().toExpectation(defaultAction));
399 }
400
401 @Override
402 public ReceiverClause exactly(int count) {
403 ReceiverClause ret = super.exactly(count);
404 addCurrentExpectation();
405 return ret;
406 }
407
408 @Override
409 public ReceiverClause atLeast(int count) {
410 ReceiverClause ret = super.atLeast(count);
411 addCurrentExpectation();
412 return ret;
413 }
414
415 @Override
416 public ReceiverClause between(int minCount, int maxCount) {
417 ReceiverClause ret = super.between(minCount, maxCount);
418 addCurrentExpectation();
419 return ret;
420 }
421
422 @Override
423 public ReceiverClause atMost(int count) {
424 ReceiverClause ret = super.atMost(count);
425 addCurrentExpectation();
426 return ret;
427 }
428
429 }