Skip to content
This repository was archived by the owner on Sep 17, 2022. It is now read-only.

Commit 613f56f

Browse files
committed
added boolean matchers
1 parent fb7a02f commit 613f56f

File tree

6 files changed

+116
-128
lines changed

6 files changed

+116
-128
lines changed

spec/matcher/and_matcher.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package matcher
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/getapid/apid/log"
7+
)
8+
9+
type andMatcher struct {
10+
matchers []Matcher
11+
}
12+
13+
func AndMatcherWithOptions(params interface{}) Matcher {
14+
switch v := params.(type) {
15+
case []interface{}:
16+
var matchers []Matcher
17+
for _, value := range v {
18+
matchers = append(matchers, GetMatcher(value))
19+
}
20+
return &andMatcher{matchers: matchers}
21+
default:
22+
log.L.Fatalf("invalid and matcher values (expected array), got %v", params)
23+
}
24+
return nil
25+
}
26+
27+
func (m andMatcher) Match(data interface{}, location string) (ok bool, pass []string, fail []string) {
28+
for _, matcher := range m.matchers {
29+
_, p, f := matcher.Match(data, location)
30+
pass = append(pass, p...)
31+
fail = append(fail, f...)
32+
}
33+
ok = len(fail) == 0
34+
return
35+
}
36+
37+
func (m andMatcher) String() string {
38+
return fmt.Sprintf("%d", m.matchers)
39+
}

spec/matcher/len_matcher.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ func (m lenMatcher) Match(data interface{}, location string) (bool, []string, []
4545
default:
4646
return false, nil, []string{fmt.Sprintf("`%s` not a map, array or string", location)}
4747
}
48-
4948
}
5049

5150
func (m lenMatcher) String() string {

spec/matcher/matcher.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ func tryGetMatcherFromMap(m map[string]interface{}) Matcher {
5252
return ArrayMatcherWithOptions(params)
5353
case "len":
5454
return LenMatcherWithOptions(params)
55+
case "and":
56+
return AndMatcherWithOptions(params)
57+
case "or":
58+
return OrMatcherWithOptions(params)
5559
default:
5660
log.L.Fatalf("unknown matcher type %s", t)
5761
return nil

spec/matcher/or_matcher.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package matcher
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/getapid/apid/log"
7+
)
8+
9+
type orMatcher struct {
10+
matchers []Matcher
11+
}
12+
13+
func OrMatcherWithOptions(params interface{}) Matcher {
14+
switch v := params.(type) {
15+
case []interface{}:
16+
var matchers []Matcher
17+
for _, value := range v {
18+
matchers = append(matchers, GetMatcher(value))
19+
}
20+
return &orMatcher{matchers: matchers}
21+
default:
22+
log.L.Fatalf("invalid or matcher values (expected array), got %v", params)
23+
}
24+
return nil
25+
}
26+
27+
func (m orMatcher) Match(data interface{}, location string) (ok bool, pass []string, fail []string) {
28+
for _, matcher := range m.matchers {
29+
if pa, p, _ := matcher.Match(data, location); pa {
30+
pass = append(pass, p...)
31+
ok = true
32+
return
33+
}
34+
}
35+
ok = false
36+
fail = append(fail, fmt.Sprintf("`%s` did not meet any criteria %s", location, m.matchers))
37+
return
38+
}
39+
40+
func (m orMatcher) String() string {
41+
return fmt.Sprintf("%d", m.matchers)
42+
}

tests/passing/apid/is.libsonnet

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,18 @@ local len_matcher(len) =
5757
'$$matcher_params$$': len,
5858
};
5959

60+
local and_matcher(matchers) =
61+
{
62+
'$$matcher_type$$': 'and',
63+
'$$matcher_params$$': matchers,
64+
};
65+
66+
local or_matcher(matchers) =
67+
{
68+
'$$matcher_type$$': 'or',
69+
'$$matcher_params$$': matchers,
70+
};
71+
6072
local json_to_string(json) = std.manifestJsonEx(json, '');
6173

6274
{
@@ -66,6 +78,7 @@ local json_to_string(json) = std.manifestJsonEx(json, '');
6678
int(int):: '%s%s' % [SHORTHAND_MATCHER_PREFIX, json_to_string(int_matcher(int))],
6779
float(float):: '%s%s' % [SHORTHAND_MATCHER_PREFIX, json_to_string(float_matcher(float))],
6880
len(len):: '%s%s' % [SHORTHAND_MATCHER_PREFIX, json_to_string(len_matcher(len))],
81+
or(matchers):: '%s%s' % [SHORTHAND_MATCHER_PREFIX, json_to_string(or_matcher(matchers))],
6982
},
7083

7184
any():: any_matcher(),
@@ -76,4 +89,6 @@ local json_to_string(json) = std.manifestJsonEx(json, '');
7689
json(json, subset=false):: json_matcher(json, subset),
7790
array(array, subset=false):: array_matcher(array, subset),
7891
len(len):: len_matcher(len),
92+
and(matchers):: and_matcher(matchers),
93+
or(matchers):: or_matcher(matchers),
7994
}

tests/passing/body_pass.jsonnet

