162 lines
4.8 KiB
Crystal
162 lines
4.8 KiB
Crystal
require "./standard_matcher"
|
|
|
|
module Spectator::Matchers
|
|
# Matcher that tests whether a value is truthy or falsey.
|
|
# Falsey means a value is considered false by an if-statement,
|
|
# which are false and nil in Crystal.
|
|
# Truthy is the opposite of falsey.
|
|
#
|
|
# Additionally, different matchers can be created
|
|
# by using the `#<`, `#<=`, `#>`, `#>=`, `#==`, and `#!=` operators.
|
|
struct TruthyMatcher < StandardMatcher
|
|
# Creates the truthy matcher.
|
|
# The *truthy* argument should be true to match "truthy" values,
|
|
# and false to match "falsey" values.
|
|
def initialize(@truthy : Bool = true)
|
|
end
|
|
|
|
# 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
|
|
"is #{label}"
|
|
end
|
|
|
|
# Creates a matcher that checks if a value is less than an expected value.
|
|
# The spec would look like:
|
|
# ```
|
|
# expect(0).to be < 1
|
|
# ```
|
|
def <(value)
|
|
expected = Value.new(value)
|
|
LessThanMatcher.new(expected)
|
|
end
|
|
|
|
# Creates a matcher that checks if a value is less than or equal to an expected value.
|
|
# The spec would look like:
|
|
# ```
|
|
# expect(0).to be <= 1
|
|
# ```
|
|
def <=(value)
|
|
expected = Value.new(value)
|
|
LessThanEqualMatcher.new(expected)
|
|
end
|
|
|
|
# Creates a matcher that checks if a value is greater than an expected value.
|
|
# The spec would look like:
|
|
# ```
|
|
# expect(2).to be > 1
|
|
# ```
|
|
def >(value)
|
|
expected = Value.new(value)
|
|
GreaterThanMatcher.new(expected)
|
|
end
|
|
|
|
# Creates a matcher that checks if a value is greater than or equal to an expected value.
|
|
# The spec would look like:
|
|
# ```
|
|
# expect(2).to be >= 1
|
|
# ```
|
|
def >=(value)
|
|
expected = Value.new(value)
|
|
GreaterThanEqualMatcher.new(expected)
|
|
end
|
|
|
|
# Creates a matcher that checks if a value is equal to an expected value.
|
|
# The spec would look like:
|
|
# ```
|
|
# expect(0).to be == 0
|
|
# ```
|
|
def ==(value)
|
|
expected = Value.new(value)
|
|
EqualityMatcher.new(expected)
|
|
end
|
|
|
|
# Creates a matcher that checks if a value is not equal to an expected value.
|
|
# The spec would look like:
|
|
# ```
|
|
# expect(0).to be != 1
|
|
# ```
|
|
def !=(value)
|
|
expected = Value.new(value)
|
|
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 = Value.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 = Value.new(value)
|
|
RegexMatcher.new(expected)
|
|
end
|
|
|
|
# Checks whether the matcher is satisfied with the expression given to it.
|
|
private def match?(actual : Expression(T)) : Bool forall T
|
|
@truthy == !!actual.value
|
|
end
|
|
|
|
# Message displayed when the matcher isn't satisfied.
|
|
#
|
|
# 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} is #{negated_label}"
|
|
end
|
|
|
|
# Message displayed when the matcher isn't satisfied 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} is #{label}"
|
|
end
|
|
|
|
# Additional information about the match failure.
|
|
# The return value is a NamedTuple with Strings for each value.
|
|
private def values(actual)
|
|
{
|
|
expected: @truthy ? "Not false or nil" : "false or nil",
|
|
actual: actual.value.inspect,
|
|
truthy: (!!actual.value).inspect,
|
|
}
|
|
end
|
|
|
|
# Additional information about the match failure when negated.
|
|
# The return value is a NamedTuple with Strings for each value.
|
|
private def negated_values(actual)
|
|
{
|
|
expected: @truthy ? "false or nil" : "Not false or nil",
|
|
actual: actual.value.inspect,
|
|
truthy: (!!actual.value).inspect,
|
|
}
|
|
end
|
|
|
|
# Generated, user-friendly, string for the expected value.
|
|
private def label
|
|
@truthy ? "truthy" : "falsey"
|
|
end
|
|
|
|
# Generated, user-friendly, string for the unexpected value.
|
|
private def negated_label
|
|
@truthy ? "falsey" : "truthy"
|
|
end
|
|
end
|
|
end
|