File: InvocationExpectationBuilder.java

package info (click to toggle)
jmock2 2.5.1%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 1,296 kB
  • sloc: java: 7,436; xml: 541; sh: 122; makefile: 24; ansic: 9
file content (138 lines) | stat: -rw-r--r-- 4,596 bytes parent folder | download
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();
    }
}