spaceborne 0.1.36 → 0.1.37

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8aff74d5d3bedfe5854840e95db163e1c1cd71849172d21f01067ec952b29451
4
- data.tar.gz: 6bbc1007251b0c9415d74dd838c5ea9182a9d3063d778f3c15791026a10f4537
3
+ metadata.gz: 8713e4121c4170d47c98acc0c85efbd98bdc8d891f7f977fc792cbeddacc7435
4
+ data.tar.gz: 147f591492eb63348d02e0c88cb19086fd39e8d61851e6d82d86d0f3d45ae62d
5
5
  SHA512:
6
- metadata.gz: 57eefe3812beebd37b2a6e879ce8b518c99fff0cb434779a122dab68b911c7ba355306009421455bac34f02ee1becde5b1bb237908678cf7b6f5d527a7973e75
7
- data.tar.gz: e9bb102e8fe35b2e65046c7bd8e7b25ff60f8bcce8173bf88da60816ea14add4df1019cd62530fd31aefe147966ead18a2675d57afd48af940fb54aaa001c695
6
+ metadata.gz: a29ff847e0b2c67e3d55799b3b933e6d448cc817a6a2e1365b23f0b92a1cb65fc8ece56d6142cb8eaf13baf1e84e090875b17fc641137942669174b78761ce66
7
+ data.tar.gz: 77b947419bc8c04318e0cb07ac47d122844f5e0a3ad1c0ceb993264f4966e99e54b0ca38b974a112dc9d94578b8a29547b0acaa9a09f2083546899d04d5b3276
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 extension # 6 works
211
+ The following example shows how extensions # 6 & 8 work
211
212
 
212
213
  ```ruby
213
214
  { "array_of_hashes": [
214
- { "husband": {"first": "fred", "last": "flinstone"}},
215
- { "buddy": {"first": "barney", "last": "rubble"}},
216
- { "wife": {"first": "wilma", "last": "flinstone"}}
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
- { "husband": {"first": "fred", "last": "flinstone"},
220
- "buddy": {"first": "barney", "last": "rubble"},
221
- "wife": {"first": "wilma", "last": "flinstone"}
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,7 +51,7 @@ module Spaceborne
51
51
  rescue Exception => e
52
52
  raise e unless response
53
53
 
54
- raise RSpec::Expectations::ExpectationNotMetError.new(e.message + request_info)
54
+ raise RSpec::Expectations::ExpectationNotMetError, e.message + request_info
55
55
  end
56
56
  end
57
57
 
@@ -227,44 +227,75 @@ module Airborne
227
227
  end
228
228
 
229
229
  def handle_type(type, path, json, &block)
230
- if type == '*'
230
+ case type
231
+ when '*'
231
232
  handle_container(json, &block)
232
- elsif type == '?'
233
+ when '?'
233
234
  expect_one(path, json, &block)
234
235
  else
235
236
  yield json
236
237
  end
237
238
  end
238
239
 
240
+ def path_to_s(path)
241
+ path.is_a?(Airborne::OptionalHashTypeExpectations) ? path.hash.to_s : path
242
+ end
243
+
244
+ def make_path_optional(path, sub_path)
245
+ if path.is_a?(Airborne::OptionalHashTypeExpectations)
246
+ Airborne::OptionalHashTypeExpectations.new(sub_path)
247
+ else
248
+ sub_path
249
+ end
250
+ end
251
+
239
252
  def iterate_path(path)
240
- raise PathError, "Invalid Path, contains '..'" if /\.\./ =~ path
253
+ raise PathError, "Invalid Path, contains '..'" if /\.\./ =~ path_to_s(path)
241
254
 
242
- parts = path.to_s.split('.')
255
+ parts = path_to_s(path).to_s.split('.')
243
256
  parts.each_with_index do |part, index|
244
- yield(parts, part, index)
257
+ use_part = make_path_optional(path, part)
258
+ yield(parts, use_part, index)
245
259
  end
246
260
  end
247
261
 
248
- def get_by_path(path, json, type = false, &block)
262
+ def get_by_path(path, json, type: false, &block)
249
263
  iterate_path(path) do |parts, part, index|
250
- if %w[* ?].include?(part)
264
+ if %w[* ?].include?(path_to_s(part))
251
265
  ensure_array_or_hash(path, json)
252
266
  type = part
253
267
  walk_with_path(type, index, path, parts, json, &block) && return if index < parts.length.pred
254
268
 
255
269
  next
256
270
  end
257
- json = do_process_json(part, json)
271
+ json = do_process_json(path_to_s(part), json)
258
272
  end
259
273
  handle_type(type, path, json, &block)
260
274
  end
261
275
 
262
276
  def ensure_array_or_hash(path, json)
263
- return if json.class == Array || json.class == Hash
277
+ return if json.instance_of?(Array) || json.instance_of?(Hash)
264
278
 
265
279
  raise RSpec::Expectations::ExpectationNotMetError,
266
280
  "Expected #{path} to be array or hash, got #{json.class}"\
267
281
  ' from JSON response'
268
282
  end
283
+
284
+ def walk_with_path(type, index, path, parts, json, &block)
285
+ last_error = nil
286
+ item_count = json.length
287
+ error_count = 0
288
+ json.each do |element|
289
+ begin
290
+ sub_path = parts[(index.next)...(parts.length)].join('.')
291
+ get_by_path(make_path_optional(path, sub_path), element, &block)
292
+ rescue Exception => e
293
+ last_error = e
294
+ error_count += 1
295
+ end
296
+ ensure_match_all(last_error) if type == '*'
297
+ ensure_match_one(path, item_count, error_count) if type == '?'
298
+ end
299
+ end
269
300
  end
270
301
  end
@@ -1,3 +1,3 @@
1
1
  module Spaceborne
2
- VERSION = '0.1.36'.freeze
2
+ VERSION = '0.1.37'.freeze
3
3
  end
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.36
4
+ version: 0.1.37
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-07-12 00:00:00.000000000 Z
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.8
203
+ rubygems_version: 3.0.9
204
204
  signing_key:
205
205
  specification_version: 4
206
206
  summary: Gem supporting API testing