mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
Merge branch 'defer' into 'release/0.9'
Ability to defer expectations to after the test and hooks run See merge request arctic-fox/spectator!23
This commit is contained in:
commit
d1e401af96
4 changed files with 58 additions and 4 deletions
|
@ -37,6 +37,24 @@ module Spectator::Expectations
|
||||||
to_not(matcher)
|
to_not(matcher)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Asserts that some criteria defined by the matcher is eventually satisfied.
|
||||||
|
# The expectation is checked after the example finishes and all hooks have run.
|
||||||
|
def to_eventually(matcher) : Nil
|
||||||
|
Harness.current.defer { to(matcher) }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Asserts that some criteria defined by the matcher is never satisfied.
|
||||||
|
# The expectation is checked after the example finishes and all hooks have run.
|
||||||
|
def to_never(matcher) : Nil
|
||||||
|
Harness.current.defer { to_not(matcher) }
|
||||||
|
end
|
||||||
|
|
||||||
|
# ditto
|
||||||
|
@[AlwaysInline]
|
||||||
|
def never_to(matcher) : Nil
|
||||||
|
to_never(matcher)
|
||||||
|
end
|
||||||
|
|
||||||
# Reports an expectation to the current harness.
|
# Reports an expectation to the current harness.
|
||||||
private def report(match_data : Matchers::MatchData)
|
private def report(match_data : Matchers::MatchData)
|
||||||
expectation = Expectation.new(match_data, @source)
|
expectation = Expectation.new(match_data, @source)
|
||||||
|
|
|
@ -51,10 +51,22 @@ module Spectator
|
||||||
@reporter.expectations
|
@reporter.expectations
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Marks a block of code to run later.
|
||||||
|
def defer(&block : ->) : Nil
|
||||||
|
@deferred << block
|
||||||
|
end
|
||||||
|
|
||||||
|
# Runs all deferred blocks.
|
||||||
|
def run_deferred : Nil
|
||||||
|
@deferred.each(&.call)
|
||||||
|
@deferred.clear
|
||||||
|
end
|
||||||
|
|
||||||
# Creates a new harness.
|
# Creates a new harness.
|
||||||
# The example the harness is for should be passed in.
|
# The example the harness is for should be passed in.
|
||||||
private def initialize(@example)
|
private def initialize(@example)
|
||||||
@reporter = Expectations::ExpectationReporter.new
|
@reporter = Expectations::ExpectationReporter.new
|
||||||
|
@deferred = Deque(->).new
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,6 +20,7 @@ module Spectator
|
||||||
context.run_before_hooks(self)
|
context.run_before_hooks(self)
|
||||||
run_example(result)
|
run_example(result)
|
||||||
context.run_after_hooks(self)
|
context.run_after_hooks(self)
|
||||||
|
run_deferred(result)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -40,6 +41,17 @@ module Spectator
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Runs the deferred blocks of code and captures the result.
|
||||||
|
private def run_deferred(result)
|
||||||
|
result.elapsed += Time.measure do
|
||||||
|
begin
|
||||||
|
Harness.current.run_deferred
|
||||||
|
rescue ex # Catch all errors and handle them later.
|
||||||
|
result.error = ex
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Creates a result instance from captured result information.
|
# Creates a result instance from captured result information.
|
||||||
private def translate_result(result, expectations)
|
private def translate_result(result, expectations)
|
||||||
case (error = result.error)
|
case (error = result.error)
|
||||||
|
|
|
@ -16,7 +16,7 @@ class Object
|
||||||
# ```
|
# ```
|
||||||
# require "spectator/should"
|
# require "spectator/should"
|
||||||
# ```
|
# ```
|
||||||
def should(matcher : ::Spectator::Matchers::Matcher)
|
def should(matcher)
|
||||||
# First argument of the `Expectation` initializer is the expression label.
|
# First argument of the `Expectation` initializer is the expression label.
|
||||||
# However, since this isn't a macro and we can't "look behind" this method call
|
# However, since this isn't a macro and we can't "look behind" this method call
|
||||||
# to see what it was invoked on, the argument is an empty string.
|
# to see what it was invoked on, the argument is an empty string.
|
||||||
|
@ -28,17 +28,29 @@ class Object
|
||||||
|
|
||||||
# Works the same as `#should` except the condition is inverted.
|
# Works the same as `#should` except the condition is inverted.
|
||||||
# When `#should` succeeds, this method will fail, and vice-versa.
|
# When `#should` succeeds, this method will fail, and vice-versa.
|
||||||
def should_not(matcher : ::Spectator::Matchers::Matcher)
|
def should_not(matcher)
|
||||||
actual = ::Spectator::TestValue.new(self)
|
actual = ::Spectator::TestValue.new(self)
|
||||||
source = ::Spectator::Source.new(__FILE__, __LINE__)
|
source = ::Spectator::Source.new(__FILE__, __LINE__)
|
||||||
::Spectator::Expectations::ExpectationPartial.new(actual, source).to_not(matcher)
|
::Spectator::Expectations::ExpectationPartial.new(actual, source).to_not(matcher)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Works the same as `#should` except that the condition check is postphoned.
|
||||||
|
# The expectation is checked after the example finishes and all hooks have run.
|
||||||
|
def should_eventually(matcher)
|
||||||
|
::Spectator::Harness.current.defer { should(matcher) }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Works the same as `#should_not` except that the condition check is postphoned.
|
||||||
|
# The expectation is checked after the example finishes and all hooks have run.
|
||||||
|
def should_never(matcher)
|
||||||
|
::Spectator::Harness.current.defer { should_not(matcher) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
struct Proc(*T, R)
|
struct Proc(*T, R)
|
||||||
# Extension method to create an expectation for a block of code (proc).
|
# Extension method to create an expectation for a block of code (proc).
|
||||||
# Depending on the matcher, the proc may be executed multiple times.
|
# Depending on the matcher, the proc may be executed multiple times.
|
||||||
def should(matcher : ::Spectator::Matchers::Matcher)
|
def should(matcher)
|
||||||
actual = ::Spectator::TestBlock.new(self)
|
actual = ::Spectator::TestBlock.new(self)
|
||||||
source = ::Spectator::Source.new(__FILE__, __LINE__)
|
source = ::Spectator::Source.new(__FILE__, __LINE__)
|
||||||
::Spectator::Expectations::ExpectationPartial.new(actual, source).to(matcher)
|
::Spectator::Expectations::ExpectationPartial.new(actual, source).to(matcher)
|
||||||
|
@ -46,7 +58,7 @@ struct Proc(*T, R)
|
||||||
|
|
||||||
# Works the same as `#should` except the condition is inverted.
|
# Works the same as `#should` except the condition is inverted.
|
||||||
# When `#should` succeeds, this method will fail, and vice-versa.
|
# When `#should` succeeds, this method will fail, and vice-versa.
|
||||||
def should_not(matcher : ::Spectator::Matchers::Matcher)
|
def should_not(matcher)
|
||||||
actual = ::Spectator::TestBlock.new(self)
|
actual = ::Spectator::TestBlock.new(self)
|
||||||
source = ::Spectator::Source.new(__FILE__, __LINE__)
|
source = ::Spectator::Source.new(__FILE__, __LINE__)
|
||||||
::Spectator::Expectations::BlockExpectationPartial.new(actual, source).to_not(matcher)
|
::Spectator::Expectations::BlockExpectationPartial.new(actual, source).to_not(matcher)
|
||||||
|
|
Loading…
Reference in a new issue