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

Commit

Permalink
fix works in hashes with nested hashes
Browse files Browse the repository at this point in the history
  • Loading branch information
KarlHeitmann committed Apr 24, 2024
1 parent 8c81146 commit e4ece3d
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 3 deletions.
32 changes: 29 additions & 3 deletions lib/rspec/support/differ.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,15 @@ def diff_as_string(actual, expected)
# 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]
@keys_with_anything.each do |keys|
pointer_expected = expected
pointer_actual = actual
final_key = keys.pop
keys.each do |k|
pointer_expected = pointer_expected[k]
pointer_actual = pointer_actual[k]
end
pointer_expected[final_key] = pointer_actual[final_key]
end
diff_as_object(actual, expected)
end
Expand All @@ -85,7 +92,26 @@ def initialize(opts={})
private

def hash_with_anything?(arg)
safely_flatten(arg).any? { |a| RSpec::Mocks::ArgumentMatchers::AnyArgMatcher === a }
@keys_with_anything = recursive_get_keys(arg)
@keys_with_anything.any?
end

def recursive_get_keys(hash)
klass = RSpec::Mocks::ArgumentMatchers::AnyArgMatcher
hash.reduce([]) do |acc, pair|
if klass === pair[1]
acc << [pair[0]]
else
if Hash === pair[1]
keys = recursive_get_keys(pair[1])
keys.each do |key|
key.prepend pair[0]
acc << key
end
end
end
acc
end
end

def no_procs?(*args)
Expand Down
48 changes: 48 additions & 0 deletions spec/rspec/support/differ_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,54 @@ def inspect; "<BrokenObject>"; end
EOD
expect(diff).to be_diffed_as(expected_diff)
end

context "with nested hash" do
it "outputs only key value pair that triggered diff, anything_key should absorb actual value" do
actual = { :an_key => "dummy", :fixed => "fixed", :nested => { :name => "foo", :trigger => "trigger", :anything_key => "bcdd0399-1cfe-4de1-a481-ca6b17d41ed8" } }
expected = { :an_key => anything, :fixed => "fixed", :nested => { :name => "foo", :trigger => "wrong", :anything_key => anything } }
diff = differ.diff(actual, expected)
expected_diff = dedent(<<-'EOD')
|
|@@ -1,4 +1,4 @@
| :an_key => "dummy",
| :fixed => "fixed",
|-:nested => {:anything_key=>"bcdd0399-1cfe-4de1-a481-ca6b17d41ed8", :name=>"foo", :trigger=>"wrong"},
|+:nested => {:anything_key=>"bcdd0399-1cfe-4de1-a481-ca6b17d41ed8", :name=>"foo", :trigger=>"trigger"},
|
EOD
expect(diff).to be_diffed_as(expected_diff)
end
end

context "with nested hash and subnested hash" do
it "outputs only key value pair that triggered diff, anything_key should absorb actual value" do
actual = {
:an_key => "dummy", :fixed => "fixed",
:nested => {
:nested_anything_key => "9930ddcb-1cfe-4de1-a481-ca6b17d41ed8",
:subnested => { :name => "foo", :trigger => "trigger", :subnested_anything_key => "bcdd0399-1cfe-4de1-a481-ca6b17d41ed8" }
}
}
expected = {
:an_key => anything, :fixed => "fixed",
:nested => {
:nested_anything_key => anything,
:subnested => { :name => "foo", :trigger => "wrong", :subnested_anything_key => anything }
}
}
diff = differ.diff(actual, expected)
expected_diff = dedent(<<-'EOD')
|
|@@ -1,4 +1,4 @@
| :an_key => "dummy",
| :fixed => "fixed",
|-:nested => {:nested_anything_key=>"9930ddcb-1cfe-4de1-a481-ca6b17d41ed8", :subnested=>{:name=>"foo", :subnested_anything_key=>"bcdd0399-1cfe-4de1-a481-ca6b17d41ed8", :trigger=>"wrong"}},
|+:nested => {:nested_anything_key=>"9930ddcb-1cfe-4de1-a481-ca6b17d41ed8", :subnested=>{:name=>"foo", :subnested_anything_key=>"bcdd0399-1cfe-4de1-a481-ca6b17d41ed8", :trigger=>"trigger"}},
|
EOD
expect(diff).to be_diffed_as(expected_diff)
end
end
end
end
end
Expand Down

0 comments on commit e4ece3d

Please sign in to comment.