diff --git a/src/spectator/formatting/components/block.cr b/src/spectator/formatting/components/block.cr new file mode 100644 index 0000000..19286c8 --- /dev/null +++ b/src/spectator/formatting/components/block.cr @@ -0,0 +1,20 @@ +module Spectator::Formatting::Components + abstract struct Block + private INDENT = 2 + + def initialize(*, @indent : Int32 = INDENT) + end + + private def indent(amount = INDENT) + @indent += amount + yield + @indent -= amount + end + + private def line(io) + @indent.times { io << ' ' } + yield + io.puts + end + end +end diff --git a/src/spectator/formatting/components/comment.cr b/src/spectator/formatting/components/comment.cr index 75b67df..7405c6e 100644 --- a/src/spectator/formatting/components/comment.cr +++ b/src/spectator/formatting/components/comment.cr @@ -1,3 +1,5 @@ +require "colorize" + module Spectator::Formatting::Components struct Comment(T) private COLOR = :cyan diff --git a/src/spectator/formatting/components/error_block.cr b/src/spectator/formatting/components/error_block.cr deleted file mode 100644 index 64650dc..0000000 --- a/src/spectator/formatting/components/error_block.cr +++ /dev/null @@ -1,44 +0,0 @@ -require "../../example" -require "../../error_result" -require "./comment" - -module Spectator::Formatting::Components - struct ErrorBlock - private INDENT = 2 - - def initialize(@example : Example, @result : ErrorResult, @index : Int32) - end - - def to_s(io) - 2.times { io << ' ' } - io << @index - io << ')' - io << ' ' - io.puts @example - indent = INDENT + index_digit_count + 2 - indent.times { io << ' ' } - error = @result.error - io << "Error: ".colorize(:red) - io.puts error.message - io.puts - indent.times { io << ' ' } - io << error.class - io.puts ':' - indent += INDENT - error.backtrace?.try do |trace| - trace.each do |entry| - indent.times { io << ' ' } - entry = entry.colorize.dim unless entry.starts_with?(/src\/|spec\//) - io.puts entry - end - end - indent -= INDENT - indent.times { io << ' ' } - io.puts Comment.colorize(@example.location) # TODO: Use location of failed expectation. - end - - private def index_digit_count - (Math.log(@index.to_f + 1) / Math.log(10)).ceil.to_i - end - end -end diff --git a/src/spectator/formatting/components/error_result_block.cr b/src/spectator/formatting/components/error_result_block.cr new file mode 100644 index 0000000..10d9826 --- /dev/null +++ b/src/spectator/formatting/components/error_result_block.cr @@ -0,0 +1,40 @@ +require "colorize" +require "../../example" +require "../../error_result" +require "./result_block" + +module Spectator::Formatting::Components + struct ErrorResultBlock < ResultBlock + def initialize(index : Int32, example : Example, @result : ErrorResult) + super(index, example) + end + + private def subtitle + @result.error.message + end + + private def subtitle_label + "Error: ".colorize(:red) + end + + private def content(io) + error = @result.error + + line(io) do + io << "#{error.class}: ".colorize(:red) + io << error.message + end + + error.backtrace?.try do |backtrace| + indent { write_backtrace(io, backtrace) } + end + end + + private def write_backtrace(io, backtrace) + backtrace.each do |entry| + entry = entry.colorize.dim unless entry.starts_with?(/(src|spec)\//) + line(io) { io << entry } + end + end + end +end diff --git a/src/spectator/formatting/components/fail_result_block.cr b/src/spectator/formatting/components/fail_result_block.cr new file mode 100644 index 0000000..9b20a1b --- /dev/null +++ b/src/spectator/formatting/components/fail_result_block.cr @@ -0,0 +1,24 @@ +require "colorize" +require "../../example" +require "../../fail_result" +require "./result_block" + +module Spectator::Formatting::Components + struct FailResultBlock < ResultBlock + def initialize(index : Int32, example : Example, @result : FailResult) + super(index, example) + end + + private def subtitle + @result.error.message + end + + private def subtitle_label + "Failure: ".colorize(:red) + end + + private def content(io) + # TODO: Display match data. + end + end +end diff --git a/src/spectator/formatting/components/failure_block.cr b/src/spectator/formatting/components/failure_block.cr deleted file mode 100644 index 1980ec9..0000000 --- a/src/spectator/formatting/components/failure_block.cr +++ /dev/null @@ -1,32 +0,0 @@ -require "../../example" -require "../../fail_result" -require "./comment" - -module Spectator::Formatting::Components - struct FailureBlock - private INDENT = 2 - - def initialize(@example : Example, @result : FailResult, @index : Int32) - end - - def to_s(io) - 2.times { io << ' ' } - io << @index - io << ')' - io << ' ' - io.puts @example - indent = INDENT + index_digit_count + 2 - indent.times { io << ' ' } - io << "Failure: ".colorize(:red) - io.puts @result.error.message - io.puts - # TODO: Expectation values - indent.times { io << ' ' } - io.puts Comment.colorize(@example.location) # TODO: Use location of failed expectation. - end - - private def index_digit_count - (Math.log(@index.to_f + 1) / Math.log(10)).ceil.to_i - end - end -end diff --git a/src/spectator/formatting/components/result_block.cr b/src/spectator/formatting/components/result_block.cr new file mode 100644 index 0000000..1321b13 --- /dev/null +++ b/src/spectator/formatting/components/result_block.cr @@ -0,0 +1,58 @@ +require "../../example" +require "./block" +require "./comment" + +module Spectator::Formatting::Components + abstract struct ResultBlock < Block + def initialize(@index : Int32, @example : Example) + super() + end + + private def title + @example + end + + private abstract def subtitle + + private abstract def subtitle_label + + def to_s(io) + title_line(io) + indent(index_digit_count + 2) do + subtitle_line(io) + io.puts + content(io) + source_line(io) + end + end + + private def title_line(io) + line(io) do + io << @index + io << ')' + io << ' ' + io << title + end + end + + private def subtitle_line(io) + line(io) do + io << subtitle_label + io << subtitle + end + end + + private def source_line(io) + source = if (result = @example.result).responds_to?(:source) + result.source + else + @example.location + end + line(io) { io << Comment.colorize(source) } + end + + private def index_digit_count + (Math.log(@index.to_f + 1) / Math::LOG10).ceil.to_i + end + end +end diff --git a/src/spectator/formatting/summary.cr b/src/spectator/formatting/summary.cr index 7d07353..7dba7f2 100644 --- a/src/spectator/formatting/summary.cr +++ b/src/spectator/formatting/summary.cr @@ -38,9 +38,9 @@ module Spectator::Formatting io.puts examples.each_with_index do |example, index| if result = example.result.as?(ErrorResult) - io.puts Components::ErrorBlock.new(example, result, index + 1) + io.puts Components::ErrorResultBlock.new(index + 1, example, result) elsif result = example.result.as?(FailResult) - io.puts Components::FailureBlock.new(example, result, index + 1) + io.puts Components::FailResultBlock.new(index + 1, example, result) end end end