Check that actual value is a collection

Previously, a compilation error would occur if the actual value didn't 
respond to `to_a`.
A way to reproduce this is for the actual value to be nilable.
This commit is contained in:
Michael Miller 2020-04-03 11:32:37 -06:00
parent 748c25afcb
commit 7fadd92f62
2 changed files with 24 additions and 4 deletions

View file

@ -23,7 +23,10 @@ module Spectator::Matchers
# Actually performs the test against the expression.
def match(actual : TestExpression(T)) : MatchData forall T
actual_elements = actual.value.to_a
actual_value = actual.value
return unexpected(actual_value, actual.label) unless actual_value.responds_to?(:to_a)
actual_elements = actual_value.to_a
expected_elements = expected.value.to_a
missing, extra = compare_arrays(expected_elements, actual_elements)
@ -44,7 +47,10 @@ module Spectator::Matchers
# Performs the test against the expression, but inverted.
# A successful match with `#match` should normally fail for this method, and vice-versa.
def negated_match(actual : TestExpression(T)) : MatchData forall T
actual_elements = actual.value.to_a
actual_value = actual.value
return unexpected(actual_value, actual.label) unless actual_value.responds_to?(:to_a)
actual_elements = actual_value.to_a
expected_elements = expected.value.to_a
missing, extra = compare_arrays(expected_elements, actual_elements)
@ -108,5 +114,9 @@ module Spectator::Matchers
Array.new(count, element)
end.flatten
end
private def unexpected(value, label)
raise "#{label} is not a collection (must respond to `#to_a`). #{label}: #{value.inspect}"
end
end
end

View file

@ -20,7 +20,10 @@ module Spectator::Matchers
# Actually performs the test against the expression.
def match(actual : TestExpression(T)) : MatchData forall T
actual_elements = actual.value.to_a
actual_value = actual.value
return unexpected(actual_value, actual.label) unless actual_value.responds_to?(:to_a)
actual_elements = actual_value.to_a
expected_elements = expected.value.to_a
missing, extra = array_diff(expected_elements, actual_elements)
@ -39,7 +42,10 @@ module Spectator::Matchers
# Performs the test against the expression, but inverted.
# A successful match with `#match` should normally fail for this method, and vice-versa.
def negated_match(actual : TestExpression(T)) : MatchData forall T
actual_elements = actual.value.to_a
actual_value = actual.value
return unexpected(actual_value, actual.label) unless actual_value.responds_to?(:to_a)
actual_elements = actual_value.to_a
expected_elements = expected.value.to_a
missing, extra = array_diff(expected_elements, actual_elements)
@ -71,5 +77,9 @@ module Spectator::Matchers
{missing, extra}
end
private def unexpected(value, label)
raise "#{label} is not a collection (must respond to `#to_a`). #{label}: #{value.inspect}"
end
end
end