forked from karatelabs/karate
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathschema-like.feature
185 lines (141 loc) · 4.99 KB
/
schema-like.feature
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
Feature: json-schema like validation
Scenario: but simpler and more powerful
* def response = read('odds.json')
# here we enclose in round-brackets to preserve the optional embedded expression
# so that it can be used later in a "match"
* def oddSchema = ({ price: '#string', status: '#? _ < 3', ck: '##number', name: '#regex[0-9X]' })
* def isValidTime = read('time-validator.js')
Then match response ==
"""
{
id: '#regex[0-9]+',
count: '#number',
odd: '#(oddSchema)',
data: {
countryId: '#number',
countryName: '#string',
leagueName: '##string',
status: '#number? _ >= 0',
sportName: '#string',
time: '#? isValidTime(_)'
},
odds: '#[] oddSchema'
}
"""
# other examples
# should be an array
* match $.odds == '#[]'
# should be an array of size 4
* match $.odds == '#[4]'
# optionally present (or null) and should be an array of size greater than zero
* match $.odds == '##[_ > 0]'
# should be an array of size equal to $.count
* match $ contains { odds: '#[$.count]' }
# use a predicate function to validate each array element
* def isValidOdd = function(o){ return o.name.length == 1 }
* match $.odds == '#[]? isValidOdd(_)'
# for simple arrays, types can be 'in-line'
* def foo = ['bar', 'baz']
# should be an array
* match foo == '#[]'
# should be an array of size 2
* match foo == '#[2]'
# should be an array of strings with size 2
* match foo == '#[2] #string'
# each item of the array should be of length 3
* match foo == '#[]? _.length == 3'
# should be an array of strings each of length 3
* match foo == '#[] #string? _.length == 3'
# should be null or an array of strings
* match foo == '##[] #string'
# each item of the array should match regex (with backslash involved)
* match foo == '#[] #regex \\w+'
# contains
* def actual = [{ a: 1, b: 'x' }, { a: 2, b: 'y' }]
* def schema = { a: '#number', b: '#string' }
* def partSchema = { a: '#number' }
* def badSchema = { c: '#boolean' }
* def mixSchema = { a: '#number', c: '#boolean' }
* def shuffled = [{ a: 2, b: 'y' }, { b: 'x', a: 1 }]
* def first = { a: 1, b: 'x' }
* def part = { a: 1 }
* def mix = { b: 'y', c: true }
* def other = [{ a: 3, b: 'u' }, { a: 4, b: 'v' }]
* def some = [{ a: 1, b: 'x' }, { a: 5, b: 'w' }]
* match actual[0] == schema
* match actual[0] == '#(schema)'
* match actual[0] contains partSchema
* match actual[0] == '#(^partSchema)'
* match actual[0] contains any mixSchema
* match actual[0] == '#(^*mixSchema)'
* match actual[0] !contains badSchema
* match actual[0] == '#(!^badSchema)'
* match each actual == schema
* match actual == '#[] schema'
* match each actual contains partSchema
* match actual == '#[] ^partSchema'
* match each actual contains any mixSchema
* match actual == '#[] ^*mixSchema'
* match each actual !contains badSchema
* match actual == '#[] !^badSchema'
* match actual contains only shuffled
* match actual == '#(^^shuffled)'
* match actual contains first
* match actual == '#(^first)'
* match actual contains any some
* match actual == '#(^*some)'
* match actual !contains other
* match actual == '#(!^other)'
* match actual contains deep part
* match actual == '#(^+part)'
# no in-line equivalent !
* match actual contains '#(^part)'
# no in-line equivalent !
* match actual contains '#(^*mix)'
* assert actual.length == 2
* match actual == '#[2]'
# contains deep
* def actualDeep = [{ a: [1, 2], b: 'x' }, { a: [3, 4], b: 'y' }]
* def partDeep = { a: [1] }
* match actual contains deep part
Scenario: complex nested arrays
* def json =
"""
{
"foo": {
"bars": [
{ "barOne": "dc", "barTwos": [] },
{ "barOne": "dc", "barTwos": [{ title: 'blah' }] },
{ "barOne": "dc", "barTwos": [{ title: 'blah' }], barThrees: [] },
{ "barOne": "dc", "barTwos": [{ title: 'blah' }], barThrees: [{ num: 1 }] }
]
}
}
"""
* def barTwo = { title: '#string' }
* def barThree = { num: '#number' }
* def bar = { barOne: '#string', barTwos: '#[] barTwo', barThrees: '##[] barThree' }
* match json.foo.bars == '#[] bar'
Scenario: re-usable json chunks as nodes, but optional
* def dogSchema = { id: '#string', color: '#string' }
# here we enclose in round-brackets to preserve the optional embedded expression
# so that it can be used later in a "match"
* def schema = ({ id: '#string', name: '#string', dog: '##(dogSchema)' })
* def response1 = { id: '123', name: 'foo' }
* match response1 == schema
* def response2 = { id: '123', name: 'foo', dog: { id: '456', color: 'brown' } }
* match response2 == schema
Scenario: pretty print json
* def json = read('odds.json')
* print 'pretty print:\n' + karate.pretty(json)
Scenario: more pretty print
* def myJson = { foo: 'bar', baz: [1, 2, 3]}
* print 'pretty print:\n' + karate.pretty(myJson)
Scenario: various ways of checking that a string ends with a number
* def foo = 'hello1'
* match foo == '#regex hello[0-9]+'
* match foo == '#regex .+[0-9]+'
* match foo contains 'hello'
* assert foo.startsWith('hello')
* def isHello = function(s){ return s.startsWith('hello') && karate.match(s, '#regex .+[0-9]+').pass }
* match foo == '#? isHello(_)'