mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
Cleanup have_ variant by using a new matcher
This commit is contained in:
parent
16bcce59ae
commit
091cbaa81a
2 changed files with 69 additions and 3 deletions
|
@ -579,9 +579,11 @@ module Spectator::DSL
|
|||
{% if call.name.starts_with?("be_") %}
|
||||
# Remove `be_` prefix.
|
||||
{% method_name = call.name[3..-1] %}
|
||||
{% matcher = "PredicateMatcher" %}
|
||||
{% elsif call.name.starts_with?("have_") %}
|
||||
# Swap `have_` with `has_`.
|
||||
{% method_name = ("has_" + call.name[5..-1].stringify).id %}
|
||||
# Remove `have_` prefix.
|
||||
{% method_name = call.name[5..-1] %}
|
||||
{% matcher = "HavePredicateMatcher" %}
|
||||
{% else %}
|
||||
{% raise "Undefined local variable or method '#{call}'" %}
|
||||
{% end %}
|
||||
|
@ -598,7 +600,7 @@ module Spectator::DSL
|
|||
{% end %}
|
||||
label << ')'
|
||||
{% end %}
|
||||
::Spectator::Matchers::PredicateMatcher.new(descriptor, label.to_s)
|
||||
::Spectator::Matchers::{{matcher.id}}.new(descriptor, label.to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
64
src/spectator/matchers/have_predicate_matcher.cr
Normal file
64
src/spectator/matchers/have_predicate_matcher.cr
Normal file
|
@ -0,0 +1,64 @@
|
|||
require "./value_matcher"
|
||||
|
||||
module Spectator::Matchers
|
||||
# Matcher that tests one or more "has" predicates
|
||||
# (methods ending in '?' and starting with 'has_').
|
||||
# The `ExpectedType` type param should be a `NamedTuple`.
|
||||
# Each key in the tuple is a predicate (without the '?' and 'has_' prefix) to test.
|
||||
# Each value is a a `Tuple` of arguments to pass to the predicate method.
|
||||
struct HavePredicateMatcher(ExpectedType) < ValueMatcher(ExpectedType)
|
||||
# Determines whether the matcher is satisfied with the value given to it.
|
||||
private def match?(values)
|
||||
# Test each predicate and immediately return false if one is false.
|
||||
{% for attribute in ExpectedType.keys %}
|
||||
return false unless values[{{attribute.symbolize}}]
|
||||
{% end %}
|
||||
|
||||
# All checks passed if this point is reached.
|
||||
true
|
||||
end
|
||||
|
||||
# Determines whether the matcher is satisfied with the partial given to it.
|
||||
# `MatchData` is returned that contains information about the match.
|
||||
def match(partial) : MatchData
|
||||
values = snapshot_values(partial.actual)
|
||||
MatchData.new(match?(values), values, partial.label, label)
|
||||
end
|
||||
|
||||
# Captures all of the actual values.
|
||||
# A `NamedTuple` is returned,
|
||||
# with each key being the attribute.
|
||||
private def snapshot_values(actual)
|
||||
{% begin %}
|
||||
{
|
||||
{% for attribute in ExpectedType.keys %}
|
||||
{{attribute}}: actual.has_{{attribute}}?(*@expected[{{attribute.symbolize}}]),
|
||||
{% end %}
|
||||
}
|
||||
{% end %}
|
||||
end
|
||||
|
||||
# Match data specific to this matcher.
|
||||
private struct MatchData(ActualType) < MatchData
|
||||
# Creates the match data.
|
||||
def initialize(matched, @named_tuple : ActualType, @actual_label : String, @expected_label : String)
|
||||
super(matched)
|
||||
end
|
||||
|
||||
# Information about the match.
|
||||
getter named_tuple
|
||||
|
||||
# Describes the condition that satisfies the matcher.
|
||||
# This is informational and displayed to the end-user.
|
||||
def message
|
||||
"#{@actual_label} has #{@expected_label}"
|
||||
end
|
||||
|
||||
# Describes the condition that won't satsify the matcher.
|
||||
# This is informational and displayed to the end-user.
|
||||
def negated_message
|
||||
"#{@actual_label} does not have #{@expected_label}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue