Initial work on JSON formatter

This commit is contained in:
Michael Miller 2019-03-22 20:11:58 -06:00
parent ba0453c5ea
commit 82a4a15ba9
2 changed files with 108 additions and 0 deletions

View file

@ -22,6 +22,7 @@ module Spectator
parser.on("-l", "--line LINE", "Run examples whose line matches LINE") { |line| raise NotImplementedError.new("-l") }
parser.on("-p", "--profile", "Display the 10 slowest specs") { raise NotImplementedError.new("-p") }
parser.on("--location FILE:LINE", "Run the example at line 'LINE' in the file 'FILE', multiple allowed") { |location| raise NotImplementedError.new("--location") }
parser.on("--json", "Generate JSON output") { builder.formatter = Formatting::JsonFormatter.new }
parser.on("--junit_output OUTPUT_DIR", "Generate JUnit XML output") { |output_dir| raise NotImplementedError.new("--juni_output") }
parser.on("--tap", "Generate TAP output (Test Anything Protocol)") { raise NotImplementedError.new("--tap") }
parser.on("--no-color", "Disable colored output") { raise NotImplementedError.new("--no-color") }

View file

@ -0,0 +1,107 @@
require "json"
require "./formatter"
module Spectator::Formatting
# Produces a JSON document containing the test results.
class JsonFormatter < Formatter
# Creates the formatter.
# By default, output is sent to STDOUT.
def initialize(io : IO = STDOUT)
@json = ::JSON::Builder.new(io)
end
# Called when a test suite is starting to execute.
def start_suite(suite : TestSuite)
@json.start_document
@json.start_object
@json.string("examples")
@json.start_array
end
# Called when a test suite finishes.
# The results from the entire suite are provided.
def end_suite(report : Report)
@json.end_array # examples
@json.end_object
end
# Called before a test starts.
def start_example(example : Example)
end
# Called when a test finishes.
# The result of the test is provided.
def end_example(result : Result)
result.to_json(@json)
end
end
end
module Spectator
abstract class Result
def to_json(json : ::JSON::Builder)
json.object do
common_json_fields(json)
end
end
private def common_json_fields(json : ::JSON::Builder)
json.field("name") { example.to_json(json) }
json.field("location") { example.source.to_json(json) }
json.field("result", to_s)
end
end
abstract class FinishedResult < Result
def to_json(json : ::JSON::Builder)
json.object do
finished_json_fields(json)
end
end
private def finished_json_fields(json)
common_json_fields(json)
json.field("time", elapsed.to_s)
json.field("expectations") { expectations.to_json(json) }
end
end
abstract class Example < ExampleComponent
def to_json(json : ::JSON::Builder)
json.string(to_s)
end
end
struct Source
def to_json(json : ::JSON::Builder)
json.string(to_s)
end
end
module Expectations
class ExampleExpectations
def to_json(json : ::JSON::Builder)
json.array do
each &.to_json(json)
end
end
end
class Expectation
def to_json(json : ::JSON::Builder)
json.object do
json.field("satisfied") { satisfied?.to_json(json) }
json.field("expected") { expected_message.to_json(json) }
json.field("actual") { actual_message.to_json(json) }
json.field("values") do
json.object do
values.each do |labeled_value|
json.field(labeled_value.label, labeled_value.value.to_s)
end
end
end
end
end
end
end
end