shard-spectator/src/spectator/formatting/junit_test_suite.cr

78 lines
2.3 KiB
Crystal

module Spectator::Formatting
# Mapping of a single spec file into a JUnit test suite.
private struct JUnitTestSuite
# Creates the JUnit test suite.
# The *path* should be the file that all results are from.
# The *results* is a subset of all results that share the path.
def initialize(@path : String, results : Array(Tuple(Example, Result)))
@report = Report.new(results)
end
# Generates the XML for the test suite (and all nested test cases).
def to_xml(xml : ::XML::Builder)
xml.element("testsuite",
tests: @report.example_count,
failures: @report.failed_count,
errors: @report.error_count,
skipped: @report.pending_count,
time: @report.runtime.total_seconds,
name: name,
package: package) do
add_test_cases(xml)
end
end
# Adds the test case elements to the XML.
private def add_test_cases(xml)
@report.each do |(example, result)|
test_case = result.accept(JUnitTestCaseSelector) { |r| {example, r} }
test_case.to_xml(xml)
end
end
# Java-ified name of the test suite.
private def name
file = File.basename(@path)
ext = File.extname(file)
name = file[0...-(ext.size)]
name.camelcase
end
# Java-ified package (path) of the test suite.
private def package
file = File.basename(@path)
dir = @path[0...-(file.size + 1)]
dir.gsub('/', '.').underscore
end
# Selector for creating a JUnit test case based on a result.
private module JUnitTestCaseSelector
extend self
# Creates a successful JUnit test case.
def pass(result)
example, result = result
SuccessfulJUnitTestCase.new(example, result.as(PassResult))
end
# Creates a failure JUnit test case.
def failure(result)
example, result = result
FailureJUnitTestCase.new(example, result.as(FailResult))
end
# Creates an error JUnit test case.
def error(result)
example, result = result
ErrorJUnitTestCase.new(example, result.as(ErrorResult))
end
# Creates a skipped JUnit test case.
def pending(result)
example, result = result
SkippedJUnitTestCase.new(example, result.as(PendingResult))
end
end
end
end