Browse Source

Rework lua tests structure, require external busted.

tags/0.9.0
Vsevolod Stakhov 9 years ago
parent
commit
0c5dfb9541
40 changed files with 38 additions and 2858 deletions
  1. 0
    22
      test/LICENSE.busted
  2. 0
    1
      test/lua/busted.lua
  3. 0
    60
      test/lua/busted/compatibility.lua
  4. 0
    91
      test/lua/busted/context.lua
  5. 0
    237
      test/lua/busted/core.lua
  6. 0
    115
      test/lua/busted/done.lua
  7. 0
    45
      test/lua/busted/environment.lua
  8. 0
    227
      test/lua/busted/init.lua
  9. 0
    40
      test/lua/busted/languages/ar.lua
  10. 0
    40
      test/lua/busted/languages/de.lua
  11. 0
    47
      test/lua/busted/languages/en.lua
  12. 0
    43
      test/lua/busted/languages/fr.lua
  13. 0
    41
      test/lua/busted/languages/ja.lua
  14. 0
    41
      test/lua/busted/languages/nl.lua
  15. 0
    36
      test/lua/busted/languages/ru.lua
  16. 0
    41
      test/lua/busted/languages/th.lua
  17. 0
    36
      test/lua/busted/languages/ua.lua
  18. 0
    41
      test/lua/busted/languages/zh.lua
  19. 0
    34
      test/lua/busted/modules/configuration_loader.lua
  20. 0
    24
      test/lua/busted/modules/files/lua.lua
  21. 0
    107
      test/lua/busted/modules/files/moonscript.lua
  22. 0
    24
      test/lua/busted/modules/files/terra.lua
  23. 0
    23
      test/lua/busted/modules/helper_loader.lua
  24. 0
    22
      test/lua/busted/modules/luacov.lua
  25. 0
    31
      test/lua/busted/modules/output_handler_loader.lua
  26. 0
    84
      test/lua/busted/modules/test_file_loader.lua
  27. 0
    51
      test/lua/busted/outputHandlers/TAP.lua
  28. 0
    177
      test/lua/busted/outputHandlers/base.lua
  29. 0
    21
      test/lua/busted/outputHandlers/json.lua
  30. 0
    136
      test/lua/busted/outputHandlers/junit.lua
  31. 0
    175
      test/lua/busted/outputHandlers/plainTerminal.lua
  32. 0
    36
      test/lua/busted/outputHandlers/sound.lua
  33. 0
    176
      test/lua/busted/outputHandlers/utfTerminal.lua
  34. 0
    399
      test/lua/busted/runner.lua
  35. 0
    43
      test/lua/busted/status.lua
  36. 0
    51
      test/lua/busted/utils.lua
  37. 0
    2
      test/lua/rsa.lua
  38. 32
    36
      test/rspamd_lua_test.c
  39. 5
    1
      test/rspamd_test_suite.c
  40. 1
    1
      test/tests.h

+ 0
- 22
test/LICENSE.busted View File

@@ -1,22 +0,0 @@
MIT License Terms
=================

Copyright (c) 2012 Olivine Labs, LLC.

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

+ 0
- 1
test/lua/busted.lua View File

@@ -1,3 +0,0 @@
return require 'busted.init'

+ 0
- 60
test/lua/busted/compatibility.lua View File

@@ -1,60 +0,0 @@
return {
getfenv = getfenv or function(f)
f = (type(f) == 'function' and f or debug.getinfo(f + 1, 'f').func)
local name, value
local up = 0

repeat
up = up + 1
name, value = debug.getupvalue(f, up)
until name == '_ENV' or name == nil

return value
end,

setfenv = setfenv or function(f, t)
f = (type(f) == 'function' and f or debug.getinfo(f + 1, 'f').func)
local name
local up = 0

repeat
up = up + 1
name = debug.getupvalue(f, up)
until name == '_ENV' or name == nil

if name then
debug.upvaluejoin(f, up, function() return name end, 1)
debug.setupvalue(f, up, t)
end

if f ~= 0 then return f end
end,

unpack = table.unpack or unpack,

osexit = function(code, close)
if close and _VERSION == 'Lua 5.1' then
-- From Lua 5.1 manual:
-- > The userdata itself is freed only in the next
-- > garbage-collection cycle.
-- Call collectgarbage() while collectgarbage('count')
-- changes + 3 times, at least 3 times,
-- at max 100 times (to prevent infinite loop).
local times_const = 0
for i = 1, 100 do
local count_before = collectgarbage("count")
collectgarbage()
local count_after = collectgarbage("count")
if count_after == count_before then
times_const = times_const + 1
if times_const > 3 then
break
end
else
times_const = 0
end
end
end
os.exit(code, close)
end,
}

+ 0
- 91
test/lua/busted/context.lua View File

@@ -1,91 +0,0 @@
local tablex = require 'pl.tablex'

local function save()
local g = {}
for k,_ in next, _G, nil do
g[k] = rawget(_G, k)
end
return {
gmt = getmetatable(_G),
g = g,
loaded = tablex.copy(package.loaded)
}
end

local function restore(state)
setmetatable(_G, state.gmt)
for k,_ in next, _G, nil do
rawset(_G, k, state.g[k])
end
for k,_ in pairs(package.loaded) do
package.loaded[k] = state.loaded[k]
end
end

return function()
local context = {}

local data = {}
local parents = {}
local children = {}
local stack = {}

function context.ref()
local ref = {}
local ctx = data

function ref.get(key)
if not key then return ctx end
return ctx[key]
end

function ref.set(key, value)
ctx[key] = value
end

function ref.clear()
data = {}
parents = {}
children = {}
stack = {}
ctx = data
end

function ref.attach(child)
if not children[ctx] then children[ctx] = {} end
parents[child] = ctx
table.insert(children[ctx], child)
end

function ref.children(parent)
return children[parent] or {}
end

function ref.parent(child)
return parents[child]
end

function ref.push(current)
if not parents[current] then error('Detached child. Cannot push.') end
if ctx ~= current and current.descriptor == 'file' then
current.state = save()
end
table.insert(stack, ctx)
ctx = current
end

function ref.pop()
local current = ctx
ctx = table.remove(stack)
if ctx ~= current and current.state then
restore(current.state)
current.state = nil
end
if not ctx then error('Context stack empty. Cannot pop.') end
end

return ref
end

return context
end

+ 0
- 237
test/lua/busted/core.lua View File

@@ -1,237 +0,0 @@
local getfenv = require 'busted.compatibility'.getfenv
local setfenv = require 'busted.compatibility'.setfenv
local unpack = require 'busted.compatibility'.unpack
local path = require 'pl.path'
local pretty = require 'pl.pretty'
local throw = error

local failureMt = {
__index = {},
__tostring = function(e) return tostring(e.message) end,
__type = 'failure'
}

local failureMtNoString = {
__index = {},
__type = 'failure'
}

local pendingMt = {
__index = {},
__tostring = function(p) return p.message end,
__type = 'pending'
}

local function metatype(obj)
local otype = type(obj)
return otype == 'table' and (getmetatable(obj) or {}).__type or otype
end

local function hasToString(obj)
return type(obj) == 'string' or (getmetatable(obj) or {}).__tostring
end

return function()
local mediator = require 'mediator'()

local busted = {}
busted.version = '2.0.rc6-0'

local root = require 'busted.context'()
busted.context = root.ref()

local environment = require 'busted.environment'(busted.context)
busted.environment = {
set = environment.set,

wrap = function(callable)
if (type(callable) == 'function' or getmetatable(callable).__call) then
-- prioritize __call if it exists, like in files
environment.wrap((getmetatable(callable) or {}).__call or callable)
end
end
}

busted.executors = {}
local executors = {}

busted.status = require 'busted.status'

function busted.getTrace(element, level, msg)
level = level or 3

local thisdir = path.dirname(debug.getinfo(1, 'Sl').source)
local info = debug.getinfo(level, 'Sl')
while info.what == 'C' or info.short_src:match('luassert[/\\].*%.lua$') or
(info.source:sub(1,1) == '@' and thisdir == path.dirname(info.source)) do
level = level + 1
info = debug.getinfo(level, 'Sl')
end

info.traceback = debug.traceback('', level)
info.message = msg

local file = busted.getFile(element)
return file.getTrace(file.name, info)
end

function busted.rewriteMessage(element, message, trace)
local file = busted.getFile(element)
local msg = hasToString(message) and tostring(message)
msg = msg or (message ~= nil and pretty.write(message) or 'Nil error')
msg = (file.rewriteMessage and file.rewriteMessage(file.name, msg) or msg)

local hasFileLine = msg:match('^[^\n]-:%d+: .*')
if not hasFileLine then
local trace = trace or busted.getTrace(element, 3, message)
local fileline = trace.short_src .. ':' .. trace.currentline .. ': '
msg = fileline .. msg
end

return msg
end

function busted.publish(...)
return mediator:publish(...)
end

function busted.subscribe(...)
return mediator:subscribe(...)
end

function busted.getFile(element)
local parent = busted.context.parent(element)

while parent do
if parent.file then
local file = parent.file[1]
return {
name = file.name,
getTrace = file.run.getTrace,
rewriteMessage = file.run.rewriteMessage
}
end

if parent.descriptor == 'file' then
return {
name = parent.name,
getTrace = parent.run.getTrace,
rewriteMessage = parent.run.rewriteMessage
}
end

parent = busted.context.parent(parent)
end

return parent
end

function busted.fail(msg, level)
local rawlevel = (type(level) ~= 'number' or level <= 0) and level
local level = level or 1
local _, emsg = pcall(throw, msg, rawlevel or level+2)
local e = { message = emsg }
setmetatable(e, hasToString(msg) and failureMt or failureMtNoString)
throw(e, rawlevel or level+1)
end

function busted.pending(msg)
local p = { message = msg }
setmetatable(p, pendingMt)
throw(p)
end

function busted.replaceErrorWithFail(callable)
local env = {}
local f = (getmetatable(callable) or {}).__call or callable
setmetatable(env, { __index = getfenv(f) })
env.error = busted.fail
setfenv(f, env)
end

function busted.safe(descriptor, run, element)
busted.context.push(element)
local trace, message
local status = 'success'

local ret = { xpcall(run, function(msg)
local errType = metatype(msg)
status = ((errType == 'pending' or errType == 'failure') and errType or 'error')
trace = busted.getTrace(element, 3, msg)
message = busted.rewriteMessage(element, msg, trace)
end) }

