diff --git a/lib/pact/matching_rules/merge.rb b/lib/pact/matching_rules/merge.rb index 384e78c..0692fda 100644 --- a/lib/pact/matching_rules/merge.rb +++ b/lib/pact/matching_rules/merge.rb @@ -13,11 +13,12 @@ def initialize expected, matching_rules, root_path @expected = expected @matching_rules = standardise_paths(matching_rules) @root_path = JsonPath.new(root_path).to_s + @used_rules = [] end def call return @expected if @matching_rules.nil? || @matching_rules.empty? - recurse @expected, @root_path + recurse(@expected, @root_path).tap { log_ignored_rules } end private @@ -46,14 +47,18 @@ def recurse_hash hash, path end def recurse_array array, path - array_like_children_path = "#{path}[*]*" parent_match_rule = @matching_rules[path] && @matching_rules[path]['match'] + log_used_rule(path, 'match', parent_match_rule) if parent_match_rule + + array_like_children_path = "#{path}[*]*" children_match_rule = @matching_rules[array_like_children_path] && @matching_rules[array_like_children_path]['match'] + log_used_rule(array_like_children_path, 'match', children_match_rule) if children_match_rule + min = @matching_rules[path] && @matching_rules[path]['min'] + log_used_rule(path, 'min', min) if min if min && (children_match_rule == 'type' || (children_match_rule.nil? && parent_match_rule == 'type')) warn_when_not_one_example_item(array, path) - # log_ignored_rules(path, @matching_rules[path], {'min' => min}) Pact::ArrayLike.new(recurse(array.first, "#{path}[*]"), min: min) else new_array = [] @@ -81,30 +86,37 @@ def wrap object, path elsif rules['regex'] handle_regex(object, path, rules) else - log_ignored_rules(path, rules, {}) object end end def handle_match_type object, path, rules - log_ignored_rules(path, rules, {'match' => 'type'}) + log_used_rule(path, 'match', 'type') Pact::SomethingLike.new(object) end def handle_regex object, path, rules - log_ignored_rules(path, rules, {'match' => 'regex', 'regex' => rules['regex']}) + log_used_rule(path, 'match', 'regex') # assumed to be present + log_used_rule(path, 'regex', rules['regex']) Pact::Term.new(generate: object, matcher: Regexp.new(rules['regex'])) end - def log_ignored_rules path, rules, used_rules - dup_rules = rules.dup - used_rules.each_pair do | used_key, used_value | - dup_rules.delete(used_key) if dup_rules[used_key] == used_value + def log_ignored_rules + dup_rules = @matching_rules.dup + @used_rules.each do | (path, key, value) | + dup_rules[path].delete(key) if dup_rules[path][key] == value end + if dup_rules.any? - $stderr.puts "WARN: Ignoring unsupported matching rules #{dup_rules} for path #{path}" + dup_rules.each do | path, rules | + $stderr.puts "WARN: Ignoring unsupported matching rules #{rules} for path #{path}" if rules.any? + end end end + + def log_used_rule path, key, value + @used_rules << [path, key, value] + end end end end diff --git a/spec/lib/pact/matching_rules/merge_spec.rb b/spec/lib/pact/matching_rules/merge_spec.rb index a17dfef..2b652af 100644 --- a/spec/lib/pact/matching_rules/merge_spec.rb +++ b/spec/lib/pact/matching_rules/merge_spec.rb @@ -7,10 +7,16 @@ module MatchingRules subject { Merge.(expected, matching_rules, "$.body") } before do - allow($stderr).to receive(:puts) + allow($stderr).to receive(:puts) do | message | + raise "Was not expecting stderr to receive #{message.inspect} in this spec. This may be because of a missed call to log_used_rule in Merge." + end end describe "no recognised rules" do + before do + allow($stderr).to receive(:puts) + end + let(:expected) do { "_links" => { @@ -63,6 +69,10 @@ module MatchingRules end describe "type based matching" do + before do + allow($stderr).to receive(:puts) + end + let(:expected) do { "name" => "Mary" @@ -89,6 +99,10 @@ module MatchingRules describe "regular expressions" do describe "in a hash" do + before do + allow($stderr).to receive(:puts) + end + let(:expected) do { "_links" => { @@ -178,6 +192,7 @@ module MatchingRules "$.body.alligators[*].*" => { 'match' => 'type'} } end + it "creates a Pact::ArrayLike at the appropriate path" do expect(subject["alligators"]).to be_instance_of(Pact::ArrayLike) expect(subject["alligators"].contents).to eq 'name' => 'Mary' @@ -259,6 +274,10 @@ module MatchingRules end describe "with an example array with more than one item" do + before do + allow(Pact.configuration.error_stream).to receive(:puts) + end + let(:expected) do { @@ -277,13 +296,7 @@ module MatchingRules } end - xit "doesn't warn about the min size being ignored" do - expect(Pact.configuration.error_stream).to receive(:puts).once - subject - end - it "warns that the other items will be ignored" do - allow(Pact.configuration.error_stream).to receive(:puts) expect(Pact.configuration.error_stream).to receive(:puts).with(/WARN: Only the first item/) subject end