mirror of
https://github.com/neovim/neovim.git
synced 2024-12-23 20:55:18 -07:00
tests: Use our own output handler on travis
Reasoning: 1. gtest is better then something like utfTerminal, yet it is way too verbose. 2. gtest cannot be configured to show colors always. 3. Actually I am going to add a CMake target which will allow running tests (especially, functional tests) in parallel, but this is not going to work well with any of the default output handlers. Build in this case must be more or less silent, yet debuggable. New handler does not support this in this commit though.
This commit is contained in:
parent
d7fb7de70a
commit
d909724d70
@ -25,7 +25,7 @@ env:
|
||||
- CMAKE_FLAGS="-DTRAVIS_CI_BUILD=ON
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX
|
||||
-DBUSTED_OUTPUT_TYPE=gtest
|
||||
-DBUSTED_OUTPUT_TYPE=neovim
|
||||
-DDEPS_PREFIX=$DEPS_BUILD_DIR/usr
|
||||
-DMIN_LOG_LEVEL=2"
|
||||
- DEPS_CMAKE_FLAGS="-DDEPS_DOWNLOAD_DIR:PATH=$DEPS_DOWNLOAD_DIR"
|
||||
|
301
busted/outputHandlers/neovim.lua
Normal file
301
busted/outputHandlers/neovim.lua
Normal file
@ -0,0 +1,301 @@
|
||||
local s = require 'say'
|
||||
local pretty = require 'pl.pretty'
|
||||
local term = require 'term'
|
||||
|
||||
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.time('%.2f ms') .. ' ' .. c.succ('OK') .. '\n'
|
||||
local skippedString = c.time('%.2f ms') .. ' ' .. 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 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)
|
||||
if options.deferPrint then
|
||||
string = string .. getDescription(t)
|
||||
end
|
||||
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
|
||||
|
||||
handler.suiteEnd = function(suite, count, total)
|
||||
local elapsedTime_ms = suite.duration * 1000
|
||||
local tests = (testCount == 1 and 'test' or 'tests')
|
||||
local files = (fileCount == 1 and 'file' or 'files')
|
||||
io.write(globalTeardown)
|
||||
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 = file.duration * 1000
|
||||
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 = element.duration * 1000
|
||||
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
|
||||
io.write(string:format(elapsedTime_ms))
|
||||
io.flush()
|
||||
end
|
||||
|
||||
return nil, true
|
||||
end
|
||||
|
||||
handler.testFailure = function(element, parent, message, debug)
|
||||
io.write(failureString)
|
||||
io.flush()
|
||||
|
||||
if not options.deferPrint then
|
||||
io.write(failureDescription(handler.failures[#handler.failures]))
|
||||
io.flush()
|
||||
end
|
||||
return nil, true
|
||||
end
|
||||
|
||||
handler.testError = function(element, parent, message, debug)
|
||||
io.write(errorString)
|
||||
io.flush()
|
||||
|
||||
if not options.deferPrint then
|
||||
io.write(failureDescription(handler.errors[#handler.errors]))
|
||||
io.flush()
|
||||
end
|
||||
return nil, true
|
||||
end
|
||||
|
||||
handler.error = function(element, parent, message, debug)
|
||||
if element.descriptor ~= 'it' then
|
||||
if not options.deferPrint then
|
||||
io.write(failureDescription(handler.errors[#handler.errors]))
|
||||
io.flush()
|
||||
end
|
||||
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
|
Loading…
Reference in New Issue
Block a user