diff --git a/src/spectator/formatting/error_junit_test_case.cr b/src/spectator/formatting/error_junit_test_case.cr index 2c2fc32..f832355 100644 --- a/src/spectator/formatting/error_junit_test_case.cr +++ b/src/spectator/formatting/error_junit_test_case.cr @@ -1,26 +1,19 @@ +require "./failure_junit_test_case" + module Spectator::Formatting - private struct ErrorJUnitTestCase + # JUnit test case for a errored result. + private class ErrorJUnitTestCase < FailureJUnitTestCase + # Result for this test case. + private getter result + + # Creates the JUnit test case. def initialize(@result : ErroredResult) end - def to_xml(xml : ::XML::Builder) - xml.element("testcase", - name: @result.example, - status: @result, - time: @result.elapsed.total_seconds, - classname: classname, - assertions: @result.expectations.size) do - xml.element("error", message: @result.error.message, type: @result.error.class) - @result.expectations.each_unsatisfied do |expectation| - xml.element("failure", message: expectation.actual_message) do - # TODO: Add values as text to this block. - end - end - end - end - - private def classname - "TODO" + # Adds the exception to the XML block. + private def content(xml) + xml.element("error", message: @result.error.message, type: @result.error.class) + super end end end diff --git a/src/spectator/formatting/failure_junit_test_case.cr b/src/spectator/formatting/failure_junit_test_case.cr index 785a330..1d0aced 100644 --- a/src/spectator/formatting/failure_junit_test_case.cr +++ b/src/spectator/formatting/failure_junit_test_case.cr @@ -1,25 +1,23 @@ +require "./finished_junit_test_case" + module Spectator::Formatting - private struct FailureJUnitTestCase + # JUnit test case for a failed result. + private class FailureJUnitTestCase < FinishedJUnitTestCase + # Result for this test case. + private getter result + + # Creates the JUnit test case. def initialize(@result : FailedResult) end - def to_xml(xml : ::XML::Builder) - xml.element("testcase", - name: @result.example, - status: @result, - time: @result.elapsed.total_seconds, - classname: classname, - assertions: @result.expectations.size) do - @result.expectations.each_unsatisfied do |expectation| - xml.element("failure", message: expectation.actual_message) do - # TODO: Add values as text to block. - end + # Adds the failed expectations to the XML block. + private def content(xml) + super + @result.expectations.each_unsatisfied do |expectation| + xml.element("failure", message: expectation.actual_message) do + # TODO: Add values as text to block. end end end - - private def classname - "TODO" - end end end diff --git a/src/spectator/formatting/finished_junit_test_case.cr b/src/spectator/formatting/finished_junit_test_case.cr new file mode 100644 index 0000000..0db79de --- /dev/null +++ b/src/spectator/formatting/finished_junit_test_case.cr @@ -0,0 +1,21 @@ +require "./junit_test_case" + +module Spectator::Formatting + # Commonalities of all test cases that ran (success or failure). + private abstract class FinishedJUnitTestCase < JUnitTestCase + # Produces the test case XML element. + def to_xml(xml : ::XML::Builder) + xml.element("testcase", **full_attributes) do + content(xml) + end + end + + # Attributes that go in the "testcase" XML element. + private def full_attributes + attributes.merge( + time: result.elapsed.total_seconds, + assertions: result.expectations.size + ) + end + end +end diff --git a/src/spectator/formatting/junit_test_case.cr b/src/spectator/formatting/junit_test_case.cr index d803219..4f7e4cb 100644 --- a/src/spectator/formatting/junit_test_case.cr +++ b/src/spectator/formatting/junit_test_case.cr @@ -1,26 +1,34 @@ module Spectator::Formatting - # Selector for creating a JUnit test case based on a result. - private module JUnitTestCase - extend self - - # Creates a successful JUnit test case. - def success(result) - SuccessfulJUnitTestCase.new(result.as(SuccessfulResult)) + # Base type for all JUnit test case results. + private abstract class JUnitTestCase + # Produces the test case XML element. + def to_xml(xml : ::XML::Builder) + xml.element("testcase", **attributes) do + content(xml) + end end - # Creates a failure JUnit test case. - def failure(result) - FailureJUnitTestCase.new(result.as(FailedResult)) + # Attributes that go in the "testcase" XML element. + private def attributes + { + name: result.example, + status: result, + classname: classname, + } end - # Creates an error JUnit test case. - def error(result) - ErrorJUnitTestCase.new(result.as(ErroredResult)) + # Result to pull values from. + private abstract def result + + # Adds additional content to the "testcase" XML block. + # Override this to add more content. + private def content(xml) + # ... end - # Creates a skipped JUnit test case. - def pending(result) - SkippedJUnitTestCase.new(result.as(PendingResult)) + # Java-ified class name created from the spec. + private def classname + "TODO" end end end diff --git a/src/spectator/formatting/junit_test_suite.cr b/src/spectator/formatting/junit_test_suite.cr index 9645df1..ffff476 100644 --- a/src/spectator/formatting/junit_test_suite.cr +++ b/src/spectator/formatting/junit_test_suite.cr @@ -18,19 +18,51 @@ module Spectator::Formatting time: @report.runtime.total_seconds, name: name, package: package) do - @report.each do |result| - test_case = result.call(JUnitTestCase) { |r| r } - test_case.to_xml(xml) - end + add_test_cases(xml) end end + # Adds the test case elements to the XML. + private def add_test_cases(xml) + @report.each do |result| + test_case = result.call(JUnitTestCaseSelector) { |r| r } + test_case.to_xml(xml) + end + end + + # Java-ified name of the test suite. private def name "TODO" end + # Java-ified package (path) of the test suite. private def package "TODO" end + + # Selector for creating a JUnit test case based on a result. + private module JUnitTestCaseSelector + extend self + + # Creates a successful JUnit test case. + def success(result) + SuccessfulJUnitTestCase.new(result.as(SuccessfulResult)) + end + + # Creates a failure JUnit test case. + def failure(result) + FailureJUnitTestCase.new(result.as(FailedResult)) + end + + # Creates an error JUnit test case. + def error(result) + ErrorJUnitTestCase.new(result.as(ErroredResult)) + end + + # Creates a skipped JUnit test case. + def pending(result) + SkippedJUnitTestCase.new(result.as(PendingResult)) + end + end end end diff --git a/src/spectator/formatting/skipped_junit_test_case.cr b/src/spectator/formatting/skipped_junit_test_case.cr index 4be4e81..2ec0c01 100644 --- a/src/spectator/formatting/skipped_junit_test_case.cr +++ b/src/spectator/formatting/skipped_junit_test_case.cr @@ -1,19 +1,19 @@ +require "./junit_test_case" + module Spectator::Formatting - private struct SkippedJUnitTestCase + # JUnit test case for a pending result. + private class SkippedJUnitTestCase < JUnitTestCase + # Result for this test case. + private getter result + + # Creates the JUnit test case. def initialize(@result : PendingResult) end - def to_xml(xml : ::XML::Builder) - xml.element("testcase", - name: @result.example, - status: @result, - classname: classname) do - xml.element("skipped") - end - end - - private def classname - "TODO" + # Adds the skipped tag to the XML block. + private def content(xml) + super + xml.element("skipped") end end end diff --git a/src/spectator/formatting/successful_junit_test_case.cr b/src/spectator/formatting/successful_junit_test_case.cr index 4eb3ab1..f8f0227 100644 --- a/src/spectator/formatting/successful_junit_test_case.cr +++ b/src/spectator/formatting/successful_junit_test_case.cr @@ -1,19 +1,11 @@ module Spectator::Formatting - private struct SuccessfulJUnitTestCase + # JUnit test case for a successful result. + private class SuccessfulJUnitTestCase < FinishedJUnitTestCase + # Result for this test case. + private getter result + + # Creates the JUnit test case. def initialize(@result : SuccessfulResult) end - - def to_xml(xml : ::XML::Builder) - xml.element("testcase", - name: @result.example, - status: @result, - time: @result.elapsed.total_seconds, - classname: classname, - assertions: @result.expectations.size) - end - - private def classname - "TODO" - end end end