Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.

Commit d6bdd9f

Browse files
authored
Merge pull request #599 from KarlHeitmann/fix_diff_fuzzy_matcher_anything_v2
Fix diff output when a fuzzy finder anything is inside an expected hash
2 parents 5334c64 + 6b7ff69 commit d6bdd9f

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

lib/rspec/support/differ.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ def diff(actual, expected)
1818
if any_multiline_strings?(actual, expected)
1919
diff = diff_as_string(coerce_to_string(actual), coerce_to_string(expected))
2020
end
21+
elsif all_hashes?(actual, expected)
22+
diff = diff_hashes_as_object(actual, expected)
2123
elsif no_procs?(actual, expected) && no_numbers?(actual, expected)
2224
diff = diff_as_object(actual, expected)
2325
end
@@ -56,6 +58,25 @@ def diff_as_string(actual, expected)
5658
end
5759
# rubocop:enable Metrics/MethodLength
5860

61+
if defined?(RSpec::Mocks::ArgumentMatchers::AnyArgMatcher)
62+
def diff_hashes_as_object(actual, expected)
63+
actual_to_diff =
64+
actual.keys.reduce({}) do |hash, key|
65+
if RSpec::Mocks::ArgumentMatchers::AnyArgMatcher === expected[key]
66+
hash[key] = expected[key]
67+
else
68+
hash[key] = actual[key]
69+
end
70+
hash
71+
end
72+
diff_as_object(actual_to_diff, expected)
73+
end
74+
else
75+
def diff_hashes_as_object(actual, expected)
76+
diff_as_object(actual, expected)
77+
end
78+
end
79+
5980
def diff_as_object(actual, expected)
6081
actual_as_string = object_to_string(actual)
6182
expected_as_string = object_to_string(expected)
@@ -77,6 +98,10 @@ def no_procs?(*args)
7798
safely_flatten(args).none? { |a| Proc === a }
7899
end
79100

101+
def all_hashes?(actual, expected)
102+
(Hash === actual) && (Hash === expected)
103+
end
104+
80105
def all_strings?(*args)
81106
safely_flatten(args).all? { |a| String === a }
82107
end

spec/rspec/support/differ_spec.rb

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
module RSpec
88
module Support
9-
RSpec.describe Differ do
9+
RSpec.describe "Differ" do
1010
include Spec::DiffHelpers
1111

1212
describe '#diff' do
@@ -555,6 +555,31 @@ def inspect; "<BrokenObject>"; end
555555
expect(differ.diff(false, true)).to_not be_empty
556556
end
557557
end
558+
559+
describe "fuzzy matcher anything" do
560+
it "outputs only key value pair that triggered diff, anything_key should absorb actual value" do
561+
actual = { :fixed => "fixed", :trigger => "trigger", :anything_key => "bcdd0399-1cfe-4de1-a481-ca6b17d41ed8" }
562+
expected = { :fixed => "fixed", :trigger => "wrong", :anything_key => anything }
563+
diff = differ.diff(actual, expected)
564+
expected_diff = dedent(<<-'EOD')
565+
|
566+
|@@ -1,4 +1,4 @@
567+
| :anything_key => anything,
568+
| :fixed => "fixed",
569+
|-:trigger => "wrong",
570+
|+:trigger => "trigger",
571+
|
572+
EOD
573+
expect(diff).to be_diffed_as(expected_diff)
574+
end
575+
576+
it "checks the 'expected' var continues having the 'anything' fuzzy matcher, it has not mutated" do
577+
actual = { :fixed => "fixed", :trigger => "trigger", :anything_key => "bcdd0399-1cfe-4de1-a481-ca6b17d41ed8" }
578+
expected = { :fixed => "fixed", :trigger => "wrong", :anything_key => anything }
579+
differ.diff(actual, expected)
580+
expect(expected).to eq({ :fixed => "fixed", :trigger => "wrong", :anything_key => anything })
581+
end
582+
end
558583
end
559584
end
560585
end

0 commit comments

Comments
 (0)