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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
local uv = require('luv')
local dump = require('lib/utils').dump
local stdout = require('lib/utils').stdout
local function protect(...)
local n = select('#', ...)
local arguments = {...}
for i = 1, n do
arguments[i] = tostring(arguments[i])
end
local text = table.concat(arguments, "\t")
text = " " .. string.gsub(text, "\n", "\n ")
print(text)
end
local function pprotect(...)
local n = select('#', ...)
local arguments = { ... }
for i = 1, n do
arguments[i] = dump(arguments[i])
end
protect(table.concat(arguments, "\t"))
end
local tests = {};
local function run()
local passed = 0
if #tests < 1 then
error("No tests specified!")
end
print("1.." .. #tests)
for i = 1, #tests do
local test = tests[i]
local cwd = uv.cwd()
local pass, err = xpcall(function ()
local expected = 0
local function expect(fn, count)
expected = expected + (count or 1)
return function (...)
expected = expected - 1
local ret = fn(...)
collectgarbage()
return ret
end
end
test.fn(protect, pprotect, expect, uv)
collectgarbage()
uv.run()
collectgarbage()
if expected > 0 then
error("Missing " .. expected .. " expected call" .. (expected == 1 and "" or "s"))
elseif expected < 0 then
error("Found " .. -expected .. " unexpected call" .. (expected == -1 and "" or "s"))
end
collectgarbage()
local unclosed = 0
uv.walk(function (handle)
if handle == stdout then return end
unclosed = unclosed + 1
print("UNCLOSED", handle)
end)
if unclosed > 0 then
error(unclosed .. " unclosed handle" .. (unclosed == 1 and "" or "s"))
end
if uv.cwd() ~= cwd then
error("Test moved cwd from " .. cwd .. " to " .. uv.cwd())
end
collectgarbage()
end, debug.traceback)
-- Flush out any more opened handles
uv.stop()
uv.walk(function (handle)
if handle == stdout then return end
if not uv.is_closing(handle) then uv.close(handle) end
end)
uv.run()
uv.chdir(cwd)
if pass then
print("ok " .. i .. " " .. test.name)
passed = passed + 1
else
protect(err)
print("not ok " .. i .. " " .. test.name)
end
end
local failed = #tests - passed
if failed == 0 then
print("# All tests passed")
else
print("#" .. failed .. " failed test" .. (failed == 1 and "" or "s"))
end
-- Close all then handles, including stdout
uv.walk(uv.close)
uv.run()
os.exit(-failed)
end
local single = true
local prefix
local function tap(suite)
if type(suite) == "function" then
-- Pass in suite directly for single mode
suite(function (name, fn)
if prefix then
name = prefix .. ' - ' .. name
end
tests[#tests + 1] = {
name = name,
fn = fn
}
end)
prefix = nil
elseif type(suite) == "string" then
prefix = suite
single = false
else
-- Or pass in false to collect several runs of tests
-- And then pass in true in a later call to flush tests queue.
single = suite
end
if single then run() end
end
--[[
-- Sample Usage
local passed, failed, total = tap(function (test)
test("add 1 to 2", function(print)
print("Adding 1 to 2")
assert(1 + 2 == 3)
end)
test("close handle", function (print, p, expect, uv)
local handle = uv.new_timer()
uv.close(handle, expect(function (self)
assert(self == handle)
end))
end)
test("simulate failure", function ()
error("Oopsie!")
end)
end)
]]
return tap
|