Navigation Menu

Skip to content

Commit

Permalink
Make the error message more useful when using match_array
Browse files Browse the repository at this point in the history
* Now the error message will let you know if you're trying to match an
  array against something that isn't an array-like thing.
* Closes #186
* Fixes #185
  • Loading branch information
Sam Phippen authored and alindeman committed Oct 27, 2012
1 parent e2ef482 commit e2a9e3f
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 6 deletions.
3 changes: 3 additions & 0 deletions Changelog.md
Expand Up @@ -8,6 +8,9 @@ Enhancements
matcher (Myron Marston) matcher (Myron Marston)
* Print a warning when users accidentally pass a non-string argument * Print a warning when users accidentally pass a non-string argument
as an expectation message (Sam Phippen) as an expectation message (Sam Phippen)
* `=~` and `match_array` matchers output a more useful error message when
the actual value is not an array (or an object that responds to `#to_ary`)
(Sam Phippen)


Bug fixes Bug fixes


Expand Down
18 changes: 12 additions & 6 deletions lib/rspec/matchers/built_in/match_array.rb
Expand Up @@ -3,16 +3,22 @@ module Matchers
module BuiltIn module BuiltIn
class MatchArray < BaseMatcher class MatchArray < BaseMatcher
def match(expected, actual) def match(expected, actual)
return false unless actual.respond_to? :to_ary
@extra_items = difference_between_arrays(actual, expected) @extra_items = difference_between_arrays(actual, expected)
@missing_items = difference_between_arrays(expected, actual) @missing_items = difference_between_arrays(expected, actual)
@extra_items.empty? & @missing_items.empty? @extra_items.empty? & @missing_items.empty?
end end


def failure_message_for_should def failure_message_for_should
message = "expected collection contained: #{safe_sort(expected).inspect}\n" if actual.respond_to? :to_ary
message += "actual collection contained: #{safe_sort(actual).inspect}\n" message = "expected collection contained: #{safe_sort(expected).inspect}\n"
message += "the missing elements were: #{safe_sort(@missing_items).inspect}\n" unless @missing_items.empty? message += "actual collection contained: #{safe_sort(actual).inspect}\n"
message += "the extra elements were: #{safe_sort(@extra_items).inspect}\n" unless @extra_items.empty? message += "the missing elements were: #{safe_sort(@missing_items).inspect}\n" unless @missing_items.empty?
message += "the extra elements were: #{safe_sort(@extra_items).inspect}\n" unless @extra_items.empty?
else
message = "expected an array, actual collection was #{actual.inspect}"
end

message message
end end


Expand All @@ -31,8 +37,8 @@ def safe_sort(array)
end end


def difference_between_arrays(array_1, array_2) def difference_between_arrays(array_1, array_2)
difference = array_1.dup difference = array_1.to_ary.dup
array_2.each do |element| array_2.to_ary.each do |element|
if index = difference.index(element) if index = difference.index(element)
difference.delete_at(index) difference.delete_at(index)
end end
Expand Down
14 changes: 14 additions & 0 deletions spec/rspec/matchers/match_array_spec.rb
Expand Up @@ -122,3 +122,17 @@ def ==(other)
}.should fail_with(/Matcher does not support should_not/) }.should fail_with(/Matcher does not support should_not/)
end end
end end

describe "matching against things that aren't arrays" do
it "fails with nil and the expected error message is given" do
expect { nil.should match_array([1,2,3]) }.to fail_with(/expected an array/)
end

it "fails with a float and the expected error message is given" do
expect { (3.7).should match_array([1,2,3]) }.to fail_with(/expected an array/)
end

it "fails with a string and the expected error message is given" do
expect { "I like turtles".should match_array([1,2,3]) }.to fail_with(/expected an array/)
end
end

0 comments on commit e2a9e3f

Please sign in to comment.