-
Notifications
You must be signed in to change notification settings - Fork 25
/
testhelper.lua
139 lines (117 loc) · 3.54 KB
/
testhelper.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
function mergetests(name, tests)
local parent = {name = name, failcount = 0, okcount = 0}
for k, testcase in ipairs(tests) do
local status = testcase.status
local category = status and "ok" or "fail"
parent[category] = parent[category] or {}
table.insert(parent[category], testcase)
parent.failcount = parent.failcount + testcase.failcount
parent.okcount = parent.okcount + testcase.okcount
end
parent.status = parent.failcount == 0
return parent
end
local parent
local function createTestcase(name)
if type(name) ~= "string" then
name = debugstacktrace(nil, 3, 1):match("([a-z0-9%.]+:[0-9]+)")
end
local testcase = {name = name, okcount = 0, failcount = 0}
return testcase
end
local function storeTestcase(testcase, status, errormessage, stacktrace)
testcase.okcount = testcase.okcount + (status and 1 or 0)
testcase.failcount = testcase.failcount + (status and 0 or 1)
local category = "ok"
if status and testcase.fail then
category = "fail"
status = false
errormessage, stacktrace = nil
elseif not status then
category = "fail"
testcase.error = errormessage
testcase.stacktrace = stacktrace
end
testcase.status = status
if parent then
parent[category] = parent[category] or {}
table.insert(parent[category], testcase)
parent.okcount = parent.okcount + testcase.okcount
parent.failcount = parent.failcount + testcase.failcount
end
assert(type(testcase) == "table")
return testcase
end
function testCall(name, f, ...)
if type(name) == "function" then
name, f = f, name
end
assert(type(f) == "function", "expected a function, but got " .. tostring(f))
local testcase = createTestcase(name)
local oldParent = parent
parent = testcase
local status, errormessage, stacktrace = pcall(f, ...)
if status then
errormessage, stacktrace = nil, nil
end
parent = oldParent
local stacktrace2 = debugstacktrace(nil, 3, nil, 1)
assert(stacktrace == nil or type(stacktrace) == "string", type(stacktrace))
assert(type(stacktrace2) == "string")
storeTestcase(testcase, status, errormessage, (stacktrace or "") .. stacktrace2)
assert(type(testcase) == "table")
return testcase
end
function testAssert(name, condition, errormessage)
if type(name) ~= "string" then
condition, errormessage = name, condition
end
if not errormessage then
errormessage = "Assertion failed"
end
local testcase = createTestcase(name)
storeTestcase(testcase, condition, errormessage, debugstacktrace(nil, 2, nil, 1))
end
local template, template_test
function string:gsubplain(pattern, repl, n)
return self:gsub(pattern, string.gsub(repl, "%%", "%%%%"), n)
end
local append = table.insert
local function indentstring(indent, s)
local tmp = string.gsub(s, "\n", "\n" .. indent)
return indent .. tmp:sub(1, #tmp - #indent)
end
function generatereport(tests)
local printTest
local function printSubtests(test, output, indent)
if test.fail then
for k, v in ipairs(test.fail) do
printTest(v, output, indent)
end
end
return output
end
function printTest(test, output, indent)
if test.status then
return output
end
local error = test.error
if test.fail then
error = ""
end
if error then
append(output, indent)
append(output, test.name or "<nameless>")
append(output, ": ")
append(output, error)
append(output, "\n")
if test.stacktrace then
append(output, indentstring(indent .. " ", test.stacktrace))
end
end
return printSubtests(test, output, indent .. " ")
end
local output = printSubtests(tests, {}, "")
local text = table.concat(output)
return text, tests.okcount, tests.failcount
end