Permalink
Browse files

Updated diff_matcher to use RSpec Matcher DSL, with expected hack

  • Loading branch information...
1 parent a6e0930 commit 4f3c36e630d32f93482e136a91faea8140b379aa @cjheath committed Jun 3, 2012
Showing with 100 additions and 124 deletions.
  1. +18 −35 spec/helpers/array_matcher.rb
  2. +32 −13 spec/helpers/diff_matcher.rb
  3. +27 −43 spec/helpers/file_matcher.rb
  4. +23 −33 spec/helpers/string_matcher.rb
@@ -1,40 +1,23 @@
-module RSpec
- module Matchers
- class ArrayMatcher < Matcher
- def initialize expected
- super(:be_different_array_from, expected) do |*_expected|
- match_for_should do |actual|
- perform_match(actual, _expected[0])
- @extra + @missing != []
- end
-
- match_for_should_not do |actual|
- perform_match(actual, _expected[0])
- @extra + @missing == []
- end
-
- def perform_match(actual, expected)
- @extra = actual - expected
- @missing = expected - actual
- end
+RSpec::Matchers.define :be_different_array_from do |x|
+ match do |actual|
+ perform_match(actual, expected)
+ @extra + @missing != []
+ end
- def failure_message_for_should
- "expected a difference in the two lists, but got none"
- end
+ def perform_match(actual, expected)
+ @extra = actual - expected
+ @missing = expected - actual
+ end
- failure_message_for_should_not do |actual|
- "expected no difference, but result #{
- [ (@missing.empty? ? nil : 'lacks '+@missing.sort.inspect),
- (@extra.empty? ? nil : 'has extra '+@extra.sort.inspect)
- ].compact * ' and '
- }"
- end
- end
- end
- end
+ failure_message_for_should do |actual|
+ "expected a difference in the two lists, but got none"
+ end
- def be_different_array_from(expected)
- ArrayMatcher.new(expected)
- end
+ failure_message_for_should_not do |actual|
+ "expected no difference, but result #{
+ [ (@missing.empty? ? nil : 'lacks '+@missing.sort.inspect),
+ (@extra.empty? ? nil : 'has extra '+@extra.sort.inspect)
+ ].compact * ' and '
+ }"
end
end
@@ -1,18 +1,37 @@
require 'pathname'
-module RSpec
- module Matchers
- def differ_from(expected)
- case expected
- when Pathname
- FileMatcher.new(expected)
- when Array
- ArrayMatcher.new(expected)
- when String
- FileMatcher.new(expected)
- else
- raise "DiffMatcher doesn't know how to match a #{expected.class}"
- end
+class RSpec::Matchers::DSL::Matcher
+ attr_writer :expected
+end
+
+RSpec::Matchers.define :differ_from do |expected|
+ match do |actual|
+ case expected
+ when Pathname
+ @m = have_different_contents
+ @m.expected = expected
+ @m.matches?(actual)
+ when Array
+ # If we pass "expected" here, it expects an array.
+ # Works here, but not for Pathname or String
+ # Hence the need for the attr_writer hack above.
+ @m = be_different_array_from
+ @m.expected = expected
+ @m.matches?(actual)
+ when String
+ @m = have_different_contents
+ @m.expected = expected
+ @m.matches?(actual)
+ else
+ raise "DiffMatcher doesn't know how to match a #{expected.class}"
end
end
+
+ failure_message_for_should do |actual|
+ @m.failure_message_for_should
+ end
+
+ failure_message_for_should_not do |actual|
+ @m.failure_message_for_should_not
+ end
end
@@ -1,50 +1,34 @@
require 'diff/lcs'
-module RSpec
- module Matchers
- class FileMatcher < Matcher
- def initialize expected
- super(:have_different_contents, expected) do |*_expected|
- match_for_should do |actual|
- perform_match(actual, _expected[0])
- end
-
- match_for_should_not do |actual|
- !perform_match(actual, _expected[0])
- end
-
- def perform_match(actual, expected)
- expected = File.open(expected).read if expected.is_a?(Pathname)
- expected = expected.scan(/[^\n]+/) unless expected.is_a?(Array)
-
- actual = File.open(actual).read if actual.is_a?(Pathname)
- actual = actual.scan(/[^\n]+/) unless actual.is_a?(Array)
-
- differences = Diff::LCS::diff(expected, actual)
- @diff = differences.map do |chunk|
- added_at = (add = chunk.detect{|d| d.action == '+'}) && add.position+1
- removed_at = (remove = chunk.detect{|d| d.action == '-'}) && remove.position+1
- "Line #{added_at}/#{removed_at}:\n"+
- chunk.map do |change|
- "#{change.action} #{change.element}"
- end*"\n"
- end*"\n"
- @diff != ''
- end
+RSpec::Matchers.define :have_different_contents do |x|
+ match do |actual|
+ perform_match(actual, expected)
+ end
- def failure_message_for_should
- "expected a difference, but got none"
- end
+ def perform_match(actual, expected)
+ expected = File.open(expected).read if expected.is_a?(Pathname)
+ expected = expected.scan(/[^\n]+/) unless expected.is_a?(Array)
+
+ actual = File.open(actual).read if actual.is_a?(Pathname)
+ actual = actual.scan(/[^\n]+/) unless actual.is_a?(Array)
+
+ differences = Diff::LCS::diff(expected, actual)
+ @diff = differences.map do |chunk|
+ added_at = (add = chunk.detect{|d| d.action == '+'}) && add.position+1
+ removed_at = (remove = chunk.detect{|d| d.action == '-'}) && remove.position+1
+ "Line #{added_at}/#{removed_at}:\n"+
+ chunk.map do |change|
+ "#{change.action} #{change.element}"
+ end*"\n"
+ end*"\n"
+ @diff != ''
+ end
- failure_message_for_should_not do |actual|
- "expected no difference, but got:\n#{@diff}"
- end
- end
- end
- end
+ failure_message_for_should do |actual|
+ "expected a difference, but got none"
+ end
- def have_different_contents(expected)
- FileMatcher.new(expected)
- end
+ failure_message_for_should_not do |actual|
+ "expected no difference, but got:\n#{@diff}"
end
end
@@ -1,40 +1,30 @@
require 'diff/lcs'
-module RSpec
- module Matchers
- def have_different_contents(expected)
- Matcher.new :have_different_contents, expected do |*_expected|
- match_for_should do |actual|
- perform_match(actual, _expected)
- end
-
- match_for_should_not do |actual|
- !perform_match(actual, _expected)
- end
+RSpec::Matchers.define :have_different_contents do |x|
+ match do |actual|
+ perform_match(actual, expected)
+ end
- def perform_match(actual, expected)
- expected_lines = expected.scan(/[^\n]+/)
- actual_lines = actual.scan(/[^\n]+/)
- differences = Diff::LCS::diff(expected_lines, actual_lines)
- @diff = differences.map do |chunk|
- added_at = (add = chunk.detect{|d| d.action == '+'}) && add.position+1
- removed_at = (remove = chunk.detect{|d| d.action == '-'}) && remove.position+1
- "Line #{added_at}/#{removed_at}:\n"+
- chunk.map do |change|
- "#{change.action} #{change.element}"
- end*"\n"
- end*"\n"
- @diff != ''
- end
+ def perform_match(actual, expected)
+ expected_lines = expected.scan(/[^\n]+/)
+ actual_lines = actual.scan(/[^\n]+/)
+ differences = Diff::LCS::diff(expected_lines, actual_lines)
+ @diff = differences.map do |chunk|
+ added_at = (add = chunk.detect{|d| d.action == '+'}) && add.position+1
+ removed_at = (remove = chunk.detect{|d| d.action == '-'}) && remove.position+1
+ "Line #{added_at}/#{removed_at}:\n"+
+ chunk.map do |change|
+ "#{change.action} #{change.element}"
+ end*"\n"
+ end*"\n"
+ @diff != ''
+ end
- def failure_message_for_should
- "expected a difference, but got none"
- end
+ failure_message_for_should do |actual|
+ "expected a difference, but got none"
+ end
- failure_message_for_should_not do |actual|
- "expected no difference, but got:\n#{@diff}"
- end
- end
- end
+ failure_message_for_should_not do |actual|
+ "expected no difference, but got:\n#{@diff}"
end
end

0 comments on commit 4f3c36e

Please sign in to comment.