Add support for be === and be =~

Addresses https://github.com/icy-arctic-fox/spectator/issues/26
This commit is contained in:
Michael Miller 2021-05-19 19:46:46 -06:00
parent 18fb2d3879
commit e3576c8924
No known key found for this signature in database
GPG key ID: FB9F12F7C646A4AD
2 changed files with 61 additions and 0 deletions

View file

@ -0,0 +1,41 @@
require "./value_matcher"
module Spectator::Matchers
# Common matcher that tests whether a value matches another.
# The values are compared with the === operator.
# This is the same as `CaseMatcher`, but the operands are flipped.
struct PatternMatcher(ExpectedType) < ValueMatcher(ExpectedType)
# Short text about the matcher's purpose.
# This explains what condition satisfies the matcher.
# The description is used when the one-liner syntax is used.
def description : String
"matches #{expected.label}"
end
# Checks whether the matcher is satisifed with the expression given to it.
private def match?(actual : TestExpression(T)) : Bool forall T
actual.value === expected.value
end
# Message displayed when the matcher isn't satisifed.
#
# This is only called when `#match?` returns false.
#
# The message should typically only contain the test expression labels.
# Actual values should be returned by `#values`.
private def failure_message(actual) : String
"#{actual.label} does not match #{expected.label}"
end
# Message displayed when the matcher isn't satisifed and is negated.
# This is essentially what would satisfy the matcher if it wasn't negated.
#
# This is only called when `#does_not_match?` returns false.
#
# The message should typically only contain the test expression labels.
# Actual values should be returned by `#values`.
private def failure_message_when_negated(actual) : String
"#{actual.label} matched #{expected.label}"
end
end
end

View file

@ -82,6 +82,26 @@ module Spectator::Matchers
InequalityMatcher.new(expected)
end
# Creates a matcher that checks if a value is semantically equal to an expected value.
# The spec would look like:
# ```
# expect("foobar").to be === /foo/
# ```
def ===(value)
expected = TestValue.new(value)
PatternMatcher.new(expected)
end
# Creates a matcher that checks if a value matches the pattern of an expected value.
# The spec would look like:
# ```
# expect("foobar").to be =~ /foo/
# ```
def =~(value)
expected = TestValue.new(value)
PatternMatcher.new(expected)
end
# Checks whether the matcher is satisifed with the expression given to it.
private def match?(actual : TestExpression(T)) : Bool forall T
@truthy == !!actual.value