spaceborne 0.1.34 → 0.1.38
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +17 -8
- data/lib/spaceborne.rb +60 -17
- data/lib/spaceborne/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d742ea06ad022126a7a61fb008131b02d0f0f1db485d832570b85f845299c655
|
4
|
+
data.tar.gz: d7d452c83c164adebc69df71aef6aa2f12d50375be2e354463f7b7789b07c290
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e16b9d1bc60eabc5257afb91510d4a715bd8ce76acccc820a255a96ad4b19f87732360d98e3dfbfcfd0f53bd2d7524a72868602df29b2bc5fa871a15128e40e
|
7
|
+
data.tar.gz: 0bac75438755e532b9d39c10864d91430d9a7d281f7d89b9ee1d1943ab7951381432fb0e48ccd39bbc95725dafb8db93a99ba4edc9a53eebec3d6c4bc8e15e59
|
data/README.md
CHANGED
@@ -206,26 +206,35 @@ Validation for headers follows the same pattern as above, although nesting of mu
|
|
206
206
|
5. It is possible to use non-json data in a request
|
207
207
|
6. Expectations on a response with an array of hashes with keys that are unknown, but that have a defined structure are supported (using the '*' in a path)
|
208
208
|
7. Responses that have header with Content-Encoding of gzip are gunzip'd in json_body
|
209
|
+
8. For type checks specified in a path containing array(s), you can make the path optional, so that if the data is present it is type checked, but an empty array or element without the array is fine
|
209
210
|
|
210
|
-
The following example shows how
|
211
|
+
The following example shows how extensions # 6 & 8 work
|
211
212
|
|
212
213
|
```ruby
|
213
214
|
{ "array_of_hashes": [
|
214
|
-
|
215
|
-
|
216
|
-
|
215
|
+
{ "husband": {"first": "fred", "last": "flinstone"}},
|
216
|
+
{ "buddy": {"first": "barney", "last": "rubble"}},
|
217
|
+
{ "wife": {"first": "wilma", "last": "flinstone"}}
|
217
218
|
],
|
218
219
|
"hash_of_hashes":
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
}
|
220
|
+
{ "husband": {"first": "fred", "last": "flinstone"},
|
221
|
+
"buddy": {"first": "barney", "last": "rubble"},
|
222
|
+
"wife": {"first": "wilma", "last": "flinstone"}
|
223
|
+
},
|
224
|
+
"lowest_array": [{ "array": [{ "present": "name" }]},
|
225
|
+
{ "array": null },
|
226
|
+
{ "array": [] },
|
227
|
+
{ "foo": "bar" }],
|
228
|
+
"highest_array": [ null,
|
229
|
+
{ "array": [{ "present": "name" }]}]
|
223
230
|
}
|
224
231
|
```
|
225
232
|
You can now validate the fact that each element in the collection has a key which is variant, but a value that has a defined format (the first and last field values are strings).
|
226
233
|
|
227
234
|
expect_json_types('array_of_hashes.*.*', first: :string, last: :string)
|
228
235
|
expect_json_types('hash_of_hashes.*', first: :string, last: :string)
|
236
|
+
expect_json_types(optional('lowest_array.*.array.*'), present: :string)
|
237
|
+
expect_json_types(optional('highest_array.*.array.*'), present: :string)
|
229
238
|
|
230
239
|
|
231
240
|
## Development
|
data/lib/spaceborne.rb
CHANGED
@@ -51,8 +51,7 @@ module Spaceborne
|
|
51
51
|
rescue Exception => e
|
52
52
|
raise e unless response
|
53
53
|
|
54
|
-
e.message
|
55
|
-
raise e
|
54
|
+
raise RSpec::Expectations::ExpectationNotMetError, e.message + request_info
|
56
55
|
end
|
57
56
|
end
|
58
57
|
|
@@ -157,6 +156,22 @@ module Airborne
|
|
157
156
|
|
158
157
|
# Extend airborne's expectations
|
159
158
|
module RequestExpectations
|
159
|
+
class OptionalPathExpectations
|
160
|
+
def initialize(string)
|
161
|
+
@string = string
|
162
|
+
end
|
163
|
+
def to_s
|
164
|
+
@string.to_s
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def do_process_json(part, json)
|
169
|
+
json = process_json(part, json)
|
170
|
+
rescue StandardError
|
171
|
+
raise PathError,
|
172
|
+
"Expected #{json.class}\nto be an object with property #{part}"
|
173
|
+
end
|
174
|
+
|
160
175
|
def call_with_relative_path(data, args)
|
161
176
|
if args.length == 2
|
162
177
|
get_by_path(args[0], data) do |json_chunk|
|
@@ -205,17 +220,18 @@ module Airborne
|
|
205
220
|
end
|
206
221
|
end
|
207
222
|
end
|
223
|
+
|
224
|
+
def optional(data)
|
225
|
+
if data.is_a?(Hash)
|
226
|
+
OptionalHashTypeExpectations.new(data)
|
227
|
+
else
|
228
|
+
OptionalPathExpectations.new(data)
|
229
|
+
end
|
230
|
+
end
|
208
231
|
end
|
209
232
|
|
210
233
|
# extension to handle hash value checking
|
211
234
|
module PathMatcher
|
212
|
-
def do_process_json(part, json)
|
213
|
-
json = process_json(part, json)
|
214
|
-
rescue StandardError
|
215
|
-
raise PathError,
|
216
|
-
"Expected #{json.class}\nto be an object with property #{part}"
|
217
|
-
end
|
218
|
-
|
219
235
|
def handle_container(json, &block)
|
220
236
|
case json.class.name
|
221
237
|
when 'Array'
|
@@ -228,44 +244,71 @@ module Airborne
|
|
228
244
|
end
|
229
245
|
|
230
246
|
def handle_type(type, path, json, &block)
|
231
|
-
|
247
|
+
case type
|
248
|
+
when '*'
|
232
249
|
handle_container(json, &block)
|
233
|
-
|
250
|
+
when '?'
|
234
251
|
expect_one(path, json, &block)
|
235
252
|
else
|
236
253
|
yield json
|
237
254
|
end
|
238
255
|
end
|
239
256
|
|
257
|
+
def make_sub_path_optional(path, sub_path)
|
258
|
+
if path.is_a?(Airborne::OptionalPathExpectations)
|
259
|
+
Airborne::OptionalPathExpectations.new(sub_path)
|
260
|
+
else
|
261
|
+
sub_path
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
240
265
|
def iterate_path(path)
|
241
|
-
raise PathError, "Invalid Path, contains '..'" if /\.\./ =~ path
|
266
|
+
raise PathError, "Invalid Path, contains '..'" if /\.\./ =~ path.to_s
|
242
267
|
|
243
268
|
parts = path.to_s.split('.')
|
244
269
|
parts.each_with_index do |part, index|
|
245
|
-
|
270
|
+
use_part = make_sub_path_optional(path, part)
|
271
|
+
yield(parts, use_part, index)
|
246
272
|
end
|
247
273
|
end
|
248
274
|
|
249
|
-
def get_by_path(path, json, type
|
275
|
+
def get_by_path(path, json, type: false, &block)
|
250
276
|
iterate_path(path) do |parts, part, index|
|
251
|
-
if %w[* ?].include?(part)
|
277
|
+
if %w[* ?].include?(part.to_s)
|
252
278
|
ensure_array_or_hash(path, json)
|
253
279
|
type = part
|
254
280
|
walk_with_path(type, index, path, parts, json, &block) && return if index < parts.length.pred
|
255
281
|
|
256
282
|
next
|
257
283
|
end
|
258
|
-
json = do_process_json(part, json)
|
284
|
+
json = do_process_json(part.to_s, json)
|
259
285
|
end
|
260
286
|
handle_type(type, path, json, &block)
|
261
287
|
end
|
262
288
|
|
263
289
|
def ensure_array_or_hash(path, json)
|
264
|
-
return if json.
|
290
|
+
return if json.instance_of?(Array) || json.instance_of?(Hash)
|
265
291
|
|
266
292
|
raise RSpec::Expectations::ExpectationNotMetError,
|
267
293
|
"Expected #{path} to be array or hash, got #{json.class}"\
|
268
294
|
' from JSON response'
|
269
295
|
end
|
296
|
+
|
297
|
+
def walk_with_path(type, index, path, parts, json, &block)
|
298
|
+
last_error = nil
|
299
|
+
item_count = json.length
|
300
|
+
error_count = 0
|
301
|
+
json.each do |element|
|
302
|
+
begin
|
303
|
+
sub_path = parts[(index.next)...(parts.length)].join('.')
|
304
|
+
get_by_path(make_sub_path_optional(path, sub_path), element, &block)
|
305
|
+
rescue Exception => e
|
306
|
+
last_error = e
|
307
|
+
error_count += 1
|
308
|
+
end
|
309
|
+
ensure_match_all(last_error) if type == '*'
|
310
|
+
ensure_match_one(path, item_count, error_count) if type == '?'
|
311
|
+
end
|
312
|
+
end
|
270
313
|
end
|
271
314
|
end
|
data/lib/spaceborne/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spaceborne
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.38
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Keith Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -200,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
200
200
|
- !ruby/object:Gem::Version
|
201
201
|
version: '0'
|
202
202
|
requirements: []
|
203
|
-
rubygems_version: 3.0.
|
203
|
+
rubygems_version: 3.0.9
|
204
204
|
signing_key:
|
205
205
|
specification_version: 4
|
206
206
|
summary: Gem supporting API testing
|