if not ret[1] then
busted.publish({ status, descriptor }, element, busted.context.parent(element), message, trace)
end
ret[1] = busted.status(status)

busted.context.pop()
return unpack(ret)
end

function busted.register(descriptor, executor)
executors[descriptor] = executor

local publisher = function(name, fn)
if not fn and type(name) == 'function' then
fn = name
name = nil
end

local trace

local ctx = busted.context.get()
if busted.context.parent(ctx) then
trace = busted.getTrace(ctx, 3, name)
end

local publish = function(f)
busted.publish({ 'register', descriptor }, name, f, trace)
end

if fn then publish(fn) else return publish end
end

busted.executors[descriptor] = publisher
if descriptor ~= 'file' then
environment.set(descriptor, publisher)
end

busted.subscribe({ 'register', descriptor }, function(name, fn, trace)
local ctx = busted.context.get()
local plugin = {
descriptor = descriptor,
name = name,
run = fn,
trace = trace
}

busted.context.attach(plugin)

if not ctx[descriptor] then
ctx[descriptor] = { plugin }
else
ctx[descriptor][#ctx[descriptor]+1] = plugin
end
end)
end

function busted.alias(alias, descriptor)
local publisher = busted.executors[descriptor]
busted.executors[alias] = publisher
environment.set(alias, publisher)
end

function busted.execute(current)
if not current then current = busted.context.get() end
for _, v in pairs(busted.context.children(current)) do
local executor = executors[v.descriptor]
if executor and not busted.skipAll then
busted.safe(v.descriptor, function() executor(v) end, v)
end
end
end

return busted
end

+ 0
- 115
test/lua/busted/done.lua View File

@@ -1,121 +0,0 @@
local M = {}

M.wait = function(self, ...)
local tlist = { ... }

for _, token in ipairs(tlist) do
if type(token) ~= 'string' then
error('Wait tokens must be strings. Got '..type(token), 2)
end
table.insert(self.tokens, token)
end
end

M.wait_unordered = function(self, ...)
self.ordered = false
self:wait(...)
end

M.wait_ordered = function(self, ...)
self.ordered = true
self:wait(...)
end

M.tokenlist = function(self)
local list

if #self.tokens_done == 0 then
list = 'No tokens received.'
else
list = 'Tokens received ('..tostring(#self.tokens_done)..')'
local s = ': '

for _,t in ipairs(self.tokens_done) do
list = list .. s .. '\''..t..'\''
s = ', '
end

list = list .. '.'
end

if #self.tokens == 0 then
list = list .. ' No more tokens expected.'
else
list = list .. ' Tokens not received ('..tostring(#self.tokens)..')'
local s = ': '

for _, t in ipairs(self.tokens) do
list = list .. s .. '\''..t..'\''
s = ', '
end

list = list .. '.'
end

return list
end

M.done = function(self, ...) self:_done(...) end -- extra wrapper for same error level constant as __call method
M._done = function(self, token)
if token then
if type(token) ~= 'string' then
error('Wait tokens must be strings. Got '..type(token), 3)
end

if self.ordered then
if self.tokens[1] == token then
table.remove(self.tokens, 1)
table.insert(self.tokens_done, token)
else
if self.tokens[1] then
error(('Bad token, expected \'%s\' got \'%s\'. %s'):format(self.tokens[1], token, self:tokenlist()), 3)
else
error(('Bad token (no more tokens expected) got \'%s\'. %s'):format(token, self:tokenlist()), 3)
end
end
else
-- unordered
for i, t in ipairs(self.tokens) do
if t == token then
table.remove(self.tokens, i)
table.insert(self.tokens_done, token)
token = nil
break
end
end

if token then
error(('Unknown token \'%s\'. %s'):format(token, self:tokenlist()), 3)
end
end
end
if not next(self.tokens) then
-- no more tokens, so we're really done...
self.done_cb()
end
end


M.new = function(done_callback)
local obj = {
tokens = {},
tokens_done = {},
done_cb = done_callback,
ordered = true, -- default for sign off of tokens
}

return setmetatable( obj, {
__call = function(self, ...)
self:_done(...)
end,
__index = M,
})
end

return M

+ 0
- 45
test/lua/busted/environment.lua View File

@@ -1,45 +0,0 @@
local setfenv = require 'busted.compatibility'.setfenv

return function(context)

local environment = {}

local function getEnv(self, key)
if not self then return nil end
return
self.env and self.env[key] or
getEnv(context.parent(self), key) or
_G[key]
end

local function setEnv(self, key, value)
if not self.env then self.env = {} end
self.env[key] = value
end

local function __index(self, key)
return getEnv(context.get(), key)
end

local function __newindex(self, key, value)
setEnv(context.get(), key, value)
end

local env = setmetatable({}, { __index=__index, __newindex=__newindex })

function environment.wrap(fn)
return setfenv(fn, env)
end

function environment.set(key, value)
local env = context.get('env')

if not env then
env = {}
context.set('env', env)
end

env[key] = value
end
return environment
end

+ 0
- 227
test/lua/busted/init.lua View File

@@ -1,227 +0,0 @@
local unpack = require 'busted.compatibility'.unpack
local shuffle = require 'busted.utils'.shuffle

local function sort(elements)
table.sort(elements, function(t1, t2)
if t1.name and t2.name then
return t1.name < t2.name
end
return t2.name ~= nil
end)
return elements
end

local function remove(descriptors, element)
for _, descriptor in ipairs(descriptors) do
element.env[descriptor] = function(...)
error("'" .. descriptor .. "' not supported inside current context block", 2)
end
end
end

local function init(busted)
local function exec(descriptor, element)
if not element.env then element.env = {} end

remove({ 'randomize' }, element)
remove({ 'pending' }, element)
remove({ 'describe', 'context', 'it', 'spec', 'test' }, element)
remove({ 'setup', 'teardown', 'before_each', 'after_each' }, element)

local parent = busted.context.parent(element)
setmetatable(element.env, {
__newindex = function(self, key, value)
if not parent.env then parent.env = {} end
parent.env[key] = value
end
})

local ret = { busted.safe(descriptor, element.run, element) }
return unpack(ret)
end

local function execAll(descriptor, current, propagate)
local parent = busted.context.parent(current)

if propagate and parent then
local success, ancestor = execAll(descriptor, parent, propagate)
if not success then
return success, ancestor
end
end

local list = current[descriptor] or {}

local success = true
for _, v in pairs(list) do
if not exec(descriptor, v):success() then
success = nil
end
end
return success, current
end

local function dexecAll(descriptor, current, propagate)
local parent = busted.context.parent(current)
local list = current[descriptor] or {}

local success = true
for _, v in pairs(list) do
if not exec(descriptor, v):success() then
success = nil
end
end

if propagate and parent then
if not dexecAll(descriptor, parent, propagate) then
success = nil
end
end
return success
end

local file = function(file)
busted.publish({ 'file', 'start' }, file.name)

busted.environment.wrap(file.run)
if not file.env then file.env = {} end

local randomize = busted.randomize
file.env.randomize = function() randomize = true end

if busted.safe('file', file.run, file):success() then
if randomize then
file.randomseed = busted.randomseed
shuffle(busted.context.children(file), busted.randomseed)
elseif busted.sort then
sort(busted.context.children(file))
end
if execAll('setup', file) then
busted.execute(file)
end
dexecAll('teardown', file)
end

busted.publish({ 'file', 'end' }, file.name)
end

local describe = function(describe)
local parent = busted.context.parent(describe)

busted.publish({ 'describe', 'start' }, describe, parent)

if not describe.env then describe.env = {} end

local randomize = busted.randomize
describe.env.randomize = function() randomize = true end

if busted.safe('describe', describe.run, describe):success() then
if randomize then
describe.randomseed = busted.randomseed
shuffle(busted.context.children(describe), busted.randomseed)
elseif busted.sort then
sort(busted.context.children(describe))
end
if execAll('setup', describe) then
busted.execute(describe)
end
dexecAll('teardown', describe)
end

busted.publish({ 'describe', 'end' }, describe, parent)
end

local it = function(element)
local parent = busted.context.parent(element)
local finally

busted.publish({ 'test', 'start' }, element, parent)

if not element.env then element.env = {} end

remove({ 'randomize' }, element)
remove({ 'describe', 'context', 'it', 'spec', 'test' }, element)
remove({ 'setup', 'teardown', 'before_each', 'after_each' }, element)
element.env.finally = function(fn) finally = fn end
element.env.pending = function(msg) busted.pending(msg) end

local status = busted.status('success')
local updateErrorStatus = function(descriptor)
if element.message then element.message = element.message .. '\n' end
element.message = (element.message or '') .. 'Error in ' .. descriptor
status:update('error')
end

local pass, ancestor = execAll('before_each', parent, true)
if pass then
status:update(busted.safe('it', element.run, element))
else
updateErrorStatus('before_each')
end

if not element.env.done then
remove({ 'pending' }, element)
if finally then status:update(busted.safe('finally', finally, element)) end
if not dexecAll('after_each', ancestor, true) then
updateErrorStatus('after_each')
end

busted.publish({ 'test', 'end' }, element, parent, tostring(status))
end
end

local pending = function(element)
local parent = busted.context.parent(element)
busted.publish({ 'test', 'start' }, element, parent)
busted.publish({ 'test', 'end' }, element, parent, 'pending')
end

busted.register('file', file)

busted.register('describe', describe)

busted.register('it', it)

busted.register('pending', pending)

busted.register('setup')
busted.register('teardown')
busted.register('before_each')
busted.register('after_each')

busted.alias('context', 'describe')
busted.alias('spec', 'it')
busted.alias('test', 'it')

local assert = require 'luassert'
local spy = require 'luassert.spy'
local mock = require 'luassert.mock'
local stub = require 'luassert.stub'

busted.environment.set('assert', assert)
busted.environment.set('spy', spy)
busted.environment.set('mock', mock)
busted.environment.set('stub', stub)

busted.replaceErrorWithFail(assert)
busted.replaceErrorWithFail(assert.True)

return busted
end

return setmetatable({}, {
__call = function(self, busted)
local root = busted.context.get()
init(busted)

return setmetatable(self, {
__index = function(self, key)
return rawget(root.env, key) or busted.executors[key]
end,

__newindex = function(self, key, value)
error('Attempt to modify busted')
end
})
end
})

+ 0
- 40
test/lua/busted/languages/ar.lua View File

@@ -1,42 +0,0 @@
local s = require('say')

s:set_namespace('ar')

s:set('output.pending', 'عالِق')
s:set('output.failure', 'فَشَل')
s:set('output.failure', 'نَجاح')

s:set('output.pending_plural', 'عالِق')
s:set('output.failure_plural', 'إخْفاقات')
s:set('output.success_plural', 'نَجاحات')

s:set('output.pending_zero', 'عالِق')
s:set('output.failure_zero', 'إخْفاقات')
s:set('output.success_zero', 'نَجاحات')

s:set('output.pending_single', 'عالِق')
s:set('output.failure_single', 'فَشَل')
s:set('output.success_single', 'نَجاح')

s:set('output.seconds', 'ثَوانٍ')

return {
failure_messages = {
'فَشِلَت %d مِنْ الإِختِبارات',
'فَشِلَت إخْتِباراتُك',
'برمجيَّتُكَ ضَعيْفة، أنْصَحُكَ بالتَّقاعُد',
'تقع برمجيَّتُكَ في مَنطِقَةِ الخَطَر',
'أقترِحُ ألّا تَتَقَدَّم بالإختِبار، علَّ يبْقى الطابِقُ مَستوراَ',
'جَدَّتي، فِي أَثْناءِ نَومِها، تَكتبُ بَرمَجياتٍ أفْضلُ مِن هذه',
'يَوَدُّ ليْ مُساعَدَتُكْ، لَكِنّْ...'
},
success_messages = {
'رائِع! تَمَّ إجْتِيازُ جَميعُ الإختِباراتِ بِنَجاحٍ',
'قُل ما شِئت، لا أكتَرِث: busted شَهِدَ لي!',
'حَقَّ عَليْكَ الإفتِخار',
'نَجاحٌ مُبْهِر!',
'عَليكَ بالإحتِفال؛ نَجَحَت جَميعُ التَجارُب'
}
}

+ 0
- 40
test/lua/busted/languages/de.lua View File

@@ -1,42 +0,0 @@
local s = require('say')

s:set_namespace('de')

s:set('output.pending', 'Noch nicht erledigt')
s:set('output.failure', 'Fehlgeschlagen')
s:set('output.success', 'Erfolgreich')

s:set('output.pending_plural', 'übersprungen')
s:set('output.failure_plural', 'fehlgeschlagen')
s:set('output.success_plural', 'erfolgreich')

s:set('output.pending_zero', 'übersprungen')
s:set('output.failure_zero', 'fehlgeschlagen')
s:set('output.success_zero', 'erfolgreich')

s:set('output.pending_single', 'übersprungen')
s:set('output.failure_single', 'fehlgeschlagen')
s:set('output.success_single', 'erfolgreich')

s:set('output.seconds', 'Sekunden')

return {
failure_messages = {
'Du hast %d kaputte Tests.',
'Deine Tests sind kaputt.',
'Dein Code ist schlecht; du solltest dich schlecht fühlen.',
'Dein Code befindet sich in der Gefahrenzone.',
'Ein seltsames Spiel. Der einzig gewinnbringende Zug ist nicht zu testen.',
'Meine Großmutter hat auf einem 386er bessere Tests geschrieben.',
'Immer wenn ein Test fehlschlägt, stirbt ein kleines Kätzchen.',
'Das fühlt sich schlecht an, oder?'
},
success_messages = {
'Yeah, die Tests laufen durch.',
'Fühlt sich gut an, oder?',
'Großartig!',
'Tests sind durchgelaufen, Zeit für ein Bier.',
}
}

+ 0
- 47
test/lua/busted/languages/en.lua View File

@@ -1,49 +0,0 @@
local s = require('say')

s:set_namespace('en')

s:set('output.pending', 'Pending')
s:set('output.failure', 'Failure')
s:set('output.error', 'Error')
s:set('output.success', 'Success')

s:set('output.pending_plural', 'pending')
s:set('output.failure_plural', 'failures')
s:set('output.error_plural', 'errors')
s:set('output.success_plural', 'successes')

s:set('output.pending_zero', 'pending')
s:set('output.failure_zero', 'failures')
s:set('output.error_zero', 'errors')
s:set('output.success_zero', 'successes')

s:set('output.pending_single', 'pending')
s:set('output.failure_single', 'failure')
s:set('output.error_single', 'error')
s:set('output.success_single', 'success')

s:set('output.seconds', 'seconds')

s:set('output.no_test_files_match', 'No test files found matching Lua pattern: %s')

return {
failure_messages = {
'You have %d busted specs',
'Your specs are busted',
'Your code is bad and you should feel bad',
'Your code is in the Danger Zone',
'Strange game. The only way to win is not to test',
'My grandmother wrote better specs on a 3 86',
'Every time there\'s a failure, drink another beer',
'Feels bad man'
},
success_messages = {
'Aww yeah, passing specs',
'Doesn\'t matter, had specs',
'Feels good, man',
'Great success',
'Tests pass, drink another beer',
}
}

+ 0
- 43
test/lua/busted/languages/fr.lua View File

@@ -1,45 +0,0 @@
local s = require('say')

s:set_namespace('fr')

s:set('output.pending', 'En attente')
s:set('output.failure', 'Echec')
s:set('output.success', 'Reussite')

s:set('output.pending_plural', 'en attente')
s:set('output.failure_plural', 'echecs')
s:set('output.success_plural', 'reussites')

s:set('output.pending_zero', 'en attente')
s:set('output.failure_zero', 'echec')
s:set('output.success_zero', 'reussite')

s:set('output.pending_single', 'en attente')
s:set('output.failure_single', 'echec')
s:set('output.success_single', 'reussite')

s:set('output.seconds', 'secondes')

s:set('output.no_test_files_match', 'Aucun test n\'est pourrait trouvé qui corresponde au motif de Lua: %s')

return {
failure_messages = {
'Vous avez %d test(s) qui a/ont echoue(s)',
'Vos tests ont echoue.',
'Votre code source est mauvais et vous devrez vous sentir mal',
'Vous avez un code source de Destruction Massive',
'Jeu plutot etrange game. Le seul moyen de gagner est de ne pas l\'essayer',
'Meme ma grand-mere ecrivait de meilleurs tests sur un PIII x86',
'A chaque erreur, prenez une biere',
'Ca craint, mon pote'
},
success_messages = {
'Oh yeah, tests reussis',
'Pas grave, y\'a eu du succes',
'C\'est du bon, mon pote. Que du bon!',
'Reussi, haut la main!',
'Test reussi. Un de plus. Offre toi une biere, sur mon compte!',
}
}

+ 0
- 41
test/lua/busted/languages/ja.lua View File

@@ -1,43 +0,0 @@
local s = require('say')

s:set_namespace('ja')

s:set('output.pending', '保留')
s:set('output.failure', '失敗')
s:set('output.success', '成功')

s:set('output.pending_plural', '保留')
s:set('output.failure_plural', '失敗')
s:set('output.success_plural', '成功')

s:set('output.pending_zero', '保留')
s:set('output.failure_zero', '失敗')
s:set('output.success_zero', '成功')

s:set('output.pending_single', '保留')
s:set('output.failure_single', '失敗')
s:set('output.success_single', '成功')

s:set('output.seconds', '秒')

return {
failure_messages = {
'%d個の仕様が破綻しています',
'仕様が破綻しています',
'あなたの書くコードは良くないので反省するべきです',
'あなたの書くコードは危険地帯にあります',
'おかしなゲームです。勝利する唯一の方法はテストをしないことです',
'私の祖母でもPentium Pentium III x86の上でもっといいコードを書いていましたよ',
'いつも失敗しているのでビールでも飲みましょう',
'罪悪感を持ちましょう',
},
success_messages = {
'オォーイェー、テストが通った',
'問題ない、テストがある',
'順調ですね',
'大成功',
'テストが通ったし、ビールでも飲もう',
}
}

+ 0
- 41
test/lua/busted/languages/nl.lua View File

@@ -1,43 +0,0 @@
local s = require('say')

s:set_namespace('nl')

s:set('output.pending', 'Hangend')
s:set('output.failure', 'Mislukt')
s:set('output.success', 'Succes')

s:set('output.pending_plural', 'hangenden')
s:set('output.failure_plural', 'mislukkingen')
s:set('output.success_plural', 'successen')

s:set('output.pending_zero', 'hangend')
s:set('output.failure_zero', 'mislukt')
s:set('output.success_zero', 'successen')

s:set('output.pending_single', 'hangt')
s:set('output.failure_single', 'mislukt')
s:set('output.success_single', 'succes')

s:set('output.seconds', 'seconden')

return {
failure_messages = {
'Je hebt %d busted specs',
'Je specs zijn busted',
'Je code is slecht en zo zou jij je ook moeten voelen',
'Je code zit in de Gevaren Zone',
'Vreemd spelletje. The enige manier om te winnen is door niet te testen',
'Mijn oma schreef betere specs op een 3 86',
'Elke keer dat iets mislukt, nog een biertje drinken',
'Voelt klote man'
},
success_messages = {
'Joeperdepoep, de specs zijn er door',
'Doet er niet toe, had specs',
'Voelt goed, man',
'Fantastisch success',
'Testen geslaagd, neem nog een biertje',
}
}

+ 0
- 36
test/lua/busted/languages/ru.lua View File

@@ -1,37 +0,0 @@
local s = require('say')

s:set_namespace('ru')

s:set('output.pending', 'Ожидает')
s:set('output.failure', 'Поломалcя')
s:set('output.success', 'Прошeл')

s:set('output.pending_plural', 'ожидают')
s:set('output.failure_plural', 'поломалиcь')
s:set('output.success_plural', 'прошли')

s:set('output.pending_zero', 'ожидающих')
s:set('output.failure_zero', 'поломанных')
s:set('output.success_zero', 'прошедших')

s:set('output.pending_single', 'ожидает')
s:set('output.failure_single', 'поломался')
s:set('output.success_single', 'прошел')

s:set('output.seconds', 'секунд')

---- definitions following are not used within the 'say' namespace
return {
failure_messages = {
'У тебя %d просратых тестов',
'Твои тесты поломаны',
'Твой код говеный - пойди напейся!'
},
success_messages = {
'Поехали!',
'Жизнь - хороша!',
'Ффух в этот раз пронесло!',
'Ура!'
}
}

+ 0
- 41
test/lua/busted/languages/th.lua View File

@@ -1,43 +0,0 @@
local s = require('say')

s:set_namespace('th')

s:set('output.pending', 'อยู่ระหว่างดำเนินการ')
s:set('output.failure', 'ล้มเหลว')
s:set('output.success', 'สำเร็จ')

s:set('output.pending_plural', 'อยู่ระหว่างดำเนินการ')
s:set('output.failure_plural', 'ล้มเหลว')
s:set('output.success_plural', 'สำเร็จ')

s:set('output.pending_zero', 'อยู่ระหว่างดำเนินการ')
s:set('output.failure_zero', 'ล้มเหลว')
s:set('output.success_zero', 'สำเร็จ')

s:set('output.pending_single', 'อยู่ระหว่างดำเนินการ')
s:set('output.failure_single', 'ล้มเหลว')
s:set('output.success_single', 'สำเร็จ')

s:set('output.seconds', 'วินาที')

return {
failure_messages = {
'คุณมี %d บัสเต็ดสเปค',
'สเปคของคุณคือ บัสเต็ด',
'โค้ดของคุณไม่ดีเลย คุณควรรู้สึกแย่น่ะ',
'โค้ดของคุณอยู่ในเขตอันตราย!',
'มันแปลกๆน่ะ วิธีที่จะชนะไม่ได้มีแค่เทสอย่างเดียว',
'ยายผมเขียนสเปคดีกว่านี้อีก บนเครื่อง 386',
'ทุกๆครั้งที่ล้มเหลว, ดื่มเบียร์แก้วใหม่',
'แย่จัง นายท่าน'
},
success_messages = {
'อุ๊ตะ!!!, สเปคผ่าน!',
'ไม่สำคัญ, มีสเปค',
'ฟินเลยดิ นายท่าน',
'สำเร็จ ยอดเยี่ยม',
'เทสผ่าน, ดื่มเบียร์ๆๆๆ',
}
}

+ 0
- 36
test/lua/busted/languages/ua.lua View File

@@ -1,37 +0,0 @@
local s = require('say')

s:set_namespace('ua')

s:set('output.pending', 'Очікує')
s:set('output.failure', 'Зламався')
s:set('output.success', 'Пройшов')

s:set('output.pending_plural', 'очікують')
s:set('output.failure_plural', 'зламались')
s:set('output.success_plural', 'пройшли')

s:set('output.pending_zero', 'очікуючих')
s:set('output.failure_zero', 'зламаних')
s:set('output.success_zero', 'пройдених')

s:set('output.pending_single', 'очікує')
s:set('output.failure_single', 'зламався')
s:set('output.success_single', 'пройшов')

s:set('output.seconds', 'секунд')


---- definitions following are not used within the 'say' namespace
return {
failure_messages = {
'Ти зрадив %d тестів!',
'Ой йо..',
'Вороги поламали наші тести!'
},
success_messages = {
'Слава Україні! Героям Слава!',
'Тестування успішно пройдено!',
'Всі баги знищено!'
}
}

+ 0
- 41
test/lua/busted/languages/zh.lua View File

@@ -1,43 +0,0 @@
local s = require('say')

s:set_namespace('zh')

s:set('output.pending', '开发中')
s:set('output.failure', '失败')
s:set('output.success', '成功')

s:set('output.pending_plural', '开发中')
s:set('output.failure_plural', '失败')
s:set('output.success_plural', '成功')

s:set('output.pending_zero', '开发中')
s:set('output.failure_zero', '失败')
s:set('output.success_zero', '成功')

s:set('output.pending_single', '开发中')
s:set('output.failure_single', '失败')
s:set('output.success_single', '成功')

s:set('output.seconds', '秒')

return {
failure_messages = {
'你一共提交了[%d]个测试用例',
'又出错了!',
'到底哪里不对呢?',
'出错了,又要加班了!',
'囧,出Bug了!',
'据说比尔盖兹也写了一堆Bug,别灰心!',
'又出错了,休息一下吧',
'Bug好多,心情好坏!'
},
success_messages = {
'牛X,测试通过了!',
'测试通过了,感觉不错吧,兄弟!',
'哥们,干得漂亮!',
'终于通过了!干一杯先!',
'阿弥陀佛~,菩萨显灵了!',
}
}

+ 0
- 34
test/lua/busted/modules/configuration_loader.lua View File

@@ -1,34 +0,0 @@
return function()
local tablex = require 'pl.tablex'

-- Function to load the .busted configuration file if available
local loadBustedConfigurationFile = function(configFile, config, defaults)
if type(configFile) ~= 'table' then
return config, '.busted file does not return a table.'
end

local defaults = defaults or {}
local run = config.run or defaults.run

if run and run ~= '' then
local runConfig = configFile[run]

if type(runConfig) == 'table' then
config = tablex.merge(runConfig, config, true)
else
return config, 'Task `' .. run .. '` not found, or not a table.'
end
end

if type(configFile.default) == 'table' then
config = tablex.merge(configFile.default, config, true)
end

config = tablex.merge(defaults, config, true)

return config
end

return loadBustedConfigurationFile
end


+ 0
- 24
test/lua/busted/modules/files/lua.lua View File

@@ -1,24 +0,0 @@
local path = require 'pl.path'

local ret = {}

local getTrace = function(filename, info)
local index = info.traceback:find('\n%s*%[C]')
info.traceback = info.traceback:sub(1, index)
return info, false
end

ret.match = function(busted, filename)
return path.extension(filename) == '.lua'
end


ret.load = function(busted, filename)
local file, err = loadfile(filename)
if not file then
busted.publish({ 'error', 'file' }, { descriptor = 'file', name = filename }, nil, err, {})
end
return file, getTrace
end

return ret

+ 0
- 107
test/lua/busted/modules/files/moonscript.lua View File

@@ -1,108 +0,0 @@
local path = require 'pl.path'

local ok, moonscript, line_tables, util = pcall(function()
return require 'moonscript', require 'moonscript.line_tables', require 'moonscript.util'
end)

local _cache = {}

local lookup_line = function(fname, pos)
if not _cache[fname] then
local f = io.open(fname)
_cache[fname] = f:read('*a')
f:close()
end

return util.pos_to_line(_cache[fname], pos)
end

local rewrite_linenumber = function(fname, lineno)
local tbl = line_tables['@' .. fname]
if fname and tbl then
for i = lineno, 0 ,-1 do
if tbl[i] then
return lookup_line(fname, tbl[i])
end
end
end

return lineno
end

local rewrite_filename = function(filename)
-- sometimes moonscript gives files like [string "./filename.moon"], so
-- we'll chop it up to only get the filename.
return filename:match('string "(.+)"') or filename
end

local rewrite_traceback = function(fname, trace)
local rewrite_one = function(line, pattern, sub)
if line == nil then return '' end

local fname, lineno = line:match(pattern)

if fname and lineno then
fname = rewrite_filename(fname)
local new_lineno = rewrite_linenumber(fname, tonumber(lineno))
if new_lineno then
line = line:gsub(sub:format(tonumber(lineno)), sub:format(tonumber(new_lineno)))
end
end

return line
end

local lines = {}
local j = 0

for line in trace:gmatch('[^\r\n]+') do
j = j + 1
line = rewrite_one(line, '%s*(.-):(%d+): ', ':%d:')
line = rewrite_one(line, '<(.*):(%d+)>', ':%d>')
lines[j] = line
end

return '\n' .. table.concat(lines, trace:match('[\r\n]+')) .. '\n'
end

local ret = {}

local getTrace = function(filename, info)
local index = info.traceback:find('\n%s*%[C]')
info.traceback = info.traceback:sub(1, index)

info.short_src = rewrite_filename(info.short_src)
info.traceback = rewrite_traceback(filename, info.traceback)
info.linedefined = rewrite_linenumber(filename, info.linedefined)
info.currentline = rewrite_linenumber(filename, info.currentline)

return info
end

local rewriteMessage = function(filename, message)
local fname, line, msg = message:match('^([^\n]-):(%d+): (.*)')
if not fname then
return message
end

fname = rewrite_filename(fname)
line = rewrite_linenumber(fname, tonumber(line))

return fname .. ':' .. tostring(line) .. ': ' .. msg
end

ret.match = function(busted, filename)
return ok and path.extension(filename) == '.moon'
end


ret.load = function(busted, filename)
local file, err = moonscript.loadfile(filename)
if not file then
busted.publish({ 'error', 'file' }, { descriptor = 'file', name = filename }, nil, err, {})
end
return file, getTrace, rewriteMessage
end

return ret

+ 0
- 24
test/lua/busted/modules/files/terra.lua View File

@@ -1,24 +0,0 @@
local path = require 'pl.path'

local ret = {}
local ok, terralib = pcall(function() return require 'terralib' end)

local getTrace = function(filename, info)
local index = info.traceback:find('\n%s*%[C]')
info.traceback = info.traceback:sub(1, index)
return info
end

ret.match = function(busted, filename)
return ok and path.extension(filename) == '.t'
end

ret.load = function(busted, filename)
local file, err = terralib.loadfile(filename)
if not file then
busted.publish({ 'error', 'file' }, { descriptor = 'file', name = filename }, nil, err, {})
end
return file, getTrace
end

return ret

+ 0
- 23
test/lua/busted/modules/helper_loader.lua View File

@@ -1,23 +0,0 @@
local utils = require 'busted.utils'
local hasMoon, moonscript = pcall(require, 'moonscript')

return function()
local loadHelper = function(helper, hpath, options, busted)
local success, err = pcall(function()
arg = options.arguments
if helper:match('%.lua$') then
dofile(utils.normpath(hpath))
elseif hasMoon and helper:match('%.moon$') then
moonscript.dofile(utils.normpath(hpath))
else
require(helper)
end
end)

if not success then
busted.publish({ 'error', 'helper' }, { descriptor = 'helper', name = helper }, nil, err, {})
end
end

return loadHelper
end

+ 0
- 22
test/lua/busted/modules/luacov.lua View File

@@ -1,22 +0,0 @@
return function()
-- Function to initialize luacov if available
local loadLuaCov = function()
local result, luacov = pcall(require, 'luacov.runner')

if not result then
return print('LuaCov not found on the system, try running without --coverage option, or install LuaCov first')
end

-- call it to start
luacov()

-- exclude busted files
table.insert(luacov.configuration.exclude, 'busted_bootstrap$')
table.insert(luacov.configuration.exclude, 'busted%.')
table.insert(luacov.configuration.exclude, 'luassert%.')
table.insert(luacov.configuration.exclude, 'say%.')
table.insert(luacov.configuration.exclude, 'pl%.')
end

return loadLuaCov
end

+ 0
- 31
test/lua/busted/modules/output_handler_loader.lua View File

@@ -1,31 +0,0 @@
local utils = require 'busted.utils'
local hasMoon, moonscript = pcall(require, 'moonscript')

return function()
local loadOutputHandler = function(output, opath, options, busted, defaultOutput)
local handler

local success, err = pcall(function()
if output:match('%.lua$') then
handler = dofile(utils.normpath(opath))
elseif hasMoon and output:match('%.moon$') then
handler = moonscript.dofile(utils.normpath(opath))
else
handler = require('busted.outputHandlers.' .. output)
end
end)

if not success and err:match("module '.-' not found:") then
success, err = pcall(function() handler = require(output) end)
end

if not success then
busted.publish({ 'error', 'output' }, { descriptor = 'output', name = output }, nil, err, {})
handler = require('busted.outputHandlers.' .. defaultOutput)
end

return handler(options, busted)
end

return loadOutputHandler
end

+ 0
- 84
test/lua/busted/modules/test_file_loader.lua View File

@@ -1,84 +0,0 @@
local s = require 'say'

return function(busted, loaders, options)
local path = require 'pl.path'
local dir = require 'pl.dir'
local tablex = require 'pl.tablex'
local shuffle = require 'busted.utils'.shuffle
local fileLoaders = {}

for _, v in pairs(loaders) do
local loader = require('busted.modules.files.'..v)
fileLoaders[#fileLoaders+1] = loader
end

local getTestFiles = function(rootFile, pattern)
local fileList

if path.isfile(rootFile) then
fileList = { rootFile }
elseif path.isdir(rootFile) then
local getfiles = options.recursive and dir.getallfiles or dir.getfiles
fileList = getfiles(rootFile)

fileList = tablex.filter(fileList, function(filename)
return path.basename(filename):find(pattern)
end)

fileList = tablex.filter(fileList, function(filename)
if path.is_windows then
return not filename:find('%\\%.%w+.%w+')
else
return not filename:find('/%.%w+.%w+')
end
end)
else
fileList = {}
end

return fileList
end

-- runs a testfile, loading its tests
local loadTestFile = function(busted, filename)
for _, v in pairs(fileLoaders) do
if v.match(busted, filename) then
return v.load(busted, filename)
end
end
end

local loadTestFiles = function(rootFile, pattern, loaders)
local fileList = getTestFiles(rootFile, pattern)

if options.shuffle then
shuffle(fileList, options.seed)
elseif options.sort then
table.sort(fileList)
end

for i, fileName in ipairs(fileList) do
local testFile, getTrace, rewriteMessage = loadTestFile(busted, fileName, loaders)

if testFile then
local file = setmetatable({
getTrace = getTrace,
rewriteMessage = rewriteMessage
}, {
__call = testFile
})

busted.executors.file(fileName, file)
end
end

if #fileList == 0 then
busted.publish({ 'error' }, {}, nil, s('output.no_test_files_match'):format(pattern), {})
end

return fileList
end

return loadTestFiles, loadTestFile, getTestFiles
end


+ 0
- 51
test/lua/busted/outputHandlers/TAP.lua View File

@@ -1,51 +0,0 @@
local pretty = require 'pl.pretty'

return function(options, busted)
local handler = require 'busted.outputHandlers.base'(busted)

handler.suiteEnd = function()
local total = handler.successesCount + handler.errorsCount + handler.failuresCount
print('1..' .. total)

local success = 'ok %u - %s'
local failure = 'not ' .. success
local counter = 0

for i,t in pairs(handler.successes) do
counter = counter + 1
print(success:format(counter, t.name))
end

local showFailure = function(t)
counter = counter + 1
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)
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

for i,t in pairs(handler.errors) do
showFailure(t)
end
for i,t in pairs(handler.failures) do
showFailure(t)
end

return nil, true
end

busted.subscribe({ 'suite', 'end' }, handler.suiteEnd)

return handler
end

+ 0
- 177
test/lua/busted/outputHandlers/base.lua View File

@@ -1,177 +0,0 @@
return function(busted)
local handler = {
successes = {},
successesCount = 0,
pendings = {},
pendingsCount = 0,
failures = {},
failuresCount = 0,
errors = {},
errorsCount = 0,
inProgress = {}
}

handler.cancelOnPending = function(element, parent, status)
return not ((element.descriptor == 'pending' or status == 'pending') and handler.options.suppressPending)
end

handler.subscribe = function(handler, options)
require('busted.languages.en')
handler.options = options

if options.language ~= 'en' then
require('busted.languages.' .. options.language)
end

busted.subscribe({ 'suite', 'reinitialize' }, handler.baseSuiteRepeat, { priority = 1 })
busted.subscribe({ 'suite', 'start' }, handler.baseSuiteStart, { priority = 1 })
busted.subscribe({ 'suite', 'end' }, handler.baseSuiteEnd, { priority = 1 })
busted.subscribe({ 'test', 'start' }, handler.baseTestStart, { priority = 1, predicate = handler.cancelOnPending })
busted.subscribe({ 'test', 'end' }, handler.baseTestEnd, { priority = 1, predicate = handler.cancelOnPending })
busted.subscribe({ 'pending' }, handler.basePending, { priority = 1, predicate = handler.cancelOnPending })
busted.subscribe({ 'failure', 'it' }, handler.baseTestFailure, { priority = 1 })
busted.subscribe({ 'error', 'it' }, handler.baseTestError, { priority = 1 })
busted.subscribe({ 'failure' }, handler.baseError, { priority = 1 })
busted.subscribe({ 'error' }, handler.baseError, { priority = 1 })
end

handler.getFullName = function(context)
local parent = busted.context.parent(context)
local names = { (context.name or context.descriptor) }

while parent and (parent.name or parent.descriptor) and
parent.descriptor ~= 'file' do

table.insert(names, 1, parent.name or parent.descriptor)
parent = busted.context.parent(parent)
end

return table.concat(names, ' ')
end

handler.format = function(element, parent, message, debug, isError)
local formatted = {
trace = debug or element.trace,
element = element,
name = handler.getFullName(element),
message = message,
isError = isError
}
formatted.element.trace = element.trace or debug

return formatted
end

handler.getDuration = function()
if not handler.endTime or not handler.startTime then
return 0
end

return handler.endTime - handler.startTime
end

handler.baseSuiteStart = function()
handler.startTime = os.clock()
return nil, true
end

handler.baseSuiteRepeat = function()
handler.successes = {}
handler.successesCount = 0
handler.pendings = {}
handler.pendingsCount = 0
handler.failures = {}
handler.failuresCount = 0
handler.errors = {}
handler.errorsCount = 0
handler.inProgress = {}

return nil, true
end

handler.baseSuiteEnd = function()
handler.endTime = os.clock()
return nil, true
end

handler.baseTestStart = function(element, parent)
handler.inProgress[tostring(element)] = {}
return nil, true
end

handler.baseTestEnd = function(element, parent, status, debug)
local isError
local insertTable

if status == 'success' then
insertTable = handler.successes
handler.successesCount = handler.successesCount + 1
elseif status == 'pending' then
insertTable = handler.pendings
handler.pendingsCount = handler.pendingsCount + 1
elseif status == 'failure' then
insertTable = handler.failures
-- failure count already incremented in error handler
elseif status == 'error' then
-- error count already incremented in error handler
insertTable = handler.errors
isError = true
end

local formatted = handler.format(element, parent, element.message, debug, isError)

local id = tostring(element)
if handler.inProgress[id] then
for k, v in pairs(handler.inProgress[id]) do
formatted[k] = v
end

handler.inProgress[id] = nil
end

table.insert(insertTable, formatted)

return nil, true
end

local function saveInProgress(element, message, debug)
local id = tostring(element)
handler.inProgress[id].message = message
handler.inProgress[id].trace = debug
end

local function saveError(element, parent, message, debug)
if parent.randomseed then
message = 'Random Seed: ' .. parent.randomseed .. '\n' .. message
end
saveInProgress(element, message, debug)
end

handler.basePending = function(element, parent, message, debug)
saveInProgress(element, message, debug)
return nil, true
end

handler.baseTestFailure = function(element, parent, message, debug)
handler.failuresCount = handler.failuresCount + 1
saveError(element, parent, message, debug)
return nil, true
end

handler.baseTestError = function(element, parent, message, debug)
handler.errorsCount = handler.errorsCount + 1
saveError(element, parent, message, debug)
return nil, true
end

handler.baseError = function(element, parent, message, debug)
if element.descriptor ~= 'it' then
handler.errorsCount = handler.errorsCount + 1
table.insert(handler.errors, handler.format(element, parent, message, debug, true))
end

return nil, true
end

return handler
end

+ 0
- 21
test/lua/busted/outputHandlers/json.lua View File

@@ -1,21 +0,0 @@
local json = require 'dkjson'

return function(options, busted)
local handler = require 'busted.outputHandlers.base'(busted)

handler.suiteEnd = function()
print(json.encode({
pendings = handler.pendings,
successes = handler.successes,
failures = handler.failures,
errors = handler.errors,
duration = handler.getDuration()
}))

return nil, true
end

busted.subscribe({ 'suite', 'end' }, handler.suiteEnd)

return handler
end

+ 0
- 136
test/lua/busted/outputHandlers/junit.lua View File

@@ -1,136 +0,0 @@
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

+ 0
- 175
test/lua/busted/outputHandlers/plainTerminal.lua View File

@@ -1,175 +0,0 @@
local s = require 'say'
local pretty = require 'pl.pretty'

return function(options, busted)
local handler = require 'busted.outputHandlers.base'(busted)

local successDot = '+'
local failureDot = '-'
local errorDot = '*'
local pendingDot = '.'

local pendingDescription = function(pending)
local name = pending.name

local string = s('output.pending') .. ' → ' ..
pending.trace.short_src .. ' @ ' ..
pending.trace.currentline ..
'\n' .. name

if type(pending.message) == 'string' then
string = string .. '\n' .. pending.message
elseif pending.message ~= nil then
string = string .. '\n' .. pretty.write(pending.message)
end

return string
end

local failureMessage = function(failure)
local string
if type(failure.message) == 'string' then
string = failure.message
elseif failure.message == nil then
string = 'Nil error'
else
string = pretty.write(failure.message)
end

return string
end

local failureDescription = function(failure, isError)
local string = s('output.failure') .. ' → '
if isError then
string = s('output.error') .. ' → '
end

if not failure.element.trace or not failure.element.trace.short_src then
string = string ..
failureMessage(failure) .. '\n' ..
failure.name
else
string = string ..
failure.element.trace.short_src .. ' @ ' ..
failure.element.trace.currentline .. '\n' ..
failure.name .. '\n' ..
failureMessage(failure)
end

if options.verbose and failure.trace and failure.trace.traceback then
string = string .. '\n' .. failure.trace.traceback
end

return string
end

local statusString = function()
local successString = s('output.success_plural')
local failureString = s('output.failure_plural')
local pendingString = s('output.pending_plural')
local errorString = s('output.error_plural')

local ms = handler.getDuration()
local successes = handler.successesCount
local pendings = handler.pendingsCount
local failures = handler.failuresCount
local errors = handler.errorsCount

if successes == 0 then
successString = s('output.success_zero')
elseif successes == 1 then
successString = s('output.success_single')
end

if failures == 0 then
failureString = s('output.failure_zero')
elseif failures == 1 then
failureString = s('output.failure_single')
end

if pendings == 0 then
pendingString = s('output.pending_zero')
elseif pendings == 1 then
pendingString = s('output.pending_single')
end

if errors == 0 then
errorString = s('output.error_zero')
elseif errors == 1 then
errorString = s('output.error_single')
end

local formattedTime = ('%.6f'):format(ms):gsub('([0-9])0+$', '%1')

return successes .. ' ' .. successString .. ' / ' ..
failures .. ' ' .. failureString .. ' / ' ..
errors .. ' ' .. errorString .. ' / ' ..
pendings .. ' ' .. pendingString .. ' : ' ..
formattedTime .. ' ' .. s('output.seconds')
end

handler.testEnd = function(element, parent, status, debug)
if not options.deferPrint then
local string = successDot

if status == 'pending' then
string = pendingDot
elseif status == 'failure' then
string = failureDot
elseif status == 'error' then
string = errorDot
end

io.write(string)
io.flush()
end

return nil, true
end

handler.suiteStart = function(count, total)
local runString = (total > 1 and '\nRepeating all tests (run %d of %d) . . .\n\n' or '')
io.write(runString:format(count, total))
io.flush()
end

handler.suiteEnd = function()
print('')
print(statusString())

for i, pending in pairs(handler.pendings) do
print('')
print(pendingDescription(pending))
end

for i, err in pairs(handler.failures) do
print('')
print(failureDescription(err))
end

for i, err in pairs(handler.errors) do
print('')
print(failureDescription(err, true))
end

return nil, true
end

handler.error = function(element, parent, message, debug)
io.write(errorDot)
io.flush()

return nil, true
end

busted.subscribe({ 'test', 'end' }, handler.testEnd, { predicate = handler.cancelOnPending })
busted.subscribe({ 'suite', 'start' }, handler.suiteStart)
busted.subscribe({ 'suite', 'end' }, handler.suiteEnd)
busted.subscribe({ 'error', 'file' }, handler.error)
busted.subscribe({ 'failure', 'file' }, handler.error)
busted.subscribe({ 'error', 'describe' }, handler.error)
busted.subscribe({ 'failure', 'describe' }, handler.error)

return handler
end

+ 0
- 36
test/lua/busted/outputHandlers/sound.lua View File

@@ -1,36 +0,0 @@
local app = require 'pl.app'
return function(options, busted)
local handler = require 'busted.outputHandlers.base'(busted)
local language = require('busted.languages.' .. options.language)

handler.suiteEnd = function()
local system = app.platform()
local sayer_pre, sayer_post
local messages

if system == 'Linux' then
sayer_pre = 'espeak -s 160 '
sayer_post = ' > /dev/null 2>&1'
elseif system and system:match('^Windows') then
sayer_pre = 'echo '
sayer_post = ' | ptts'
else
sayer_pre = 'say '
sayer_post = ''
end

if handler.failuresCount > 0 then
messages = language.failure_messages
else
messages = language.success_messages
end

io.popen(sayer_pre .. '"' .. messages[math.random(1, #messages)] .. '"' .. sayer_post)

return nil, true
end

busted.subscribe({ 'suite', 'end' }, handler.suiteEnd)

return handler
end

+ 0
- 176
test/lua/busted/outputHandlers/utfTerminal.lua View File

@@ -1,176 +0,0 @@
local ansicolors = require 'ansicolors'
local s = require 'say'
local pretty = require 'pl.pretty'

return function(options, busted)
local handler = require 'busted.outputHandlers.base'(busted)

local successDot = ansicolors('%{green}●')
local failureDot = ansicolors('%{red}◼')
local errorDot = ansicolors('%{magenta}✱')
local pendingDot = ansicolors('%{yellow}◌')

local pendingDescription = function(pending)
local name = pending.name

local string = ansicolors('%{yellow}' .. s('output.pending')) .. ' → ' ..
ansicolors('%{cyan}' .. pending.trace.short_src) .. ' @ ' ..
ansicolors('%{cyan}' .. pending.trace.currentline) ..
'\n' .. ansicolors('%{bright}' .. name)

if type(pending.message) == 'string' then
string = string .. '\n' .. pending.message
elseif pending.message ~= nil then
string = string .. '\n' .. pretty.write(pending.message)
end

return string
end

local failureMessage = function(failure)
local string
if type(failure.message) == 'string' then
string = failure.message
elseif failure.message == nil then
string = 'Nil error'
else
string = pretty.write(failure.message)
end

return string
end

local failureDescription = function(failure, isError)
local string = ansicolors('%{red}' .. s('output.failure')) .. ' → '
if isError then
string = ansicolors('%{magenta}' .. s('output.error')) .. ' → '
end

if not failure.element.trace or not failure.element.trace.short_src then
string = string ..
ansicolors('%{cyan}' .. failureMessage(failure)) .. '\n' ..
ansicolors('%{bright}' .. failure.name)
else
string = string ..
ansicolors('%{cyan}' .. failure.element.trace.short_src) .. ' @ ' ..
ansicolors('%{cyan}' .. failure.element.trace.currentline) .. '\n' ..
ansicolors('%{bright}' .. failure.name) .. '\n' ..
failureMessage(failure)
end

if options.verbose and failure.trace and failure.trace.traceback then
string = string .. '\n' .. failure.trace.traceback
end

return string
end

local statusString = function()
local successString = s('output.success_plural')
local failureString = s('output.failure_plural')
local pendingString = s('output.pending_plural')
local errorString = s('output.error_plural')

local ms = handler.getDuration()
local successes = handler.successesCount
local pendings = handler.pendingsCount
local failures = handler.failuresCount
local errors = handler.errorsCount

if successes == 0 then
successString = s('output.success_zero')
elseif successes == 1 then
successString = s('output.success_single')
end

if failures == 0 then
failureString = s('output.failure_zero')
elseif failures == 1 then
failureString = s('output.failure_single')
end

if pendings == 0 then
pendingString = s('output.pending_zero')
elseif pendings == 1 then
pendingString = s('output.pending_single')
end

if errors == 0 then
errorString = s('output.error_zero')
elseif errors == 1 then
errorString = s('output.error_single')
end

local formattedTime = ('%.6f'):format(ms):gsub('([0-9])0+$', '%1')

return ansicolors('%{green}' .. successes) .. ' ' .. successString .. ' / ' ..
ansicolors('%{red}' .. failures) .. ' ' .. failureString .. ' / ' ..
ansicolors('%{magenta}' .. errors) .. ' ' .. errorString .. ' / ' ..
ansicolors('%{yellow}' .. pendings) .. ' ' .. pendingString .. ' : ' ..
ansicolors('%{bright}' .. formattedTime) .. ' ' .. s('output.seconds')
end

handler.testEnd = function(element, parent, status, debug)
if not options.deferPrint then
local string = successDot

if status == 'pending' then
string = pendingDot
elseif status == 'failure' then
string = failureDot
elseif status == 'error' then
string = errorDot
end

io.write(string)
io.flush()
end

return nil, true
end

handler.suiteStart = function(count, total)
local runString = (total > 1 and '\nRepeating all tests (run %d of %d) . . .\n\n' or '')
io.write(runString:format(count, total))
io.flush()
end

handler.suiteEnd = function(count, total)
print('')
print(statusString())

for i, pending in pairs(handler.pendings) do
print('')
print(pendingDescription(pending))
end

for i, err in pairs(handler.failures) do
print('')
print(failureDescription(err))
end

for i, err in pairs(handler.errors) do
print('')
print(failureDescription(err, true))
end

return nil, true
end

handler.error = function(element, parent, message, debug)
io.write(errorDot)
io.flush()

return nil, true
end

busted.subscribe({ 'test', 'end' }, handler.testEnd, { predicate = handler.cancelOnPending })
busted.subscribe({ 'suite', 'start' }, handler.suiteStart)
busted.subscribe({ 'suite', 'end' }, handler.suiteEnd)
busted.subscribe({ 'error', 'file' }, handler.error)
busted.subscribe({ 'failure', 'file' }, handler.error)
busted.subscribe({ 'error', 'describe' }, handler.error)
busted.subscribe({ 'failure', 'describe' }, handler.error)

return handler
end

+ 0
- 399
test/lua/busted/runner.lua View File

@@ -1,400 +0,0 @@

local path = require 'pl.path'
local term = require 'term'
local utils = require 'busted.utils'
local loaded = false

return function(options)
if loaded then return else loaded = true end

local opt = options or {}
local isBatch = opt.batch
local cli = require 'cliargs'
local busted = require 'busted.core'()

local configLoader = require 'busted.modules.configuration_loader'()
local helperLoader = require 'busted.modules.helper_loader'()
local outputHandlerLoader = require 'busted.modules.output_handler_loader'()

local luacov = require 'busted.modules.luacov'()

local osexit = require 'busted.compatibility'.osexit

require 'busted'(busted)

-- Default cli arg values
local defaultOutput = term.isatty(io.stdout) and 'utfTerminal' or 'plainTerminal'
local defaultLoaders = 'lua,moonscript'
local defaultPattern = '_spec'
local defaultSeed = 'os.time()'
local lpathprefix = './src/?.lua;./src/?/?.lua;./src/?/init.lua'
local cpathprefix = path.is_windows and './csrc/?.dll;./csrc/?/?.dll;' or './csrc/?.so;./csrc/?/?.so;'

local level = 2
local info = debug.getinfo(level, 'Sf')
local source = info.source
local fileName = source:sub(1,1) == '@' and source:sub(2) or source

local cliArgsParsed = {}

local function processOption(key, value, altkey, opt)
if altkey then cliArgsParsed[altkey] = value end
cliArgsParsed[key] = value
return true
end

local function processNumber(key, value, altkey, opt)
local number = tonumber(value)
if not number then
return nil, 'argument to ' .. opt:gsub('=.*', '') .. ' must be a number'
end
if altkey then cliArgsParsed[altkey] = number end
cliArgsParsed[key] = number
return true
end

local function processVersion()
-- Return early if asked for the version
print(busted.version)
osexit(0, true)
end

-- Load up the command-line interface options
cli:set_name(path.basename(fileName))
cli:add_flag('--version', 'prints the program version and exits', processVersion)

if isBatch then
cli:optarg('ROOT', 'test script file/folder. Folders will be traversed for any file that matches the --pattern option.', 'spec', 1)

cli:add_option('-p, --pattern=PATTERN', 'only run test files matching the Lua pattern', defaultPattern, processOption)
end

cli:add_option('-o, --output=LIBRARY', 'output library to load', defaultOutput, processOption)
cli:add_option('-d, --cwd=cwd', 'path to current working directory', './', processOption)
cli:add_option('-t, --tags=TAGS', 'only run tests with these #tags', nil, processOption)
cli:add_option('--exclude-tags=TAGS', 'do not run tests with these #tags, takes precedence over --tags', nil, processOption)
cli:add_option('--filter=PATTERN', 'only run test names matching the Lua pattern', nil, processOption)
cli:add_option('--filter-out=PATTERN', 'do not run test names matching the Lua pattern, takes precedence over --filter', nil, processOption)
cli:add_option('-m, --lpath=PATH', 'optional path to be prefixed to the Lua module search path', lpathprefix, processOption)
cli:add_option('--cpath=PATH', 'optional path to be prefixed to the Lua C module search path', cpathprefix, processOption)
cli:add_option('-r, --run=RUN', 'config to run from .busted file', nil, processOption)
cli:add_option('--repeat=COUNT', 'run the tests repeatedly', '1', processNumber)
cli:add_option('--seed=SEED', 'random seed value to use for shuffling test order', defaultSeed, processNumber)
cli:add_option('--lang=LANG', 'language for error messages', 'en', processOption)
cli:add_option('--loaders=NAME', 'test file loaders', defaultLoaders, processOption)
cli:add_option('--helper=PATH', 'A helper script that is run before tests', nil, processOption)

cli:add_option('-Xoutput OPTION', 'pass `OPTION` as an option to the output handler. If `OPTION` contains commas, it is split into multiple options at the commas.', nil, processOption)
cli:add_option('-Xhelper OPTION', 'pass `OPTION` as an option to the helper script. If `OPTION` contains commas, it is split into multiple options at the commas.', nil, processOption)

cli:add_flag('-c, --coverage', 'do code coverage analysis (requires `LuaCov` to be installed)', processOption)
cli:add_flag('-v, --verbose', 'verbose output of errors', processOption)
cli:add_flag('-s, --enable-sound', 'executes `say` command if available', processOption)
cli:add_flag('-l, --list', 'list the names of all tests instead of running them', processOption)
cli:add_flag('--no-keep-going', 'quit after first error or failure', processOption)
cli:add_flag('--no-recursive', 'do not recurse into subdirectories', processOption)
cli:add_flag('--shuffle', 'randomize file and test order, takes precedence over --sort (--shuffle-test and --shuffle-files)', processOption)
cli:add_flag('--shuffle-files', 'randomize file execution order, takes precedence over --sort-files', processOption)
cli:add_flag('--shuffle-tests', 'randomize test order within a file, takes precedence over --sort-tests', processOption)
cli:add_flag('--sort', 'sort file and test order (--sort-tests and --sort-files)', processOption)
cli:add_flag('--sort-files', 'sort file execution order', processOption)
cli:add_flag('--sort-tests', 'sort test order within a file', processOption)
cli:add_flag('--suppress-pending', 'suppress `pending` test output', processOption)
cli:add_flag('--defer-print', 'defer print to when test suite is complete', processOption)

-- Parse the cli arguments
local cliArgs = cli:parse(arg)
if not cliArgs then
osexit(1, true)
end

-- Load current working directory
local fpath = utils.normpath(cliArgs.cwd)

-- Load busted config file if available
local configFile = { }
local bustedConfigFilePath = utils.normpath(path.join(fpath, '.busted'))
local bustedConfigFile = pcall(function() configFile = loadfile(bustedConfigFilePath)() end)
if bustedConfigFile then
local config, err = configLoader(configFile, cliArgsParsed, cliArgs)
if err then
print('Error: ' .. err)
osexit(1, true)
else
cliArgs = config
end
end

local tags = {}
local excludeTags = {}

if cliArgs.tags and cliArgs.tags ~= '' then
tags = utils.split(cliArgs.tags, ',')
end

if cliArgs['exclude-tags'] and cliArgs['exclude-tags'] ~= '' then
excludeTags = utils.split(cliArgs['exclude-tags'], ',')
end

-- If coverage arg is passed in, load LuaCovsupport
if cliArgs.coverage then
luacov()
end

-- Add additional package paths based on lpath and cpath cliArgs
if #cliArgs.lpath > 0 then
lpathprefix = cliArgs.lpath
lpathprefix = lpathprefix:gsub('^%.([/%\\])', fpath .. '%1')
lpathprefix = lpathprefix:gsub(';%.([/%\\])', ';' .. fpath .. '%1')
package.path = (lpathprefix .. ';' .. package.path):gsub(';;',';')
end

if #cliArgs.cpath > 0 then
cpathprefix = cliArgs.cpath
cpathprefix = cpathprefix:gsub('^%.([/%\\])', fpath .. '%1')
cpathprefix = cpathprefix:gsub(';%.([/%\\])', ';' .. fpath .. '%1')
package.cpath = (cpathprefix .. ';' .. package.cpath):gsub(';;',';')
end

local loaders = {}
if #cliArgs.loaders > 0 then
string.gsub(cliArgs.loaders, '([^,]+)', function(c) loaders[#loaders+1] = c end)
end

-- We report an error if the same tag appears in both `options.tags`
-- and `options.excluded_tags` because it does not make sense for the
-- user to tell Busted to include and exclude the same tests at the
-- same time.
for _, excluded in pairs(excludeTags) do
for _, included in pairs(tags) do
if excluded == included then
print('Error: Cannot use --tags and --exclude-tags for the same tags')
osexit(1, true)
end
end
end

-- watch for test errors
local failures = 0
local errors = 0
local quitOnError = cliArgs['no-keep-going']

busted.subscribe({ 'error', 'output' }, function(element, parent, message)
print('Error: Cannot load output library: ' .. element.name .. '\n' .. message)
return nil, true
end)

busted.subscribe({ 'error', 'helper' }, function(element, parent, message)
print('Error: Cannot load helper script: ' .. element.name .. '\n' .. message)
return nil, true
end)

busted.subscribe({ 'error' }, function(element, parent, message)
errors = errors + 1
busted.skipAll = quitOnError
return nil, true
end)

busted.subscribe({ 'failure' }, function(element, parent, message)
if element.descriptor == 'it' then
failures = failures + 1
else
errors = errors + 1
end
busted.skipAll = quitOnError
return nil, true
end)

-- Set up output handler to listen to events
local outputHandlerOptions = {
verbose = cliArgs.verbose,
suppressPending = cliArgs['suppress-pending'],
language = cliArgs.lang,
deferPrint = cliArgs['defer-print'],
arguments = utils.split(cliArgs.Xoutput or '', ',') or {}
}

local opath = utils.normpath(path.join(fpath, cliArgs.output))
local outputHandler = outputHandlerLoader(cliArgs.output, opath, outputHandlerOptions, busted, defaultOutput)
outputHandler:subscribe(outputHandlerOptions)

if cliArgs['enable-sound'] then
require 'busted.outputHandlers.sound'(outputHandlerOptions, busted)
end

-- Set up randomization options
busted.sort = cliArgs['sort-tests'] or cliArgs.sort
busted.randomize = cliArgs['shuffle-tests'] or cliArgs.shuffle
busted.randomseed = tonumber(cliArgs.seed) or os.time()

local getFullName = function(name)
local parent = busted.context.get()
local names = { name }

while parent and (parent.name or parent.descriptor) and
parent.descriptor ~= 'file' do
table.insert(names, 1, parent.name or parent.descriptor)
parent = busted.context.parent(parent)
end

return table.concat(names, ' ')
end

local hasTag = function(name, tag)
local found = name:find('#' .. tag)
return (found ~= nil)
end

local filterExcludeTags = function(name)
for i, tag in pairs(excludeTags) do
if hasTag(name, tag) then
return nil, false
end
end
return nil, true
end

local filterTags = function(name)
local fullname = getFullName(name)
for i, tag in pairs(tags) do
if hasTag(fullname, tag) then
return nil, true
end
end
return nil, (#tags == 0)
end

local filterOutNames = function(name)
local found = (getFullName(name):find(cliArgs['filter-out']) ~= nil)
return nil, not found
end

local filterNames = function(name)
local found = (getFullName(name):find(cliArgs.filter) ~= nil)
return nil, found
end

local printNameOnly = function(name, fn, trace)
local fullname = getFullName(name)
if trace and trace.what == 'Lua' then
print(trace.short_src .. ':' .. trace.currentline .. ': ' .. fullname)
else
print(fullname)
end
return nil, false
end

local ignoreAll = function()
return nil, false
end

local skipOnError = function()
return nil, (failures == 0 and errors == 0)
end

local applyFilter = function(descriptors, name, fn)
if cliArgs[name] and cliArgs[name] ~= '' then
for _, descriptor in ipairs(descriptors) do
busted.subscribe({ 'register', descriptor }, fn, { priority = 1 })
end
end
end

if cliArgs.list then
busted.subscribe({ 'suite', 'start' }, ignoreAll, { priority = 1 })
busted.subscribe({ 'suite', 'end' }, ignoreAll, { priority = 1 })
applyFilter({ 'setup', 'teardown', 'before_each', 'after_each' }, 'list', ignoreAll)
applyFilter({ 'it', 'pending' }, 'list', printNameOnly)
end

applyFilter({ 'setup', 'teardown', 'before_each', 'after_each' }, 'no-keep-going', skipOnError)
applyFilter({ 'file', 'describe', 'it', 'pending' }, 'no-keep-going', skipOnError)

-- The following filters are applied in reverse order
applyFilter({ 'it', 'pending' } , 'filter' , filterNames )
applyFilter({ 'describe', 'it', 'pending' }, 'filter-out' , filterOutNames )
applyFilter({ 'it', 'pending' } , 'tags' , filterTags )
applyFilter({ 'describe', 'it', 'pending' }, 'exclude-tags', filterExcludeTags)

-- Set up helper script
if cliArgs.helper and cliArgs.helper ~= '' then
local helperOptions = {
verbose = cliArgs.verbose,
language = cliArgs.lang,
arguments = utils.split(cliArgs.Xhelper or '', ',') or {}
}

local hpath = utils.normpath(path.join(fpath, cliArgs.helper))
helperLoader(cliArgs.helper, hpath, helperOptions, busted)
end

-- Set up test loader options
local testFileLoaderOptions = {
verbose = cliArgs.verbose,
sort = cliArgs['sort-files'] or cliArgs.sort,
shuffle = cliArgs['shuffle-files'] or cliArgs.shuffle,
recursive = not cliArgs['no-recursive'],
seed = busted.randomseed
}

-- Load test directory
local rootFile = cliArgs.ROOT and utils.normpath(path.join(fpath, cliArgs.ROOT)) or fileName
local pattern = cliArgs.pattern
local testFileLoader = require 'busted.modules.test_file_loader'(busted, loaders, testFileLoaderOptions)
local fileList = testFileLoader(rootFile, pattern)

if not cliArgs.ROOT then
local ctx = busted.context.get()
local file = busted.context.children(ctx)[1]
getmetatable(file.run).__call = info.func
end

busted.subscribe({'suite', 'reinitialize'}, function()
local oldctx = busted.context.get()
local children = busted.context.children(oldctx)

busted.context.clear()
local ctx = busted.context.get()
for k, v in pairs(oldctx) do
ctx[k] = v
end

for _, child in pairs(children) do
for descriptor, _ in pairs(busted.executors) do
child[descriptor] = nil
end
busted.context.attach(child)
end

busted.randomseed = tonumber(cliArgs.seed) or os.time()

return nil, true
end)

local runs = tonumber(cliArgs['repeat']) or 1
for i = 1, runs do
if i > 1 then
busted.publish({ 'suite', 'reinitialize' })
end

busted.publish({ 'suite', 'start' }, i, runs)
busted.execute()
busted.publish({ 'suite', 'end' }, i, runs)

if quitOnError and (failures > 0 or errors > 0) then
break
end
end

busted.publish({ 'exit' })

local exit = 0
if failures > 0 or errors > 0 then
exit = failures + errors
if exit > 255 then
exit = 255
end
end
osexit(exit, true)
end

+ 0
- 43
test/lua/busted/status.lua View File

@@ -1,43 +0,0 @@
local function get_status(status)
local smap = {
['success'] = 'success',
['pending'] = 'pending',
['failure'] = 'failure',
['error'] = 'error',
['true'] = 'success',
['false'] = 'failure',
['nil'] = 'error',
}
return smap[tostring(status)] or 'error'
end

return function(inital_status)
local objstat = get_status(inital_status)
local obj = {
success = function(self) return (objstat == 'success') end,
pending = function(self) return (objstat == 'pending') end,
failure = function(self) return (objstat == 'failure') end,
error = function(self) return (objstat == 'error') end,

get = function(self)
return objstat
end,

set = function(self, status)
objstat = get_status(status)
end,

update = function(self, status)
-- prefer current failure/error status over new status
status = get_status(status)
if objstat == 'success' or (objstat == 'pending' and status ~= 'success') then
objstat = status
end
end
}

return setmetatable(obj, {
__index = {},
__tostring = function(self) return objstat end
})
end

+ 0
- 51
test/lua/busted/utils.lua View File

@@ -1,53 +0,0 @@
local path = require 'pl.path'

math.randomseed(os.time())

local function normpath(fpath)
if type(fpath) ~= 'string' then
error(fpath .. ' is not a string')
end
local sep = '/'
if path.is_windows then
sep = '\\'
if fpath:match '^\\\\' then -- UNC
return '\\\\' .. normpath(fpath:sub(3))
end
fpath = fpath:gsub('/','\\')
end
local np_gen1, np_gen2 = '([^SEP]+)SEP(%.%.SEP?)', 'SEP+%.?SEP'
local np_pat1 = np_gen1:gsub('SEP', sep)
local np_pat2 = np_gen2:gsub('SEP', sep)
local k
repeat -- /./ -> /
fpath, k = fpath:gsub(np_pat2, sep)
until k == 0
repeat -- A/../ -> (empty)
local oldpath = fpath
fpath, k = fpath:gsub(np_pat1, function(d, up)
if d == '..' then return nil end
if d == '.' then return up end
return ''
end)
until k == 0 or oldpath == fpath
if fpath == '' then fpath = '.' end
return fpath
end

return {
split = require 'pl.utils'.split,

normpath = normpath,

shuffle = function(t, seed)
if seed then math.randomseed(seed) end
local n = #t
while n >= 2 do
local k = math.random(n)
t[n], t[k] = t[k], t[n]
n = n - 1
end
return t
end
}

+ 0
- 2
test/lua/rsa.lua View File

@@ -1,7 +1,5 @@
-- Test rsa signing

require "busted" ()

describe("rsa signarture test", function()
local rsa_privkey = require "rspamd_rsa_privkey"
local rsa_pubkey = require "rspamd_rsa_pubkey"

+ 32
- 36
test/rspamd_lua_test.c View File

@@ -29,15 +29,12 @@
static const char *lua_src = "./lua";

void
rspamd_lua_test_func (void)
rspamd_lua_test_func (int argc, char **argv)
{
lua_State *L = rspamd_lua_init (NULL);
gchar *lua_file;
gchar rp[PATH_MAX];
glob_t globbuf;
gchar *pattern;
guint i, len;
struct stat st;
gchar rp[PATH_MAX], path_buf[PATH_MAX];
const gchar *old_path;
guint i;

msg_info ("Starting lua tests");

@@ -46,40 +43,39 @@ rspamd_lua_test_func (void)
g_assert (0);
}

globbuf.gl_offs = 0;
len = strlen (rp) + sizeof ("*.lua") + 1;
pattern = g_malloc (len);
rspamd_snprintf (pattern, len, "%s/%s", rp, "*.lua");
/* Set lua path */
lua_getglobal (L, "package");
lua_getfield (L, -1, "path");
old_path = luaL_checkstring (L, -1);

if (glob (pattern, GLOB_DOOFFS, NULL, &globbuf) == 0) {
for (i = 0; i < globbuf.gl_pathc; i++) {
lua_file = globbuf.gl_pathv[i];
rspamd_snprintf (path_buf, sizeof (path_buf), "%s;%s/?.lua;%s/busted/?.lua",
old_path, rp, rp);
lua_pop (L, 1);
lua_pushstring (L, path_buf);
lua_setfield (L, -2, "path");
lua_pop (L, 1);

if (stat (lua_file, &st) == -1 || !S_ISREG (st.st_mode)) {
continue;
}
lua_getglobal (L, "arg");

if (strstr (lua_file, "busted") != NULL) {
/* Skip busted code itself */
continue;
}
if (lua_type (L, -1) != LUA_TTABLE) {
lua_newtable (L);
}

if (luaL_loadfile (L, lua_file) != 0) {
msg_err ("load test from %s failed", lua_file);
g_assert (0);
}
/* Now do it */
if (lua_pcall (L, 0, LUA_MULTRET, 0) != 0) {
msg_err ("run test from %s failed: %s", lua_file,
lua_tostring (L, -1));
g_assert (0);
}
}
globfree (&globbuf);
g_free (pattern);
for (i = 0; i < argc - 1; i ++) {
lua_pushinteger (L, i + 1);
lua_pushstring (L, argv[i]);
lua_settable (L, -3);
}
else {
msg_err ("glob for %s failed: %s", pattern, strerror (errno));

lua_setglobal (L, "arg");
lua_pop (L, 1);

rspamd_snprintf (path_buf, sizeof (path_buf),
"require 'busted.runner'({ batch = true })");
if (luaL_dostring (L, path_buf) != 0) {
rspamd_fprintf (stderr, "run test failed: %s", lua_tostring (L, -1));
g_assert (0);
}

exit (EXIT_SUCCESS);
}

+ 5
- 1
test/rspamd_test_suite.c View File

@@ -13,6 +13,11 @@ main (int argc, char **argv)
{
struct rspamd_config *cfg;

if (argc > 0 && strcmp (argv[1], "lua") == 0) {
/* Special lua testing mode */
rspamd_lua_test_func (argc - 1, &argv[2]);
}

g_test_init (&argc, &argv, NULL);

rspamd_main = (struct rspamd_main *)g_malloc (sizeof (struct rspamd_main));
@@ -56,7 +61,6 @@ main (int argc, char **argv)
g_test_add_func ("/rspamd/upstream", rspamd_upstream_test_func);
g_test_add_func ("/rspamd/shingles", rspamd_shingles_test_func);
g_test_add_func ("/rspamd/http", rspamd_http_test_func);
g_test_add_func ("/rspamd/lua", rspamd_lua_test_func);

g_test_run ();


+ 1
- 1
test/tests.h View File

@@ -41,6 +41,6 @@ void rspamd_shingles_test_func (void);

void rspamd_http_test_func (void);

void rspamd_lua_test_func (void);
void rspamd_lua_test_func (int argc, char **argv);

#endif

Loading…
Cancel
Save