Improvements all around
This commit is contained in:
parent
e11ec95fb5
commit
e994147512
|
@ -3,6 +3,14 @@ local lexer = assert(require((... and select('1', ...):match('.+%.') or '')..'lu
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local EXPECTED_GLOBAL = { -- TODO: Expand with other functions.
|
||||||
|
['type'] = 'function',
|
||||||
|
['tonumber'] = 'function',
|
||||||
|
['math'] = 'table',
|
||||||
|
}
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
local function get_value_of_string (string_str)
|
local function get_value_of_string (string_str)
|
||||||
if string_str:sub(1, 1) == '"' or string_str:sub(1, 1) == '\'' then
|
if string_str:sub(1, 1) == '"' or string_str:sub(1, 1) == '\'' then
|
||||||
return string_str:sub(2, -2)
|
return string_str:sub(2, -2)
|
||||||
|
@ -59,7 +67,8 @@ local function get_variable (var_name, info)
|
||||||
until not name
|
until not name
|
||||||
|
|
||||||
-- Global
|
-- Global
|
||||||
return getfenv(info.func)[var_name], 'global'
|
local env = getfenv(info.func)[var_name]
|
||||||
|
return env, 'global'
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_value_from_lvalue (lvalue, info)
|
local function get_value_from_lvalue (lvalue, info)
|
||||||
|
@ -96,6 +105,13 @@ local function parse (tokens)
|
||||||
[1] = get_value_token(tokens[1]),
|
[1] = get_value_token(tokens[1]),
|
||||||
[2] = get_value_token(tokens[3])
|
[2] = get_value_token(tokens[3])
|
||||||
}
|
}
|
||||||
|
elseif #tokens == 4 and tokens[1].token == 'HASHTAG' and VALUE_TOKEN[tokens[2].token] and COMPARE_BINOP[tokens[3].token] and VALUE_TOKEN[tokens[4].token] then
|
||||||
|
return {
|
||||||
|
exp = 'COMPARE',
|
||||||
|
binop = tokens[3].token,
|
||||||
|
[1] = { exp = 'UNOP', get_value_token(tokens[2]) } ,
|
||||||
|
[2] = get_value_token(tokens[4])
|
||||||
|
}
|
||||||
elseif #tokens == 3 and tokens[1].token == 'IDENTIFIER' and tokens[2].token == 'DOT' and tokens[3].token == 'IDENTIFIER' then
|
elseif #tokens == 3 and tokens[1].token == 'IDENTIFIER' and tokens[2].token == 'DOT' and tokens[3].token == 'IDENTIFIER' then
|
||||||
return { exp = 'LVALUE', tokens[1].text, { exp = 'STRING', value = tokens[3].text } }
|
return { exp = 'LVALUE', tokens[1].text, { exp = 'STRING', value = tokens[3].text } }
|
||||||
elseif #tokens == 4 and tokens[1].token == 'IDENTIFIER' and tokens[2].token == 'LBRACK' and VALUE_TOKEN[tokens[3].token] and tokens[4].token == 'RBRACK' then
|
elseif #tokens == 4 and tokens[1].token == 'IDENTIFIER' and tokens[2].token == 'LBRACK' and VALUE_TOKEN[tokens[3].token] and tokens[4].token == 'RBRACK' then
|
||||||
|
@ -103,17 +119,31 @@ local function parse (tokens)
|
||||||
elseif #tokens == 1 then
|
elseif #tokens == 1 then
|
||||||
return get_value_token(tokens[1])
|
return get_value_token(tokens[1])
|
||||||
else
|
else
|
||||||
io.stderr:write '[assert-gooder/internal]: Unknown AST structure!'
|
io.stderr:write '[assert-gooder/internal]: Unknown AST structure!\n'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function populate_ast_with_semantics (node, info)
|
local function for_each_node_in_ast (ast, func)
|
||||||
if type(node) ~= 'table' then return end
|
assert(type(ast) == 'table')
|
||||||
for i = 1, #node do populate_ast_with_semantics(node[i], info) end
|
assert(type(func) == 'function')
|
||||||
--
|
--
|
||||||
|
for _, node in ipairs(ast) do
|
||||||
|
if type(node) == 'table' then
|
||||||
|
for_each_node_in_ast(node, func)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--
|
||||||
|
return func(ast)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function populate_ast_with_semantics (ast, info)
|
||||||
|
assert(type(ast) == 'table')
|
||||||
|
assert(type(info) == 'table')
|
||||||
|
return for_each_node_in_ast(ast, function(node)
|
||||||
if node.exp == 'LVALUE' then
|
if node.exp == 'LVALUE' then
|
||||||
node.value = get_value_from_lvalue(node, info)
|
node.value = get_value_from_lvalue(node, info)
|
||||||
end
|
end
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@ -123,9 +153,9 @@ local function get_assert_body_text (call_info)
|
||||||
-- Find filetext
|
-- Find filetext
|
||||||
local filetext = nil
|
local filetext = nil
|
||||||
if call_info.source:find '^@' then
|
if call_info.source:find '^@' then
|
||||||
local f = io.open(call_info.short_src, 'r')
|
local filehandle = io.open(call_info.short_src, 'r')
|
||||||
filetext = f:read '*all'
|
filetext = filehandle:read '*all'
|
||||||
f:close()
|
filehandle:close()
|
||||||
elseif call_info.short_src:find '^%[string' then
|
elseif call_info.short_src:find '^%[string' then
|
||||||
filetext = call_info.source
|
filetext = call_info.source
|
||||||
else
|
else
|
||||||
|
@ -147,10 +177,6 @@ local function get_assert_body_text (call_info)
|
||||||
error 'Not implemented yet!'
|
error 'Not implemented yet!'
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_assert_body (call_info)
|
|
||||||
local text = get_assert_body_text(call_info)
|
|
||||||
return lexer:lex(text), text
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get_function_name (call_info)
|
local function get_function_name (call_info)
|
||||||
--
|
--
|
||||||
|
@ -178,10 +204,17 @@ end
|
||||||
|
|
||||||
local function fmt_lvalue (lvalue, var_scope)
|
local function fmt_lvalue (lvalue, var_scope)
|
||||||
assert(type(lvalue) == 'table' and lvalue.exp == 'LVALUE')
|
assert(type(lvalue) == 'table' and lvalue.exp == 'LVALUE')
|
||||||
if #lvalue == 1 then return string.format('%s \'%s\'', var_scope, lvalue[1])
|
--
|
||||||
elseif #lvalue == 2 then return string.format('key %s in %s \'%s\'', fmt_val(lvalue[2].value), var_scope, lvalue[1])
|
local base_var = tostring(lvalue[1])
|
||||||
|
if var_scope then
|
||||||
|
base_var = ('%s \'%s\''):format(var_scope, lvalue[1])
|
||||||
|
end
|
||||||
|
--
|
||||||
|
if #lvalue == 1 then return base_var
|
||||||
|
elseif #lvalue == 2 then return string.format('key %s in %s', fmt_val(lvalue[2].value), base_var)
|
||||||
else error 'Not implemented yet!'
|
else error 'Not implemented yet!'
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_variable_and_prefix (lvalue, call_info)
|
local function get_variable_and_prefix (lvalue, call_info)
|
||||||
|
@ -217,33 +250,89 @@ end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local function get_assert_body (call_info)
|
||||||
|
return lexer:lex(text), text
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
local function determine_error_message (call_info, msg, condition)
|
local function determine_error_message (call_info, msg, condition)
|
||||||
local tokens, body_text = get_assert_body(call_info)
|
-- Error checking.
|
||||||
|
assert(type(call_info) == 'table')
|
||||||
|
assert(type(msg) == 'table' and type(msg[1]) == 'string')
|
||||||
|
assert(not condition)
|
||||||
|
|
||||||
|
-- Get assert body.
|
||||||
|
local body_text = get_assert_body_text(call_info)
|
||||||
|
|
||||||
|
-- Simplest formatting.
|
||||||
|
-- No analysis of the assert-body, just report that it failed,
|
||||||
|
-- along with it's body.
|
||||||
|
msg[1] = ('expression `%s` evaluated to %s'):format(body_text, condition)
|
||||||
|
|
||||||
|
-- Lex text.
|
||||||
|
local tokens = lexer:lex(body_text)
|
||||||
|
assert(type(tokens) == 'table')
|
||||||
|
|
||||||
|
-- Find identifiers and provide simple explanations of their
|
||||||
|
-- values.
|
||||||
|
do
|
||||||
|
local l, seen_variables = {}, {}
|
||||||
|
for i, token in ipairs(tokens) do
|
||||||
|
local variable_name = token.text
|
||||||
|
if token.token == 'IDENTIFIER' and (i == 1 or tokens[i-1].token ~= 'COLON' and tokens[i-1].token ~= 'DOT') and not seen_variables[variable_name] then
|
||||||
|
seen_variables[variable_name] = true
|
||||||
|
local value = get_variable(variable_name, call_info)
|
||||||
|
if EXPECTED_GLOBAL[variable_name] == nil then
|
||||||
|
l[#l+1] = ('%s was %s'):format(token.text, fmt_val_with_type(value))
|
||||||
|
elseif EXPECTED_GLOBAL[variable_name] ~= type(value) then
|
||||||
|
l[#l+1] = ('standard-%s %s was %s'):format(EXPECTED_GLOBAL[variable_name], token.text, fmt_val_with_type(value))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
msg[2] = #l > 0 and table.concat(l,', ') or nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
local ast = parse(tokens)
|
local ast = parse(tokens)
|
||||||
|
if not ast then return end
|
||||||
|
assert(type(ast) == 'table')
|
||||||
populate_ast_with_semantics(ast, call_info)
|
populate_ast_with_semantics(ast, call_info)
|
||||||
|
|
||||||
msg[1] = ('expression `%s` evaluated to %s'):format(body_text, condition)
|
-- Alternative more detailed formatting.
|
||||||
|
-- Identical to last message, but now with values of each involved
|
||||||
|
-- identifier.
|
||||||
|
do
|
||||||
|
local l = {}
|
||||||
|
for_each_node_in_ast(ast, function(node)
|
||||||
|
if node.exp == 'LVALUE' then
|
||||||
|
l[#l+1] = fmt_lvalue(node) ..' was ' .. fmt_val_with_type(node.value)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
msg[2] = #l > 0 and table.concat(l,', ') or nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- More specific types
|
||||||
local var_prefix = function(token) return get_variable_and_prefix(token, call_info) end
|
local var_prefix = function(token) return get_variable_and_prefix(token, call_info) end
|
||||||
|
|
||||||
if not ast then return nil
|
if not ast then return nil
|
||||||
elseif ast.exp == 'COMPARE' and ast.binop == 'EQ' and ast[1].exp == 'CALL' and ast[1][1].exp == 'LVALUE' and ast[1][1][1] == 'type' then
|
elseif ast.exp == 'COMPARE' and ast.binop == 'EQ' and ast[1].exp == 'CALL' and ast[1][1].exp == 'LVALUE' and ast[1][1][1] == 'type' then
|
||||||
local gotten_val, prefix = var_prefix(ast[1][2])
|
local gotten_val, prefix = var_prefix(ast[1][2])
|
||||||
msg[1] = ('%s (%s expected, but got %s)'):format(prefix, ast[2].value, fmt_val_with_type(gotten_val))
|
msg[1], msg[2] = prefix, ('%s expected, but got %s'):format(ast[2].value, fmt_val_with_type(gotten_val))
|
||||||
|
|
||||||
elseif ast.exp == 'COMPARE' and ast.binop == 'EQ' then
|
elseif ast.exp == 'COMPARE' and ast.binop == 'EQ' then
|
||||||
local gotten_value, prefix = var_prefix(ast[1])
|
local gotten_value, prefix = var_prefix(ast[1])
|
||||||
local expected_value = ast[2].value
|
local expected_value = ast[2].value
|
||||||
local fmt_gotten = (type(expected_value) == type(gotten_value)) and fmt_val or fmt_val_with_type
|
local fmt_gotten = (type(expected_value) == type(gotten_value)) and fmt_val or fmt_val_with_type
|
||||||
msg[1] = ('%s (%s expected, but got %s)'):format(prefix, fmt_val_with_type(expected_value), fmt_gotten(gotten_value))
|
msg[1], msg[2] = prefix, ('%s expected, but got %s'):format(fmt_val_with_type(expected_value), fmt_gotten(gotten_value))
|
||||||
|
|
||||||
elseif ast.exp == 'COMPARE' and ast.binop == 'NEQ' then
|
elseif ast.exp == 'COMPARE' and ast.binop == 'NEQ' then
|
||||||
local gotten_val, prefix = var_prefix(ast[1])
|
local gotten_val, prefix = var_prefix(ast[1])
|
||||||
local expected_value = ast[2].value
|
local expected_value = ast[2].value
|
||||||
msg[1] = ('%s (expected anything other than %s, but got %s)'):format(prefix, fmt_val_with_type(expected_value), fmt_val(gotten_val))
|
msg[1], msg[2] = prefix, ('expected anything other than %s, but got %s'):format(fmt_val_with_type(expected_value), fmt_val(gotten_val))
|
||||||
|
|
||||||
elseif ast.exp == 'LVALUE' then
|
elseif ast.exp == 'LVALUE' then
|
||||||
local gotten_val, prefix = var_prefix(ast)
|
local gotten_val, prefix = var_prefix(ast)
|
||||||
msg[1] = ('%s (truthy expected, but got %s)'):format(prefix, fmt_val(gotten_val))
|
msg[1], msg[2] = prefix, ('truthy expected, but got %s'):format(fmt_val(gotten_val))
|
||||||
|
|
||||||
elseif CONSTANT_VALUE_TOKEN[ast.exp] then
|
elseif CONSTANT_VALUE_TOKEN[ast.exp] then
|
||||||
local func_name = get_function_name(call_info)
|
local func_name = get_function_name(call_info)
|
||||||
|
@ -263,7 +352,6 @@ return function (condition)
|
||||||
for i = 1, math.huge do
|
for i = 1, math.huge do
|
||||||
local name, value = debug.getlocal(level, i)
|
local name, value = debug.getlocal(level, i)
|
||||||
if not name then break end
|
if not name then break end
|
||||||
print(value, i <= call_info.nparams)
|
|
||||||
call_info.locals[name] = { value, i <= call_info.nparams, i }
|
call_info.locals[name] = { value, i <= call_info.nparams, i }
|
||||||
end
|
end
|
||||||
--
|
--
|
||||||
|
@ -271,9 +359,17 @@ return function (condition)
|
||||||
local success, internal_error_msg = pcall(determine_error_message, call_info, msg_container, condition)
|
local success, internal_error_msg = pcall(determine_error_message, call_info, msg_container, condition)
|
||||||
-- Handle internal errors
|
-- Handle internal errors
|
||||||
if not success then
|
if not success then
|
||||||
io.stderr:write(('[assert-gooder/internal]: Internal error occured while determining error message for calling assert:\n %s'):format(internal_error_msg))
|
io.stderr:write(('[assert-gooder/internal]: Internal error occured while determining error message for calling assert:\n %s\n'):format(internal_error_msg))
|
||||||
end
|
end
|
||||||
--
|
--
|
||||||
error(('assertion failed! %s'):format(msg_container[1]), 2)
|
assert(#msg_container <= 2 and type(msg_container[1]) == 'string')
|
||||||
|
local l = {'assertion failed! ', msg_container[1]}
|
||||||
|
if msg_container[2] then
|
||||||
|
assert(type(msg_container[2]) == 'string')
|
||||||
|
l[3] = ' ('
|
||||||
|
l[4] = msg_container[2]
|
||||||
|
l[5] = ')'
|
||||||
|
end
|
||||||
|
error(table.concat(l, ''), 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ end)
|
||||||
SUITE:addTest('subscript constant', function ()
|
SUITE:addTest('subscript constant', function ()
|
||||||
local _, msg = pcall(function ()
|
local _, msg = pcall(function ()
|
||||||
local a = { 4, 2, 3, 6 }
|
local a = { 4, 2, 3, 6 }
|
||||||
assert(type(a.b) == 'string')
|
assert(type(a[2]) == 'string')
|
||||||
end)
|
end)
|
||||||
assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad key 2 in local \'a\' (string expected, but got number 2)', msg)
|
assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad key 2 in local \'a\' (string expected, but got number 2)', msg)
|
||||||
end)
|
end)
|
||||||
|
@ -67,7 +67,7 @@ end)
|
||||||
SUITE:addTest('subscript variable', function ()
|
SUITE:addTest('subscript variable', function ()
|
||||||
local _, msg = pcall(function ()
|
local _, msg = pcall(function ()
|
||||||
local a, i = { 4, 2, 3, 6 }, 2
|
local a, i = { 4, 2, 3, 6 }, 2
|
||||||
assert(type(a.b) == 'string')
|
assert(type(a[i]) == 'string')
|
||||||
end)
|
end)
|
||||||
assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad key 2 in local \'a\' (string expected, but got number 2)', msg)
|
assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad key 2 in local \'a\' (string expected, but got number 2)', msg)
|
||||||
end)
|
end)
|
||||||
|
@ -85,7 +85,16 @@ SUITE:addTest('really complicated expression', function ()
|
||||||
assert(a == 3 and math.floor(2.522) == 2 or 5 == n)
|
assert(a == 3 and math.floor(2.522) == 2 or 5 == n)
|
||||||
end
|
end
|
||||||
local _, msg = pcall(f, 2)
|
local _, msg = pcall(f, 2)
|
||||||
assert_equal('./test/test_assert-gooder.lua:'..curline(-3)..': '..'assertion failed! expression `a == 3 and math.floor(2.522) == 2 or 5 == n` evaluated to false', msg)
|
assert_equal('./test/test_assert-gooder.lua:'..curline(-3)..': '..'assertion failed! expression `a == 3 and math.floor(2.522) == 2 or 5 == n` evaluated to false (a was nil, n was nil)', msg)
|
||||||
|
end)
|
||||||
|
|
||||||
|
SUITE:addTest('really complicated expression with modified global', function ()
|
||||||
|
tonumber = nil
|
||||||
|
local f = function ()
|
||||||
|
assert(a == 3 and math.floor(2.522) == 2 or 5 == n and tonumber)
|
||||||
|
end
|
||||||
|
local _, msg = pcall(f, 2)
|
||||||
|
assert_equal('./test/test_assert-gooder.lua:'..curline(-3)..': '..'assertion failed! expression `a == 3 and math.floor(2.522) == 2 or 5 == n and tonumber` evaluated to false (a was nil, n was nil, standard-function tonumber was nil)', msg)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@ -182,6 +191,119 @@ SUITE:addTest('function as type argument', function ()
|
||||||
assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad upvalue \'f\' (string expected, but got '..tostring(f)..')', msg)
|
assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad upvalue \'f\' (string expected, but got '..tostring(f)..')', msg)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
SUITE:addTest('length of sequence EQUAL', function ()
|
||||||
|
local _, msg = pcall(function ()
|
||||||
|
local seq = {1, 2, 3, 4}
|
||||||
|
assert(#seq == 5)
|
||||||
|
end)
|
||||||
|
assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad length of local \'seq\' (length 5 expected, but got length 4)', msg)
|
||||||
|
end)
|
||||||
|
|
||||||
|
SUITE:addTest('length of sequence LESS THAN', function ()
|
||||||
|
local _, msg = pcall(function ()
|
||||||
|
local seq = {1, 2, 3, 4}
|
||||||
|
assert(#seq < 3)
|
||||||
|
end)
|
||||||
|
assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad length of local \'seq\' (length less than 3 expected, but got length 4)', msg)
|
||||||
|
end)
|
||||||
|
|
||||||
|
SUITE:addTest('length of sequence COMPARE', function ()
|
||||||
|
local _, msg = pcall(function ()
|
||||||
|
local seq_a = {1, 2, 3, 4}
|
||||||
|
local seq_b = {1, 2, 3}
|
||||||
|
assert(#seq_a == #seq_b)
|
||||||
|
end)
|
||||||
|
assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad lengths of locals \'seq_a\' and \'seq_b\' (equal lengths expected, but got lengths 4 and 3)', msg)
|
||||||
|
end)
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- Tables
|
||||||
|
|
||||||
|
SUITE:addTest('table with keys', function ()
|
||||||
|
local _, msg = pcall(function ()
|
||||||
|
local obj = { a = 42, b = 'euclidian fantasyland' }
|
||||||
|
assert(type(obj) == 'table' and type(obj.a) == 'string' and type(obj.b) == 'number')
|
||||||
|
end)
|
||||||
|
assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad of local \'obj\' (table similar to { a: string, b: number, ... } expected, but got { a = 42, b = "euclidian fantasyland" })', msg)
|
||||||
|
end)
|
||||||
|
|
||||||
|
SUITE:addTest('table with more keys', function ()
|
||||||
|
-- obj now has an extra key, this is reflected in the error
|
||||||
|
-- message, by adding the extra ellipsis.
|
||||||
|
local _, msg = pcall(function ()
|
||||||
|
local obj = { a = 42, b = 'euclidian fantasyland', c = {} }
|
||||||
|
assert(type(obj) == 'table' and type(obj.a) == 'string' and type(obj.b) == 'number')
|
||||||
|
end)
|
||||||
|
assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad of local \'obj\' (table similar to { a: string, b: number, ... } expected, but got { a = 42, b = "euclidian fantasyland", ... })', msg)
|
||||||
|
end)
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
SUITE:addTest('Number below something', function ()
|
||||||
|
local _, msg = pcall(function ()
|
||||||
|
local a = 6
|
||||||
|
assert(a < 5)
|
||||||
|
end)
|
||||||
|
assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad local \'a\' (number less than 5 expected, but got 6)', msg)
|
||||||
|
end)
|
||||||
|
|
||||||
|
SUITE:addTest('Number above something', function ()
|
||||||
|
local _, msg = pcall(function ()
|
||||||
|
local a = 6
|
||||||
|
assert(a > 10)
|
||||||
|
end)
|
||||||
|
assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad local \'a\' (number greater than 10 expected, but got 6)', msg)
|
||||||
|
end)
|
||||||
|
|
||||||
|
SUITE:addTest('Number between something', function ()
|
||||||
|
local _, msg = pcall(function ()
|
||||||
|
local a = 11
|
||||||
|
assert(a < 10 and 5 < a)
|
||||||
|
end)
|
||||||
|
assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad local \'a\' (number in range ]5,10[ expected, but got 6)', msg)
|
||||||
|
end)
|
||||||
|
|
||||||
|
SUITE:addTest('Number between something 2', function ()
|
||||||
|
local _, msg = pcall(function ()
|
||||||
|
local a = 11
|
||||||
|
assert(a < 10 and 7 <= a)
|
||||||
|
end)
|
||||||
|
assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad local \'a\' (number in range [7,10[ expected, but got 6)', msg)
|
||||||
|
end)
|
||||||
|
|
||||||
|
SUITE:addTest('Identify positive number', function ()
|
||||||
|
local _, msg = pcall(function ()
|
||||||
|
local a = -20
|
||||||
|
assert(0 <= a)
|
||||||
|
end)
|
||||||
|
assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad local \'a\' (positive number expected, but got negative number -20)', msg)
|
||||||
|
end)
|
||||||
|
|
||||||
|
SUITE:addTest('Identify integer', function ()
|
||||||
|
local _, msg = pcall(function ()
|
||||||
|
local a = 5.21
|
||||||
|
assert(a % 1 == 0)
|
||||||
|
end)
|
||||||
|
assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad local \'a\' (integer expected, but got floating-point number 5.21)', msg)
|
||||||
|
end)
|
||||||
|
|
||||||
|
SUITE:addTest('Identify even number', function ()
|
||||||
|
local _, msg = pcall(function ()
|
||||||
|
local a = 5
|
||||||
|
assert(a % 2 == 0)
|
||||||
|
end)
|
||||||
|
assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad local \'a\' (even number expected, but got odd number 5)', msg)
|
||||||
|
end)
|
||||||
|
|
||||||
|
SUITE:addTest('Identify odd number', function ()
|
||||||
|
local _, msg = pcall(function ()
|
||||||
|
local a = 6
|
||||||
|
assert(a % 2 == 1)
|
||||||
|
end)
|
||||||
|
assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad local \'a\' (odd number expected, but got even number 5.21)', msg)
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
return SUITE
|
return SUITE
|
||||||
|
|
Loading…
Reference in New Issue
Block a user