Initial pass at removing example from Result
This commit is contained in:
parent
6d815a78d6
commit
12d8bcb32c
|
@ -17,10 +17,7 @@ module Spectator
|
||||||
getter? finished : Bool = false
|
getter? finished : Bool = false
|
||||||
|
|
||||||
# Retrieves the result of the last time the example ran.
|
# Retrieves the result of the last time the example ran.
|
||||||
def result : Result
|
getter result : Result = PendingResult.new
|
||||||
# TODO: Set to pending immediately (requires circular dependency between Example <-> Result removed).
|
|
||||||
@result ||= PendingResult.new(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Creates the example.
|
# Creates the example.
|
||||||
# An instance to run the test code in is given by *context*.
|
# An instance to run the test code in is given by *context*.
|
||||||
|
@ -62,7 +59,7 @@ module Spectator
|
||||||
|
|
||||||
if pending?
|
if pending?
|
||||||
Log.debug { "Skipping example #{self} - marked pending" }
|
Log.debug { "Skipping example #{self} - marked pending" }
|
||||||
return @result = PendingResult.new(self)
|
return @result = PendingResult.new
|
||||||
end
|
end
|
||||||
|
|
||||||
previous_example = @@current
|
previous_example = @@current
|
||||||
|
|
|
@ -11,8 +11,9 @@ module Spectator
|
||||||
# Creates a failure result.
|
# Creates a failure result.
|
||||||
# The *elapsed* argument is the length of time it took to run the example.
|
# The *elapsed* argument is the length of time it took to run the example.
|
||||||
# The *error* is the exception raised that caused the failure.
|
# The *error* is the exception raised that caused the failure.
|
||||||
def initialize(example, elapsed, @error, expectations = [] of Expectation)
|
# *expectations* stores the expectations checked in the example.
|
||||||
super(example, elapsed, expectations)
|
def initialize(elapsed, @error : Exception, expectations = [] of Expectation)
|
||||||
|
super(elapsed, expectations)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Calls the `failure` method on *visitor*.
|
# Calls the `failure` method on *visitor*.
|
||||||
|
|
|
@ -27,9 +27,9 @@ module Spectator::Formatting
|
||||||
end
|
end
|
||||||
|
|
||||||
# Produces a single character output based on a result.
|
# Produces a single character output based on a result.
|
||||||
def end_example(result)
|
def end_example(example, result)
|
||||||
@previous_hierarchy.size.times { @io.print INDENT }
|
@previous_hierarchy.size.times { @io.print INDENT }
|
||||||
@io.puts result.accept(Color) { result.example.name }
|
@io.puts result.accept(Color) { example.name }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Produces a list of groups making up the hierarchy for an example.
|
# Produces a list of groups making up the hierarchy for an example.
|
||||||
|
|
|
@ -20,7 +20,7 @@ module Spectator::Formatting
|
||||||
end
|
end
|
||||||
|
|
||||||
# Produces a single character output based on a result.
|
# Produces a single character output based on a result.
|
||||||
def end_example(result)
|
def end_example(example, result)
|
||||||
@io.print result.accept(Character)
|
@io.print result.accept(Character)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,8 @@ module Spectator::Formatting
|
||||||
private getter result
|
private getter result
|
||||||
|
|
||||||
# Creates the JUnit test case.
|
# Creates the JUnit test case.
|
||||||
def initialize(@result : ErrorResult)
|
def initialize(example : Example, @result : ErrorResult)
|
||||||
|
super(example, @result)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Adds the exception to the XML block.
|
# Adds the exception to the XML block.
|
||||||
|
|
|
@ -16,7 +16,7 @@ module Spectator::Formatting
|
||||||
# Creates the failure block.
|
# Creates the failure block.
|
||||||
# The *index* uniquely identifies the failure in the output.
|
# The *index* uniquely identifies the failure in the output.
|
||||||
# The *result* is the outcome of the failed example.
|
# The *result* is the outcome of the failed example.
|
||||||
def initialize(@index : Int32, @result : FailResult)
|
def initialize(@index : Int32, @example : Example, @result : FailResult)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Creates the block of text describing the failure.
|
# Creates the block of text describing the failure.
|
||||||
|
@ -39,7 +39,7 @@ module Spectator::Formatting
|
||||||
# 1) Example name
|
# 1) Example name
|
||||||
# ```
|
# ```
|
||||||
private def title(indent)
|
private def title(indent)
|
||||||
indent.line(NumberedItem.new(@index, @result.example))
|
indent.line(NumberedItem.new(@index, @example))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Produces the main content of the failure block.
|
# Produces the main content of the failure block.
|
||||||
|
@ -105,7 +105,7 @@ module Spectator::Formatting
|
||||||
|
|
||||||
# Produces the location line of the failure block.
|
# Produces the location line of the failure block.
|
||||||
private def location(indent)
|
private def location(indent)
|
||||||
indent.line(Comment.color(@result.example.location))
|
indent.line(Comment.color(@example.location))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Gets the number of characters a positive integer spans in base 10.
|
# Gets the number of characters a positive integer spans in base 10.
|
||||||
|
|
|
@ -12,8 +12,8 @@ module Spectator::Formatting
|
||||||
end
|
end
|
||||||
|
|
||||||
# Colorizes the command instance based on the result.
|
# Colorizes the command instance based on the result.
|
||||||
def self.color(result)
|
def self.color(example, result)
|
||||||
result.accept(Color) { new(result.example) }
|
result.accept(Color) { new(example) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,8 @@ module Spectator::Formatting
|
||||||
private getter result
|
private getter result
|
||||||
|
|
||||||
# Creates the JUnit test case.
|
# Creates the JUnit test case.
|
||||||
def initialize(@result : FailResult)
|
def initialize(example : Example, @result : FailResult)
|
||||||
|
super(example)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Status string specific to the result type.
|
# Status string specific to the result type.
|
||||||
|
|
|
@ -22,6 +22,6 @@ module Spectator::Formatting
|
||||||
|
|
||||||
# Called when a test finishes.
|
# Called when a test finishes.
|
||||||
# The result of the test is provided.
|
# The result of the test is provided.
|
||||||
abstract def end_example(result : Result)
|
abstract def end_example(example : Example, result : Result)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -36,7 +36,7 @@ module Spectator::Formatting
|
||||||
|
|
||||||
# Called when a test finishes.
|
# Called when a test finishes.
|
||||||
# The result of the test is provided.
|
# The result of the test is provided.
|
||||||
def end_example(result : Result)
|
def end_example(example, result : Result)
|
||||||
result.to_json(@json)
|
result.to_json(@json)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -74,8 +74,8 @@ module Spectator::Formatting
|
||||||
@json.field("percentage", profile.percentage)
|
@json.field("percentage", profile.percentage)
|
||||||
@json.field("results") do
|
@json.field("results") do
|
||||||
@json.array do
|
@json.array do
|
||||||
profile.each do |result|
|
profile.each do |(example, result)|
|
||||||
profile_entry(result)
|
profile_entry(example, result)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -84,11 +84,11 @@ module Spectator::Formatting
|
||||||
end
|
end
|
||||||
|
|
||||||
# Adds a profile entry to the document.
|
# Adds a profile entry to the document.
|
||||||
private def profile_entry(result)
|
private def profile_entry(example, result)
|
||||||
@json.object do
|
@json.object do
|
||||||
@json.field("example", result.example)
|
@json.field("example", example)
|
||||||
@json.field("time", result.elapsed.total_seconds)
|
@json.field("time", result.elapsed.total_seconds)
|
||||||
@json.field("location", result.example.location)
|
@json.field("location", example.location)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -38,7 +38,7 @@ module Spectator::Formatting
|
||||||
|
|
||||||
# Called when a test finishes.
|
# Called when a test finishes.
|
||||||
# The result of the test is provided.
|
# The result of the test is provided.
|
||||||
def end_example(result : Result)
|
def end_example(example : Example, result : Result)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Creates the "testsuites" block in the XML.
|
# Creates the "testsuites" block in the XML.
|
||||||
|
@ -55,7 +55,7 @@ module Spectator::Formatting
|
||||||
|
|
||||||
# Adds all of the individual test suite blocks.
|
# Adds all of the individual test suite blocks.
|
||||||
private def add_test_suites(report)
|
private def add_test_suites(report)
|
||||||
report.group_by(&.example.location.path).each do |path, results|
|
report.group_by(&.[0].location.path).each do |path, results|
|
||||||
JUnitTestSuite.new(path, results).to_xml(@xml)
|
JUnitTestSuite.new(path, results).to_xml(@xml)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
module Spectator::Formatting
|
module Spectator::Formatting
|
||||||
# Base type for all JUnit test case results.
|
# Base type for all JUnit test case results.
|
||||||
private abstract class JUnitTestCase
|
private abstract class JUnitTestCase
|
||||||
|
def initialize(@example : Example)
|
||||||
|
end
|
||||||
|
|
||||||
# Produces the test case XML element.
|
# Produces the test case XML element.
|
||||||
def to_xml(xml : ::XML::Builder)
|
def to_xml(xml : ::XML::Builder)
|
||||||
xml.element("testcase", **attributes) do
|
xml.element("testcase", **attributes) do
|
||||||
|
@ -11,7 +14,7 @@ module Spectator::Formatting
|
||||||
# Attributes that go in the "testcase" XML element.
|
# Attributes that go in the "testcase" XML element.
|
||||||
private def attributes
|
private def attributes
|
||||||
{
|
{
|
||||||
name: result.example,
|
name: @example.to_s,
|
||||||
status: status,
|
status: status,
|
||||||
classname: classname,
|
classname: classname,
|
||||||
}
|
}
|
||||||
|
@ -31,7 +34,7 @@ module Spectator::Formatting
|
||||||
|
|
||||||
# Java-ified class name created from the spec.
|
# Java-ified class name created from the spec.
|
||||||
private def classname
|
private def classname
|
||||||
path = result.example.location.path
|
path = @example.location.path
|
||||||
file = File.basename(path)
|
file = File.basename(path)
|
||||||
ext = File.extname(file)
|
ext = File.extname(file)
|
||||||
name = file[0...-(ext.size)]
|
name = file[0...-(ext.size)]
|
||||||
|
|
|
@ -4,7 +4,7 @@ module Spectator::Formatting
|
||||||
# Creates the JUnit test suite.
|
# Creates the JUnit test suite.
|
||||||
# The *path* should be the file that all results are from.
|
# The *path* should be the file that all results are from.
|
||||||
# The *results* is a subset of all results that share the path.
|
# The *results* is a subset of all results that share the path.
|
||||||
def initialize(@path : String, results : Array(Result))
|
def initialize(@path : String, results : Array(Tuple(Example, Result)))
|
||||||
@report = Report.new(results)
|
@report = Report.new(results)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -24,8 +24,8 @@ module Spectator::Formatting
|
||||||
|
|
||||||
# Adds the test case elements to the XML.
|
# Adds the test case elements to the XML.
|
||||||
private def add_test_cases(xml)
|
private def add_test_cases(xml)
|
||||||
@report.each do |result|
|
@report.each do |(example, result)|
|
||||||
test_case = result.accept(JUnitTestCaseSelector) { |r| r }
|
test_case = result.accept(JUnitTestCaseSelector) { |r| {example, r} }
|
||||||
test_case.to_xml(xml)
|
test_case.to_xml(xml)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -51,22 +51,26 @@ module Spectator::Formatting
|
||||||
|
|
||||||
# Creates a successful JUnit test case.
|
# Creates a successful JUnit test case.
|
||||||
def pass(result)
|
def pass(result)
|
||||||
SuccessfulJUnitTestCase.new(result.as(PassResult))
|
example, result = result
|
||||||
|
SuccessfulJUnitTestCase.new(example, result.as(PassResult))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Creates a failure JUnit test case.
|
# Creates a failure JUnit test case.
|
||||||
def failure(result)
|
def failure(result)
|
||||||
FailureJUnitTestCase.new(result.as(FailResult))
|
example, result = result
|
||||||
|
FailureJUnitTestCase.new(example, result.as(FailResult))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Creates an error JUnit test case.
|
# Creates an error JUnit test case.
|
||||||
def error(result)
|
def error(result)
|
||||||
ErrorJUnitTestCase.new(result.as(ErrorResult))
|
example, result = result
|
||||||
|
ErrorJUnitTestCase.new(example, result.as(ErrorResult))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Creates a skipped JUnit test case.
|
# Creates a skipped JUnit test case.
|
||||||
def pending(result)
|
def pending(result)
|
||||||
SkippedJUnitTestCase.new(result.as(PendingResult))
|
example, result = result
|
||||||
|
SkippedJUnitTestCase.new(example, result.as(PendingResult))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,17 +11,17 @@ module Spectator::Formatting
|
||||||
|
|
||||||
indent = Indent.new(io)
|
indent = Indent.new(io)
|
||||||
indent.increase do
|
indent.increase do
|
||||||
@profile.each do |result|
|
@profile.each do |(example, result)|
|
||||||
entry(indent, result)
|
entry(indent, example, result)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Adds a result entry to the output.
|
# Adds a result entry to the output.
|
||||||
private def entry(indent, result)
|
private def entry(indent, example, result)
|
||||||
indent.line(result.example)
|
indent.line(example)
|
||||||
indent.increase do
|
indent.increase do
|
||||||
indent.line(LocationTiming.new(result.elapsed, result.example.location))
|
indent.line(LocationTiming.new(result.elapsed, example.location))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,7 +20,7 @@ module Spectator::Formatting
|
||||||
|
|
||||||
# Called when a test finishes.
|
# Called when a test finishes.
|
||||||
# The result of the test is provided.
|
# The result of the test is provided.
|
||||||
def end_example(result : Result)
|
def end_example(example : Example, result : Result)
|
||||||
# ... crickets ...
|
# ... crickets ...
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,8 @@ module Spectator::Formatting
|
||||||
private getter result
|
private getter result
|
||||||
|
|
||||||
# Creates the JUnit test case.
|
# Creates the JUnit test case.
|
||||||
def initialize(@result : PendingResult)
|
def initialize(example : Example, @result : PendingResult)
|
||||||
|
super(example)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Status string specific to the result type.
|
# Status string specific to the result type.
|
||||||
|
|
|
@ -5,7 +5,8 @@ module Spectator::Formatting
|
||||||
private getter result
|
private getter result
|
||||||
|
|
||||||
# Creates the JUnit test case.
|
# Creates the JUnit test case.
|
||||||
def initialize(@result : PassResult)
|
def initialize(example : Example, @result : PassResult)
|
||||||
|
super(example)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Status string specific to the result type.
|
# Status string specific to the result type.
|
||||||
|
|
|
@ -33,8 +33,8 @@ module Spectator::Formatting
|
||||||
private def failures(failures)
|
private def failures(failures)
|
||||||
@io.puts "Failures:"
|
@io.puts "Failures:"
|
||||||
@io.puts
|
@io.puts
|
||||||
failures.each_with_index do |result, index|
|
failures.each_with_index do |(example, result), index|
|
||||||
@io.puts FailureBlock.new(index + 1, result)
|
@io.puts FailureBlock.new(index + 1, example, result)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -68,10 +68,10 @@ module Spectator::Formatting
|
||||||
@io.puts
|
@io.puts
|
||||||
@io.puts "Failed examples:"
|
@io.puts "Failed examples:"
|
||||||
@io.puts
|
@io.puts
|
||||||
failures.each do |result|
|
failures.each do |(example, result)|
|
||||||
@io << FailureCommand.color(result)
|
@io << FailureCommand.color(example, result)
|
||||||
@io << ' '
|
@io << ' '
|
||||||
@io.puts Comment.color(result.example)
|
@io.puts Comment.color(example)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -28,8 +28,8 @@ module Spectator::Formatting
|
||||||
|
|
||||||
# Called when a test finishes.
|
# Called when a test finishes.
|
||||||
# The result of the test is provided.
|
# The result of the test is provided.
|
||||||
def end_example(result : Result)
|
def end_example(example : Example, result : Result)
|
||||||
@io.puts TAPTestLine.new(@index, result)
|
@io.puts TAPTestLine.new(@index, example, result)
|
||||||
@index += 1
|
@index += 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -39,19 +39,19 @@ module Spectator::Formatting
|
||||||
|
|
||||||
indent = Indent.new(@io)
|
indent = Indent.new(@io)
|
||||||
indent.increase do
|
indent.increase do
|
||||||
profile.each do |result|
|
profile.each do |example, result|
|
||||||
profile_entry(indent, result)
|
profile_entry(indent, example, result)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Adds a profile result entry to the output.
|
# Adds a profile result entry to the output.
|
||||||
private def profile_entry(indent, result)
|
private def profile_entry(indent, example, result)
|
||||||
@io << "# "
|
@io << "# "
|
||||||
indent.line(result.example)
|
indent.line(example)
|
||||||
indent.increase do
|
indent.increase do
|
||||||
@io << "# "
|
@io << "# "
|
||||||
indent.line(LocationTiming.new(result.elapsed, result.example.location))
|
indent.line(LocationTiming.new(result.elapsed, example.location))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,7 @@ module Spectator::Formatting
|
||||||
# Produces a formatted TAP test line.
|
# Produces a formatted TAP test line.
|
||||||
private struct TAPTestLine
|
private struct TAPTestLine
|
||||||
# Creates the test line.
|
# Creates the test line.
|
||||||
def initialize(@index : Int32, @result : Result)
|
def initialize(@index : Int32, @example : Example, @result : Result)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Appends the line to the output.
|
# Appends the line to the output.
|
||||||
|
@ -11,7 +11,7 @@ module Spectator::Formatting
|
||||||
io << ' '
|
io << ' '
|
||||||
io << @index
|
io << @index
|
||||||
io << " - "
|
io << " - "
|
||||||
io << example
|
io << @example
|
||||||
io << " # skip" if pending?
|
io << " # skip" if pending?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -20,11 +20,6 @@ module Spectator::Formatting
|
||||||
@result.is_a?(FailResult) ? "not ok" : "ok"
|
@result.is_a?(FailResult) ? "not ok" : "ok"
|
||||||
end
|
end
|
||||||
|
|
||||||
# The example that was tested.
|
|
||||||
private def example
|
|
||||||
@result.example
|
|
||||||
end
|
|
||||||
|
|
||||||
# Indicates whether this test was skipped.
|
# Indicates whether this test was skipped.
|
||||||
private def pending?
|
private def pending?
|
||||||
@result.is_a?(PendingResult)
|
@result.is_a?(PendingResult)
|
||||||
|
|
|
@ -94,14 +94,13 @@ module Spectator
|
||||||
# Takes the *elapsed* time and a possible *error* from the test.
|
# Takes the *elapsed* time and a possible *error* from the test.
|
||||||
# Returns a type of `Result`.
|
# Returns a type of `Result`.
|
||||||
private def translate(elapsed, error) : Result
|
private def translate(elapsed, error) : Result
|
||||||
example = Example.current # TODO: Remove this.
|
|
||||||
case error
|
case error
|
||||||
when nil
|
when nil
|
||||||
PassResult.new(example, elapsed, @expectations)
|
PassResult.new(elapsed, @expectations)
|
||||||
when ExpectationFailed
|
when ExpectationFailed
|
||||||
FailResult.new(example, elapsed, error, @expectations)
|
FailResult.new(elapsed, error, @expectations)
|
||||||
else
|
else
|
||||||
ErrorResult.new(example, elapsed, error, @expectations)
|
ErrorResult.new(elapsed, error, @expectations)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,8 @@ module Spectator
|
||||||
class PendingResult < Result
|
class PendingResult < Result
|
||||||
# Creates the result.
|
# Creates the result.
|
||||||
# *elapsed* is the length of time it took to run the example.
|
# *elapsed* is the length of time it took to run the example.
|
||||||
def initialize(example, elapsed = Time::Span::ZERO, expectations = [] of Expectation)
|
# *expectations* stores the expectations checked in the example.
|
||||||
|
def initialize(elapsed = Time::Span::ZERO, expectations = [] of Expectation)
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
module Spectator
|
module Spectator
|
||||||
# Information about the runtimes of examples.
|
# Information about the runtimes of examples.
|
||||||
class Profile
|
class Profile
|
||||||
include Indexable(Result)
|
include Indexable(Tuple(Example, Result))
|
||||||
|
|
||||||
# Total length of time it took to run all examples in the test suite.
|
# Total length of time it took to run all examples in the test suite.
|
||||||
getter total_time : Time::Span
|
getter total_time : Time::Span
|
||||||
|
|
||||||
# Creates the profiling information.
|
# Creates the profiling information.
|
||||||
# The *slowest* results must already be sorted, longest time first.
|
# The *slowest* results must already be sorted, longest time first.
|
||||||
private def initialize(@slowest : Array(Result), @total_time)
|
private def initialize(@slowest : Array(Tuple(Example, Result)), @total_time)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Number of results in the profile.
|
# Number of results in the profile.
|
||||||
|
@ -23,7 +23,7 @@ module Spectator
|
||||||
|
|
||||||
# Length of time it took to run the results in the profile.
|
# Length of time it took to run the results in the profile.
|
||||||
def time
|
def time
|
||||||
@slowest.sum(&.elapsed)
|
@slowest.sum(&.[1].elapsed)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Percentage (from 0 to 1) of time the results in this profile took compared to all examples.
|
# Percentage (from 0 to 1) of time the results in this profile took compared to all examples.
|
||||||
|
@ -34,7 +34,7 @@ module Spectator
|
||||||
# Produces the profile from a report.
|
# Produces the profile from a report.
|
||||||
def self.generate(report, size = 10)
|
def self.generate(report, size = 10)
|
||||||
results = report.to_a
|
results = report.to_a
|
||||||
sorted_results = results.sort_by(&.elapsed)
|
sorted_results = results.sort_by(&.[1].elapsed)
|
||||||
slowest = sorted_results.last(size).reverse
|
slowest = sorted_results.last(size).reverse
|
||||||
self.new(slowest, report.example_runtime)
|
self.new(slowest, report.example_runtime)
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@ require "./result"
|
||||||
module Spectator
|
module Spectator
|
||||||
# Outcome of all tests in a suite.
|
# Outcome of all tests in a suite.
|
||||||
class Report
|
class Report
|
||||||
include Enumerable(Result)
|
include Enumerable(Tuple(Example, Result))
|
||||||
|
|
||||||
# Total length of time it took to execute the test suite.
|
# Total length of time it took to execute the test suite.
|
||||||
# This includes examples, hooks, and framework processes.
|
# This includes examples, hooks, and framework processes.
|
||||||
|
@ -34,8 +34,8 @@ module Spectator
|
||||||
# The *remaining_count* is the number of tests skipped due to fail-fast.
|
# The *remaining_count* is the number of tests skipped due to fail-fast.
|
||||||
# The *fail_blank* flag indicates whether it is a failure if there were no tests run.
|
# The *fail_blank* flag indicates whether it is a failure if there were no tests run.
|
||||||
# The *random_seed* is the seed used for random number generation.
|
# The *random_seed* is the seed used for random number generation.
|
||||||
def initialize(@results : Array(Result), @runtime, @remaining_count = 0, @fail_blank = false, @random_seed = nil)
|
def initialize(@results : Array(Tuple(Example, Result)), @runtime, @remaining_count = 0, @fail_blank = false, @random_seed = nil)
|
||||||
@results.each do |result|
|
@results.each do |_example, result|
|
||||||
case result
|
case result
|
||||||
when PassResult
|
when PassResult
|
||||||
@successful_count += 1
|
@successful_count += 1
|
||||||
|
@ -57,15 +57,15 @@ module Spectator
|
||||||
# This constructor is intended for reports of subsets of results.
|
# This constructor is intended for reports of subsets of results.
|
||||||
# The *results* are from running the examples in the test suite.
|
# The *results* are from running the examples in the test suite.
|
||||||
# The runtime is calculated from the *results*.
|
# The runtime is calculated from the *results*.
|
||||||
def initialize(results : Array(Result))
|
def initialize(results : Array(Tuple(Example, Result)))
|
||||||
runtime = results.sum(&.elapsed)
|
runtime = results.sum(&.[1].elapsed)
|
||||||
initialize(results, runtime)
|
initialize(results, runtime)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Yields each result in turn.
|
# Yields each result in turn.
|
||||||
def each
|
def each
|
||||||
@results.each do |result|
|
@results.each do |entry|
|
||||||
yield result
|
yield entry
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -92,19 +92,27 @@ module Spectator
|
||||||
|
|
||||||
# Returns a set of results for all failed examples.
|
# Returns a set of results for all failed examples.
|
||||||
def failures
|
def failures
|
||||||
@results.each.compact_map(&.as?(FailResult))
|
@results.each.compact_map do |(example, result)|
|
||||||
|
if (r = result.as?(FailResult))
|
||||||
|
{example, r}
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns a set of results for all errored examples.
|
# Returns a set of results for all errored examples.
|
||||||
def errors
|
def errors
|
||||||
@results.each.compact_map(&.as?(ErrorResult))
|
@results.each.compact_map do |(example, result)|
|
||||||
|
if (r = result.as?(ErrorResult))
|
||||||
|
{example, r}
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Length of time it took to run just example code.
|
# Length of time it took to run just example code.
|
||||||
# This does not include hooks,
|
# This does not include hooks,
|
||||||
# but it does include pre- and post-conditions.
|
# but it does include pre- and post-conditions.
|
||||||
def example_runtime
|
def example_runtime
|
||||||
@results.sum(&.elapsed)
|
@results.sum(&.[1].elapsed)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Length of time spent in framework processes and hooks.
|
# Length of time spent in framework processes and hooks.
|
||||||
|
|
|
@ -2,19 +2,16 @@ module Spectator
|
||||||
# Base class that represents the outcome of running an example.
|
# Base class that represents the outcome of running an example.
|
||||||
# Sub-classes contain additional information specific to the type of result.
|
# Sub-classes contain additional information specific to the type of result.
|
||||||
abstract class Result
|
abstract class Result
|
||||||
# Example that generated the result.
|
|
||||||
# TODO: Remove this.
|
|
||||||
getter example : Example
|
|
||||||
|
|
||||||
# Length of time it took to run the example.
|
# Length of time it took to run the example.
|
||||||
getter elapsed : Time::Span
|
getter elapsed : Time::Span
|
||||||
|
|
||||||
# The assertions checked in the example.
|
# The expectations checked in the example.
|
||||||
getter expectations : Enumerable(Expectation)
|
getter expectations : Enumerable(Expectation)
|
||||||
|
|
||||||
# Creates the result.
|
# Creates the result.
|
||||||
# *elapsed* is the length of time it took to run the example.
|
# *elapsed* is the length of time it took to run the example.
|
||||||
def initialize(@example, @elapsed, @expectations = [] of Expectation)
|
# *expectations* stores the expectations checked in the example.
|
||||||
|
def initialize(@elapsed, @expectations = [] of Expectation)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Calls the corresponding method for the type of result.
|
# Calls the corresponding method for the type of result.
|
||||||
|
@ -30,8 +27,8 @@ module Spectator
|
||||||
|
|
||||||
# Adds the common fields for a result to a JSON builder.
|
# Adds the common fields for a result to a JSON builder.
|
||||||
private def add_json_fields(json : ::JSON::Builder)
|
private def add_json_fields(json : ::JSON::Builder)
|
||||||
json.field("name", example)
|
json.field("name", "TODO: Example name")
|
||||||
json.field("location", example.location)
|
json.field("location", "TODO: Example location")
|
||||||
json.field("result", to_s)
|
json.field("result", to_s)
|
||||||
json.field("time", elapsed.total_seconds)
|
json.field("time", elapsed.total_seconds)
|
||||||
json.field("expectations", expectations)
|
json.field("expectations", expectations)
|
||||||
|
|
|
@ -16,7 +16,7 @@ module Spectator
|
||||||
@config.each_formatter(&.start_suite(@suite))
|
@config.each_formatter(&.start_suite(@suite))
|
||||||
|
|
||||||
# Run all examples and capture the results.
|
# Run all examples and capture the results.
|
||||||
results = Array(Result).new(@suite.size)
|
results = Array(Tuple(Example, Result)).new(@suite.size)
|
||||||
elapsed = Time.measure do
|
elapsed = Time.measure do
|
||||||
collect_results(results)
|
collect_results(results)
|
||||||
end
|
end
|
||||||
|
@ -34,7 +34,7 @@ module Spectator
|
||||||
private def collect_results(results)
|
private def collect_results(results)
|
||||||
example_order.each do |example|
|
example_order.each do |example|
|
||||||
result = run_example(example).as(Result)
|
result = run_example(example).as(Result)
|
||||||
results << result
|
results << {example, result}
|
||||||
if @config.fail_fast? && result.is_a?(FailResult)
|
if @config.fail_fast? && result.is_a?(FailResult)
|
||||||
example.group.call_once_after_all
|
example.group.call_once_after_all
|
||||||
break
|
break
|
||||||
|
@ -60,14 +60,14 @@ module Spectator
|
||||||
else
|
else
|
||||||
example.run
|
example.run
|
||||||
end
|
end
|
||||||
@config.each_formatter(&.end_example(result))
|
@config.each_formatter(&.end_example(example, result))
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
# Creates a fake result for an example.
|
# Creates a fake result for an example.
|
||||||
private def dry_run_result(example)
|
private def dry_run_result(example)
|
||||||
expectations = [] of Expectation
|
expectations = [] of Expectation
|
||||||
PassResult.new(example, Time::Span.zero, expectations)
|
PassResult.new(Time::Span.zero, expectations)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Generates and returns a profile if one should be displayed.
|
# Generates and returns a profile if one should be displayed.
|
||||||
|
|
Loading…
Reference in New Issue