1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
package org.jmock.internal;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.hamcrest.Matcher;
import org.jmock.Sequence;
import org.jmock.api.Action;
import org.jmock.api.Expectation;
import org.jmock.api.Invocation;
import org.jmock.internal.matcher.MethodNameMatcher;
import org.jmock.internal.matcher.MockObjectMatcher;
import org.jmock.internal.matcher.AllParametersMatcher;
import org.jmock.syntax.MethodClause;
import org.jmock.syntax.ParametersClause;
import org.jmock.syntax.ReceiverClause;
public class InvocationExpectationBuilder
implements ExpectationCapture,
ReceiverClause, MethodClause, ParametersClause
{
private final InvocationExpectation expectation = new InvocationExpectation();
private boolean isFullySpecified = false;
private boolean needsDefaultAction = true;
private List<Matcher<?>> capturedParameterMatchers = new ArrayList<Matcher<?>>();
public Expectation toExpectation(Action defaultAction) {
if (needsDefaultAction) {
expectation.setAction(defaultAction);
}
return expectation;
}
public void setCardinality(Cardinality cardinality) {
expectation.setCardinality(cardinality);
}
public void addParameterMatcher(Matcher<?> matcher) {
capturedParameterMatchers.add(matcher);
}
public void addOrderingConstraint(OrderingConstraint constraint) {
expectation.addOrderingConstraint(constraint);
}
public void addInSequenceOrderingConstraint(Sequence sequence) {
sequence.constrainAsNextInSequence(expectation);
}
public void setAction(Action action) {
expectation.setAction(action);
needsDefaultAction = false;
}
public void addSideEffect(SideEffect sideEffect) {
expectation.addSideEffect(sideEffect);
}
private <T> T captureExpectedObject(T mockObject) {
if (!(mockObject instanceof CaptureControl)) {
throw new IllegalArgumentException("can only set expectations on mock objects");
}
expectation.setObjectMatcher(new MockObjectMatcher(mockObject));
isFullySpecified = true;
Object capturingImposter = ((CaptureControl)mockObject).captureExpectationTo(this);
return asMockedType(mockObject, capturingImposter);
}
// Damn you Java generics! Damn you to HELL!
@SuppressWarnings("unchecked")
private <T> T asMockedType(@SuppressWarnings("unused") T mockObject,
Object capturingImposter)
{
return (T) capturingImposter;
}
public void createExpectationFrom(Invocation invocation) {
expectation.setMethod(invocation.getInvokedMethod());
if (capturedParameterMatchers.isEmpty()) {
expectation.setParametersMatcher(new AllParametersMatcher(invocation.getParametersAsArray()));
}
else {
checkParameterMatcherCount(invocation);
expectation.setParametersMatcher(new AllParametersMatcher(capturedParameterMatchers));
}
}
private void checkParameterMatcherCount(Invocation invocation) {
if (capturedParameterMatchers.size() != invocation.getParameterCount()) {
throw new IllegalArgumentException("not all parameters were given explicit matchers: either all parameters must be specified by matchers or all must be specified by values, you cannot mix matchers and values");
}
}
public void checkWasFullySpecified() {
if (!isFullySpecified) {
throw new IllegalStateException("expectation was not fully specified");
}
}
/*
* Syntactic sugar
*/
public <T> T of(T mockObject) {
return captureExpectedObject(mockObject);
}
public MethodClause of(Matcher<?> objectMatcher) {
expectation.setObjectMatcher(objectMatcher);
isFullySpecified = true;
return this;
}
public ParametersClause method(Matcher<Method> methodMatcher) {
expectation.setMethodMatcher(methodMatcher);
return this;
}
public ParametersClause method(String nameRegex) {
return method(new MethodNameMatcher(nameRegex));
}
public void with(Matcher<?>... parameterMatchers) {
expectation.setParametersMatcher(new AllParametersMatcher(Arrays.asList(parameterMatchers)));
}
public void withNoArguments() {
with();
}
}
|