Merge pull request #48 from 4O4/lust-update
Update lust and test runner script
This commit is contained in:
commit
d885bb6b86
130
tests/lust.lua
130
tests/lust.lua
@ -1,11 +1,13 @@
|
|||||||
-- lust - Lua test framework
|
-- lust v0.1.0 - Lua test framework
|
||||||
-- https://github.com/bjornbytes/lust
|
-- https://github.com/bjornbytes/lust
|
||||||
-- License - MIT, see LICENSE for details.
|
-- MIT LICENSE
|
||||||
|
|
||||||
local lust = {}
|
local lust = {}
|
||||||
lust.level = 0
|
lust.level = 0
|
||||||
lust.passes = 0
|
lust.passes = 0
|
||||||
lust.errors = 0
|
lust.errors = 0
|
||||||
|
lust.befores = {}
|
||||||
|
lust.afters = {}
|
||||||
|
|
||||||
local red = string.char(27) .. '[31m'
|
local red = string.char(27) .. '[31m'
|
||||||
local green = string.char(27) .. '[32m'
|
local green = string.char(27) .. '[32m'
|
||||||
@ -16,11 +18,20 @@ function lust.describe(name, fn)
|
|||||||
print(indent() .. name)
|
print(indent() .. name)
|
||||||
lust.level = lust.level + 1
|
lust.level = lust.level + 1
|
||||||
fn()
|
fn()
|
||||||
|
lust.befores[lust.level] = {}
|
||||||
|
lust.afters[lust.level] = {}
|
||||||
lust.level = lust.level - 1
|
lust.level = lust.level - 1
|
||||||
end
|
end
|
||||||
|
|
||||||
function lust.it(name, fn)
|
function lust.it(name, fn)
|
||||||
if type(lust.onbefore) == 'function' then lust.onbefore(name) end
|
for level = 1, lust.level do
|
||||||
|
if lust.befores[level] then
|
||||||
|
for i = 1, #lust.befores[level] do
|
||||||
|
lust.befores[level][i](name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local success, err = pcall(fn)
|
local success, err = pcall(fn)
|
||||||
if success then lust.passes = lust.passes + 1
|
if success then lust.passes = lust.passes + 1
|
||||||
else lust.errors = lust.errors + 1 end
|
else lust.errors = lust.errors + 1 end
|
||||||
@ -30,24 +41,39 @@ function lust.it(name, fn)
|
|||||||
if err then
|
if err then
|
||||||
print(indent(lust.level + 1) .. red .. err .. normal)
|
print(indent(lust.level + 1) .. red .. err .. normal)
|
||||||
end
|
end
|
||||||
if type(lust.onafter) == 'function' then lust.onafter(name) end
|
|
||||||
|
for level = 1, lust.level do
|
||||||
|
if lust.afters[level] then
|
||||||
|
for i = 1, #lust.afters[level] do
|
||||||
|
lust.afters[level][i](name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function lust.before(fn)
|
function lust.before(fn)
|
||||||
assert(fn == nil or type(fn) == 'function', 'Must pass nil or a function to lust.before')
|
lust.befores[lust.level] = lust.befores[lust.level] or {}
|
||||||
lust.onbefore = fn
|
table.insert(lust.befores[lust.level], fn)
|
||||||
end
|
end
|
||||||
|
|
||||||
function lust.after(fn)
|
function lust.after(fn)
|
||||||
assert(fn == nil or type(fn) == 'function', 'Must pass nil or a function to lust.after')
|
lust.afters[lust.level] = lust.afters[lust.level] or {}
|
||||||
lust.onafter = fn
|
table.insert(lust.afters[lust.level], fn)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Assertions
|
-- Assertions
|
||||||
local function isa(v, x)
|
local function isa(v, x)
|
||||||
if type(x) == 'string' then return type(v) == x, tostring(v) .. ' is not a ' .. x
|
if type(x) == 'string' then
|
||||||
|
return type(v) == x,
|
||||||
|
'expected ' .. tostring(v) .. ' to be a ' .. x,
|
||||||
|
'expected ' .. tostring(v) .. ' to not be a ' .. x
|
||||||
elseif type(x) == 'table' then
|
elseif type(x) == 'table' then
|
||||||
if type(v) ~= 'table' then return false, tostring(v) .. ' is not a ' .. tostring(x) end
|
if type(v) ~= 'table' then
|
||||||
|
return false,
|
||||||
|
'expected ' .. tostring(v) .. ' to be a ' .. tostring(x),
|
||||||
|
'expected ' .. tostring(v) .. ' to not be a ' .. tostring(x)
|
||||||
|
end
|
||||||
|
|
||||||
local seen = {}
|
local seen = {}
|
||||||
local meta = v
|
local meta = v
|
||||||
while meta and not seen[meta] do
|
while meta and not seen[meta] do
|
||||||
@ -55,9 +81,13 @@ local function isa(v, x)
|
|||||||
seen[meta] = true
|
seen[meta] = true
|
||||||
meta = getmetatable(meta) and getmetatable(meta).__index
|
meta = getmetatable(meta) and getmetatable(meta).__index
|
||||||
end
|
end
|
||||||
return false, tostring(v) .. ' is not a ' .. tostring(x)
|
|
||||||
|
return false,
|
||||||
|
'expected ' .. tostring(v) .. ' to be a ' .. tostring(x),
|
||||||
|
'expected ' .. tostring(v) .. ' to not be a ' .. tostring(x)
|
||||||
end
|
end
|
||||||
return false, 'invalid type ' .. tostring(x)
|
|
||||||
|
error('invalid type ' .. tostring(x))
|
||||||
end
|
end
|
||||||
|
|
||||||
local function has(t, x)
|
local function has(t, x)
|
||||||
@ -70,7 +100,6 @@ end
|
|||||||
local function strict_eq(t1, t2)
|
local function strict_eq(t1, t2)
|
||||||
if type(t1) ~= type(t2) then return false end
|
if type(t1) ~= type(t2) then return false end
|
||||||
if type(t1) ~= 'table' then return t1 == t2 end
|
if type(t1) ~= 'table' then return t1 == t2 end
|
||||||
if #t1 ~= #t2 then return false end
|
|
||||||
for k, _ in pairs(t1) do
|
for k, _ in pairs(t1) do
|
||||||
if not strict_eq(t1[k], t2[k]) then return false end
|
if not strict_eq(t1[k], t2[k]) then return false end
|
||||||
end
|
end
|
||||||
@ -81,25 +110,57 @@ local function strict_eq(t1, t2)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local paths = {
|
local paths = {
|
||||||
[''] = {'to', 'to_not'},
|
[''] = { 'to', 'to_not' },
|
||||||
to = {'have', 'equal', 'be', 'exist', 'fail'},
|
to = { 'have', 'equal', 'be', 'exist', 'fail' },
|
||||||
to_not = {'have', 'equal', 'be', 'exist', 'fail', chain = function(a) a.negate = not a.negate end},
|
to_not = { 'have', 'equal', 'be', 'exist', 'fail', chain = function(a) a.negate = not a.negate end },
|
||||||
be = {'a', 'an', 'truthy', 'falsy', f = function(v, x)
|
a = { test = isa },
|
||||||
return v == x, tostring(v) .. ' and ' .. tostring(x) .. ' are not equal'
|
an = { test = isa },
|
||||||
end},
|
be = { 'a', 'an', 'truthy',
|
||||||
a = {f = isa},
|
test = function(v, x)
|
||||||
an = {f = isa},
|
return v == x,
|
||||||
exist = {f = function(v) return v ~= nil, tostring(v) .. ' is nil' end},
|
'expected ' .. tostring(v) .. ' and ' .. tostring(x) .. ' to be equal',
|
||||||
truthy = {f = function(v) return v, tostring(v) .. ' is not truthy' end},
|
'expected ' .. tostring(v) .. ' and ' .. tostring(x) .. ' to not be equal'
|
||||||
falsy = {f = function(v) return not v, tostring(v) .. ' is not falsy' end},
|
|
||||||
equal = {f = function(v, x) return strict_eq(v, x), tostring(v) .. ' and ' .. tostring(x) .. ' are not strictly equal' end},
|
|
||||||
have = {
|
|
||||||
f = function(v, x)
|
|
||||||
if type(v) ~= 'table' then return false, 'table "' .. tostring(v) .. '" is not a table' end
|
|
||||||
return has(v, x), 'table "' .. tostring(v) .. '" does not have ' .. tostring(x)
|
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
fail = {f = function(v) return not pcall(v), tostring(v) .. ' did not fail' end}
|
exist = {
|
||||||
|
test = function(v)
|
||||||
|
return v ~= nil,
|
||||||
|
'expected ' .. tostring(v) .. ' to exist',
|
||||||
|
'expected ' .. tostring(v) .. ' to not exist'
|
||||||
|
end
|
||||||
|
},
|
||||||
|
truthy = {
|
||||||
|
test = function(v)
|
||||||
|
return v,
|
||||||
|
'expected ' .. tostring(v) .. ' to be truthy',
|
||||||
|
'expected ' .. tostring(v) .. ' to not be truthy'
|
||||||
|
end
|
||||||
|
},
|
||||||
|
equal = {
|
||||||
|
test = function(v, x)
|
||||||
|
return strict_eq(v, x),
|
||||||
|
'expected ' .. tostring(v) .. ' and ' .. tostring(x) .. ' to be exactly equal',
|
||||||
|
'expected ' .. tostring(v) .. ' and ' .. tostring(x) .. ' to not be exactly equal'
|
||||||
|
end
|
||||||
|
},
|
||||||
|
have = {
|
||||||
|
test = function(v, x)
|
||||||
|
if type(v) ~= 'table' then
|
||||||
|
error('expected ' .. tostring(v) .. ' to be a table')
|
||||||
|
end
|
||||||
|
|
||||||
|
return has(v, x),
|
||||||
|
'expected ' .. tostring(v) .. ' to contain ' .. tostring(x),
|
||||||
|
'expected ' .. tostring(v) .. ' to not contain ' .. tostring(x)
|
||||||
|
end
|
||||||
|
},
|
||||||
|
fail = {
|
||||||
|
test = function(v)
|
||||||
|
return not pcall(v),
|
||||||
|
'expected ' .. tostring(v) .. ' to fail',
|
||||||
|
'expected ' .. tostring(v) .. ' to not fail'
|
||||||
|
end
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function lust.expect(v)
|
function lust.expect(v)
|
||||||
@ -119,9 +180,12 @@ function lust.expect(v)
|
|||||||
return rawget(t, k)
|
return rawget(t, k)
|
||||||
end,
|
end,
|
||||||
__call = function(t, ...)
|
__call = function(t, ...)
|
||||||
if paths[t.action].f then
|
if paths[t.action].test then
|
||||||
local res, err = paths[t.action].f(t.val, ...)
|
local res, err, nerr = paths[t.action].test(t.val, ...)
|
||||||
if assertion.negate then res = not res end
|
if assertion.negate then
|
||||||
|
res = not res
|
||||||
|
err = nerr or err
|
||||||
|
end
|
||||||
if not res then
|
if not res then
|
||||||
error(err or 'unknown failure', 2)
|
error(err or 'unknown failure', 2)
|
||||||
end
|
end
|
||||||
|
@ -6,18 +6,22 @@ for _, fn in pairs({'describe', 'it', 'test', 'expect', 'spy', 'before', 'after'
|
|||||||
end
|
end
|
||||||
|
|
||||||
observableSpy = function(observable)
|
observableSpy = function(observable)
|
||||||
local observer = Rx.Observer.create(_, function() end, _)
|
local onNextSpy = spy()
|
||||||
local onNext = spy(observer, '_onNext')
|
local onErrorSpy = spy()
|
||||||
local onError = spy(observer, '_onError')
|
local onCompletedSpy = spy()
|
||||||
local onCompleted = spy(observer, '_onCompleted')
|
local observer = Rx.Observer.create(
|
||||||
|
function (...) onNextSpy(...) end,
|
||||||
|
function (...) onErrorSpy(...) end,
|
||||||
|
function () onCompletedSpy() end
|
||||||
|
)
|
||||||
observable:subscribe(observer)
|
observable:subscribe(observer)
|
||||||
return onNext, onError, onCompleted
|
return onNextSpy, onErrorSpy, onCompletedSpy
|
||||||
end
|
end
|
||||||
|
|
||||||
lust.paths['produce'] = {
|
lust.paths['produce'] = {
|
||||||
'nothing',
|
'nothing',
|
||||||
'error',
|
'error',
|
||||||
f = function(observable, ...)
|
test = function(observable, ...)
|
||||||
local args = {...}
|
local args = {...}
|
||||||
local values
|
local values
|
||||||
if type(args[1]) ~= 'table' then
|
if type(args[1]) ~= 'table' then
|
||||||
@ -39,7 +43,7 @@ lust.paths['produce'] = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lust.paths['nothing'] = {
|
lust.paths['nothing'] = {
|
||||||
f = function(observable)
|
test = function(observable)
|
||||||
local onNext, onError, onCompleted = observableSpy(observable)
|
local onNext, onError, onCompleted = observableSpy(observable)
|
||||||
expect(observable).to.be.an(Rx.Observable)
|
expect(observable).to.be.an(Rx.Observable)
|
||||||
expect(#onNext).to.equal(0)
|
expect(#onNext).to.equal(0)
|
||||||
@ -50,7 +54,7 @@ lust.paths['nothing'] = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lust.paths['error'] = {
|
lust.paths['error'] = {
|
||||||
f = function(observable)
|
test = function(observable)
|
||||||
local _, onError = observableSpy(observable)
|
local _, onError = observableSpy(observable)
|
||||||
expect(observable).to.be.an(Rx.Observable)
|
expect(observable).to.be.an(Rx.Observable)
|
||||||
expect(#onError).to.equal(1)
|
expect(#onError).to.equal(1)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user