Don't store initial value in matcher

This commit is contained in:
Michael Miller 2019-07-19 12:07:50 -06:00
parent 770100891c
commit 59cf939536
2 changed files with 29 additions and 23 deletions

View file

@ -2,31 +2,36 @@ require "./value_matcher"
module Spectator::Matchers module Spectator::Matchers
# Matcher that tests whether an expression changed from a specific value. # Matcher that tests whether an expression changed from a specific value.
struct ChangeFromMatcher(ExpressionType, FromType) < ValueMatcher(ExpressionType) struct ChangeFromMatcher(ExpressionType, FromType) < Matcher
# Textual representation of what the matcher expects.
# This shouldn't be used in the conditional logic,
# but for verbose output to help the end-user.
getter label : String
# Determines whether the matcher is satisfied with the partial given to it. # Determines whether the matcher is satisfied with the partial given to it.
# `MatchData` is returned that contains information about the match. # `MatchData` is returned that contains information about the match.
def match(partial) def match(partial)
partial.actual # Invoke action that might change the expression's value. before = @expression.call # Retrieve the expression's initial value.
after = @expression.call # Retrieve the expression's value. partial.actual # Invoke action that might change the expression's value.
if expected != @actual_before after = @expression.call # Retrieve the expression's value again.
if @expected_before != before
# Initial value isn't what was expected. # Initial value isn't what was expected.
InitialMatchData.new(expected, @actual_before, after, partial.label, label) InitialMatchData.new(@expected_before, before, after, partial.label, label)
else else
# Check if the expression's value changed. # Check if the expression's value changed.
matched = expected != after same = before == after
ChangeMatchData.new(matched, expected, @actual_before, after, partial.label, label) ChangeMatchData.new(!same, @expected_before, before, after, partial.label, label)
end end
end end
# Creates a new change matcher with a custom label. # Creates a new change matcher with a custom label.
def initialize(expression_label : String, expected_before : FromType, @actual_before : ExpressionType, &expression : -> ExpressionType) def initialize(@label, @expected_before : FromType, &expression : -> ExpressionType)
super(expected_before, expression_label)
@expression = expression @expression = expression
end end
# Creates a new change matcher. # Creates a new change matcher.
def initialize(expected_before : FromType, @actual_before : ExpressionType, &expression : -> ExpressionType) def initialize(@expected_before : FromType, &expression : -> ExpressionType)
super(expected_before, expression.to_s) @label = expression.to_s
@expression = expression @expression = expression
end end

View file

@ -3,35 +3,36 @@ require "./value_matcher"
module Spectator::Matchers module Spectator::Matchers
# Matcher that tests whether an expression changed. # Matcher that tests whether an expression changed.
struct ChangeMatcher(ExpressionType) < ValueMatcher(ExpressionType) struct ChangeMatcher(ExpressionType) < Matcher
# Determines whether the matcher is satisfied with the value given to it. # Textual representation of what the matcher expects.
private def match?(after) # This shouldn't be used in the conditional logic,
expected != after # but for verbose output to help the end-user.
end getter label : String
# Determines whether the matcher is satisfied with the partial given to it. # Determines whether the matcher is satisfied with the partial given to it.
# `MatchData` is returned that contains information about the match. # `MatchData` is returned that contains information about the match.
def match(partial) def match(partial)
partial.actual # Invoke action that might change the expression's value. before = @expression.call # Retrieve the expression's initial value.
after = @expression.call # Retrieve the expression's value. partial.actual # Invoke action that might change the expression's value.
MatchData.new(match?(after), expected, after, partial.label, label) after = @expression.call # Retrieve the expression's value again.
same = before == after # Did the value change?
MatchData.new(!same, before, after, partial.label, label)
end end
# Creates a new change matcher with a custom label. # Creates a new change matcher with a custom label.
def initialize(label : String, &expression : -> ExpressionType) def initialize(@label, &expression : -> ExpressionType)
super(yield, label)
@expression = expression @expression = expression
end end
# Creates a new change matcher. # Creates a new change matcher.
def initialize(&expression : -> ExpressionType) def initialize(&expression : -> ExpressionType)
super(yield, expression.to_s) @label = expression.to_s
@expression = expression @expression = expression
end end
# Specifies what the initial value of the expression must be. # Specifies what the initial value of the expression must be.
def from(value : T) forall T def from(value : T) forall T
ChangeFromMatcher.new(label, value, expected, &@expression) ChangeFromMatcher.new(label, value, &@expression)
end end
# Match data specific to this matcher. # Match data specific to this matcher.