Permalink
Browse files

Make the error message more useful when using match_array

* 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...
1 parent e2ef482 commit e2a9e3f84f17622b832c08ed3106f4f82842bbcf @samphippen samphippen committed with alindeman Oct 26, 2012
Showing with 29 additions and 6 deletions.
  1. +3 −0 Changelog.md
  2. +12 −6 lib/rspec/matchers/built_in/match_array.rb
  3. +14 −0 spec/rspec/matchers/match_array_spec.rb
View
@@ -8,6 +8,9 @@ Enhancements
matcher (Myron Marston)
* Print a warning when users accidentally pass a non-string argument
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
@@ -3,16 +3,22 @@ module Matchers
module BuiltIn
class MatchArray < BaseMatcher
def match(expected, actual)
+ return false unless actual.respond_to? :to_ary
@extra_items = difference_between_arrays(actual, expected)
@missing_items = difference_between_arrays(expected, actual)
@extra_items.empty? & @missing_items.empty?
end
def failure_message_for_should
- message = "expected collection contained: #{safe_sort(expected).inspect}\n"
- message += "actual collection contained: #{safe_sort(actual).inspect}\n"
- 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?
+ if actual.respond_to? :to_ary
+ message = "expected collection contained: #{safe_sort(expected).inspect}\n"
+ message += "actual collection contained: #{safe_sort(actual).inspect}\n"
+ 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
end
@@ -31,8 +37,8 @@ def safe_sort(array)
end
def difference_between_arrays(array_1, array_2)
- difference = array_1.dup
- array_2.each do |element|
+ difference = array_1.to_ary.dup
+ array_2.to_ary.each do |element|
if index = difference.index(element)
difference.delete_at(index)
end
@@ -122,3 +122,17 @@ def ==(other)
}.should fail_with(/Matcher does not support should_not/)
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.