99 lines
2.8 KiB
Crystal
99 lines
2.8 KiB
Crystal
require "./example"
|
|
require "./formatting/formatter"
|
|
require "./profile"
|
|
require "./report"
|
|
require "./run_flags"
|
|
require "./runner_events"
|
|
|
|
module Spectator
|
|
# Logic for executing examples and collecting results.
|
|
struct Runner
|
|
include RunnerEvents
|
|
|
|
# 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.
|
|
# The *formatter* will be called for various events.
|
|
def initialize(@examples : Array(Example), @formatter : Formatting::Formatter,
|
|
@run_flags = RunFlags::None, @random_seed : UInt64? = nil)
|
|
end
|
|
|
|
# Runs the spec.
|
|
# This will run the provided examples
|
|
# and invoke the reporters to communicate results.
|
|
# True will be returned if the spec ran successfully,
|
|
# or false if there was at least one failure.
|
|
def run : Bool
|
|
start
|
|
elapsed = Time.measure { run_examples }
|
|
stop
|
|
|
|
report = Report.generate(@examples, elapsed, @random_seed)
|
|
profile = Profile.generate(@examples) if @run_flags.profile? && report.counts.run > 0
|
|
summarize(report, profile)
|
|
|
|
report.counts.fail.zero?
|
|
ensure
|
|
close
|
|
end
|
|
|
|
# Attempts to run all examples.
|
|
# Returns a list of examples that ran.
|
|
private def run_examples
|
|
@examples.each do |example|
|
|
result = run_example(example)
|
|
|
|
# Bail out if the example failed
|
|
# and configured to stop after the first failure.
|
|
break fail_fast if fail_fast? && result.fail?
|
|
end
|
|
end
|
|
|
|
# Runs a single example and returns the result.
|
|
# The formatter is given the example and result information.
|
|
private def run_example(example)
|
|
example_started(example)
|
|
result = if dry_run?
|
|
# TODO: Pending examples return a pending result instead of pass in RSpec dry-run.
|
|
dry_run_result
|
|
else
|
|
example.run
|
|
end
|
|
example_finished(example)
|
|
result
|
|
end
|
|
|
|
# Creates a fake result.
|
|
private def dry_run_result
|
|
expectations = [] of Expectation
|
|
PassResult.new(Time::Span.zero, expectations)
|
|
end
|
|
|
|
# Generates and returns a profile if one should be displayed.
|
|
private def profile(report)
|
|
Profile.generate(report) if @config.profile?
|
|
end
|
|
|
|
# Indicates whether examples should be simulated, but not run.
|
|
private def dry_run?
|
|
@run_flags.dry_run?
|
|
end
|
|
|
|
# Indicates whether test execution should stop after the first failure.
|
|
private def fail_fast?
|
|
@run_flags.fail_fast?
|
|
end
|
|
|
|
private def fail_fast : Nil
|
|
end
|
|
|
|
# Number of examples configured to run.
|
|
private def example_count
|
|
@examples.size
|
|
end
|
|
end
|
|
end
|