summaryrefslogtreecommitdiffstats
path: root/tests/config/tapered/src/tapered.lua
blob: de648c290ecb1d254e8a2eb53607ed7c25e8cf8d (plain)
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
-- vim: et:ts=2:sw=2
-- Helper variables and functions
local get_info = debug.getinfo
local pcall = pcall
local slice = string.sub
local sprintf = string.format
local str_find = string.find
local tonumber = tonumber
-- Lua 5.3 moved unpack to table.unpack
local unpack = unpack or table.unpack
local write = io.write
local rawget = rawget
local getmetatable = getmetatable
local exit = os.exit
local krprint = require("krprint")

---- Helper methods

--- C-like printf method
local printf = function(fmt, ...)
  write(sprintf(fmt, ...))
end

local printdiff = function(func_name, actual, expected)
  printf("Assertion %s() failed for test below (marked 'not ok'):\n", func_name)
  printf("Expected: %s\n", krprint.pprint(expected))
  printf("Got: %s\n", krprint.pprint(actual))
end

--- Compare potentially complex tables or objects
--
-- Ideas here are taken from [Penlight][p], [Underscore][u], [cwtest][cw], and
-- [luassert][l].
-- [p]: https://github.com/stevedonovan/Penlight
-- [u]: https://github.com/mirven/underscore.lua
-- [cw]: https://github.com/catwell/cwtest
-- [l]: https://github.com/Olivine-Labs/luassert
--
-- Predeclare both function names
local keyvaluesame
local deepsame
--
--- keyvaluesame(table, table) => true or false
-- Helper method to compare all the keys and values of a table
keyvaluesame = function (t1, t2)
  for k1, v1 in pairs(t1) do
    local v2 = t2[k1]
    if v2 == nil or not deepsame(v1, v2) then return false end
  end

  -- Check for any keys present in t2 but not t1
  for k2, _ in pairs(t2) do
    if t1[k2] == nil then return false end
  end

  return true
end
--
--- deepsame(item, item) => true or false
-- Compare two items of any type for identity
deepsame = function (t1, t2)
  local ty1, ty2 = type(t1), type(t2)
  if ty1 ~= ty2 then return false end
  if ty1 ~= 'table' then return t1 == t2 end

  -- If ._eq is found, use == and end quickly.
  -- As of Lua 5.3 == only cares if **one** of the two items has a __eq
  -- metamethod. Penlight, underscore and cwtest take the same approach,
  -- so I will as well.
  local eq = rawget(getmetatable(t1) or {}, '__eq')
  if (type(eq) == 'function') then
    return not not eq(t1, t2)
  else
    return keyvaluesame(t1, t2)
  end
end

---- tapered test suite

local exit_status = 0
local test_count = 0
local debug_level = 3

-- All other tests are defined in terms of this primitive, which is
-- kept private.
local _test = function (exp, msg)
  test_count = test_count + 1

  if msg then
    msg = sprintf(" - %s", msg)
  else
    msg = ''
  end

  if exp then
    printf("ok %s%s\n", test_count, msg)
  else
    exit_status = 1 + exit_status
    printf("not ok %s%s\n", test_count, msg)
    local info = get_info(debug_level)
    printf("# Trouble in %s around line %s\n",
           slice(info.source, 2), info.currentline)
  end
end

local ok = function (expression, msg)
  _test(expression, msg)
end

local nok = function (expression, msg)
  _test(not expression, msg)
end

local is = function (actual, expected, msg)
  local result = actual == expected;
  if not result then
    printdiff("is", actual, expected)
  end
  _test(result, msg)
end

local isnt = function (actual, expected, msg)
  _test(actual ~= expected, msg)
end

local same = function (actual, expected, msg)
  local result = deepsame(actual, expected)
  if not result then
    printdiff("same", actual, expected)
  end
  _test(result, msg)
end

local like = function (str, pattern, msg)
  _test(str_find(str, pattern), msg)
end

local unlike = function (str, pattern, msg)
  _test(not str_find(str, pattern), msg)
end

local pass = function (msg)
  _test(true, msg)
end

local fail = function (msg)
  _test(false, msg)
end

local boom = function (func, args, msg)
  local err, errmsg
  err, errmsg = pcall(func, unpack(args))
  _test(not err, msg)
  if not err and type(errmsg) == 'string' then
    printf('# Got this error: "%s"\n', errmsg)
  end
end

local done = function (n)
  local expected = tonumber(n)
  if not expected or test_count == expected then
    printf('1..%d\n', test_count)
  elseif expected ~= test_count then
    exit_status = 1 + exit_status
    local s
    if expected == 1 then s = '' else s = 's' end
    printf("# Bad plan. You planned %d test%s but ran %d\n",
      expected, s, test_count)
  end
  exit(exit_status)
end

local version = function ()
  return "2.3.0"
end

local author = function ()
  return "Peter Aronoff"
end

local url = function ()
  return "https://github.com/telemachus/tapered"
end

local license = function ()
  return "BSD 3-Clause"
end

return {
  ok = ok,
  nok = nok,
  is = is,
  isnt = isnt,
  same = same,
  like = like,
  unlike = unlike,
  pass = pass,
  fail = fail,
  boom = boom,
  done = done,
  version = version,
  author = author,
  url = url,
  license = license
}