From 34c6e5beaf1f02b5291fcdc27e320cda72720ad4 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 16 Jul 2019 22:02:50 +0200 Subject: tests: move "busted" dir to "test" (#10518) * tests: move "busted" dir to "test" It is used for outputHandlers only, and clearly belongs to the tests. Use the full module name with the `-o` option to `busted` then for clarity. * luacheck * test/busted/outputHandlers/TAP.lua: use/extend upstream --- .luacheckrc | 1 + busted/outputHandlers/TAP.lua | 94 ----------- busted/outputHandlers/nvim.lua | 307 ------------------------------------ cmake/RunTests.cmake | 2 +- test/busted/outputHandlers/TAP.lua | 14 ++ test/busted/outputHandlers/nvim.lua | 302 +++++++++++++++++++++++++++++++++++ 6 files changed, 318 insertions(+), 402 deletions(-) delete mode 100644 busted/outputHandlers/TAP.lua delete mode 100644 busted/outputHandlers/nvim.lua create mode 100644 test/busted/outputHandlers/TAP.lua create mode 100644 test/busted/outputHandlers/nvim.lua diff --git a/.luacheckrc b/.luacheckrc index f350ff014a..b945835bba 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -11,6 +11,7 @@ cache = true ignore = { "631", -- max_line_length + "212/_.*", -- unused argument, for vars with "_" prefix } -- Global objects defined by the C code diff --git a/busted/outputHandlers/TAP.lua b/busted/outputHandlers/TAP.lua deleted file mode 100644 index 612e633576..0000000000 --- a/busted/outputHandlers/TAP.lua +++ /dev/null @@ -1,94 +0,0 @@ --- TODO(jkeyes): Use the upstream version when busted releases it. (But how to --- inject our call to global_helpers.read_nvim_log() ?) - -local pretty = require 'pl.pretty' -local global_helpers = require('test.helpers') - -return function(options) - local busted = require 'busted' - local handler = require 'busted.outputHandlers.base'() - - local success = 'ok %u - %s' - local failure = 'not ' .. success - local skip = 'ok %u - # SKIP %s' - local counter = 0 - - handler.suiteReset = function() - counter = 0 - return nil, true - end - - handler.suiteEnd = function() - io.write(global_helpers.read_nvim_log()) - print('1..' .. counter) - io.flush() - return nil, true - end - - local function showFailure(t) - local message = t.message - local trace = t.trace or {} - - if message == nil then - message = 'Nil error' - elseif type(message) ~= 'string' then - message = pretty.write(message) - end - - print(failure:format(counter, t.name)) - print('# ' .. t.element.trace.short_src .. ' @ ' .. t.element.trace.currentline) - if t.randomseed then print('# Random seed: ' .. t.randomseed) end - print('# Failure message: ' .. message:gsub('\n', '\n# ')) - if options.verbose and trace.traceback then - print('# ' .. trace.traceback:gsub('^\n', '', 1):gsub('\n', '\n# ')) - end - end - - handler.testStart = function(element, parent) - local trace = element.trace - if options.verbose and trace and trace.short_src then - local fileline = trace.short_src .. ' @ ' .. trace.currentline .. ': ' - local testName = fileline .. handler.getFullName(element) - print('# ' .. testName) - end - io.flush() - - return nil, true - end - - handler.testEnd = function(element, parent, status, trace) - counter = counter + 1 - if status == 'success' then - local t = handler.successes[#handler.successes] - print(success:format(counter, t.name)) - elseif status == 'pending' then - local t = handler.pendings[#handler.pendings] - print(skip:format(counter, (t.message or t.name))) - elseif status == 'failure' then - showFailure(handler.failures[#handler.failures]) - elseif status == 'error' then - showFailure(handler.errors[#handler.errors]) - end - io.flush() - - return nil, true - end - - handler.error = function(element, parent, message, debug) - if element.descriptor ~= 'it' then - counter = counter + 1 - showFailure(handler.errors[#handler.errors]) - end - io.flush() - - return nil, true - end - - busted.subscribe({ 'suite', 'reset' }, handler.suiteReset) - 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' }, handler.error) - - return handler -end diff --git a/busted/outputHandlers/nvim.lua b/busted/outputHandlers/nvim.lua deleted file mode 100644 index d137300a7e..0000000000 --- a/busted/outputHandlers/nvim.lua +++ /dev/null @@ -1,307 +0,0 @@ -local s = require 'say' -local pretty = require 'pl.pretty' -local term = require 'term' -local global_helpers = require('test.helpers') - -local colors - -local isWindows = package.config:sub(1,1) == '\\' - -if isWindows then - colors = setmetatable({}, {__index = function() return function(s) return s end end}) -else - colors = require 'term.colors' -end - -return function(options) - local busted = require 'busted' - local handler = require 'busted.outputHandlers.base'() - - local c = { - succ = function(s) return colors.bright(colors.green(s)) end, - skip = function(s) return colors.bright(colors.yellow(s)) end, - fail = function(s) return colors.bright(colors.magenta(s)) end, - errr = function(s) return colors.bright(colors.red(s)) end, - test = tostring, - file = colors.cyan, - time = colors.dim, - note = colors.yellow, - sect = function(s) return colors.green(colors.dim(s)) end, - nmbr = colors.bright, - } - - local repeatSuiteString = '\nRepeating all tests (run %d of %d) . . .\n\n' - local randomizeString = c.note('Note: Randomizing test order with a seed of %d.\n') - local globalSetup = c.sect('[----------]') .. ' Global test environment setup.\n' - local fileStartString = c.sect('[----------]') .. ' Running tests from ' .. c.file('%s') .. '\n' - local runString = c.sect('[ RUN ]') .. ' ' .. c.test('%s') .. ': ' - local successString = c.succ('OK') .. '\n' - local skippedString = c.skip('SKIP') .. '\n' - local failureString = c.fail('FAIL') .. '\n' - local errorString = c.errr('ERR') .. '\n' - local fileEndString = c.sect('[----------]') .. ' '.. c.nmbr('%d') .. ' %s from ' .. c.file('%s') .. ' ' .. c.time('(%.2f ms total)') .. '\n\n' - local globalTeardown = c.sect('[----------]') .. ' Global test environment teardown.\n' - local suiteEndString = c.sect('[==========]') .. ' ' .. c.nmbr('%d') .. ' %s from ' .. c.nmbr('%d') .. ' test %s ran. ' .. c.time('(%.2f ms total)') .. '\n' - local successStatus = c.succ('[ PASSED ]') .. ' ' .. c.nmbr('%d') .. ' %s.\n' - local timeString = c.time('%.2f ms') - - local summaryStrings = { - skipped = { - header = c.skip('[ SKIPPED ]') .. ' ' .. c.nmbr('%d') .. ' %s, listed below:\n', - test = c.skip('[ SKIPPED ]') .. ' %s\n', - footer = ' ' .. c.nmbr('%d') .. ' SKIPPED %s\n', - }, - - failure = { - header = c.fail('[ FAILED ]') .. ' ' .. c.nmbr('%d') .. ' %s, listed below:\n', - test = c.fail('[ FAILED ]') .. ' %s\n', - footer = ' ' .. c.nmbr('%d') .. ' FAILED %s\n', - }, - - error = { - header = c.errr('[ ERROR ]') .. ' ' .. c.nmbr('%d') .. ' %s, listed below:\n', - test = c.errr('[ ERROR ]') .. ' %s\n', - footer = ' ' .. c.nmbr('%d') .. ' %s\n', - }, - } - - c = nil - - local fileCount = 0 - local fileTestCount = 0 - local testCount = 0 - local successCount = 0 - local skippedCount = 0 - local failureCount = 0 - local errorCount = 0 - - local pendingDescription = function(pending) - local name = pending.name - local string = '' - - if type(pending.message) == 'string' then - string = string .. pending.message .. '\n' - elseif pending.message ~= nil then - string = string .. pretty.write(pending.message) .. '\n' - end - - return string - end - - local failureDescription = function(failure) - local string = failure.randomseed and ('Random seed: ' .. failure.randomseed .. '\n') or '' - if type(failure.message) == 'string' then - string = string .. failure.message - elseif failure.message == nil then - string = string .. 'Nil error' - else - string = string .. pretty.write(failure.message) - end - - string = string .. '\n' - - if options.verbose and failure.trace and failure.trace.traceback then - string = string .. failure.trace.traceback .. '\n' - end - - return string - end - - local getFileLine = function(element) - local fileline = '' - if element.trace or element.trace.short_src then - fileline = colors.cyan(element.trace.short_src) .. ' @ ' .. - colors.cyan(element.trace.currentline) .. ': ' - end - return fileline - end - - local getTestList = function(status, count, list, getDescription) - local string = '' - local header = summaryStrings[status].header - if count > 0 and header then - local tests = (count == 1 and 'test' or 'tests') - local errors = (count == 1 and 'error' or 'errors') - string = header:format(count, status == 'error' and errors or tests) - - local testString = summaryStrings[status].test - if testString then - for _, t in ipairs(list) do - local fullname = getFileLine(t.element) .. colors.bright(t.name) - string = string .. testString:format(fullname) - string = string .. getDescription(t) - end - end - end - return string - end - - local getSummary = function(status, count) - local string = '' - local footer = summaryStrings[status].footer - if count > 0 and footer then - local tests = (count == 1 and 'TEST' or 'TESTS') - local errors = (count == 1 and 'ERROR' or 'ERRORS') - string = footer:format(count, status == 'error' and errors or tests) - end - return string - end - - local getSummaryString = function() - local tests = (successCount == 1 and 'test' or 'tests') - local string = successStatus:format(successCount, tests) - - string = string .. getTestList('skipped', skippedCount, handler.pendings, pendingDescription) - string = string .. getTestList('failure', failureCount, handler.failures, failureDescription) - string = string .. getTestList('error', errorCount, handler.errors, failureDescription) - - string = string .. ((skippedCount + failureCount + errorCount) > 0 and '\n' or '') - string = string .. getSummary('skipped', skippedCount) - string = string .. getSummary('failure', failureCount) - string = string .. getSummary('error', errorCount) - - return string - end - - handler.suiteReset = function() - fileCount = 0 - fileTestCount = 0 - testCount = 0 - successCount = 0 - skippedCount = 0 - failureCount = 0 - errorCount = 0 - - return nil, true - end - - handler.suiteStart = function(suite, count, total, randomseed) - if total > 1 then - io.write(repeatSuiteString:format(count, total)) - end - if randomseed then - io.write(randomizeString:format(randomseed)) - end - io.write(globalSetup) - io.flush() - - return nil, true - end - - local function getElapsedTime(tbl) - if tbl.duration then - return tbl.duration * 1000 - else - return tonumber('nan') - end - end - - handler.suiteEnd = function(suite, count, total) - local elapsedTime_ms = getElapsedTime(suite) - local tests = (testCount == 1 and 'test' or 'tests') - local files = (fileCount == 1 and 'file' or 'files') - io.write(globalTeardown) - io.write(global_helpers.read_nvim_log()) - io.write(suiteEndString:format(testCount, tests, fileCount, files, elapsedTime_ms)) - io.write(getSummaryString()) - io.flush() - - return nil, true - end - - handler.fileStart = function(file) - fileTestCount = 0 - io.write(fileStartString:format(file.name)) - io.flush() - return nil, true - end - - handler.fileEnd = function(file) - local elapsedTime_ms = getElapsedTime(file) - local tests = (fileTestCount == 1 and 'test' or 'tests') - fileCount = fileCount + 1 - io.write(fileEndString:format(fileTestCount, tests, file.name, elapsedTime_ms)) - io.flush() - return nil, true - end - - handler.testStart = function(element, parent) - io.write(runString:format(handler.getFullName(element))) - io.flush() - - return nil, true - end - - handler.testEnd = function(element, parent, status, debug) - local elapsedTime_ms = getElapsedTime(element) - local string - - fileTestCount = fileTestCount + 1 - testCount = testCount + 1 - if status == 'success' then - successCount = successCount + 1 - string = successString - elseif status == 'pending' then - skippedCount = skippedCount + 1 - string = skippedString - elseif status == 'failure' then - failureCount = failureCount + 1 - string = nil - elseif status == 'error' then - errorCount = errorCount + 1 - string = nil - end - - if string ~= nil then - if elapsedTime_ms == elapsedTime_ms then - string = timeString:format(elapsedTime_ms) .. ' ' .. string - end - io.write(string) - io.flush() - end - - return nil, true - end - - handler.testFailure = function(element, parent, message, debug) - io.write(failureString) - io.flush() - - io.write(failureDescription(handler.failures[#handler.failures])) - io.flush() - return nil, true - end - - handler.testError = function(element, parent, message, debug) - io.write(errorString) - io.flush() - - io.write(failureDescription(handler.errors[#handler.errors])) - io.flush() - return nil, true - end - - handler.error = function(element, parent, message, debug) - if element.descriptor ~= 'it' then - io.write(failureDescription(handler.errors[#handler.errors])) - io.flush() - errorCount = errorCount + 1 - end - - return nil, true - end - - busted.subscribe({ 'suite', 'reset' }, handler.suiteReset) - busted.subscribe({ 'suite', 'start' }, handler.suiteStart) - busted.subscribe({ 'suite', 'end' }, handler.suiteEnd) - busted.subscribe({ 'file', 'start' }, handler.fileStart) - busted.subscribe({ 'file', 'end' }, handler.fileEnd) - busted.subscribe({ 'test', 'start' }, handler.testStart, { predicate = handler.cancelOnPending }) - busted.subscribe({ 'test', 'end' }, handler.testEnd, { predicate = handler.cancelOnPending }) - busted.subscribe({ 'failure', 'it' }, handler.testFailure) - busted.subscribe({ 'error', 'it' }, handler.testError) - busted.subscribe({ 'failure' }, handler.error) - busted.subscribe({ 'error' }, handler.error) - - return handler -end diff --git a/cmake/RunTests.cmake b/cmake/RunTests.cmake index f5b3f01778..5406a07fc8 100644 --- a/cmake/RunTests.cmake +++ b/cmake/RunTests.cmake @@ -43,7 +43,7 @@ execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory $ENV{TMPDIR}) set(ENV{SYSTEM_NAME} ${CMAKE_HOST_SYSTEM_NAME}) # used by test/helpers.lua. execute_process( - COMMAND ${BUSTED_PRG} -v -o ${BUSTED_OUTPUT_TYPE} + COMMAND ${BUSTED_PRG} -v -o test.busted.outputHandlers.${BUSTED_OUTPUT_TYPE} --lazy --helper=${TEST_DIR}/${TEST_TYPE}/preload.lua --lpath=${BUILD_DIR}/?.lua --lpath=${WORKING_DIR}/runtime/lua/?.lua diff --git a/test/busted/outputHandlers/TAP.lua b/test/busted/outputHandlers/TAP.lua new file mode 100644 index 0000000000..3dd171dc1b --- /dev/null +++ b/test/busted/outputHandlers/TAP.lua @@ -0,0 +1,14 @@ +-- Extends the upstream TAP handler, to display the log with suiteEnd. + +local global_helpers = require('test.helpers') + +return function(options) + local handler = require 'busted.outputHandlers.TAP'(options) + + handler.suiteEnd = function() + io.write(global_helpers.read_nvim_log()) + return handler.suiteEnd() + end + + return handler +end diff --git a/test/busted/outputHandlers/nvim.lua b/test/busted/outputHandlers/nvim.lua new file mode 100644 index 0000000000..1b500fc999 --- /dev/null +++ b/test/busted/outputHandlers/nvim.lua @@ -0,0 +1,302 @@ +local pretty = require 'pl.pretty' +local global_helpers = require('test.helpers') + +local colors + +local isWindows = package.config:sub(1,1) == '\\' + +if isWindows then + colors = setmetatable({}, {__index = function() return function(s) return s end end}) +else + colors = require 'term.colors' +end + +return function(options) + local busted = require 'busted' + local handler = require 'busted.outputHandlers.base'() + + local c = { + succ = function(s) return colors.bright(colors.green(s)) end, + skip = function(s) return colors.bright(colors.yellow(s)) end, + fail = function(s) return colors.bright(colors.magenta(s)) end, + errr = function(s) return colors.bright(colors.red(s)) end, + test = tostring, + file = colors.cyan, + time = colors.dim, + note = colors.yellow, + sect = function(s) return colors.green(colors.dim(s)) end, + nmbr = colors.bright, + } + + local repeatSuiteString = '\nRepeating all tests (run %d of %d) . . .\n\n' + local randomizeString = c.note('Note: Randomizing test order with a seed of %d.\n') + local globalSetup = c.sect('[----------]') .. ' Global test environment setup.\n' + local fileStartString = c.sect('[----------]') .. ' Running tests from ' .. c.file('%s') .. '\n' + local runString = c.sect('[ RUN ]') .. ' ' .. c.test('%s') .. ': ' + local successString = c.succ('OK') .. '\n' + local skippedString = c.skip('SKIP') .. '\n' + local failureString = c.fail('FAIL') .. '\n' + local errorString = c.errr('ERR') .. '\n' + local fileEndString = c.sect('[----------]') .. ' '.. c.nmbr('%d') .. ' %s from ' .. c.file('%s') .. ' ' .. c.time('(%.2f ms total)') .. '\n\n' + local globalTeardown = c.sect('[----------]') .. ' Global test environment teardown.\n' + local suiteEndString = c.sect('[==========]') .. ' ' .. c.nmbr('%d') .. ' %s from ' .. c.nmbr('%d') .. ' test %s ran. ' .. c.time('(%.2f ms total)') .. '\n' + local successStatus = c.succ('[ PASSED ]') .. ' ' .. c.nmbr('%d') .. ' %s.\n' + local timeString = c.time('%.2f ms') + + local summaryStrings = { + skipped = { + header = c.skip('[ SKIPPED ]') .. ' ' .. c.nmbr('%d') .. ' %s, listed below:\n', + test = c.skip('[ SKIPPED ]') .. ' %s\n', + footer = ' ' .. c.nmbr('%d') .. ' SKIPPED %s\n', + }, + + failure = { + header = c.fail('[ FAILED ]') .. ' ' .. c.nmbr('%d') .. ' %s, listed below:\n', + test = c.fail('[ FAILED ]') .. ' %s\n', + footer = ' ' .. c.nmbr('%d') .. ' FAILED %s\n', + }, + + error = { + header = c.errr('[ ERROR ]') .. ' ' .. c.nmbr('%d') .. ' %s, listed below:\n', + test = c.errr('[ ERROR ]') .. ' %s\n', + footer = ' ' .. c.nmbr('%d') .. ' %s\n', + }, + } + + local fileCount = 0 + local fileTestCount = 0 + local testCount = 0 + local successCount = 0 + local skippedCount = 0 + local failureCount = 0 + local errorCount = 0 + + local pendingDescription = function(pending) + local string = '' + + if type(pending.message) == 'string' then + string = string .. pending.message .. '\n' + elseif pending.message ~= nil then + string = string .. pretty.write(pending.message) .. '\n' + end + + return string + end + + local failureDescription = function(failure) + local string = failure.randomseed and ('Random seed: ' .. failure.randomseed .. '\n') or '' + if type(failure.message) == 'string' then + string = string .. failure.message + elseif failure.message == nil then + string = string .. 'Nil error' + else + string = string .. pretty.write(failure.message) + end + + string = string .. '\n' + + if options.verbose and failure.trace and failure.trace.traceback then + string = string .. failure.trace.traceback .. '\n' + end + + return string + end + + local getFileLine = function(element) + local fileline = '' + if element.trace or element.trace.short_src then + fileline = colors.cyan(element.trace.short_src) .. ' @ ' .. + colors.cyan(element.trace.currentline) .. ': ' + end + return fileline + end + + local getTestList = function(status, count, list, getDescription) + local string = '' + local header = summaryStrings[status].header + if count > 0 and header then + local tests = (count == 1 and 'test' or 'tests') + local errors = (count == 1 and 'error' or 'errors') + string = header:format(count, status == 'error' and errors or tests) + + local testString = summaryStrings[status].test + if testString then + for _, t in ipairs(list) do + local fullname = getFileLine(t.element) .. colors.bright(t.name) + string = string .. testString:format(fullname) + string = string .. getDescription(t) + end + end + end + return string + end + + local getSummary = function(status, count) + local string = '' + local footer = summaryStrings[status].footer + if count > 0 and footer then + local tests = (count == 1 and 'TEST' or 'TESTS') + local errors = (count == 1 and 'ERROR' or 'ERRORS') + string = footer:format(count, status == 'error' and errors or tests) + end + return string + end + + local getSummaryString = function() + local tests = (successCount == 1 and 'test' or 'tests') + local string = successStatus:format(successCount, tests) + + string = string .. getTestList('skipped', skippedCount, handler.pendings, pendingDescription) + string = string .. getTestList('failure', failureCount, handler.failures, failureDescription) + string = string .. getTestList('error', errorCount, handler.errors, failureDescription) + + string = string .. ((skippedCount + failureCount + errorCount) > 0 and '\n' or '') + string = string .. getSummary('skipped', skippedCount) + string = string .. getSummary('failure', failureCount) + string = string .. getSummary('error', errorCount) + + return string + end + + handler.suiteReset = function() + fileCount = 0 + fileTestCount = 0 + testCount = 0 + successCount = 0 + skippedCount = 0 + failureCount = 0 + errorCount = 0 + + return nil, true + end + + handler.suiteStart = function(_suite, count, total, randomseed) + if total > 1 then + io.write(repeatSuiteString:format(count, total)) + end + if randomseed then + io.write(randomizeString:format(randomseed)) + end + io.write(globalSetup) + io.flush() + + return nil, true + end + + local function getElapsedTime(tbl) + if tbl.duration then + return tbl.duration * 1000 + else + return tonumber('nan') + end + end + + handler.suiteEnd = function(suite, _count, _total) + local elapsedTime_ms = getElapsedTime(suite) + local tests = (testCount == 1 and 'test' or 'tests') + local files = (fileCount == 1 and 'file' or 'files') + io.write(globalTeardown) + io.write(global_helpers.read_nvim_log()) + io.write(suiteEndString:format(testCount, tests, fileCount, files, elapsedTime_ms)) + io.write(getSummaryString()) + io.flush() + + return nil, true + end + + handler.fileStart = function(file) + fileTestCount = 0 + io.write(fileStartString:format(file.name)) + io.flush() + return nil, true + end + + handler.fileEnd = function(file) + local elapsedTime_ms = getElapsedTime(file) + local tests = (fileTestCount == 1 and 'test' or 'tests') + fileCount = fileCount + 1 + io.write(fileEndString:format(fileTestCount, tests, file.name, elapsedTime_ms)) + io.flush() + return nil, true + end + + handler.testStart = function(element, _parent) + io.write(runString:format(handler.getFullName(element))) + io.flush() + + return nil, true + end + + handler.testEnd = function(element, _parent, status, _debug) + local elapsedTime_ms = getElapsedTime(element) + local string + + fileTestCount = fileTestCount + 1 + testCount = testCount + 1 + if status == 'success' then + successCount = successCount + 1 + string = successString + elseif status == 'pending' then + skippedCount = skippedCount + 1 + string = skippedString + elseif status == 'failure' then + failureCount = failureCount + 1 + string = nil + elseif status == 'error' then + errorCount = errorCount + 1 + string = nil + end + + if string ~= nil then + if elapsedTime_ms == elapsedTime_ms then + string = timeString:format(elapsedTime_ms) .. ' ' .. string + end + io.write(string) + io.flush() + end + + return nil, true + end + + handler.testFailure = function(_element, _parent, _message, _debug) + io.write(failureString) + io.flush() + + io.write(failureDescription(handler.failures[#handler.failures])) + io.flush() + return nil, true + end + + handler.testError = function(_element, _parent, _message, _debug) + io.write(errorString) + io.flush() + + io.write(failureDescription(handler.errors[#handler.errors])) + io.flush() + return nil, true + end + + handler.error = function(element, _parent, _message, _debug) + if element.descriptor ~= 'it' then + io.write(failureDescription(handler.errors[#handler.errors])) + io.flush() + errorCount = errorCount + 1 + end + + return nil, true + end + + busted.subscribe({ 'suite', 'reset' }, handler.suiteReset) + busted.subscribe({ 'suite', 'start' }, handler.suiteStart) + busted.subscribe({ 'suite', 'end' }, handler.suiteEnd) + busted.subscribe({ 'file', 'start' }, handler.fileStart) + busted.subscribe({ 'file', 'end' }, handler.fileEnd) + busted.subscribe({ 'test', 'start' }, handler.testStart, { predicate = handler.cancelOnPending }) + busted.subscribe({ 'test', 'end' }, handler.testEnd, { predicate = handler.cancelOnPending }) + busted.subscribe({ 'failure', 'it' }, handler.testFailure) + busted.subscribe({ 'error', 'it' }, handler.testError) + busted.subscribe({ 'failure' }, handler.error) + busted.subscribe({ 'error' }, handler.error) + + return handler +end -- cgit