DiffMatcher === [![build status](http://travis-ci.org/playup/diff_matcher.png)](http://travis-ci.org/playup/diff_matcher) Generates a diff by matching against expected values, classes, regexes and/or procs. DiffMatcher performs recursive matches on values contained in hashes, arrays and combinations thereof. Values in a containing object match when: - actual == expected - actual.is_a? expected # when expected is a class - expected.match actual # when expected is a regexp - expected.call actual # when expected is a proc Installation --- gem install diff_matcher Usage --- require 'diff_matcher' DiffMatcher::difference(actual, expected, opts={}) When `expected` != `actual` puts DiffMatcher::difference(1, 2) # => - 1+ 2 # => Where, - 1 missing, + 1 additional When `expected` == `actual` p DiffMatcher::difference(1, 1) # => nil When `actual` is an instance of the `expected` p DiffMatcher::difference(String, '1') # => nil When `actual` is a string that matches the `expected` regex p DiffMatcher::difference(/[a-z]/, "a") # => nil When `actual` is passed to an `expected` proc and it returns true is_boolean = lambda { |x| [FalseClass, TrueClass].include? x.class } p DiffMatcher::difference(is_boolean, true) # => nil When `actual` is missing one of the `expected` values puts DiffMatcher::difference([1, 2], [1]) # => [ # => - 2 # => ] # => Where, - 1 missing When `actual` has additional values to the `expected` puts DiffMatcher::difference([1], [1, 2]) # => [ # => + 2 # => ] # => Where, - 1 additional ### Options `:ignore_additional=>true` will match even if `actual` has additional items p DiffMatcher::difference([1], [1, 2], :ignore_additional=>true) # => nil `:verbose=>true` shows only missing and additional items in the output puts DiffMatcher::difference([Fixnum, 2], [1], :quiet=>true) # => [ # => - 2 # => ] # => Where, - 1 missing `:verbose=>true` shows all matched items in the output puts DiffMatcher::difference([Fixnum, 2], [1], :verbose=>true) # => [ # = > : 1, # => - 2 # => ] # => Where, - 1 missing, : 1 match_class #### prefixes NB. The `: 1` from above includes a `:` prefix that shows the `1` was matched against a class (ie. `Fixnum`) The items shown in a difference are prefixed as follows: missing => "- " additional => "+ " match value => match regexp => "~ " match class => ": " match proc => "{ " #### colours Colours (defined in colour schemes) can also appear in the difference. Using the `:default` colour scheme items shown in a difference are coloured as follows: missing => red additional => yellow match value => match regexp => green match class => blue match proc => cyan puts DiffMatcher::difference( { :a=>{ :a1=>11 }, :b=>[ 21, 22 ], :c=>/\d/, :d=>Fixnum, :e=>lambda { |x| (4..6).includes? x }, { :a=>{ :a1=>10, :a2=>12 }, :b=>[ 21 ], :c=>'3' , :d=>4 , :e=>5 }, :verbose=>true, :color_scheme=>:white_background ) ![example output](https://raw.github.com/playup/diff_matcher/master/doc/example_output.png) Similar gems --- ### String differs * (A resonably fast diff algorithm using longest common substrings) * (Provides a convenient interfaces to Unix diff) * (A simple gem for generating string diffs) * (Apply regular expression replacements to strings while presenting the result in a “diff” like format) * (Takes two pieces of source text/html and creates a neato html diff output) ### Object differs * (Super Stupid Diff) * (Calculates the differences between two tree-like structures) * (Recursive diff, merge, and unmerge for hashes and arrays) Why another differ? --- This gem came about because [rspec](http://github.com/rspec/rspec-expectations) doesn't have a decent differ for matching hashes and/or JSON. It started out as a [pull request](http://github.com/rspec/rspec-expectations/pull/79), to be implemented as a `be_hash_matching` [rspec matcher](https://www.relishapp.com/rspec/rspec-expectations), but seemed useful enough to be its own stand alone gem. Out of the similar gems above, [easy_diff](http://github.com/Blargel/easy_diff) looks like a good alternative to this gem. It has extra functionality in also being able to recursively merge hashes and arrays. [sub_diff](http://github.com/shuber/sub_diff) can use regular expressions in its match and subsequent diff DiffMatcher can match using not only regexes but classes and procs. And the difference string that it outputs can be formatted in several ways as needed. Contributing --- Fork, write some tests and send a pull request (bonus points for topic branches). Status --- Our company is using this gem to test our JSON API which has got it to a stable v1.0.0 release. There's a [pull request](http://github.com/rspec/rspec-expectations/pull/79) to use this gem in a `be_hash_matching` [rspec matcher](https://www.relishapp.com/rspec/rspec-expectations).