Resolve various duck-typing issues

This commit is contained in:
Michael Miller 2019-08-09 11:13:13 -06:00
parent 114bfa47c2
commit 3d86893f44
3 changed files with 43 additions and 42 deletions

View file

@ -17,35 +17,35 @@ module Spectator::Matchers
end end
def match(actual) def match(actual)
if actual.value.responds_to?(:ends_with?) if (value = actual.value).responds_to?(:ends_with?)
match_ends_with(actual) match_ends_with(value, actual.label)
else else
match_last(actual) match_last(value, actual.label)
end end
end end
private def match_ends_with(actual) private def match_ends_with(actual_value, actual_label)
if actual.value.ends_with?(expected.value) if actual_value.ends_with?(expected.value)
SuccessfulMatchData.new SuccessfulMatchData.new
else else
FailedMatchData.new("#{actual.label} does not end with #{expected.label} (using #ends_with?)", FailedMatchData.new("#{actual_label} does not end with #{expected.label} (using #ends_with?)",
expected: expected.value.inspect, expected: expected.value.inspect,
actual: actual.value.inspect actual: actual_value.inspect
) )
end end
end end
private def match_last(actual) private def match_last(actual_value, actual_label)
list = actual.value.to_a list = actual_value.to_a
last = list.last last = list.last
if expected.value === last if expected.value === last
SuccessfulMatchData.new SuccessfulMatchData.new
else else
FailedMatchData.new("#{actual.label} does not end with #{expected.label} (using expected === last)", FailedMatchData.new("#{actual_label} does not end with #{expected.label} (using expected === last)",
expected: expected.value, expected: expected.value.inspect,
actual: last, actual: last.inspect,
list: list list: list.inspect
) )
end end
end end
@ -75,9 +75,9 @@ module Spectator::Matchers
if expected.value === last if expected.value === last
FailedMatchData.new("#{actual.label} ends with #{expected.label} (using expected === last)", FailedMatchData.new("#{actual.label} ends with #{expected.label} (using expected === last)",
expected: expected.value, expected: expected.value.inspect,
actual: last, actual: last.inspect,
list: list list: list.inspect
) )
else else
SuccessfulMatchData.new SuccessfulMatchData.new

View file

@ -17,7 +17,7 @@ module Spectator::Matchers
# The `includes?` method is used for this check. # The `includes?` method is used for this check.
private def match_string?(value) private def match_string?(value)
expected.value.all? do |item| expected.value.all? do |item|
value.includes?(item) if item.is_a?(Char | String) value.includes?(item)
end end
end end

View file

@ -15,66 +15,67 @@ module Spectator::Matchers
end end
def match(actual) def match(actual)
if actual.value.responds_to?(:starts_with?) if (value = actual.value).responds_to?(:starts_with?)
match_starts_with(actual) match_starts_with(value, actual.label)
else else
match_first(actual) match_first(value, actual.label)
end end
end end
private def match_starts_with(actual) private def match_starts_with(actual_value, actual_label)
if actual.value.starts_with?(expected.value) if actual_value.starts_with?(expected.value)
SuccessfulMatchData.new SuccessfulMatchData.new
else else
FailedMatchData.new("#{actual.label} does not start with #{expected.label} (using #starts_with?)", FailedMatchData.new("#{actual_label} does not start with #{expected.label} (using #starts_with?)",
expected: expected.value.inspect, expected: expected.value.inspect,
actual: actual.value.inspect actual: actual_value.inspect
) )
end end
end end
private def match_first(value, actual) private def match_first(actual_value, actual_label)
list = actual_value.to_a
first = list.first first = list.first
if expected.value === first if expected.value === first
SuccessfulMatchData.new SuccessfulMatchData.new
else else
FailedMatchData.new("#{actual.label} does not start with #{expected.label} (using expected === first)", FailedMatchData.new("#{actual_label} does not start with #{expected.label} (using expected === first)",
expected: expected.value, expected: expected.value.inspect,
actual: first, actual: first.inspect,
list: list list: list.inspect
) )
end end
end end
def negated_match(actual) def negated_match(actual)
if actual.value.responds_to?(:starts_with?) if (value = actual.value).responds_to?(:starts_with?)
negated_match_starts_with(actual) negated_match_starts_with(value, actual.label)
else else
negated_match_first(actual) negated_match_first(value, actual.label)
end end
end end
private def negated_match_starts_with(actual) private def negated_match_starts_with(actual_value, actual_label)
if actual.value.starts_with?(expected.value) if actual_value.starts_with?(expected.value)
FailedMatchData.new("#{actual.label} starts with #{expected.label} (using #starts_with?)", FailedMatchData.new("#{actual_label} starts with #{expected.label} (using #starts_with?)",
expected: expected.value.inspect, expected: expected.value.inspect,
actual: actual.value.inspect actual: actual_value.inspect
) )
else else
SuccessfulMatchData.new SuccessfulMatchData.new
end end
end end
private def negated_match_first(actual) private def negated_match_first(actual_value, actual_label)
list = actual.value.to_a list = actual_value.to_a
first = list.first first = list.first
if expected.value === first if expected.value === first
FailedMatchData.new("#{actual.label} starts with #{expected.label} (using expected === first)", FailedMatchData.new("#{actual_label} starts with #{expected.label} (using expected === first)",
expected: expected.value, expected: expected.value.inspect,
actual: first, actual: first.inspect,
list: list list: list.inspect
) )
else else
SuccessfulMatchData.new SuccessfulMatchData.new