@@ -24,114 +24,139 @@ const (
24
24
var timeExample = time .Date (2000 , 2 , 1 , 12 , 30 , 0 , 0 , time .UTC )
25
25
26
26
type eachLike struct {
27
- Type string `json:"json_class"`
28
27
Contents interface {} `json:"contents"`
28
+ Type string `json:"json_class"`
29
29
Min int `json:"min"`
30
30
}
31
31
32
+ func (m eachLike ) GetValue () interface {} {
33
+ return m .Contents
34
+ }
35
+
36
+ func (m eachLike ) isMatcher () {
37
+ }
38
+
32
39
type like struct {
33
- Type string `json:"json_class"`
34
40
Contents interface {} `json:"contents"`
41
+ Type string `json:"json_class"`
42
+ }
43
+
44
+ func (m like ) GetValue () interface {} {
45
+ return m .Contents
46
+ }
47
+
48
+ func (m like ) isMatcher () {
35
49
}
36
50
37
51
type term struct {
38
- Type string `json:"json_class"`
39
- Data struct {
40
- Generate interface {} `json:"generate"`
41
- Matcher struct {
42
- Type string `json:"json_class"`
43
- O int `json:"o"`
44
- Regex interface {} `json:"s"`
45
- } `json:"matcher"`
46
- } `json:"data"`
52
+ Data termData `json:"data"`
53
+ Type string `json:"json_class"`
54
+ }
55
+
56
+ func (m term ) GetValue () interface {} {
57
+ return m .Data .Generate
58
+ }
59
+
60
+ func (m term ) isMatcher () {
61
+ }
62
+
63
+ type termData struct {
64
+ Generate interface {} `json:"generate"`
65
+ Matcher termMatcher `json:"matcher"`
66
+ }
67
+
68
+ type termMatcher struct {
69
+ Type string `json:"json_class"`
70
+ O int `json:"o"`
71
+ Regex interface {} `json:"s"`
47
72
}
48
73
49
74
// EachLike specifies that a given element in a JSON body can be repeated
50
75
// "minRequired" times. Number needs to be 1 or greater
51
- func EachLike (content interface {}, minRequired int ) Matcher {
52
- return Matcher {
53
- "json_class" : "Pact::ArrayLike" ,
54
- "contents" : content ,
55
- "min" : minRequired ,
76
+ func EachLike (content interface {}, minRequired int ) StringMatcher {
77
+ return eachLike {
78
+ Type : "Pact::ArrayLike" ,
79
+ Contents : content ,
80
+ Min : minRequired ,
56
81
}
57
82
}
58
83
59
84
// Like specifies that the given content type should be matched based
60
85
// on type (int, string etc.) instead of a verbatim match.
61
- func Like (content interface {}) Matcher {
62
- return Matcher {
63
- "json_class" : "Pact::SomethingLike" ,
64
- "contents" : content ,
86
+ func Like (content interface {}) StringMatcher {
87
+ return like {
88
+ Type : "Pact::SomethingLike" ,
89
+ Contents : content ,
65
90
}
66
91
}
67
92
68
93
// Term specifies that the matching should generate a value
69
94
// and also match using a regular expression.
70
- func Term (generate string , matcher string ) Matcher {
71
- return Matcher {
72
- "json_class" : "Pact::Term" ,
73
- "data" : map [ string ] interface {} {
74
- "generate" : generate ,
75
- "matcher" : map [ string ] interface {} {
76
- "json_class" : "Regexp" ,
77
- "o" : 0 ,
78
- "s" : matcher ,
95
+ func Term (generate string , matcher string ) StringMatcher {
96
+ return term {
97
+ Type : "Pact::Term" ,
98
+ Data : termData {
99
+ Generate : generate ,
100
+ Matcher : termMatcher {
101
+ Type : "Regexp" ,
102
+ O : 0 ,
103
+ Regex : matcher ,
79
104
},
80
105
},
81
106
}
82
107
}
83
108
84
109
// HexValue defines a matcher that accepts hexidecimal values.
85
- func HexValue () Matcher {
110
+ func HexValue () StringMatcher {
86
111
return Regex ("3F" , hexadecimal )
87
112
}
88
113
89
114
// Identifier defines a matcher that accepts integer values.
90
- func Identifier () Matcher {
115
+ func Identifier () StringMatcher {
91
116
return Like (42 )
92
117
}
93
118
94
119
// Integer defines a matcher that accepts ints. Identical to Identifier.
95
120
var Integer = Identifier
96
121
97
122
// IPAddress defines a matcher that accepts valid IPv4 addresses.
98
- func IPAddress () Matcher {
123
+ func IPAddress () StringMatcher {
99
124
return Regex ("127.0.0.1" , ipAddress )
100
125
}
101
126
102
127
// IPv4Address matches valid IPv4 addresses.
103
128
var IPv4Address = IPAddress
104
129
105
130
// IPv6Address defines a matcher that accepts IP addresses.
106
- func IPv6Address () Matcher {
131
+ func IPv6Address () StringMatcher {
107
132
return Regex ("::ffff:192.0.2.128" , ipAddress )
108
133
}
109
134
110
135
// Decimal defines a matcher that accepts any decimal value.
111
- func Decimal () Matcher {
136
+ func Decimal () StringMatcher {
112
137
return Like (42.0 )
113
138
}
114
139
115
140
// Timestamp matches a pattern corresponding to the ISO_DATETIME_FORMAT, which
116
141
// is "yyyy-MM-dd'T'HH:mm:ss". The current date and time is used as the eaxmple.
117
- func Timestamp () Matcher {
142
+ func Timestamp () StringMatcher {
118
143
return Regex (timeExample .Format (time .RFC3339 ), timestamp )
119
144
}
120
145
121
146
// Date matches a pattern corresponding to the ISO_DATE_FORMAT, which
122
147
// is "yyyy-MM-dd". The current date is used as the eaxmple.
123
- func Date () Matcher {
148
+ func Date () StringMatcher {
124
149
return Regex (timeExample .Format ("2006-01-02" ), date )
125
150
}
126
151
127
152
// Time matches a pattern corresponding to the ISO_DATE_FORMAT, which
128
153
// is "'T'HH:mm:ss". The current tem is used as the eaxmple.
129
- func Time () Matcher {
154
+ func Time () StringMatcher {
130
155
return Regex (timeExample .Format ("T15:04:05" ), timeRegex )
131
156
}
132
157
133
158
// UUID defines a matcher that accepts UUIDs. Produces a v4 UUID as the example.
134
- func UUID () Matcher {
159
+ func UUID () StringMatcher {
135
160
return Regex ("fc763eba-0905-41c5-a27f-3934ab26786c" , uuid )
136
161
}
137
162
@@ -187,20 +212,6 @@ func (m Matcher) isMatcher() {}
187
212
// GetValue returns the raw generated value for the matcher
188
213
// without any of the matching detail context
189
214
func (m Matcher ) GetValue () interface {} {
190
- switch m ["json_class" ] {
191
- default :
192
- return nil
193
- case "Pact::ArrayLike" :
194
- return m ["contents" ]
195
- case "Pact::SomethingLike" :
196
- return m ["contents" ]
197
- case "Pact::Term" :
198
- data , ok := m ["data" ].(map [string ]interface {})
199
- if ok {
200
- return data ["generate" ]
201
- }
202
- }
203
-
204
215
return nil
205
216
}
206
217
@@ -233,20 +244,20 @@ func objectToString(obj interface{}) string {
233
244
// Supported Tag Formats
234
245
// Minimum Slice Size: `pact:"min=2"`
235
246
// String RegEx: `pact:"example=2000-01-01,regex=^\\d{4}-\\d{2}-\\d{2}$"`
236
- func Match (src interface {}) Matcher {
247
+ func Match (src interface {}) StringMatcher {
237
248
return match (reflect .TypeOf (src ), getDefaults ())
238
249
}
239
250
240
251
// match recursively traverses the provided type and outputs a
241
252
// matcher string for it that is compatible with the Pact dsl.
242
- func match (srcType reflect.Type , params params ) Matcher {
253
+ func match (srcType reflect.Type , params params ) StringMatcher {
243
254
switch kind := srcType .Kind (); kind {
244
255
case reflect .Ptr :
245
256
return match (srcType .Elem (), params )
246
257
case reflect .Slice , reflect .Array :
247
258
return EachLike (match (srcType .Elem (), getDefaults ()), params .slice .min )
248
259
case reflect .Struct :
249
- result := make ( map [ string ] interface {})
260
+ result := Matcher {}
250
261
251
262
for i := 0 ; i < srcType .NumField (); i ++ {
252
263
field := srcType .Field (i )
0 commit comments