local expect = require("lua_test.expect")
local ENV = _ENV or _G
ENV.__testContext = nil
local function chalkGreen(text)
if os.getenv("NO_COLOR") then
return text
else
return "\x1b[92m" .. text .. "\x1b[0m"
end
end
local function chalkRed(text)
if os.getenv("NO_COLOR") then
return text
else
return "\x1b[91m" .. text .. "\x1b[0m"
end
end
local function dumpTest(ctx, indent)
if ctx.children ~= nil then
print((" "):rep(indent) .. ctx.name .. "(" .. #ctx.children .. ")")
for _, child in ipairs(ctx.children) do
dumpTest(child, indent + 1)
end
else
print((" "):rep(indent) .. "*" .. ctx.name)
end
end
local function performTest(ctx, depth)
if ctx.func ~= nil then
local success, err = pcall(ctx.func)
ctx.result = {
success = success,
error = tostring(err),
}
else
ctx.result = { success = true }
for _, child in ipairs(ctx.children) do
if not performTest(child, depth + 1) then
ctx.result.success = false
end
end
end
return ctx.result.success
end
local function printTestResult(ctx, depth, path)
local errors = {}
local newPath = table.pack(table.unpack(path))
table.insert(newPath, ctx.name)
local resultMark = chalkGreen("✔")
if not ctx.result.success then
resultMark = chalkRed("✘")
end
if ctx.children ~= nil then
local successCount = 0
for _, child in ipairs(ctx.children) do
if child.result.success then
successCount = successCount + 1
end
end
local nameAndResult = table.concat({
(" "):rep(depth),
ctx.name,
" (",
successCount,
"/",
#ctx.children,
")",
resultMark,
}, "")
print(nameAndResult)
for _, child in ipairs(ctx.children) do
local childErrors = printTestResult(child, depth + 1, newPath)
for _, err in ipairs(childErrors) do
table.insert(errors, err)
end
end
print(nameAndResult)
else
print(table.concat({
(" "):rep(depth),
ctx.name,
" ",
resultMark,
}, ""))
if (not ctx.result.success) and ctx.result.error ~= nil then
table.insert(errors, {
name = table.concat(newPath, " > "),
error = ctx.result.error,
})
end
end
if depth == 0 then
if #errors == 0 then
print(chalkGreen("All tests passed."))
else
print(chalkRed(string.format("%d test(s) failed.", #errors)))
local printErrors = {}
for _, error in ipairs(errors) do
table.insert(printErrors, chalkRed("Error in " .. error.name) .. "\n" .. error.error)
end
print(table.concat(printErrors, "\n\n"))
end
end
return errors
end
local function describe(name, func)
local ctx = {
parent = nil,
name = name,
children = {},
result = nil,
}
if ENV.__testContext ~= nil then
table.insert(ENV.__testContext.children, ctx)
ctx.parent = ENV.__testContext
end
ENV.__testContext = ctx
func()
if ENV.__testContext.parent == nil then
local succeeded = performTest(ENV.__testContext, 0)
printTestResult(ENV.__testContext, 0, {})
ENV.__testContext = nil
if not succeeded then
os.exit(1)
end
else
ENV.__testContext = ENV.__testContext.parent
end
end
local function test(name, func)
if ENV.__testContext == nil then
ENV.__testContext = {
parent = nil,
name = "(anonymous)",
children = {},
result = nil,
}
end
table.insert(ENV.__testContext.children, {
name = name,
func = func,
result = nil,
})
end
return {
expect = expect,
test = test,
describe = describe,
}