mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
Rewrite ExpectationPartial and remove sub-types
The partial now contains the actual and source. It also calls the correct match method on the matcher and constructs an expectation (which needs to be updated).
This commit is contained in:
parent
42b916bdf7
commit
3a7dc7299a
4 changed files with 61 additions and 86 deletions
|
@ -1,25 +0,0 @@
|
||||||
require "./expectation_partial"
|
|
||||||
|
|
||||||
module Spectator::Expectations
|
|
||||||
# Expectation partial variation that operates on a block.
|
|
||||||
struct BlockExpectationPartial(ReturnType) < ExpectationPartial
|
|
||||||
# Actual value produced by calling the block.
|
|
||||||
def actual
|
|
||||||
@block.call
|
|
||||||
end
|
|
||||||
|
|
||||||
# Creates the expectation partial.
|
|
||||||
# The label should be a string representation of the block.
|
|
||||||
# The block is stored for later use.
|
|
||||||
def initialize(@block : Proc(ReturnType), label, source_file, source_line)
|
|
||||||
super(label, source_file, source_line)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Creates the expectation partial.
|
|
||||||
# The label is generated by calling to_s on the block.
|
|
||||||
# The block is stored for later use.
|
|
||||||
def initialize(@block : Proc(ReturnType), source_file, source_line)
|
|
||||||
super("<Proc>", source_file, source_line)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,39 +1,34 @@
|
||||||
|
require "../matchers/match_data"
|
||||||
|
require "../source"
|
||||||
|
require "./actual"
|
||||||
|
|
||||||
module Spectator::Expectations
|
module Spectator::Expectations
|
||||||
# Base class for all expectation partials.
|
# Stores part of an expectation (obviously).
|
||||||
# An "expectation partial" stores part of an expectation (obviously).
|
# The part of the expectation this type covers is the actual value and source.
|
||||||
# The part of the expectation this class covers is the actual value.
|
|
||||||
# This can also cover a block's behavior.
|
# This can also cover a block's behavior.
|
||||||
# Sub-types of this class are returned by the `DSL::ExampleDSL.expect` call.
|
struct ExpectationPartial
|
||||||
abstract struct ExpectationPartial
|
# The actual value being tested.
|
||||||
# User-friendly string displayed for the actual expression being tested.
|
# This also contains its label.
|
||||||
# For instance, in the expectation:
|
getter actual : Actual
|
||||||
# ```
|
|
||||||
# expect(foo).to eq(bar)
|
|
||||||
# ```
|
|
||||||
# This property will be "foo".
|
|
||||||
# It will be the literal string "foo",
|
|
||||||
# and not the actual value of the foo.
|
|
||||||
getter label : String
|
|
||||||
|
|
||||||
# Source file the expectation originated from.
|
# Location where this expectation was defined.
|
||||||
getter source_file : String
|
getter source : Source
|
||||||
|
|
||||||
# Line number in the source file the expectation originated from.
|
# Creates the partial.
|
||||||
getter source_line : Int32
|
def initialize(@actual, @source)
|
||||||
|
|
||||||
# Creates the base of the partial.
|
|
||||||
private def initialize(@label, @source_file, @source_line)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Asserts that some criteria defined by the matcher is satisfied.
|
# Asserts that some criteria defined by the matcher is satisfied.
|
||||||
def to(matcher) : Nil
|
def to(matcher) : Nil
|
||||||
report(eval(matcher))
|
match_data = matcher.match(@actual)
|
||||||
|
report(match_data)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Asserts that some criteria defined by the matcher is not satisfied.
|
# Asserts that some criteria defined by the matcher is not satisfied.
|
||||||
# This is effectively the opposite of `#to`.
|
# This is effectively the opposite of `#to`.
|
||||||
def to_not(matcher) : Nil
|
def to_not(matcher) : Nil
|
||||||
report(eval(matcher, true))
|
match_data = matcher.negated_match(@actual)
|
||||||
|
report(match_data)
|
||||||
end
|
end
|
||||||
|
|
||||||
# ditto
|
# ditto
|
||||||
|
@ -42,14 +37,9 @@ module Spectator::Expectations
|
||||||
to_not(matcher)
|
to_not(matcher)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Evaluates the expectation and returns it.
|
|
||||||
private def eval(matcher, negated = false)
|
|
||||||
match_data = matcher.match(self)
|
|
||||||
Expectation.new(match_data, negated)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Reports an expectation to the current harness.
|
# Reports an expectation to the current harness.
|
||||||
private def report(expectation : Expectation)
|
private def report(match_data : Matchers::MatchData)
|
||||||
|
expectation = Expectation.new(match_data, @source)
|
||||||
Internals::Harness.current.report_expectation(expectation)
|
Internals::Harness.current.report_expectation(expectation)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
require "./expectation_partial"
|
|
||||||
|
|
||||||
module Spectator::Expectations
|
|
||||||
# Expectation partial variation that operates on a value.
|
|
||||||
struct ValueExpectationPartial(ActualType) < ExpectationPartial
|
|
||||||
# Actual value produced by the test.
|
|
||||||
# This is the value passed to the `Spectator::DSL::ExampleDSL#expect` macro.
|
|
||||||
getter actual
|
|
||||||
|
|
||||||
# Creates the expectation partial.
|
|
||||||
# The label should be a string representation of the actual value.
|
|
||||||
# The actual value is stored for later use.
|
|
||||||
def initialize(@actual : ActualType, label, source_file, source_line)
|
|
||||||
super(label, source_file, source_line)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Creates the expectation partial.
|
|
||||||
# The label is generated by calling `to_s` on the actual value.
|
|
||||||
# The actual value is stored for later use.
|
|
||||||
def initialize(@actual : ActualType, source_file, source_line)
|
|
||||||
super(@actual.to_s, source_file, source_line)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -5,13 +5,47 @@ module Spectator::Matchers
|
||||||
# A matcher looks at something produced by the SUT
|
# A matcher looks at something produced by the SUT
|
||||||
# and evaluates whether it is correct or not.
|
# and evaluates whether it is correct or not.
|
||||||
abstract struct Matcher
|
abstract struct Matcher
|
||||||
# Textual representation of what the matcher expects.
|
# Short text about the matcher's purpose.
|
||||||
# This shouldn't be used in the conditional logic,
|
# This explains what condition satisfies the matcher.
|
||||||
# but for verbose output to help the end-user.
|
# The description is used when the one-liner syntax is used.
|
||||||
abstract def label : String
|
# ```
|
||||||
|
# it { is_expected.to do_something }
|
||||||
|
# ```
|
||||||
|
# The phrasing should be such that it reads "it ___."
|
||||||
|
abstract def description : String
|
||||||
|
|
||||||
# Determines whether the matcher is satisfied with the value given to it.
|
# Message displayed when the matcher isn't satisifed.
|
||||||
# True is returned if the match was successful, false otherwise.
|
# This is only called when `#matches?` returns false.
|
||||||
abstract def match(partial) : MatchData
|
abstract def failure_message : String
|
||||||
|
|
||||||
|
# Message displayed when the matcher isn't satisifed and is negated.
|
||||||
|
# This is only called when `#does_not_match?` returns false.
|
||||||
|
#
|
||||||
|
# A default implementation of this method is provided,
|
||||||
|
# which causes compilation to fail.
|
||||||
|
# If the matcher supports negation, it must override this method.
|
||||||
|
def failure_message_when_negated : String
|
||||||
|
{% raise "Negation with #{@type.name} is not supported."}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Checks whether the matcher is satisifed.
|
||||||
|
private abstract def match?(actual) : Bool
|
||||||
|
|
||||||
|
# If the expectation is negated, then this method is called instead of `#match?`.
|
||||||
|
# The default implementation of this method is to invert the result of `#match?`.
|
||||||
|
# If the matcher requires custom handling of negated matches,
|
||||||
|
# then this method should be overriden.
|
||||||
|
# Remember to override `#failure_message_when_negated` as well.
|
||||||
|
private def does_not_match?(actual) : Bool
|
||||||
|
!matches?(actual)
|
||||||
|
end
|
||||||
|
|
||||||
|
def match(actual)
|
||||||
|
matched = match?(actual)
|
||||||
|
end
|
||||||
|
|
||||||
|
def negated_match(actual)
|
||||||
|
matched = does_not_match?(actual)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue