Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Custom RSPec matcher for detailed hash compasion and diff
RSpec::Matchers.define :be_a_hash_like do |expected_hash|
match do |actual_hash|
matching_results = actual_hash == expected_hash
unless matching_results
"git --no-pager diff $(echo '#{JSON.pretty_generate(expected_hash)}' | git hash-object -w --stdin) " +
"$(echo '#{JSON.pretty_generate(actual_hash)}' | git hash-object -w --stdin) --word-diff",
out: $stdout,
err: :out
failure_message { 'Look at the Diff above! ^^^' }
# then use:
expect(actual).to be_a_hash_like(expected)

This comment has been minimized.

Copy link
Owner Author

@fabriciofreitag fabriciofreitag commented Oct 30, 2019

it produces this nice output:



This comment has been minimized.

Copy link

@TylerRick TylerRick commented Feb 6, 2020

That's really clever. I didn't know you could trick git diff into being used for general purpose diffing like that!

If anyone is interested, I made a version that:

  1. Sorts hashes before comparing so that the diff only shows actual changes between keys and values (and not diffs due to accidental differences in key order, which is almost never significant in Ruby).

  2. Uses diff-so-fancy if available. While this doesn't give you a word diff, it gives a really clean line diff (using colors instead of +/- symbols). I wish I could find a way to get a word diff like that. I find the [- -]{+ +} distracting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.