Module: Airborne::PathMatcher

Defined in:
lib/spaceborne.rb

Overview

extension to handle hash value checking

Instance Method Summary collapse

Instance Method Details

#ensure_array_or_hash(path, json) ⇒ Object

Raises:

  • (RSpec::Expectations::ExpectationNotMetError)


298
299
300
301
302
303
304
# File 'lib/spaceborne.rb', line 298

def ensure_array_or_hash(path, json)
  return if json.instance_of?(Array) || json.instance_of?(Hash)

  raise RSpec::Expectations::ExpectationNotMetError,
        "Expected #{path} to be array or hash, got #{json.class}"\
        ' from JSON response'
end

#get_by_path(path, json, type: false, &block) ⇒ Object



283
284
285
286
287
288
289
290
291
292
293
294
295
296
# File 'lib/spaceborne.rb', line 283

def get_by_path(path, json, type: false, &block)
  iterate_path(path) do |parts, part, index|
    return if shortcut_validation(path, json)

    if %w[* ?].include?(part.to_s)
      type = part
      walk_with_path(type.to_s, index, path, parts, json, &block) && return if index < parts.length.pred

      next
    end
    json = do_process_json(part.to_s, json)
  end
  handle_type(type, path, json, &block)
end

#handle_container(path, json, &block) ⇒ Object



239
240
241
242
243
244
245
246
247
248
# File 'lib/spaceborne.rb', line 239

def handle_container(path, json, &block)
  case json.class.name
  when 'Array'
    expect_all(json, &block)
  when 'Hash'
    json.each { |k, _v| yield json[k] }
  else
    raise ExpectationError, "expected array or hash at #{path}, got #{json.class.name}"
  end
end

#handle_missing_errors(type, path, sub_path, element, &block) ⇒ Object



306
307
308
309
310
# File 'lib/spaceborne.rb', line 306

def handle_missing_errors(type, path, sub_path, element, &block)
  exception_path_adder({ type: type, path: sub_path }, element) do
    get_by_path(make_sub_path_optional(path, sub_path), element, &block)
  end
end

#handle_type(type, path, json, &block) ⇒ Object



250
251
252
253
254
255
256
257
258
259
# File 'lib/spaceborne.rb', line 250

def handle_type(type, path, json, &block)
  case type.to_s
  when '*'
    handle_container(path, json, &block)
  when '?'
    expect_one(path, json, &block)
  else
    yield json
  end
end

#iterate_path(path) ⇒ Object

Raises:

  • (PathError)


269
270
271
272
273
274
275
276
277
# File 'lib/spaceborne.rb', line 269

def iterate_path(path)
  raise PathError, "Invalid Path, contains '..'" if /\.\./ =~ path.to_s

  parts = path.to_s.split('.')
  parts.each_with_index do |part, index|
    use_part = make_sub_path_optional(path, part)
    yield(parts, use_part, index)
  end
end

#make_sub_path_optional(path, sub_path) ⇒ Object



261
262
263
264
265
266
267
# File 'lib/spaceborne.rb', line 261

def make_sub_path_optional(path, sub_path)
  if path.is_a?(Airborne::OptionalPathExpectations)
    Airborne::OptionalPathExpectations.new(sub_path)
  else
    sub_path
  end
end

#shortcut_validation(path, json) ⇒ Object



279
280
281
# File 'lib/spaceborne.rb', line 279

def shortcut_validation(path, json)
  json.nil? && path.is_a?(Airborne::OptionalPathExpectations)
end

#walk_with_path(type, index, path, parts, json, &block) ⇒ Object



312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
# File 'lib/spaceborne.rb', line 312

def walk_with_path(type, index, path, parts, json, &block)
  last_error = nil
  item_count = json.length
  error_count = 0
  json.each do |element|
    sub_path = parts[(index.next)...(parts.length)].join('.')
    begin
      handle_missing_errors(type, path, sub_path, element, &block)
    rescue Exception => e
      last_error = e
      error_count += 1
    end
    ensure_match_all(last_error) if type == '*'
    ensure_match_one(path, item_count, error_count) if type == '?'
  end
end