diff --git a/src/spectator/errored_result.cr b/src/spectator/errored_result.cr index b65e67e..e930cb3 100644 --- a/src/spectator/errored_result.cr +++ b/src/spectator/errored_result.cr @@ -22,5 +22,29 @@ module Spectator def to_s(io) io << "error" end + + # Adds the common JSON fields for all result types + # and fields specific to errored results. + private def add_json_fields(json : ::JSON::Builder) + super + json.field("exceptions") do + exception = error + json.array do + while exception + error_to_json(exception, json) if exception + exception = error.cause + end + end + end + end + + # Adds a single exception to a JSON builder. + private def error_to_json(error : Exception, json : ::JSON::Builder) + json.object do + json.field("type", error.class.to_s) + json.field("message", error.message) + json.field("backtrace") { error.backtrace.to_json(json) } + end + end end end diff --git a/src/spectator/failed_result.cr b/src/spectator/failed_result.cr index 773778a..65f5c4e 100644 --- a/src/spectator/failed_result.cr +++ b/src/spectator/failed_result.cr @@ -32,5 +32,11 @@ module Spectator def to_s(io) io << "fail" end + + # Adds all of the JSON fields for finished results and failed results. + private def add_json_fields(json : ::JSON::Builder) + super + json.field("error", error.message) + end end end diff --git a/src/spectator/finished_result.cr b/src/spectator/finished_result.cr index 76f6eaa..88e3058 100644 --- a/src/spectator/finished_result.cr +++ b/src/spectator/finished_result.cr @@ -15,5 +15,13 @@ module Spectator def initialize(example, @elapsed, @expectations) super(example) end + + # Adds the common JSON fields for all result types + # and fields specific to finished results. + private def add_json_fields(json : ::JSON::Builder) + super + json.field("time", elapsed.to_s) + json.field("expectations") { expectations.to_json(json) } + end end end diff --git a/src/spectator/formatting/json_formatter.cr b/src/spectator/formatting/json_formatter.cr index 66ce605..9795887 100644 --- a/src/spectator/formatting/json_formatter.cr +++ b/src/spectator/formatting/json_formatter.cr @@ -38,34 +38,6 @@ module Spectator::Formatting 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) diff --git a/src/spectator/result.cr b/src/spectator/result.cr index 5b016ea..9c524a2 100644 --- a/src/spectator/result.cr +++ b/src/spectator/result.cr @@ -22,5 +22,19 @@ module Spectator # This variation takes a block, which is passed the result. # The value returned from the block will be returned by this method. abstract def call(interface, &block : Result -> _) + + # Creates a JSON object from the result information. + def to_json(json : ::JSON::Builder) + json.object do + add_json_fields(json) + end + end + + # Adds the common fields for a result to a JSON builder. + private def add_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 end