mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
More structure around exceptions and matching
This commit is contained in:
parent
4c2f6157af
commit
79886e9efb
9 changed files with 95 additions and 30 deletions
|
@ -1,11 +1,50 @@
|
|||
module Spectator::Expectations
|
||||
abstract class Expectation
|
||||
getter? negated : Bool
|
||||
# Min-in for all expectation types.
|
||||
# Classes that include this must implement
|
||||
# the `#satisfied?`, `#message`, and `#negated_message` methods.
|
||||
module Expectation
|
||||
# Checks whether the expectation is met.
|
||||
abstract def satisfied? : Bool
|
||||
|
||||
private def initialize(@negated)
|
||||
# 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)
|
||||
end
|
||||
|
||||
abstract def eval : Bool
|
||||
abstract def message : String
|
||||
# Information regarding the outcome of an expectation.
|
||||
class Result
|
||||
# Indicates whether the expectation was satisifed or not.
|
||||
getter? successful : Bool
|
||||
|
||||
# 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 satisfy_message
|
||||
message(@negated)
|
||||
end
|
||||
|
||||
# Description of what actually happened when the expectation was evaluated.
|
||||
def result_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
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@ module Spectator::Expectations
|
|||
private def initialize(@raise_on_failure = true)
|
||||
end
|
||||
|
||||
def report(expectation : Expectation) : Nil
|
||||
def report(result : Expectation::Result) : Nil
|
||||
raise NotImplementedError.new("ExpectationRegistry#report")
|
||||
end
|
||||
|
||||
|
@ -15,11 +15,11 @@ module Spectator::Expectations
|
|||
raise NotImplementedError.new("ExpectationRegistry.current")
|
||||
end
|
||||
|
||||
def self.start(example : Example) : ExpectationRegistry
|
||||
def self.start(example : Example) : Nil
|
||||
raise NotImplementedError.new("ExpectationRegistry.start")
|
||||
end
|
||||
|
||||
def self.finish : Nil # TODO: Define return type.
|
||||
def self.finish : ExpectationResults
|
||||
raise NotImplementedError.new("ExpectationRegistry.finish")
|
||||
end
|
||||
end
|
||||
|
|
6
src/spectator/expectations/expectation_results.cr
Normal file
6
src/spectator/expectations/expectation_results.cr
Normal file
|
@ -0,0 +1,6 @@
|
|||
module Spectator::Expectations
|
||||
class ExpectationResults
|
||||
def initialize(@results : Enumerable(ExpectationResult))
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,19 +1,26 @@
|
|||
require "./expectation"
|
||||
|
||||
module Spectator::Expectations
|
||||
class ValueExpectation(ActualType, ExpectedType) < Expectation
|
||||
def initialize(negated,
|
||||
@partial : ValueExpectationPartial(ActualType),
|
||||
@matcher : ValueMatcher(ExpectedType))
|
||||
super(negated)
|
||||
class ValueExpectation(ActualType, ExpectedType)
|
||||
include Expectation
|
||||
|
||||
def initialize(@partial : ValueExpectationPartial(ActualType),
|
||||
@matcher : Matchers::ValueMatcher(ExpectedType))
|
||||
end
|
||||
|
||||
def eval : Bool
|
||||
@matcher.match?(@partial) ^ negated?
|
||||
# Checks whether the expectation is met.
|
||||
def satisfied? : Bool
|
||||
@matcher.match?(@partial)
|
||||
end
|
||||
|
||||
# Describes the condition that must be met for the expectation to be satisifed.
|
||||
def message : String
|
||||
negated? ? @matcher.negated_message(@partial) : @matcher.message(@partial)
|
||||
@matcher.message(@partial)
|
||||
end
|
||||
|
||||
# Describes the condition under which the expectation won't be satisifed.
|
||||
def negated_message : String
|
||||
@matcher.negated_message(@partial)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,11 +9,15 @@ module Spectator::Expectations
|
|||
end
|
||||
|
||||
def to(matcher : Matchers::ValueMatcher(ExpectedType)) : Nil forall ExpectedType
|
||||
raise NotImplementedError.new("ValueExpectationPartial#to")
|
||||
expectation = ValueExpectation.new(self, matcher)
|
||||
result = expectation.eval
|
||||
ExpectationRegistry.current.report(result)
|
||||
end
|
||||
|
||||
def to_not(matcher : Matchers::ValueMatcher(ExpectedType)) : Nil forall ExpectedType
|
||||
raise NotImplementedError.new("ValueExpectationPartial#to_not")
|
||||
expectation = ValueExpectation.new(self, matcher)
|
||||
result = expectation.eval(true)
|
||||
ExpectationRegistry.current.report(result)
|
||||
end
|
||||
|
||||
# ditto
|
||||
|
|
|
@ -3,6 +3,11 @@ require "./result"
|
|||
module Spectator
|
||||
class FailedResult < Result
|
||||
getter error : Exception
|
||||
getter expectations : Expectations::ExpectationResults
|
||||
|
||||
def initialize(example, elapsed, @expectations, @error)
|
||||
super(example, elapsed)
|
||||
end
|
||||
|
||||
def passed?
|
||||
false
|
||||
|
@ -19,9 +24,5 @@ module Spectator
|
|||
def pending?
|
||||
false
|
||||
end
|
||||
|
||||
def initialize(example, elapsed, @error)
|
||||
super(example, elapsed)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,15 +2,15 @@ require "./value_matcher"
|
|||
|
||||
module Spectator::Matchers
|
||||
class EqualityMatcher(ExpectedType) < ValueMatcher(ExpectedType)
|
||||
def match?(partial : ValueExpectationPartial(ActualType)) : Bool forall ActualType
|
||||
def match?(partial : Expectations::ValueExpectationPartial(ActualType)) : Bool forall ActualType
|
||||
partial.actual == expected
|
||||
end
|
||||
|
||||
def message(partial : ValueExpectationPartial(ActualType)) : String forall ActualType
|
||||
def message(partial : Expectations::ValueExpectationPartial(ActualType)) : String forall ActualType
|
||||
"Expected #{partial.label} to equal #{label} (using ==)"
|
||||
end
|
||||
|
||||
def negated_message(partial : ValueExpectationPartial(ActualType)) : String forall ActualType
|
||||
def negated_message(partial : Expectations::ValueExpectationPartial(ActualType)) : String forall ActualType
|
||||
"Expected #{partial.label} to not equal #{label} (using ==)"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,6 +3,7 @@ require "./example"
|
|||
module Spectator
|
||||
abstract class RunnableExample < Example
|
||||
def run
|
||||
Expectations::ExpectationRegistry.start(self)
|
||||
result = ResultCapture.new
|
||||
group.run_before_all_hooks
|
||||
group.run_before_each_hooks
|
||||
|
@ -13,7 +14,8 @@ module Spectator
|
|||
group.run_after_each_hooks
|
||||
group.run_after_all_hooks
|
||||
end
|
||||
translate_result(result)
|
||||
expectations = Expectations::ExpectationRegistry.finish
|
||||
translate_result(result, expectations)
|
||||
end
|
||||
|
||||
private def wrapped_capture_result(result)
|
||||
|
@ -32,14 +34,14 @@ module Spectator
|
|||
end
|
||||
end
|
||||
|
||||
private def translate_result(result)
|
||||
private def translate_result(result, expectations)
|
||||
case (error = result.error)
|
||||
when Nil
|
||||
SuccessfulResult.new(self, result.elapsed)
|
||||
SuccessfulResult.new(self, result.elapsed, expectations)
|
||||
when ExpectationFailed
|
||||
FailedResult.new(self, result.elapsed, error)
|
||||
FailedResult.new(self, result.elapsed, expectations, error)
|
||||
else
|
||||
ErroredResult.new(self, result.elapsed, error)
|
||||
ErroredResult.new(self, result.elapsed, expectations, error)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -2,6 +2,12 @@ require "./result"
|
|||
|
||||
module Spectator
|
||||
class SuccessfulResult < Result
|
||||
getter expectations : Expectations::ExpectationResults
|
||||
|
||||
def initialize(example, elapsed, @expectations)
|
||||
super(example, elapsed)
|
||||
end
|
||||
|
||||
def passed?
|
||||
true
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue