Last active
November 22, 2023 13:27
-
-
Save localshred/8c864db91c1252ce4386 to your computer and use it in GitHub Desktop.
Minitest assert_equal sucks for comparing output diffs of two hashes. Using HashDiff, awesome_print, and StringIO we can get actual comparable hashes without pulling our hair out.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "test_helper" | |
require "awesome_print" | |
require "hashdiff" | |
class MyClass | |
def self.do_stuff | |
{a:[{y:3}, {x:11, z:33}], b:{y:22}} | |
end | |
end | |
class MyClassTest < ::Minitest::Test | |
def test_stuff | |
expected = {a:[{x:2, y:3, z:4}, {x:11, y:22, z:33}], b:{x:3, z:45}} | |
actual = MyClass.do_stuff | |
diff = ::HashDiff.diff(expected, actual) | |
if diff.empty? | |
pass("Hashes are equal") | |
else | |
out = StringIO.new | |
grouped = diff.group_by(&:first) | |
if grouped["~"] | |
out.puts "\nDifferent Values (left, right):" | |
grouped["~"].each do |(_, field, left, right)| | |
out.puts "\t#{field}: '#{left.inspect}', '#{right.inspect}'" | |
end | |
end | |
if grouped["-"] | |
out.puts "\nMissing Values from right (left):" | |
grouped["-"].each do |(_, field, left)| | |
out.puts "\t#{field}: '#{left.inspect}'" | |
end | |
end | |
if grouped["+"] | |
out.puts "\nMissing Values from left (right):" | |
grouped["+"].each do |(_, field, right)| | |
out.puts "\t#{field}: '#{right.inspect}'" | |
end | |
end | |
ap_opts = { indent: 2 } | |
out.puts | |
out.puts "Expected" | |
out.puts "--------" | |
out.puts expected.ai(ap_opts) | |
out.puts | |
out.puts "Actual" | |
out.puts "------" | |
out.puts actual.ai(ap_opts) | |
out.rewind | |
flunk("Hashes are not equal:\n\n#{out.read}") | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
MyClassTest#test_stuff [/path/to/nice_hash_comparison_test.rb:56]: | |
Hashes are not equal: | |
Missing Values from right (left): | |
a[1].y: '22' | |
a[0]: '{:x=>2, :y=>3, :z=>4}' | |
b.x: '3' | |
b.z: '45' | |
Missing Values from left (right): | |
a[0]: '{:y=>3}' | |
b.y: '22' | |
Expected | |
-------- | |
{ | |
:a => [ | |
[0] { | |
:x => 2, | |
:y => 3, | |
:z => 4 | |
}, | |
[1] { | |
:x => 11, | |
:y => 22, | |
:z => 33 | |
} | |
], | |
:b => { | |
:x => 3, | |
:z => 45 | |
} | |
} | |
Actual | |
------ | |
{ | |
:a => [ | |
[0] { | |
:y => 3 | |
}, | |
[1] { | |
:x => 11, | |
:z => 33 | |
} | |
], | |
:b => { | |
:y => 22 | |
} | |
} |
HashDiff should be Hashdiff
@fwolfst Thanks for this pointer! Didn't know about the pretty diff feature! ❤️
Just came across this and it's awesome. Would you be able to declare an MIT license for it, or else declare it as public domain?
@mvastola definitely free and available for public domain.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
[
make_my_diffs_pretty!](https://www.rubydoc.info/github/seattlerb/minitest/Minitest%2FTest.make_my_diffs_pretty!)
intest/test_helper.rb
(if on Rails) does a pretty good job, though, too.