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
|
module Spectator::Expectations
|
||||||
abstract class Expectation
|
# Min-in for all expectation types.
|
||||||
getter? negated : Bool
|
# 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
|
end
|
||||||
|
|
||||||
abstract def eval : Bool
|
# Information regarding the outcome of an expectation.
|
||||||
abstract def message : String
|
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,7 @@ module Spectator::Expectations
|
||||||
private def initialize(@raise_on_failure = true)
|
private def initialize(@raise_on_failure = true)
|
||||||
end
|
end
|
||||||
|
|
||||||
def report(expectation : Expectation) : Nil
|
def report(result : Expectation::Result) : Nil
|
||||||
raise NotImplementedError.new("ExpectationRegistry#report")
|
raise NotImplementedError.new("ExpectationRegistry#report")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -15,11 +15,11 @@ module Spectator::Expectations
|
||||||
raise NotImplementedError.new("ExpectationRegistry.current")
|
raise NotImplementedError.new("ExpectationRegistry.current")
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.start(example : Example) : ExpectationRegistry
|
def self.start(example : Example) : Nil
|
||||||
raise NotImplementedError.new("ExpectationRegistry.start")
|
raise NotImplementedError.new("ExpectationRegistry.start")
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.finish : Nil # TODO: Define return type.
|
def self.finish : ExpectationResults
|
||||||
raise NotImplementedError.new("ExpectationRegistry.finish")
|
raise NotImplementedError.new("ExpectationRegistry.finish")
|
||||||
end
|
end
|
||||||
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"
|
require "./expectation"
|
||||||
|
|
||||||
module Spectator::Expectations
|
module Spectator::Expectations
|
||||||
class ValueExpectation(ActualType, ExpectedType) < Expectation
|
class ValueExpectation(ActualType, ExpectedType)
|
||||||
def initialize(negated,
|
include Expectation
|
||||||
@partial : ValueExpectationPartial(ActualType),
|
|
||||||
@matcher : ValueMatcher(ExpectedType))
|
def initialize(@partial : ValueExpectationPartial(ActualType),
|
||||||
super(negated)
|
@matcher : Matchers::ValueMatcher(ExpectedType))
|
||||||
end
|
end
|
||||||
|
|
||||||
def eval : Bool
|
# Checks whether the expectation is met.
|
||||||
@matcher.match?(@partial) ^ negated?
|
def satisfied? : Bool
|
||||||
|
@matcher.match?(@partial)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Describes the condition that must be met for the expectation to be satisifed.
|
||||||
def message : String
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,11 +9,15 @@ module Spectator::Expectations
|
||||||
end
|
end
|
||||||
|
|
||||||
def to(matcher : Matchers::ValueMatcher(ExpectedType)) : Nil forall ExpectedType
|
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
|
end
|
||||||
|
|
||||||
def to_not(matcher : Matchers::ValueMatcher(ExpectedType)) : Nil forall ExpectedType
|
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
|
end
|
||||||
|
|
||||||
# ditto
|
# ditto
|
||||||
|
|
|
@ -3,6 +3,11 @@ require "./result"
|
||||||
module Spectator
|
module Spectator
|
||||||
class FailedResult < Result
|
class FailedResult < Result
|
||||||
getter error : Exception
|
getter error : Exception
|
||||||
|
getter expectations : Expectations::ExpectationResults
|
||||||
|
|
||||||
|
def initialize(example, elapsed, @expectations, @error)
|
||||||
|
super(example, elapsed)
|
||||||
|
end
|
||||||
|
|
||||||
def passed?
|
def passed?
|
||||||
false
|
false
|
||||||
|
@ -19,9 +24,5 @@ module Spectator
|
||||||
def pending?
|
def pending?
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(example, elapsed, @error)
|
|
||||||
super(example, elapsed)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,15 +2,15 @@ require "./value_matcher"
|
||||||
|
|
||||||
module Spectator::Matchers
|
module Spectator::Matchers
|
||||||
class EqualityMatcher(ExpectedType) < ValueMatcher(ExpectedType)
|
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
|
partial.actual == expected
|
||||||
end
|
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 ==)"
|
"Expected #{partial.label} to equal #{label} (using ==)"
|
||||||
end
|
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 ==)"
|
"Expected #{partial.label} to not equal #{label} (using ==)"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,7 @@ require "./example"
|
||||||
module Spectator
|
module Spectator
|
||||||
abstract class RunnableExample < Example
|
abstract class RunnableExample < Example
|
||||||
def run
|
def run
|
||||||
|
Expectations::ExpectationRegistry.start(self)
|
||||||
result = ResultCapture.new
|
result = ResultCapture.new
|
||||||
group.run_before_all_hooks
|
group.run_before_all_hooks
|
||||||
group.run_before_each_hooks
|
group.run_before_each_hooks
|
||||||
|
@ -13,7 +14,8 @@ module Spectator
|
||||||
group.run_after_each_hooks
|
group.run_after_each_hooks
|
||||||
group.run_after_all_hooks
|
group.run_after_all_hooks
|
||||||
end
|
end
|
||||||
translate_result(result)
|
expectations = Expectations::ExpectationRegistry.finish
|
||||||
|
translate_result(result, expectations)
|
||||||
end
|
end
|
||||||
|
|
||||||
private def wrapped_capture_result(result)
|
private def wrapped_capture_result(result)
|
||||||
|
@ -32,14 +34,14 @@ module Spectator
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private def translate_result(result)
|
private def translate_result(result, expectations)
|
||||||
case (error = result.error)
|
case (error = result.error)
|
||||||
when Nil
|
when Nil
|
||||||
SuccessfulResult.new(self, result.elapsed)
|
SuccessfulResult.new(self, result.elapsed, expectations)
|
||||||
when ExpectationFailed
|
when ExpectationFailed
|
||||||
FailedResult.new(self, result.elapsed, error)
|
FailedResult.new(self, result.elapsed, expectations, error)
|
||||||
else
|
else
|
||||||
ErroredResult.new(self, result.elapsed, error)
|
ErroredResult.new(self, result.elapsed, expectations, error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,12 @@ require "./result"
|
||||||
|
|
||||||
module Spectator
|
module Spectator
|
||||||
class SuccessfulResult < Result
|
class SuccessfulResult < Result
|
||||||
|
getter expectations : Expectations::ExpectationResults
|
||||||
|
|
||||||
|
def initialize(example, elapsed, @expectations)
|
||||||
|
super(example, elapsed)
|
||||||
|
end
|
||||||
|
|
||||||
def passed?
|
def passed?
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue