diff --git a/src/spectator/config.cr b/src/spectator/config.cr index 448f55d..cd1e144 100644 --- a/src/spectator/config.cr +++ b/src/spectator/config.cr @@ -1,8 +1,7 @@ module Spectator # Provides customization and describes specifics for how Spectator will run and report tests. class Config - # Used to report test progress and results. - getter formatter : Formatting::Formatter + @formatters : Array(Formatting::Formatter) # Indicates whether the test should abort on first failure. getter? fail_fast : Bool @@ -16,10 +15,17 @@ module Spectator # Creates a new configuration. def initialize(builder) - @formatter = builder.formatter + @formatters = builder.formatters @fail_fast = builder.fail_fast? @fail_blank = builder.fail_blank? @dry_run = builder.dry_run? end + + # Yields each formatter that should be reported to. + def each_formatter + @formatters.each do |formatter| + yield formatter + end + end end end diff --git a/src/spectator/config_builder.cr b/src/spectator/config_builder.cr index 72bf9e0..647c5da 100644 --- a/src/spectator/config_builder.cr +++ b/src/spectator/config_builder.cr @@ -8,21 +8,27 @@ module Spectator new.build end - @formatter : Formatting::Formatter? = nil + @primary_formatter : Formatting::Formatter? + @additional_formatters = [] of Formatting::Formatter @fail_fast = false @fail_blank = false @dry_run = false - # Sets the formatter to use for reporting test progress and results. + # Sets the primary formatter to use for reporting test progress and results. def formatter=(formatter : Formatting::Formatter) - @formatter = formatter + @primary_formatter = formatter end - # Retrieves the formatter to use. + # Adds an extra formater to use for reporting test progress and results. + def add_formatter(formatter : Formatting::Formatter) + @additional_formatters << formatter + end + + # Retrieves the formatters to use. # If one wasn't specified by the user, # then `#default_formatter` is returned. - def formatter - @formatter || default_formatter + def formatters + @additional_formatters + [(@primary_formatter || default_formatter)] end # The formatter that should be used, diff --git a/src/spectator/runner.cr b/src/spectator/runner.cr index 998046c..83ef37b 100644 --- a/src/spectator/runner.cr +++ b/src/spectator/runner.cr @@ -13,7 +13,7 @@ module Spectator # or false if there was at least one failure. def run : Bool # Indicate the suite is starting. - @config.formatter.start_suite(@suite) + @config.each_formatter(&.start_suite(@suite)) # Run all examples and capture the results. results = Array(Result).new(@suite.size) @@ -24,7 +24,7 @@ module Spectator # Generate a report and pass it along to the formatter. remaining = @suite.size - results.size report = Report.new(results, elapsed, remaining, @config.fail_blank?) - @config.formatter.end_suite(report) + @config.each_formatter(&.end_suite(report)) !report.failed? end @@ -41,13 +41,13 @@ module Spectator # Runs a single example and returns the result. # The formatter is given the example and result information. private def run_example(example) - @config.formatter.start_example(example) + @config.each_formatter(&.start_example(example)) result = if @config.dry_run? && example.is_a?(RunnableExample) dry_run_result(example) else Internals::Harness.run(example) end - @config.formatter.end_example(result) + @config.each_formatter(&.end_example(result)) result end