@@ -55,25 +55,7 @@ func JSONKeyTypeEqual(wantKey string, wantType gjson.Type) JSON {
55
55
}
56
56
}
57
57
58
- // JSONCheckOff returns a matcher which will loop over `wantKey` and ensure that the items
59
- // (which can be array elements or object keys)
60
- // are present exactly once in any order in `wantItems`. If there are unexpected items or items
61
- // appear more than once then the match fails. This matcher can be used to check off items in
62
- // an array/object. The `mapper` function should map the item to an interface which will be
63
- // comparable via `reflect.DeepEqual` with items in `wantItems`. The optional `fn` callback
64
- // allows more checks to be performed other than checking off the item from the list. It is
65
- // called with 2 args: the result of the `mapper` function and the element itself (or value if
66
- // it's an object).
67
- //
68
- // Usage: (ensures `events` has these events in any order, with the right event type)
69
- // JSONCheckOff("events", []interface{}{"$foo:bar", "$baz:quuz"}, func(r gjson.Result) interface{} {
70
- // return r.Get("event_id").Str
71
- // }, func(eventID interface{}, eventBody gjson.Result) error {
72
- // if eventBody.Get("type").Str != "m.room.message" {
73
- // return fmt.Errorf("expected event to be 'm.room.message'")
74
- // }
75
- // })
76
- func JSONCheckOff (wantKey string , wantItems []interface {}, mapper func (gjson.Result ) interface {}, fn func (interface {}, gjson.Result ) error ) JSON {
58
+ func jsonCheckOffInternal (wantKey string , wantItems []interface {}, allowUnwantedItems bool , mapper func (gjson.Result ) interface {}, fn func (interface {}, gjson.Result ) error ) JSON {
77
59
return func (body []byte ) error {
78
60
res := gjson .GetBytes (body , wantKey )
79
61
if ! res .Exists () {
@@ -103,12 +85,15 @@ func JSONCheckOff(wantKey string, wantItems []interface{}, mapper func(gjson.Res
103
85
break
104
86
}
105
87
}
106
- if want == - 1 {
88
+ if ! allowUnwantedItems && want == - 1 {
107
89
err = fmt .Errorf ("JSONCheckOff: unexpected item %s" , item )
108
90
return false
109
91
}
110
- // delete the wanted item
111
- wantItems = append (wantItems [:want ], wantItems [want + 1 :]... )
92
+
93
+ if want != - 1 {
94
+ // delete the wanted item
95
+ wantItems = append (wantItems [:want ], wantItems [want + 1 :]... )
96
+ }
112
97
113
98
// do further checks
114
99
if fn != nil {
@@ -130,6 +115,50 @@ func JSONCheckOff(wantKey string, wantItems []interface{}, mapper func(gjson.Res
130
115
}
131
116
}
132
117
118
+ // JSONCheckOffAllowUnwanted returns a matcher which will loop over `wantKey` and ensure that the items
119
+ // (which can be array elements or object keys)
120
+ // are present exactly once in any order in `wantItems`. Allows unexpected items or items
121
+ // appear that more than once. This matcher can be used to check off items in
122
+ // an array/object. The `mapper` function should map the item to an interface which will be
123
+ // comparable via `reflect.DeepEqual` with items in `wantItems`. The optional `fn` callback
124
+ // allows more checks to be performed other than checking off the item from the list. It is
125
+ // called with 2 args: the result of the `mapper` function and the element itself (or value if
126
+ // it's an object).
127
+ //
128
+ // Usage: (ensures `events` has these events in any order, with the right event type)
129
+ // JSONCheckOffAllowUnwanted("events", []interface{}{"$foo:bar", "$baz:quuz"}, func(r gjson.Result) interface{} {
130
+ // return r.Get("event_id").Str
131
+ // }, func(eventID interface{}, eventBody gjson.Result) error {
132
+ // if eventBody.Get("type").Str != "m.room.message" {
133
+ // return fmt.Errorf("expected event to be 'm.room.message'")
134
+ // }
135
+ // })
136
+ func JSONCheckOffAllowUnwanted (wantKey string , wantItems []interface {}, mapper func (gjson.Result ) interface {}, fn func (interface {}, gjson.Result ) error ) JSON {
137
+ return jsonCheckOffInternal (wantKey , wantItems , true , mapper , fn )
138
+ }
139
+
140
+ // JSONCheckOff returns a matcher which will loop over `wantKey` and ensure that the items
141
+ // (which can be array elements or object keys)
142
+ // are present exactly once in any order in `wantItems`. If there are unexpected items or items
143
+ // appear more than once then the match fails. This matcher can be used to check off items in
144
+ // an array/object. The `mapper` function should map the item to an interface which will be
145
+ // comparable via `reflect.DeepEqual` with items in `wantItems`. The optional `fn` callback
146
+ // allows more checks to be performed other than checking off the item from the list. It is
147
+ // called with 2 args: the result of the `mapper` function and the element itself (or value if
148
+ // it's an object).
149
+ //
150
+ // Usage: (ensures `events` has these events in any order, with the right event type)
151
+ // JSONCheckOff("events", []interface{}{"$foo:bar", "$baz:quuz"}, func(r gjson.Result) interface{} {
152
+ // return r.Get("event_id").Str
153
+ // }, func(eventID interface{}, eventBody gjson.Result) error {
154
+ // if eventBody.Get("type").Str != "m.room.message" {
155
+ // return fmt.Errorf("expected event to be 'm.room.message'")
156
+ // }
157
+ // })
158
+ func JSONCheckOff (wantKey string , wantItems []interface {}, mapper func (gjson.Result ) interface {}, fn func (interface {}, gjson.Result ) error ) JSON {
159
+ return jsonCheckOffInternal (wantKey , wantItems , false , mapper , fn )
160
+ }
161
+
133
162
// JSONArrayEach returns a matcher which will check that `wantKey` is an array then loops over each
134
163
// item calling `fn`. If `fn` returns an error, iterating stops and an error is returned.
135
164
func JSONArrayEach (wantKey string , fn func (gjson.Result ) error ) JSON {
0 commit comments