diff --git a/assert-gooder.lua b/assert-gooder.lua index fba35ea..7405e37 100644 --- a/assert-gooder.lua +++ b/assert-gooder.lua @@ -62,6 +62,22 @@ local function get_variable (var_name, level) return getfenv(level + 1)[var_name], 'global' end +local function get_function_name (call_info) + -- + if call_info.name then return string.format('\'%s\'', call_info.name) end + -- + local where = nil + if call_info.source:find '^@' then + where = 'at '..call_info.short_src..':'..call_info.linedefined + elseif call_info.short_src:find '^%[string' then + where = 'from loaded string' + else + error 'not yet implemented' + end + -- + return string.format('the anonymous function %s', where) +end + local function get_value_of_string (string_str) if string_str:sub(1, 1) == '"' or string_str:sub(1, 1) == '\'' then return string_str:sub(2, -2) @@ -82,7 +98,7 @@ local function get_variable_and_prefix (gotten_name, level) assert(type(level) == 'number') -- local gotten_val, var_scope, in_func = get_variable(gotten_name, level + 1) - local func_name = (in_func == '' and ' to anonymous function') or in_func and (' to \''..in_func..'\'') or '' + local func_name = in_func and (' to '..get_function_name(debug.getinfo(level + 1))) or '' return gotten_val, ('assertion failed! bad %s \'%s\'%s'):format(var_scope, gotten_name, func_name) end @@ -146,8 +162,12 @@ return function (condition) elseif #tokens == 1 and tokens[1].token == 'IDENTIFIER' then local gotten_val, prefix = get_variable_and_prefix(tokens[1].text, 2) error(('%s (truthy expected, but got %s)'):format(prefix, fmt_val(gotten_val)), 2) + elseif #tokens == 1 and (tokens[1].token == 'NIL' or tokens[1].token == 'FALSE') then + local func_name = get_function_name(call_info) + error(('assertion failed! this assert will always fail, as it\'s body is `%s`. assumingly this should be an unreachable part of %s'):format(body_text, func_name), 2) + elseif #tokens == 1 then + error 'should be unreachable!' else - print(require'pretty'(tokens)) error(('assertion failed! expression `%s` evaluated to %s'):format(body_text, condition), 2) end end diff --git a/test/test_assert-gooder.lua b/test/test_assert-gooder.lua index 7a34bb9..002b61b 100644 --- a/test/test_assert-gooder.lua +++ b/test/test_assert-gooder.lua @@ -31,10 +31,12 @@ SUITE:addTest('global variable', function () end) SUITE:addTest('argument to anon function', function () - local _, msg = pcall(function (a) - assert(type(a) == 'string') - end, 2) - assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! bad argument #1 \'a\' to anonymous function (string expected, but got number: 2)', msg) + local _, msg = pcall(function() + (function (a) + assert(type(a) == 'string') + end)(2) + end) + assert_equal('./test/test_assert-gooder.lua:'..curline(-3)..': '..'assertion failed! bad argument #1 \'a\' to the anonymous function at ./test/test_assert-gooder.lua:'..curline(-4)..' (string expected, but got number: 2)', msg) end) SUITE:addTest('argument to named function', function () @@ -50,7 +52,7 @@ end) SUITE:addTest('can improve asserts in loaded strings too', function () local func = loadstring "return function(a) assert(type(a) == 'string') end" () local _, msg = pcall(setfenv(func, getfenv()), 42) - assert_equal('[string "return function(a) assert(type(a) == \'string\'..."]:1: '..'assertion failed! bad argument #1 \'a\' to anonymous function (string expected, but got number: 42)', msg) + assert_equal('[string "return function(a) assert(type(a) == \'string\'..."]:1: '..'assertion failed! bad argument #1 \'a\' to the anonymous function from loaded string (string expected, but got number: 42)', msg) end) SUITE:addTest('really complicated expression', function () @@ -107,6 +109,23 @@ end, { data = { { '42', 'expected anything other than number 42, but got 42' }, }}) +SUITE:addTest('constant false', function () + local function f () + assert(false) + end + local _, msg = pcall(function() f() end) + assert_equal('./test/test_assert-gooder.lua:'..curline(-3)..': '..'assertion failed! this assert will always fail, as it\'s body is `false`. assumingly this should be an unreachable part of \'f\'', msg) +end) + +SUITE:addTest('constant nil', function () + local _, msg = pcall(function () + assert(nil) + end) + assert_equal('./test/test_assert-gooder.lua:'..curline(-2)..': '..'assertion failed! this assert will always fail, as it\'s body is `nil`. assumingly this should be an unreachable part of the anonymous function at ./test/test_assert-gooder.lua:'..curline(-3), msg) +end) + + + -------------------------------------------------------------------------------- return SUITE