Fix EndWithMatcher compile errors

This commit is contained in:
Michael Miller 2019-03-04 21:43:26 -07:00
parent 7b0f607a6a
commit 52f8c52a58

View file

@ -7,7 +7,11 @@ module Spectator::Matchers
struct EndWithMatcher(ExpectedType) < ValueMatcher(ExpectedType) struct EndWithMatcher(ExpectedType) < ValueMatcher(ExpectedType)
# Determines whether the matcher is satisfied with the value given to it. # Determines whether the matcher is satisfied with the value given to it.
private def match?(actual) private def match?(actual)
compare_method(actual, &.eval(actual, expected)) if actual.responds_to?(:ends_with?)
actual.ends_with?(expected)
else
expected === actual.last
end
end end
# Determines whether the matcher is satisfied with the partial given to it. # Determines whether the matcher is satisfied with the partial given to it.
@ -17,23 +21,6 @@ module Spectator::Matchers
MatchData.new(match?(values.actual), values) MatchData.new(match?(values.actual), values)
end end
# Returns the method that should be used for comparison.
# Call `eval(actual, expected)` on the returned value.
private macro compare_method(actual, &block)
# If the actual type defines `ends_with?`,
# then use that for the comparison.
# Otherwise, treat the actual type as an `Indexable`,
# and retrieve the last value to compare with.
# FIXME: Is there a better way to do this?
if {{actual}}.responds_to?(:ends_with?)
{{block.args.first}} = EndsWithCompareMethod.new
{{block.body}}
else
{{block.args.first}} = IndexableCompareMethod.new
{{block.body}}
end
end
# Match data specific to this matcher. # Match data specific to this matcher.
private struct MatchData(ExpectedType, ActualType) < MatchData private struct MatchData(ExpectedType, ActualType) < MatchData
# Creates the match data. # Creates the match data.
@ -52,42 +39,22 @@ module Spectator::Matchers
# Describes the condition that satisfies the matcher. # Describes the condition that satisfies the matcher.
# This is informational and displayed to the end-user. # This is informational and displayed to the end-user.
def message def message
method_string = compare_method(partial.actual, &.to_s) "#{@values.actual_label} ends with #{@values.expected_label} (using #{comparison_method})"
"#{values.actual_label} ends with #{values.expected_label} (using #{method_string})"
end end
# Describes the condition that won't satsify the matcher. # Describes the condition that won't satsify the matcher.
# This is informational and displayed to the end-user. # This is informational and displayed to the end-user.
def negated_message def negated_message
method_string = compare_method(partial.actual, &.to_s) "#{@values.actual_label} does not end with #{@values.expected_label} (using #{comparison_method})"
"#{values.actual_label} does not end with #{values.expected_label} (using #{method_string})"
end
end end
# Comparison method for types that define the `ends_with?` method. private def comparison_method
private struct EndsWithCompareMethod if @values.actual.responds_to?(:ends_with?)
# Evaluates the condition to determine whether the matcher is satisfied.
def eval(actual, expected)
actual.ends_with?(expected)
end
# String representation for end-user output.
def to_s
"#ends_with?" "#ends_with?"
end else
end
# Comparison method for `Indexable` types.
private struct IndexableCompareMethod
# Evaluates the condition to determine whether the matcher is satisfied.
def eval(actual, expected)
expected === actual.last
end
# String representation for end-user output.
def to_s
"expected === actual.last" "expected === actual.last"
end end
end end
end end
end end
end