spaceborne 0.1.33 → 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: f58273cad226d88a4d39c7065f1c1628990f779024ca7e4c4a5456b8381c033d
4
- data.tar.gz: 19eae317b4a2cd4a69a14b5e2afe8f721c08728ead59ff6a6cba732c4722afbd
3
+ metadata.gz: 8713e4121c4170d47c98acc0c85efbd98bdc8d891f7f977fc792cbeddacc7435
4
+ data.tar.gz: 147f591492eb63348d02e0c88cb19086fd39e8d61851e6d82d86d0f3d45ae62d
5
5
  SHA512:
6
- metadata.gz: 41c07d21fdd9bad257bff28db8c911e3339846e1691cf72ebeedb26d0ab1afd3253a731d7d847af00f9b32a15b7cf4f8e6bda9eab5271c8a32388858e9858333
7
- data.tar.gz: e60a31d5d9ad75915c4ef6d31615b96e8ca45c22b40dd0eb3ad77c7f91fcf4163a6f95c1ce4abff8c98b35b717d978c6d968223a7200368849b84cef28a2e2a8
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
@@ -26,7 +26,7 @@ module Spaceborne
26
26
  end
27
27
 
28
28
  def add_response
29
- "RESPONSE: #{response.code}\n"\
29
+ "\nRESPONSE: #{response.code}\n"\
30
30
  " HEADERS:\n#{JSON.pretty_generate(response.headers)}\n"\
31
31
  << response_body
32
32
  end
@@ -51,8 +51,7 @@ module Spaceborne
51
51
  rescue Exception => e
52
52
  raise e unless response
53
53
 
54
- e.message << request_info
55
- raise e
54
+ raise RSpec::Expectations::ExpectationNotMetError, e.message + request_info
56
55
  end
57
56
  end
58
57
 
@@ -228,44 +227,75 @@ module Airborne
228
227
  end
229
228
 
230
229
  def handle_type(type, path, json, &block)
231
- if type == '*'
230
+ case type
231
+ when '*'
232
232
  handle_container(json, &block)
233
- elsif type == '?'
233
+ when '?'
234
234
  expect_one(path, json, &block)
235
235
  else
236
236
  yield json
237
237
  end
238
238
  end
239
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
+
240
252
  def iterate_path(path)
241
- raise PathError, "Invalid Path, contains '..'" if /\.\./ =~ path
253
+ raise PathError, "Invalid Path, contains '..'" if /\.\./ =~ path_to_s(path)
242
254
 
243
- parts = path.to_s.split('.')
255
+ parts = path_to_s(path).to_s.split('.')
244
256
  parts.each_with_index do |part, index|
245
- yield(parts, part, index)
257
+ use_part = make_path_optional(path, part)
258
+ yield(parts, use_part, index)
246
259
  end
247
260
  end
248
261
 
249
- def get_by_path(path, json, type = false, &block)
262
+ def get_by_path(path, json, type: false, &block)
250
263
  iterate_path(path) do |parts, part, index|
251
- if %w[* ?].include?(part)
264
+ if %w[* ?].include?(path_to_s(part))
252
265
  ensure_array_or_hash(path, json)
253
266
  type = part
254
267
  walk_with_path(type, index, path, parts, json, &block) && return if index < parts.length.pred
255
268
 
256
269
  next
257
270
  end
258
- json = do_process_json(part, json)
271
+ json = do_process_json(path_to_s(part), json)
259
272
  end
260
273
  handle_type(type, path, json, &block)
261
274
  end
262
275
 
263
276
  def ensure_array_or_hash(path, json)
264
- return if json.class == Array || json.class == Hash
277
+ return if json.instance_of?(Array) || json.instance_of?(Hash)
265
278
 
266
279
  raise RSpec::Expectations::ExpectationNotMetError,
267
280
  "Expected #{path} to be array or hash, got #{json.class}"\
268
281
  ' from JSON response'
269
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
270
300
  end
271
301
  end
@@ -1,3 +1,3 @@
1
1
  module Spaceborne
2
- VERSION = '0.1.33'.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.33
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-01 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