1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
|
module RSpec
module Expectations
class << self
# @private
def differ
@differ ||= Differ.new
end
# Raises an RSpec::Expectations::ExpectationNotMetError with message.
# @param [String] message
# @param [Object] expected
# @param [Object] actual
#
# Adds a diff to the failure message when `expected` and `actual` are
# both present.
def fail_with(message, expected=nil, actual=nil)
if !message
raise ArgumentError, "Failure message is nil. Does your matcher define the " +
"appropriate failure_message_for_* method to return a string?"
end
if actual && expected
if all_strings?(actual, expected)
if any_multiline_strings?(actual, expected)
message << "\nDiff:" << differ.diff_as_string(coerce_to_string(actual), coerce_to_string(expected))
end
elsif no_procs?(actual, expected) && no_numbers?(actual, expected)
message << "\nDiff:" << differ.diff_as_object(actual, expected)
end
end
raise(RSpec::Expectations::ExpectationNotMetError.new(message))
end
private
def no_procs?(*args)
args.flatten.none? {|a| Proc === a}
end
def all_strings?(*args)
args.flatten.all? {|a| String === a}
end
def any_multiline_strings?(*args)
all_strings?(*args) && args.flatten.any? { |a| multiline?(a) }
end
def no_numbers?(*args)
args.flatten.none? {|a| Numeric === a}
end
def coerce_to_string(string_or_array)
return string_or_array unless Array === string_or_array
diffably_stringify(string_or_array).join("\n")
end
def diffably_stringify(array)
array.map do |entry|
if Array === entry
entry.inspect
else
entry.to_s.gsub("\n", "\\n")
end
end
end
if String.method_defined?(:encoding)
def multiline?(string)
string.include?("\n".encode(string.encoding))
end
else
def multiline?(string)
string.include?("\n")
end
end
end
end
end
|