blob: 2c7a65b0898acd0f8c6d7bd82054c02e69974200 [file] [log] [blame]
local json = require("json")
local lunit = require("lunit")
local math = require("math")
local testutil = require("testutil")
local encode = json.encode
-- DECODE NOT 'local' due to requirement for testutil to access it
decode = json.decode.getDecoder(false)
module("lunit-calls", lunit.testcase, package.seeall)
function setup()
-- Ensure that the decoder is reset
_G["decode"] = json.decode.getDecoder(false)
end
local values = {
0,
1,
0.2,
"Hello",
true,
{hi=true},
{1,2}
}
function test_identity()
local function testFunction(capturedName, ...)
assert_equal('call', capturedName)
return (...)
end
local strict = {
calls = { defs = {
call = testFunction
} }
}
local decode = json.decode.getDecoder(strict)
for i, v in ipairs(values) do
local str = "call(" .. encode(v) .. ")"
local decoded = decode(str)
if type(decoded) == 'table' then
for k2, v2 in pairs(v) do
assert_equal(v2, decoded[k2])
decoded[k2] = nil
end
assert_nil(next(decoded))
else
assert_equal(v, decoded)
end
end
end
-- Test for a function that throws
function test_function_failure()
local function testFunction(...)
error("CANNOT CONTINUE")
end
local strict = {
calls = { defs = {
call = testFunction
} }
}
local decode = json.decode.getDecoder(strict)
for i, v in ipairs(values) do
local str = "call(" .. encode(v) .. ")"
assert_error(function()
decode(str)
end)
end
end
-- Test for a function that is not a function
function test_not_a_function_fail()
local notFunction = {
0/0, 1/0, -1/0, 0, 1, "Hello", {}, coroutine.create(function() end)
}
for _, v in ipairs(notFunction) do
assert_error(function()
local strict = {
calls = { defs = {
call = v
}, allowUndefined = false }
}
json.decode.getDecoder(strict)
end)
end
end
function test_not_permitted_fail()
local strict = {
calls = {
defs = { call = false }
}
}
local decoder = json.decode.getDecoder(strict)
assert_error(function()
decoder("call(1)")
end)
end
function test_permitted()
local strict = {
calls = {
defs = { call = true }
}
}
local decoder = json.decode.getDecoder(strict)
assert(decoder("call(1)").name == 'call')
end
function test_not_defined_fail()
local decoder = json.decode.getDecoder({
calls = {
allowUndefined = false
}
})
assert_error(function()
decoder("call(1)")
end)
end
function test_not_defined_succeed()
local decoder = json.decode.getDecoder({
calls = {
allowUndefined = true
}
})
assert(decoder("call(1)").name == 'call')
end
-- Test for a name that is not a string
function test_name_not_string()
local notString = {
true, false, 0/0, 1/0, -1/0, 0, 1, {}, function() end, coroutine.create(function() end)
}
for _, v in ipairs(notString) do
assert_error(function()
local defs = {
[v] = function() end
}
local strict = {
calls = { defs = defs }
}
json.decode.getDecoder(strict)
end)
end
end
-- Test for a name that is a string or a pattern
function test_name_matches_string_or_pattern()
local matchedValues = {
["mystring"] = "mystring",
[lpeg.C(lpeg.P("m") * (lpeg.P("y") + lpeg.P("Y")) * "string")] = "mystring",
[lpeg.C(lpeg.P("m") * (lpeg.P("y") + lpeg.P("Y")) * "string")] = "mYstring"
}
for pattern, value in pairs(matchedValues) do
local matched = false
local function mustBeCalled(capturedName, ...)
assert_equal(value, capturedName)
matched = true
end
matched = false
local strict = {
calls = { defs = {
[pattern] = mustBeCalled
} }
}
json.decode.getDecoder(strict)(value .. "(true)")
assert_true(matched, "Value <" .. value .. "> did not match the given pattern")
end
end