This repository has been archived by the owner on Mar 22, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
tasty.lua
145 lines (121 loc) · 3.14 KB
/
tasty.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
139
140
141
142
143
144
145
------------------------------------------------------------------------
--- Assertors
local assertors = {}
local function register_assertor (name, callback, error_message)
assertors[name] = function (...)
local bool = callback(...)
if bool then
return
end
local success, formatted_message =
pcall(string.format, error_message, ...)
if not success then
error('assertion failed, and error message could not be formatted', 2)
end
error('\n' .. formatted_message or 'assertion failed!', 2)
end
end
--- Value is truthy
local function is_truthy (x)
return x ~= false and x ~= nil
end
--- Value is falsy
local function is_falsy (x)
return not is_truthy(x)
end
--- Value is nil
local function is_nil (x)
return x == nil
end
--- Values are equal
local function are_equal (x, y)
return x == y
end
local function cycle_aware_compare(t1, t2, cache)
if cache[t1] and cache[t1][t2] then return true end
local ty1 = type(t1)
local ty2 = type(t2)
-- if t1 == t2 then return true end
if ty1 ~= ty2 then return false end
if ty1 ~= 'table' then return t1 == t2 end
-- Check tables have the same set of keys
for k1 in pairs(t1) do
if t2[k1] == nil then return false end
end
for k2 in pairs(t2) do
if t1[k2] == nil then return false end
end
-- cache comparison result
cache[t1] = cache[t1] or {}
cache[t1][t2] = true
for k1, v1 in pairs(t1) do
local v2 = t2[k1]
if not cycle_aware_compare(v1, v2, cache) then return false end
end
return true
end
--- Check if tables are the same
local function are_same(x, y)
return cycle_aware_compare(x, y, {})
end
local function error_matches(fn, pattern)
local success, msg = pcall(fn)
if success then
return false
end
return tostring(msg):match(pattern)
end
register_assertor('is_truthy', is_truthy, "expected a truthy value, got %s")
register_assertor('is_falsy', is_falsy, "expected a falsy value, got %s")
register_assertor('is_nil', is_nil, "expected nil, got %s")
register_assertor('are_same', are_same, 'expected same values, got %s and %s')
register_assertor(
'are_equal',
are_equal,
"expected values to be equal, got '%s' and '%s'"
)
register_assertor(
'error_matches',
error_matches,
'no error matching the given pattern was raised'
)
------------------------------------------------------------------------
local ok = true
local function test_success (name)
return {
name = name,
result = ok,
}
end
local function test_failure (name, err_msg)
return {
name = name,
result = err_msg,
}
end
------------------------------------------------------------------------
-- Test definitions
local function test_case (name, callback)
local success, err_msg = pcall(callback)
return success
and test_success(name)
or test_failure(name, err_msg)
end
local function test_group (name, tests)
if tests == nil then
-- let's try to curry
return function (tests_)
return tests_ and test_group(name, tests_) or error('no tests')
end
end
return {
name = name,
result = tests,
}
end
return {
assert = assertors,
ok = ok,
test_case = test_case,
test_group = test_group
}