Lines changed: 16 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
local apid = import 'apid/apid.libsonnet';
2-
local is = import 'apid/is.libsonnet';
2+
local _ = import 'apid/is.libsonnet';
33

44
local vars = import 'vars.libsonnet';
55

@@ -38,12 +38,15 @@ local steps(method, body, expected) = [
3838
for body in [vars.json]
3939
for expected in [
4040
{
41-
'random float': is.float(66.861),
42-
[is.key.string('random')]: is.int(88),
43-
[is.key.regex('first\\w+')]: 'Lilith',
44-
Stephanie: {
41+
'random float': _.float(66.861),
42+
[_.key.string('random')]: _.int(88),
43+
[_.key.regex('first\\w+')]: 'Lilith',
44+
[_.key.or([
45+
_.string("Stephanie"),
46+
_.len(9)
47+
])]: {
4548
age: 93,
46-
address: is.json({
49+
address: _.json({
4750
city: 'Kobe',
4851
country: 'Australia',
4952
countryCode: 'VE',
@@ -53,126 +56,12 @@ local steps(method, body, expected) = [
5356
'Marline',
5457
'Catharine',
5558
],
56-
countryCode: is.len(2),
59+
countryCode: _.and(
60+
[
61+
_.len(2),
62+
_.string('VE')
63+
]
64+
)
5765
},
5866
]
59-
}
60-
// + {
61-
// ['string-%s-%s-%s' % [method, 'body', expected]]: json_body_spec(method, body, expected)
62-
// for method in ['POST', 'PUT', 'PATCH', 'DELETE']
63-
// for body in [vars.json]
64-
// for expected in [
65-
// [
66-
// {
67-
// selector: 'firstname',
68-
// is: 'Lilith',
69-
// },
70-
// ],
71-
// ]
72-
// } + {
73-
// ['json-%s-%s-%s' % [method, 'body', expected]]: json_body_spec(method, body, expected)
74-
// for method in ['POST', 'PUT', 'PATCH', 'DELETE']
75-
// for body in [vars.json]
76-
// for expected in [
77-
// [
78-
// {
79-
// selector: 'Stephanie',
80-
// is: {
81-
// age: 93,
82-
// },
83-
// },
84-
// ],
85-
// ]
86-
// } + {
87-
// ['array-%s-%s-%s' % [method, 'body', expected]]: json_body_spec(method, body, expected)
88-
// for method in ['POST', 'PUT', 'PATCH', 'DELETE']
89-
// for body in [vars.json]
90-
// for expected in [
91-
// [
92-
// {
93-
// selector: 'array of objects',
94-
// is: [
95-
// {
96-
// index: 0,
97-
// 'index start at 5': 5,
98-
// },
99-
// {
100-
// index: 1,
101-
// 'index start at 5': 6,
102-
// },
103-
// {
104-
// index: 2,
105-
// 'index start at 5': 7,
106-
// },
107-
// ],
108-
// },
109-
// ],
110-
// ]
111-
// } + {
112-
// ['unordered-array-%s-%s-%s' % [method, 'body', expected]]: json_body_spec(method, body, expected)
113-
// for method in ['POST', 'PUT', 'PATCH', 'DELETE']
114-
// for body in [vars.json]
115-
// for expected in [
116-
// [
117-
// {
118-
// selector: 'array of objects',
119-
// is: [
120-
// {
121-
// index: 2,
122-
// 'index start at 5': 7,
123-
// },
124-
// {
125-
// index: 0,
126-
// 'index start at 5': 5,
127-
// },
128-
// {
129-
// index: 1,
130-
// 'index start at 5': 6,
131-
// },
132-
// ],
133-
// },
134-
// ],
135-
// ]
136-
// } + {
137-
// ['array-index-array-%s-%s-%s' % [method, 'body', expected]]: json_body_spec(method, body, expected)
138-
// for method in ['POST', 'PUT', 'PATCH', 'DELETE']
139-
// for body in [vars.json]
140-
// for expected in [
141-
// [
142-
// {
143-
// selector: 'array of objects.1',
144-
// is: {
145-
// index: 1,
146-
// 'index start at 5': 6,
147-
// },
148-
// },
149-
// ],
150-
// ]
151-
// } + {
152-
// ['regex-simple-%s-%s-%s' % [method, 'body', expected]]: json_body_spec(method, body, expected)
153-
// for method in ['POST', 'PUT', 'PATCH', 'DELETE']
154-
// for body in [vars.json]
155-
// for expected in [
156-
// [
157-
// {
158-
// selector: 'regEx',
159-
// is: 'hello+ to you',
160-
// },
161-
// ],
162-
// ]
163-
// } + {
164-
// ['regex-email-%s-%s-%s' % [method, 'body', expected]]: json_body_spec(method, body, expected)
165-
// for method in ['POST', 'PUT', 'PATCH', 'DELETE']
166-
// for body in [vars.json]
167-
// for expected in [
168-
// [
169-
// {
170-
// selector: 'email uses current data',
171-
// is: '^\\S+@\\S+\\.\\S+$',
172-
// },
173-
// ],
174-
// ]
175-
// }
176-
177-
178-
67+
}

0 commit comments

Comments
 (0)