Implement TAP formatter

This commit is contained in:
Michael Miller 2021-05-29 23:09:28 -06:00
parent 40e189a1d1
commit 7215e28d75
No known key found for this signature in database
GPG key ID: F9A0C5C65B162436
2 changed files with 99 additions and 0 deletions

View file

@ -0,0 +1,32 @@
require "../../profile"
require "./runtime"
module Spectator::Formatting::Components
struct TAPProfile
def initialize(@profile : Spectator::Profile)
end
def to_s(io)
io << "# Top "
io << @profile.size
io << " slowest examples ("
io << Runtime.new(@profile.time)
io << ", "
io << @profile.percentage.round(2)
io.puts "% of total time):"
@profile.each do |example|
example_profile(io, example)
end
end
private def example_profile(io, example)
io << "# "
io.puts example
io << "# "
io << Runtime.new(example.result.elapsed)
io << ' '
io.puts example.location
end
end
end

View file

@ -1,6 +1,73 @@
require "./formatter"
module Spectator::Formatting
# Produces TAP output from test results.
# See: https://testanything.org/
# Version 12 of the specification is used.
class TAPFormatter < Formatter
@counter = 0
# Creates the formatter.
def initialize(@io : IO = STDOUT)
end
# Invoked when the test suite begins.
def start(notification)
@io << "1.."
@io.puts notification.example_count
end
# Invoked just after an example completes.
def example_finished(_notification)
@counter += 1
end
# Invoked after an example completes successfully.
def example_passed(notification)
@io << "ok "
@io << @counter
@io << " - "
@io.puts notification.example
end
# Invoked after an example is skipped or marked as pending.
def example_pending(notification)
@io << "not ok " # TODO: Skipped tests should report ok.
@io << @counter
@io << " - "
@io << notification.example
@io << " # TODO "
@io.puts "No reason given" # TODO: Get reason from result.
end
# Invoked after an example fails.
def example_failed(notification)
@io << "not ok "
@io << @counter
@io << " - "
@io.puts notification.example
end
# Invoked after an example fails from an unexpected error.
def example_error(notification)
example_failed(notification)
end
# Called whenever the example or framework produces a message.
# This is typically used for logging.
def message(notification)
@io << "# "
@io.puts notification.message
end
# Invoked after testing completes with profiling information.
def dump_profile(notification)
@io << Components::TAPProfile.new(notification.profile)
end
# Invoked after testing completes with summarized information from the test suite.
def dump_summary(notification)
@io.puts "Bail out!" if notification.report.counts.remaining?
end
end
end