summaryrefslogtreecommitdiffstats
path: root/test/lua/busted/outputHandlers/junit.lua
diff options
context:
space:
mode:
Diffstat (limited to 'test/lua/busted/outputHandlers/junit.lua')
-rw-r--r--test/lua/busted/outputHandlers/junit.lua136
1 files changed, 136 insertions, 0 deletions
diff --git a/test/lua/busted/outputHandlers/junit.lua b/test/lua/busted/outputHandlers/junit.lua
new file mode 100644
index 000000000..36e78936e
--- /dev/null
+++ b/test/lua/busted/outputHandlers/junit.lua
@@ -0,0 +1,136 @@
+local xml = require 'pl.xml'
+local socket = require("socket")
+local string = require("string")
+
+return function(options, busted)
+ local handler = require 'busted.outputHandlers.base'(busted)
+ local top = {
+ start_time = socket.gettime(),
+ xml_doc = xml.new('testsuites', {
+ tests = 0,
+ errors = 0,
+ failures = 0,
+ skip = 0,
+ })
+ }
+ local stack = {}
+ local testStartTime
+
+ handler.suiteStart = function(count, total)
+ local suite = {
+ start_time = socket.gettime(),
+ xml_doc = xml.new('testsuite', {
+ name = 'Run ' .. count .. ' of ' .. total,
+ tests = 0,
+ errors = 0,
+ failures = 0,
+ skip = 0,
+ timestamp = os.date('!%Y-%m-%dT%T'),
+ })
+ }
+ top.xml_doc:add_direct_child(suite.xml_doc)
+ table.insert(stack, top)
+ top = suite
+
+ return nil, true
+ end
+
+ local function elapsed(start_time)
+ return string.format("%.2f", (socket.gettime() - start_time))
+ end
+
+ handler.suiteEnd = function(count, total)
+ local suite = top
+ suite.xml_doc.attr.time = elapsed(suite.start_time)
+
+ top = table.remove(stack)
+ top.xml_doc.attr.tests = top.xml_doc.attr.tests + suite.xml_doc.attr.tests
+ top.xml_doc.attr.errors = top.xml_doc.attr.errors + suite.xml_doc.attr.errors
+ top.xml_doc.attr.failures = top.xml_doc.attr.failures + suite.xml_doc.attr.failures
+ top.xml_doc.attr.skip = top.xml_doc.attr.skip + suite.xml_doc.attr.skip
+
+ return nil, true
+ end
+
+ handler.exit = function()
+ top.xml_doc.attr.time = elapsed(top.start_time)
+ print(xml.tostring(top.xml_doc, '', '\t', nil, false))
+
+ return nil, true
+ end
+
+ local function testStatus(element, parent, message, status, trace)
+ local testcase_node = xml.new('testcase', {
+ classname = element.trace.short_src .. ':' .. element.trace.currentline,
+ name = handler.getFullName(element),
+ time = elapsed(testStartTime)
+ })
+ top.xml_doc:add_direct_child(testcase_node)
+
+ if status ~= 'success' then
+ testcase_node:addtag(status)
+ if message then testcase_node:text(message) end
+ if trace and trace.traceback then testcase_node:text(trace.traceback) end
+ testcase_node:up()
+ end
+ end
+
+ handler.testStart = function(element, parent)
+ testStartTime = socket.gettime()
+
+ return nil, true
+ end
+
+ handler.testEnd = function(element, parent, status)
+ top.xml_doc.attr.tests = top.xml_doc.attr.tests + 1
+
+ if status == 'success' then
+ testStatus(element, parent, nil, 'success')
+ elseif status == 'pending' then
+ top.xml_doc.attr.skip = top.xml_doc.attr.skip + 1
+ local formatted = handler.pendings[#handler.pendings]
+ local trace = element.trace ~= formatted.trace and formatted.trace
+ testStatus(element, parent, formatted.message, 'skipped', trace)
+ end
+
+ return nil, true
+ end
+
+ handler.failureTest = function(element, parent, message, trace)
+ top.xml_doc.attr.failures = top.xml_doc.attr.failures + 1
+ testStatus(element, parent, message, 'failure', trace)
+ return nil, true
+ end
+
+ handler.errorTest = function(element, parent, message, trace)
+ top.xml_doc.attr.errors = top.xml_doc.attr.errors + 1
+ testStatus(element, parent, message, 'error', trace)
+ return nil, true
+ end
+
+ handler.error = function(element, parent, message, trace)
+ if element.descriptor ~= 'it' then
+ top.xml_doc.attr.errors = top.xml_doc.attr.errors + 1
+ top.xml_doc:addtag('error')
+ top.xml_doc:text(message)
+ if trace and trace.traceback then
+ top.xml_doc:text(trace.traceback)
+ end
+ top.xml_doc:up()
+ end
+
+ return nil, true
+ end
+
+ busted.subscribe({ 'exit' }, handler.exit)
+ busted.subscribe({ 'suite', 'start' }, handler.suiteStart)
+ busted.subscribe({ 'suite', 'end' }, handler.suiteEnd)
+ busted.subscribe({ 'test', 'start' }, handler.testStart, { predicate = handler.cancelOnPending })
+ busted.subscribe({ 'test', 'end' }, handler.testEnd, { predicate = handler.cancelOnPending })
+ busted.subscribe({ 'error', 'it' }, handler.errorTest)
+ busted.subscribe({ 'failure', 'it' }, handler.failureTest)
+ busted.subscribe({ 'error' }, handler.error)
+ busted.subscribe({ 'failure' }, handler.error)
+
+ return handler
+end