Change Expectation to store the result

This removes Expectation::Result and uses Expectation and sub-types
instead.
Having two "Result" types is confusing.
This commit is contained in:
Michael Miller 2018-11-13 14:08:27 -07:00
parent e38747eafd
commit 06ced9f799
2 changed files with 40 additions and 63 deletions

View file

@ -1,57 +1,35 @@
module Spectator::Expectations
# Min-in for all expectation types.
# Classes that include this must implement
# the `#satisfied?`, `#message`, and `#negated_message` methods.
# Typically, expectation classes/structs store an `ExpectationPartial`
# and a `Matchers::Matcher` and then proxy calls to those instances.
module Expectation
# Checks whether the expectation is met.
abstract def satisfied? : Bool
# Describes the condition that must be met for the expectation to be satisifed.
abstract def message : String
# Describes the condition under which the expectation won't be satisifed.
abstract def negated_message : String
# Evaulates the expectation and produces a result.
# The `negated` flag should be set to true to invert the result.
def eval(negated = false) : Result
success = satisfied? ^ negated
Result.new(success, negated, self)
abstract class Expectation
# Populates the base portiion of the expectation with values.
# The `matched` flag should be true if the matcher is satisfied with the partial.
# The `negated` flag should be true if the expectation is inverted.
# These options are mutually-exclusive in this context.
# Don't flip the value of `matched` because `negated` is true.
def initialize(@matched : Bool, @negated : Bool)
end
# Information regarding the outcome of an expectation.
class Result
# Indicates whether the expectation was satisifed or not.
getter? successful : Bool
# Indicates whether the expectation failed.
def failure? : Bool
!@successful
end
# Creates the result.
# The expectation is stored so that information from it may be lazy-loaded.
protected def initialize(@successful, @negated : Bool, @expectation : Expectation)
end
# Description of the condition that satisfies, or meets, the expectation.
def expected_message
message(@negated)
end
# Description of what actually happened when the expectation was evaluated.
def actual_message
message(!@successful)
end
# Retrieves the message or negated message from an expectation.
# Set `negated` to true to get the negated message,
# or to false to get the regular message.
private def message(negated)
negated ? @expectation.negated_message : @expectation.message
end
# Indicates whether the expectation was satisifed.
# This is true if:
# - The matcher was satisified and the expectation is not negated.
# - The matcher wasn't satisfied and the expectation is negated.
def satisfied?
@matched ^ @negated
end
# Text that indicates the condition that must be met for the expectation to be satisifed.
def expected_message
@negated ? negated_message : message
end
# Text that indicates what the outcome was.
def actual_message
@matched ? message : negated_message
end
# Describes the condition that must be met for the matcher to be satisifed.
private abstract def message : String
# Describes the condition under which the matcher won't be satisifed.
private abstract def negated_message : String
end
end

View file

@ -5,27 +5,26 @@ module Spectator::Expectations
# There are two values - the actual and expected.
# The actual value is what the SUT returned.
# The expected value is what the test wants to see.
struct ValueExpectation(ActualType, ExpectedType)
include Expectation
class ValueExpectation(ActualType, ExpectedType) < Expectation
# Creates the expectation.
# This simply takes in the expectation partial and the matcher.
def initialize(@partial : ValueExpectationPartial(ActualType),
# The `matched` flag should be true if the matcher is satisfied with the partial.
# The `negated` flag should be true if the expectation is inverted.
# See `Expectation#initialize` for details on these two arguments.
# The `partial` and the `matcher` arguments should reference
# the actual and expected value with matcher respectively.
def initialize(matched, negated,
@partial : ValueExpectationPartial(ActualType),
@matcher : Matchers::ValueMatcher(ExpectedType))
end
# Checks whether the expectation is met.
def satisfied? : Bool
@matcher.match?(@partial)
super(matched, negated)
end
# Describes the condition that must be met for the expectation to be satisifed.
def message : String
private def message : String
@matcher.message(@partial)
end
# Describes the condition under which the expectation won't be satisifed.
def negated_message : String
private def negated_message : String
@matcher.negated_message(@partial)
end
end