class Pact::MatchingRules::V3::Merge
Public Class Methods
call(expected, matching_rules, root_path = '$')
click to toggle source
# File lib/pact/matching_rules/v3/merge.rb, line 9 def self.call expected, matching_rules, root_path = '$' new(expected, matching_rules, root_path).call end
new(expected, matching_rules, root_path)
click to toggle source
# File lib/pact/matching_rules/v3/merge.rb, line 13 def initialize expected, matching_rules, root_path @expected = expected @matching_rules = standardise_paths(matching_rules) @root_path = JsonPath.new(root_path).to_s end
Public Instance Methods
call()
click to toggle source
# File lib/pact/matching_rules/v3/merge.rb, line 19 def call return @expected if @matching_rules.nil? || @matching_rules.empty? recurse(@expected, @root_path).tap { log_ignored_rules } end
Private Instance Methods
find_rule(path, key)
click to toggle source
# File lib/pact/matching_rules/v3/merge.rb, line 127 def find_rule(path, key) @matching_rules[path] && @matching_rules[path][key] end
handle_match_type(object, path, rules)
click to toggle source
# File lib/pact/matching_rules/v3/merge.rb, line 97 def handle_match_type object, path, rules rules.delete('match') Pact::SomethingLike.new(object) end
handle_regex(object, path, rules)
click to toggle source
# File lib/pact/matching_rules/v3/merge.rb, line 102 def handle_regex object, path, rules rules.delete('match') regex = rules.delete('regex') Pact::Term.new(generate: object, matcher: Regexp.new(regex)) end
log_ignored_rules()
click to toggle source
# File lib/pact/matching_rules/v3/merge.rb, line 108 def log_ignored_rules @matching_rules.each do | jsonpath, rules_hash | rules_array = rules_hash["matchers"] if rules_array ((rules_array.length - 1)..0).each do | index | rules_array.delete_at(index) if rules_array[index].empty? end end end if @matching_rules.any? @matching_rules.each do | path, rules_hash | rules_hash.each do | key, value | $stderr.puts "WARN: Ignoring unsupported #{key} #{value} for path #{path}" if value_present?(value) end end end end
log_used_rule(path, key, value)
click to toggle source
# File lib/pact/matching_rules/v3/merge.rb, line 131 def log_used_rule path, key, value @used_rules << [path, key, value] end
recurse(expected, path)
click to toggle source
# File lib/pact/matching_rules/v3/merge.rb, line 33 def recurse expected, path recursed = case expected when Hash then recurse_hash(expected, path) when Array then recurse_array(expected, path) else expected end wrap(recursed, path) end
recurse_array(array, path)
click to toggle source
# File lib/pact/matching_rules/v3/merge.rb, line 50 def recurse_array array, path # This assumes there is only one rule! TODO make this find the appropriate rule. parent_match_rule = @matching_rules[path]['matchers'].first['match'] rescue nil array_like_children_path = "#{path}[*]*" children_match_rule = @matching_rules[array_like_children_path]['matchers'].first['match'] rescue nil min = @matching_rules[path]['matchers'].first['min'] rescue nil if min && children_match_rule == 'type' @matching_rules[path]['matchers'].first.delete('min') @matching_rules[array_like_children_path]['matchers'].first.delete('match') warn_when_not_one_example_item(array, path) Pact::ArrayLike.new(recurse(array.first, "#{path}[*]"), min: min) elsif min && parent_match_rule == 'type' @matching_rules[path]['matchers'].first.delete('min') @matching_rules[path]['matchers'].first.delete('match') warn_when_not_one_example_item(array, path) Pact::ArrayLike.new(recurse(array.first, "#{path}[*]"), min: min) else new_array = [] array.each_with_index do | item, index | new_path = path + "[#{index}]" new_array << recurse(item, new_path) end new_array end end
recurse_hash(hash, path)
click to toggle source
# File lib/pact/matching_rules/v3/merge.rb, line 43 def recurse_hash hash, path hash.each_with_object({}) do | (k, v), new_hash | new_path = path + "['#{k}']" new_hash[k] = recurse(v, new_path) end end
standardise_paths(matching_rules)
click to toggle source
# File lib/pact/matching_rules/v3/merge.rb, line 26 def standardise_paths matching_rules return matching_rules if matching_rules.nil? || matching_rules.empty? matching_rules.each_with_object({}) do | (path, rules), new_matching_rules | new_matching_rules[JsonPath.new(path).to_s] = Marshal.load(Marshal.dump(rules)) # simplest way to deep clone end end
value_present?(value)
click to toggle source
# File lib/pact/matching_rules/v3/merge.rb, line 135 def value_present? value value.respond_to?(:any?) ? value.any? : true end
warn_when_not_one_example_item(array, path)
click to toggle source
# File lib/pact/matching_rules/v3/merge.rb, line 77 def warn_when_not_one_example_item array, path unless array.size == 1 Pact.configuration.error_stream.puts "WARN: Only the first item will be used to match the items in the array at #{path}" end end
wrap(object, path)
click to toggle source
# File lib/pact/matching_rules/v3/merge.rb, line 83 def wrap object, path rules = @matching_rules[path] && @matching_rules[path]['matchers'] && @matching_rules[path]['matchers'].first array_rules = @matching_rules["#{path}[*]*"] && @matching_rules["#{path}[*]*"]['matchers'] && @matching_rules["#{path}[*]*"]['matchers'].first return object unless rules || array_rules if rules['match'] == 'type' && !rules.has_key?('min') handle_match_type(object, path, rules) elsif rules['regex'] handle_regex(object, path, rules) else object end end