From b993756c9ab69e5c19af1ac81a231784455bcdc1 Mon Sep 17 00:00:00 2001 From: Karl Heitmann Date: Tue, 23 Apr 2024 22:51:01 -0400 Subject: [PATCH] Fix diff output when a fuzzy finder anything is inside an expected hash --- lib/rspec/support/differ.rb | 23 +++++++++++++++++++++-- spec/rspec/support/differ_spec.rb | 18 ++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/lib/rspec/support/differ.rb b/lib/rspec/support/differ.rb index 9488296ed..141132b9d 100644 --- a/lib/rspec/support/differ.rb +++ b/lib/rspec/support/differ.rb @@ -18,8 +18,12 @@ def diff(actual, expected) if any_multiline_strings?(actual, expected) diff = diff_as_string(coerce_to_string(actual), coerce_to_string(expected)) end - elsif no_procs?(actual, expected) && no_numbers?(actual, expected) - diff = diff_as_object(actual, expected) + elsif no_procs_and_no_numbers?(actual, expected) + if Hash === expected && hash_with_anything?(expected) + diff = diff_as_object_with_anything(actual, expected) + else + diff = diff_as_object(actual, expected) + end end end @@ -56,6 +60,13 @@ def diff_as_string(actual, expected) end # rubocop:enable Metrics/MethodLength + def diff_as_object_with_anything(actual, expected) + expected.select { |_, v| RSpec::Mocks::ArgumentMatchers::AnyArgMatcher === v }.each_key do |k| + expected[k] = actual[k] + end + diff_as_object(actual, expected) + end + def diff_as_object(actual, expected) actual_as_string = object_to_string(actual) expected_as_string = object_to_string(expected) @@ -73,6 +84,14 @@ def initialize(opts={}) private + def hash_with_anything?(arg) + safely_flatten(arg).any? { |a| RSpec::Mocks::ArgumentMatchers::AnyArgMatcher === a } + end + + def no_procs_and_no_numbers?(*args) + no_procs?(args) && no_numbers?(args) + end + def no_procs?(*args) safely_flatten(args).none? { |a| Proc === a } end diff --git a/spec/rspec/support/differ_spec.rb b/spec/rspec/support/differ_spec.rb index cbd1ed28f..04f1422ef 100644 --- a/spec/rspec/support/differ_spec.rb +++ b/spec/rspec/support/differ_spec.rb @@ -555,6 +555,24 @@ def inspect; ""; end expect(differ.diff(false, true)).to_not be_empty end end + + describe "fuzzy matcher anything" do + it "outputs only key value pair that triggered diff, anything_key should absorb actual value" do + actual = { :fixed => "fixed", :trigger => "trigger", :anything_key => "bcdd0399-1cfe-4de1-a481-ca6b17d41ed8" } + expected = { :fixed => "fixed", :trigger => "wrong", :anything_key => anything } + diff = differ.diff(actual, expected) + expected_diff = dedent(<<-'EOD') + | + |@@ -1,4 +1,4 @@ + | :anything_key => "bcdd0399-1cfe-4de1-a481-ca6b17d41ed8", + | :fixed => "fixed", + |-:trigger => "wrong", + |+:trigger => "trigger", + | + EOD + expect(diff).to be_diffed_as(expected_diff) + end + end end end end