diff --git a/spec/helpers/spy_formatter.cr b/spec/helpers/spy_formatter.cr index 47de502..9afc644 100644 --- a/spec/helpers/spy_formatter.cr +++ b/spec/helpers/spy_formatter.cr @@ -3,7 +3,6 @@ class SpyFormatter < Spectator::Formatting::Formatter {% for item in [ {"start_suite", "Spectator::TestSuite"}, - {"end_suite", "Spectator::Report"}, {"start_example", "Spectator::Example"}, {"end_example", "Spectator::Result"}, ] %} @@ -27,6 +26,21 @@ class SpyFormatter < Spectator::Formatting::Formatter {% end %} + # Stores all invocatiosn made to `#end_suite`. + # Each element is an invocation and the value is the arguments passed to the method. + getter end_suite_calls = [] of NamedTuple(report: Spectator::Report, profile: Bool) + + # Number of times the `#end_suite` method was called. + def end_suite_call_count + @end_suite_calls.size + end + + # Increments `#end_suite_call_count` and stores the arguments. + def end_suite(report, profile) + @all_calls << :end_suite + @end_suite_calls << {report: report, profile: profile} + end + # Stores the methods that were called and in which order. # The symbols will be the method name (i.e. `:start_suite`). getter all_calls = [] of Symbol diff --git a/spec/runner_spec.cr b/spec/runner_spec.cr index a20e15a..1fa678b 100644 --- a/spec/runner_spec.cr +++ b/spec/runner_spec.cr @@ -49,8 +49,8 @@ describe Spectator::Runner do suite = new_test_suite(group) runner = Spectator::Runner.new(suite, spectator_test_config(spy, true)) runner.run - report = spy.end_suite_calls.first - report.remaining_count.should eq(3) + args = spy.end_suite_calls.first + args[:report].remaining_count.should eq(3) end end end @@ -164,7 +164,8 @@ describe Spectator::Runner do spy = SpyFormatter.new runner = Spectator::Runner.new(suite, spectator_test_config(spy)) runner.run - spy.end_example_calls.each_with_index do |result, index| + args = spy.end_suite_calls.first + args[:report].each_with_index do |result, index| if index.odd? result.should be_a(Spectator::SuccessfulResult) else @@ -180,7 +181,8 @@ describe Spectator::Runner do runner = Spectator::Runner.new(suite, spectator_test_config(spy)) max_time = Time.measure { runner.run } min_time = spy.end_example_calls.each.map(&.as(Spectator::FinishedResult)).sum(&.elapsed) - report = spy.end_suite_calls.first + args = spy.end_suite_calls.first + report = args[:report] report.runtime.should be <= max_time report.runtime.should be >= min_time end diff --git a/src/spectator/formatting/formatter.cr b/src/spectator/formatting/formatter.cr index 9696ccb..ab85900 100644 --- a/src/spectator/formatting/formatter.cr +++ b/src/spectator/formatting/formatter.cr @@ -14,7 +14,8 @@ module Spectator::Formatting # Called when a test suite finishes. # The results from the entire suite are provided. - abstract def end_suite(report : Report) + # The *profile* flag is set to true when profiling results should be generated. + abstract def end_suite(report : Report, profile : Bool) # Called before a test starts. abstract def start_example(example : Example) diff --git a/src/spectator/formatting/json_formatter.cr b/src/spectator/formatting/json_formatter.cr index 36e739f..6ab4d7f 100644 --- a/src/spectator/formatting/json_formatter.cr +++ b/src/spectator/formatting/json_formatter.cr @@ -20,10 +20,12 @@ module Spectator::Formatting # Called when a test suite finishes. # The results from the entire suite are provided. - def end_suite(report : Report) + # The *profile* flag is set to true when profiling results should be generated. + def end_suite(report : Report, profile : Bool) @json.end_array # examples totals(report) timing(report) + profile(report) if profile @json.field("result", report.failed? ? "fail" : "success") @json.end_object end @@ -62,5 +64,10 @@ module Spectator::Formatting end end end + + # Adds the profile information to the document. + private def profile(report) + raise NotImplementedError.new("profile") + end end end diff --git a/src/spectator/formatting/junit_formatter.cr b/src/spectator/formatting/junit_formatter.cr index a5ff115..3215006 100644 --- a/src/spectator/formatting/junit_formatter.cr +++ b/src/spectator/formatting/junit_formatter.cr @@ -24,7 +24,8 @@ module Spectator::Formatting # Called when a test suite finishes. # The results from the entire suite are provided. - def end_suite(report : Report) + # The *profile* flag does nothing for this formatter. + def end_suite(report : Report, profile : Bool) test_suites_block(report) @xml.end_document @xml.flush diff --git a/src/spectator/formatting/silent_formatter.cr b/src/spectator/formatting/silent_formatter.cr index b9e2eb2..eaf3464 100644 --- a/src/spectator/formatting/silent_formatter.cr +++ b/src/spectator/formatting/silent_formatter.cr @@ -9,7 +9,7 @@ module Spectator::Formatting # Called when a test suite finishes. # The results from the entire suite are provided. - def end_suite(report : Report) + def end_suite(report : Report, profile : Bool) # ... crickets ... end diff --git a/src/spectator/formatting/suite_summary.cr b/src/spectator/formatting/suite_summary.cr index b9efb7f..c0e2e2e 100644 --- a/src/spectator/formatting/suite_summary.cr +++ b/src/spectator/formatting/suite_summary.cr @@ -9,12 +9,14 @@ module Spectator::Formatting # Produces the summary of test suite from a report. # A block describing each failure is displayed. # At the end, the totals and runtime are printed. - def end_suite(report) + # The *profile* flag is set to true when profiling results should be generated. + def end_suite(report, profile : Bool) if report.example_count > 0 @io.puts if is_a?(DotsFormatter) @io.puts end failures(report.failures) if report.failed_count > 0 + profile(report) if profile stats(report) remaining(report) if report.remaining? if report.failed? @@ -36,6 +38,11 @@ module Spectator::Formatting end end + # Produces the profiling section of the summary. + private def profile(report) + raise NotImplementedError.new("profile") + end + # Produces the statistical section of the summary. # This contains how long the suite took to run # and the counts for the results (total, failures, errors, and pending). diff --git a/src/spectator/formatting/tap_formatter.cr b/src/spectator/formatting/tap_formatter.cr index 2a832de..eee6156 100644 --- a/src/spectator/formatting/tap_formatter.cr +++ b/src/spectator/formatting/tap_formatter.cr @@ -16,8 +16,9 @@ module Spectator::Formatting # Called when a test suite finishes. # The results from the entire suite are provided. - def end_suite(report : Report) + def end_suite(report : Report, profile : Bool) @io.puts "Bail out!" if report.remaining? + profile(report) if profile end # Called before a test starts. @@ -30,5 +31,10 @@ module Spectator::Formatting @io.puts TAPTestLine.new(@index, result) @index += 1 end + + # Generates profiling information for the report. + private def profile(report) + raise NotImplementedError.new("profile") + end end end diff --git a/src/spectator/runner.cr b/src/spectator/runner.cr index 21802f0..ca5942f 100644 --- a/src/spectator/runner.cr +++ b/src/spectator/runner.cr @@ -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.each_formatter(&.end_suite(report)) + @config.each_formatter(&.end_suite(report, false)) # TODO: Profile flag. !report.failed? end