-
Notifications
You must be signed in to change notification settings - Fork 7
/
called_with_matcher.go
115 lines (94 loc) · 3.65 KB
/
called_with_matcher.go
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
package matchers
import (
"fmt"
"github.com/derision-test/go-mockgen/internal/testutil"
"github.com/onsi/gomega/format"
"github.com/onsi/gomega/matchers"
"github.com/onsi/gomega/types"
)
type calledWithMatcher struct {
name string
args []interface{}
}
var _ types.GomegaMatcher = &calledWithMatcher{}
// BeCalledWith constructs a matcher that asserts the mock function object was called at least once
// with a set of arguments matching the given values. The values can be another matcher or a literal
// value. In the latter case, the values will be checked for equality.
func BeCalledWith(args ...interface{}) types.GomegaMatcher {
return &calledWithMatcher{
name: "BeCalledWith",
args: args,
}
}
func (m *calledWithMatcher) Match(actual interface{}) (bool, error) {
matchingHistory, ok := getCallHistoryWith(actual, m.args...)
if !ok {
return false, fmt.Errorf("%s expects a mock function description. Got:\n%s", m.name, format.Object(actual, 1))
}
return len(matchingHistory) > 0, nil
}
func (m *calledWithMatcher) FailureMessage(actual interface{}) string {
return format.Message(actual, "to contain at least one call with argument list matching", m.args)
}
func (m *calledWithMatcher) NegatedFailureMessage(actual interface{}) string {
return format.Message(actual, "not to contain at least one call with argument list matching", m.args)
}
// BeCalledOnceWith constructs a matcher that asserts the mock function object was called exactly once
// with a set of arguments matching the given values. The values can be another matcher or a literal
// value. In the latter case, the values will be checked for equality.
func BeCalledOnceWith(args ...interface{}) types.GomegaMatcher {
return &calledNWithMatcher{
name: "BeCalledOnceWith",
n: 1,
args: args,
}
}
type calledNWithMatcher struct {
name string
n int
args []interface{}
}
var _ types.GomegaMatcher = &calledNWithMatcher{}
// BeCalledNWith constructs a matcher that asserts the mock function object was called exactly n times
// with a set of arguments matching the given values. The values can be another matcher or a literal
// value. In the latter case, the values will be checked for equality.
func BeCalledNWith(n int, args ...interface{}) types.GomegaMatcher {
return &calledNWithMatcher{
name: "BeCalledNWith",
n: n,
args: args,
}
}
func (m *calledNWithMatcher) Match(actual interface{}) (bool, error) {
matchingHistory, ok := getCallHistoryWith(actual, m.args...)
if !ok {
return false, fmt.Errorf("%s expects a mock function description. Got:\n%s", m.name, format.Object(actual, 1))
}
return len(matchingHistory) == m.n, nil
}
func (m *calledNWithMatcher) FailureMessage(actual interface{}) string {
return format.Message(actual, "to contain one call with argument list matching", m.args)
}
func (m *calledNWithMatcher) NegatedFailureMessage(actual interface{}) string {
return format.Message(actual, "not to contain one call with argument list matching", m.args)
}
// getCallHistoryWith returns the set of call instances matching the given values. The values can
// be another matcher or a literal value. In the latter case, the values will be checked for equality.
func getCallHistoryWith(actual interface{}, args ...interface{}) ([]testutil.CallInstance, bool) {
return testutil.GetCallHistoryWith(actual, func(v testutil.CallInstance) bool {
if len(args) > len(v.Args()) {
return false
}
for i, expectedArg := range args {
matcher, ok := expectedArg.(types.GomegaMatcher)
if !ok {
matcher = &matchers.EqualMatcher{Expected: expectedArg}
}
success, err := matcher.Match(v.Args()[i])
if err != nil || !success {
return false
}
}
return true
})
}