mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
Add relative change matcher
This commit is contained in:
parent
c19f442e6c
commit
4e15487a0f
2 changed files with 73 additions and 0 deletions
|
@ -7,6 +7,7 @@ require "./successful_match_data"
|
||||||
module Spectator::Matchers
|
module Spectator::Matchers
|
||||||
# Matcher that tests whether an expression changed.
|
# Matcher that tests whether an expression changed.
|
||||||
struct ChangeMatcher(ExpressionType) < Matcher
|
struct ChangeMatcher(ExpressionType) < Matcher
|
||||||
|
# The expression that is expected to (not) change.
|
||||||
private getter expression
|
private getter expression
|
||||||
|
|
||||||
# Creates a new change matcher.
|
# Creates a new change matcher.
|
||||||
|
@ -57,6 +58,21 @@ module Spectator::Matchers
|
||||||
ChangeToMatcher.new(@expression, value)
|
ChangeToMatcher.new(@expression, value)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Specifies that t he resulting value must be some amount different.
|
||||||
|
def by(amount : T) forall T
|
||||||
|
ChangeRelativeMatcher.new(@expression, "by #{amount}") { |before, after| amount == after - before }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Specifies that the resulting value must be at least some amount different.
|
||||||
|
def by_at_least(minimum : T) forall T
|
||||||
|
ChangeRelativeMatcher.new(@expression, "by at least #{minimum}") { |before, after| minimum <= after - before }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Specifies that the resulting value must be at most some amount different.
|
||||||
|
def by_at_most(maximum : T) forall T
|
||||||
|
ChangeRelativeMatcher.new(@expression, "by at most #{maximum}") { |before, after| maximum >= after - before }
|
||||||
|
end
|
||||||
|
|
||||||
# Performs the change and reports the before and after values.
|
# Performs the change and reports the before and after values.
|
||||||
private def change(actual)
|
private def change(actual)
|
||||||
before = expression.value # Retrieve the expression's initial value.
|
before = expression.value # Retrieve the expression's initial value.
|
||||||
|
|
57
src/spectator/matchers/change_relative_matcher.cr
Normal file
57
src/spectator/matchers/change_relative_matcher.cr
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
require "./failed_match_data"
|
||||||
|
require "./matcher"
|
||||||
|
require "./successful_match_data"
|
||||||
|
|
||||||
|
module Spectator::Matchers
|
||||||
|
# Matcher that tests whether an expression changed by an amount.
|
||||||
|
struct ChangeRelativeMatcher(ExpressionType) < Matcher
|
||||||
|
# The expression that is expected to (not) change.
|
||||||
|
private getter expression
|
||||||
|
|
||||||
|
# Creates a new change matcher.
|
||||||
|
def initialize(@expression : TestBlock(ExpressionType), @relativity : String,
|
||||||
|
&evaluator : ExpressionType, ExpressionType -> Bool)
|
||||||
|
@evaluator = evaluator
|
||||||
|
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
|
||||||
|
"changes #{expression.label} #{@relativity}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Actually performs the test against the expression.
|
||||||
|
def match(actual : TestExpression(T)) : MatchData forall T
|
||||||
|
before, after = change(actual)
|
||||||
|
if before == after
|
||||||
|
FailedMatchData.new("#{actual.label} did not change #{expression.label}",
|
||||||
|
before: before.inspect,
|
||||||
|
after: after.inspect
|
||||||
|
)
|
||||||
|
elsif @evaluator.call(before, after)
|
||||||
|
SuccessfulMatchData.new
|
||||||
|
else
|
||||||
|
FailedMatchData.new("#{actual.label} did not change #{expression.label} #{@relativity}",
|
||||||
|
before: before.inspect,
|
||||||
|
after: after.inspect
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# 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
|
||||||
|
{% raise "The `expect { }.to_not change { }.by_...()` syntax is not supported (ambiguous)." %}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Performs the change and reports the before and after values.
|
||||||
|
private def change(actual)
|
||||||
|
before = expression.value # Retrieve the expression's initial value.
|
||||||
|
actual.value # Invoke action that might change the expression's value.
|
||||||
|
after = expression.value # Retrieve the expression's value again.
|
||||||
|
|
||||||
|
{before, after}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue