Begin triggering events for formatters

This commit is contained in:
Michael Miller 2021-05-15 18:31:52 -06:00
parent 4eb457f197
commit 618e9e195a
No known key found for this signature in database
GPG key ID: F9A0C5C65B162436
5 changed files with 77 additions and 2 deletions

View file

@ -31,11 +31,13 @@ module Spectator::Formatting
# This method is the first method to be invoked
# and will be called only once.
# It is called before any examples run.
# The *notification* will be a `StartNotification` type of object.
def start(_notification)
end
# Invoked just before an example runs.
# This method is called once for every example.
# The *notification* will be an `ExampleNotification` type of object.
def example_started(_notification)
end
@ -43,22 +45,26 @@ module Spectator::Formatting
# This method is called once for every example.
# One of `#example_passed`, `#example_pending` or `#example_failed`
# will be called immediately after this method, depending on the example's result.
# The *notification* will be an `ExampleNotification` type of object.
def example_finished(_notification)
end
# Invoked after an example completes successfully.
# This is called right after `#example_finished`.
# The *notification* will be an `ExampleNotification` type of object.
def example_passed(_notification)
end
# Invoked after an example is skipped or marked as pending.
# This is called right after `#example_finished`.
# The *notification* will be an `ExampleNotification` type of object.
def example_pending(_notification)
end
# Invoked after an example fails.
# This is called right after `#example_finished`.
# Errors are considered failures and will cause this method to be called.
# The *notification* will be an `ExampleNotification` type of object.
def example_failed(_notification)
end

View file

@ -0,0 +1,7 @@
require "../example"
module Spectator::Formatting
record StartNotification, example_count : Int32
record ExampleNotification, example : Example
end

View file

@ -14,7 +14,7 @@ module Spectator
# Runs all selected examples and returns the results.
def run
Runner.new(examples, @config.run_flags).run
Runner.new(examples, @config.formatter, @config.run_flags).run
end
# Selects and shuffles the examples that should run.

View file

@ -0,0 +1,49 @@
module Spectator
class Spec
# Mix-in for announcing events from a `Runner`.
# All events invoke their corresponding method on the formatter.
module Events
# Triggers the 'start' event.
# See `Formatting::Formatter#start`
private def start
notification = Formatting::StartNotification.new(example_count)
formatter.start(notification)
end
# Triggers the 'example started' event.
# Must be passed the *example* about to run.
# See `Formatting::Formatter#example_started`
private def example_started(example)
notification = Formatting::ExampleNotification.new(example)
formatter.example_started(notification)
end
# Triggers the 'example started' event.
# Also triggers the example result event corresponding to the example's outcome.
# Must be passed the completed *example*.
# See `Formatting::Formatter#example_finished`
private def example_finished(example)
notification = Formatting::ExampleNotification.new(example)
formatter.example_started(notification)
case example.result
when .fail? then formatter.example_failed(notification)
when .pass? then formatter.example_passed(notification)
else formatter.example_pending(notification)
end
end
# Triggers the 'stop' event.
# See `Formatting::Formatter#stop`
private def stop
formatter.stop(nil)
end
# Triggers the 'close' event.
# See `Formatting::Formatter#close`
private def close
formatter.close(nil)
end
end
end
end

View file

@ -1,10 +1,16 @@
require "../example"
require "../run_flags"
require "./events"
module Spectator
class Spec
# Logic for executing examples and collecting results.
private struct Runner
include Events
# Formatter to send events to.
private getter formatter : Formatting::Formatter
# Creates the runner.
# The collection of *examples* should be pre-filtered and shuffled.
# This runner will run each example in the order provided.
@ -19,12 +25,16 @@ module Spectator
# True will be returned if the spec ran successfully,
# or false if there was at least one failure.
def run : Bool
start
executed = [] of Example
elapsed = Time.measure { executed = run_examples }
stop
# TODO: Generate a report and pass it along to the formatter.
false # TODO: Report real result
ensure
close
end
# Attempts to run all examples.
@ -45,11 +55,14 @@ module Spectator
# Runs a single example and returns the result.
# The formatter is given the example and result information.
private def run_example(example)
if dry_run?
example_started(example)
result = if dry_run?
dry_run_result
else
example.run
end
example_finished(example)
result
end
# Creates a fake result.