mirror of https://github.com/rusefi/lua.git
Improvement in warn-mode '@store' (for testing)
When using warn-mode '@store', from the test library, the tests ensure not only that the expected warnings were issued, but also that there was no extra warnings.
This commit is contained in:
parent
45948e7e55
commit
9405472565
28
ltests.c
28
ltests.c
|
@ -62,8 +62,10 @@ static void pushobject (lua_State *L, const TValue *o) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void badexit (const char *fmt, const char *s) {
|
static void badexit (const char *fmt, const char *s1, const char *s2) {
|
||||||
fprintf(stderr, fmt, s);
|
fprintf(stderr, fmt, s1);
|
||||||
|
if (s2)
|
||||||
|
fprintf(stderr, "extra info: %s\n", s2);
|
||||||
/* avoid assertion failures when exiting */
|
/* avoid assertion failures when exiting */
|
||||||
l_memcontrol.numblocks = l_memcontrol.total = 0;
|
l_memcontrol.numblocks = l_memcontrol.total = 0;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -72,7 +74,7 @@ static void badexit (const char *fmt, const char *s) {
|
||||||
|
|
||||||
static int tpanic (lua_State *L) {
|
static int tpanic (lua_State *L) {
|
||||||
return (badexit("PANIC: unprotected error in call to Lua API (%s)\n",
|
return (badexit("PANIC: unprotected error in call to Lua API (%s)\n",
|
||||||
lua_tostring(L, -1)),
|
lua_tostring(L, -1), NULL),
|
||||||
0); /* do not return to Lua */
|
0); /* do not return to Lua */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,13 +90,14 @@ static int tpanic (lua_State *L) {
|
||||||
** - 2.store: all warnings go to the global '_WARN';
|
** - 2.store: all warnings go to the global '_WARN';
|
||||||
*/
|
*/
|
||||||
static void warnf (void *ud, const char *msg, int tocont) {
|
static void warnf (void *ud, const char *msg, int tocont) {
|
||||||
|
lua_State *L = cast(lua_State *, ud);
|
||||||
static char buff[200] = ""; /* should be enough for tests... */
|
static char buff[200] = ""; /* should be enough for tests... */
|
||||||
static int onoff = 1;
|
static int onoff = 1;
|
||||||
static int mode = 0; /* start in normal mode */
|
static int mode = 0; /* start in normal mode */
|
||||||
static int lasttocont = 0;
|
static int lasttocont = 0;
|
||||||
if (!lasttocont && !tocont && *msg == '@') { /* control message? */
|
if (!lasttocont && !tocont && *msg == '@') { /* control message? */
|
||||||
if (buff[0] != '\0')
|
if (buff[0] != '\0')
|
||||||
badexit("Control warning during warning: %s\naborting...\n", msg);
|
badexit("Control warning during warning: %s\naborting...\n", msg, buff);
|
||||||
if (strcmp(msg, "@off") == 0)
|
if (strcmp(msg, "@off") == 0)
|
||||||
onoff = 0;
|
onoff = 0;
|
||||||
else if (strcmp(msg, "@on") == 0)
|
else if (strcmp(msg, "@on") == 0)
|
||||||
|
@ -106,18 +109,28 @@ static void warnf (void *ud, const char *msg, int tocont) {
|
||||||
else if (strcmp(msg, "@store") == 0)
|
else if (strcmp(msg, "@store") == 0)
|
||||||
mode = 2;
|
mode = 2;
|
||||||
else
|
else
|
||||||
badexit("Invalid control warning in test mode: %s\naborting...\n", msg);
|
badexit("Invalid control warning in test mode: %s\naborting...\n",
|
||||||
|
msg, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lasttocont = tocont;
|
lasttocont = tocont;
|
||||||
if (strlen(msg) >= sizeof(buff) - strlen(buff))
|
if (strlen(msg) >= sizeof(buff) - strlen(buff))
|
||||||
badexit("%s", "warnf-buffer overflow");
|
badexit("warnf-buffer overflow (%s)\n", msg, buff);
|
||||||
strcat(buff, msg); /* add new message to current warning */
|
strcat(buff, msg); /* add new message to current warning */
|
||||||
if (!tocont) { /* message finished? */
|
if (!tocont) { /* message finished? */
|
||||||
|
lua_unlock(L);
|
||||||
|
if (lua_getglobal(L, "_WARN") == LUA_TNIL)
|
||||||
|
lua_pop(L, 1); /* ok, no previous unexpected warning */
|
||||||
|
else {
|
||||||
|
badexit("Unhandled warning in store mode: %s\naborting...\n",
|
||||||
|
lua_tostring(L, -1), buff);
|
||||||
|
}
|
||||||
|
lua_lock(L);
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case 0: { /* normal */
|
case 0: { /* normal */
|
||||||
if (buff[0] != '#' && onoff) /* unexpected warning? */
|
if (buff[0] != '#' && onoff) /* unexpected warning? */
|
||||||
badexit("Unexpected warning in test mode: %s\naborting...\n", buff);
|
badexit("Unexpected warning in test mode: %s\naborting...\n",
|
||||||
|
buff, NULL);
|
||||||
/* else */ /* FALLTHROUGH */
|
/* else */ /* FALLTHROUGH */
|
||||||
}
|
}
|
||||||
case 1: { /* allow */
|
case 1: { /* allow */
|
||||||
|
@ -126,7 +139,6 @@ static void warnf (void *ud, const char *msg, int tocont) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: { /* store */
|
case 2: { /* store */
|
||||||
lua_State *L = cast(lua_State *, ud);
|
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
lua_pushstring(L, buff);
|
lua_pushstring(L, buff);
|
||||||
lua_setglobal(L, "_WARN"); /* assign message to global '_WARN' */
|
lua_setglobal(L, "_WARN"); /* assign message to global '_WARN' */
|
||||||
|
|
|
@ -177,10 +177,15 @@ do
|
||||||
end)
|
end)
|
||||||
coroutine.resume(co)
|
coroutine.resume(co)
|
||||||
assert(x == 0)
|
assert(x == 0)
|
||||||
_WARN = nil; warn("@off"); warn("@store")
|
-- with test library, use 'store' mode to check warnings
|
||||||
|
warn(not T and "@off" or "@store")
|
||||||
local st, msg = coroutine.close(co)
|
local st, msg = coroutine.close(co)
|
||||||
warn("@on"); warn("@normal")
|
if not T then
|
||||||
assert(_WARN == nil or string.find(_WARN, "200"))
|
warn("@on")
|
||||||
|
else -- test library
|
||||||
|
assert(string.find(_WARN, "200")); _WARN = nil
|
||||||
|
warn("@normal")
|
||||||
|
end
|
||||||
assert(st == false and coroutine.status(co) == "dead" and msg == 111)
|
assert(st == false and coroutine.status(co) == "dead" and msg == 111)
|
||||||
assert(x == 200)
|
assert(x == 200)
|
||||||
|
|
||||||
|
|
|
@ -372,7 +372,7 @@ if T then
|
||||||
warn("@store")
|
warn("@store")
|
||||||
collectgarbage()
|
collectgarbage()
|
||||||
assert(string.find(_WARN, "error in __gc metamethod"))
|
assert(string.find(_WARN, "error in __gc metamethod"))
|
||||||
assert(string.match(_WARN, "@(.-)@") == "expected")
|
assert(string.match(_WARN, "@(.-)@") == "expected"); _WARN = nil
|
||||||
for i = 8, 10 do assert(s[i]) end
|
for i = 8, 10 do assert(s[i]) end
|
||||||
|
|
||||||
for i = 1, 5 do
|
for i = 1, 5 do
|
||||||
|
@ -481,6 +481,7 @@ if T then
|
||||||
u = setmetatable({}, {__gc = function () error "@expected error" end})
|
u = setmetatable({}, {__gc = function () error "@expected error" end})
|
||||||
u = nil
|
u = nil
|
||||||
collectgarbage()
|
collectgarbage()
|
||||||
|
assert(string.find(_WARN, "@expected error")); _WARN = nil
|
||||||
warn("@normal")
|
warn("@normal")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -663,9 +664,8 @@ if T then
|
||||||
else
|
else
|
||||||
assert(lastmsg == _WARN) -- subsequent error messages are equal
|
assert(lastmsg == _WARN) -- subsequent error messages are equal
|
||||||
end
|
end
|
||||||
warn("@store")
|
warn("@store"); _WARN = nil
|
||||||
error"@expected warning"
|
error"@expected warning"
|
||||||
warn("@normal")
|
|
||||||
end}
|
end}
|
||||||
for i = 10, 1, -1 do
|
for i = 10, 1, -1 do
|
||||||
-- create object and preserve it until the end
|
-- create object and preserve it until the end
|
||||||
|
|
|
@ -288,9 +288,8 @@ end
|
||||||
|
|
||||||
-- auxiliary functions for testing warnings in '__close'
|
-- auxiliary functions for testing warnings in '__close'
|
||||||
local function prepwarn ()
|
local function prepwarn ()
|
||||||
|
if not T then -- no test library?
|
||||||
warn("@off") -- do not show (lots of) warnings
|
warn("@off") -- do not show (lots of) warnings
|
||||||
if not T then
|
|
||||||
_WARN = "OFF" -- signal that warnings are not being captured
|
|
||||||
else
|
else
|
||||||
warn("@store") -- to test the warnings
|
warn("@store") -- to test the warnings
|
||||||
end
|
end
|
||||||
|
@ -298,15 +297,20 @@ end
|
||||||
|
|
||||||
|
|
||||||
local function endwarn ()
|
local function endwarn ()
|
||||||
assert(T or _WARN == "OFF")
|
if not T then
|
||||||
warn("@on") -- back to normal
|
warn("@on") -- back to normal
|
||||||
|
else
|
||||||
|
assert(_WARN == nil)
|
||||||
warn("@normal")
|
warn("@normal")
|
||||||
_WARN = nil
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function checkwarn (msg)
|
local function checkwarn (msg)
|
||||||
assert(_WARN == "OFF" or string.find(_WARN, msg))
|
if T then
|
||||||
|
assert(string.find(_WARN, msg))
|
||||||
|
_WARN = nil -- reset variable to check next warning
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -333,7 +337,8 @@ do print("testing errors in __close")
|
||||||
|
|
||||||
local y <close> =
|
local y <close> =
|
||||||
func2close(function (self, msg)
|
func2close(function (self, msg)
|
||||||
assert(string.find(msg, "@z")) -- error in 'z'
|
assert(string.find(msg, "@z")) -- first error in 'z'
|
||||||
|
checkwarn("@z") -- second error in 'z' generated a warning
|
||||||
error("@y")
|
error("@y")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
@ -378,13 +383,13 @@ do print("testing errors in __close")
|
||||||
local y <close> =
|
local y <close> =
|
||||||
func2close(function (self, msg)
|
func2close(function (self, msg)
|
||||||
assert(msg == 4) -- error in body
|
assert(msg == 4) -- error in body
|
||||||
|
checkwarn("@z")
|
||||||
error("@y")
|
error("@y")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local first = true
|
local first = true
|
||||||
local z <close> =
|
local z <close> =
|
||||||
func2close(function (self, msg)
|
func2close(function (self, msg)
|
||||||
checkwarn("@z")
|
|
||||||
-- 'z' close is called once
|
-- 'z' close is called once
|
||||||
assert(first and msg == 4)
|
assert(first and msg == 4)
|
||||||
first = false
|
first = false
|
||||||
|
@ -418,16 +423,18 @@ do print("testing errors in __close")
|
||||||
local st, msg = xpcall(foo, debug.traceback)
|
local st, msg = xpcall(foo, debug.traceback)
|
||||||
assert(string.match(msg, "^[^ ]* @X"))
|
assert(string.match(msg, "^[^ ]* @X"))
|
||||||
assert(string.find(msg, "in metamethod 'close'"))
|
assert(string.find(msg, "in metamethod 'close'"))
|
||||||
|
checkwarn("@Y")
|
||||||
|
|
||||||
-- error in toclose in vararg function
|
-- error in toclose in vararg function
|
||||||
local function foo (...)
|
local function foo (...)
|
||||||
local x123 <close> = func2close(function () error("@X") end)
|
local x123 <close> = func2close(function () error("@x123") end)
|
||||||
end
|
end
|
||||||
|
|
||||||
local st, msg = xpcall(foo, debug.traceback)
|
local st, msg = xpcall(foo, debug.traceback)
|
||||||
assert(string.match(msg, "^[^ ]* @X"))
|
assert(string.match(msg, "^[^ ]* @x123"))
|
||||||
|
|
||||||
assert(string.find(msg, "in metamethod 'close'"))
|
assert(string.find(msg, "in metamethod 'close'"))
|
||||||
|
checkwarn("@x123") -- from second call to close 'x123'
|
||||||
|
|
||||||
endwarn()
|
endwarn()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -379,12 +379,12 @@ if T then -- test library?
|
||||||
-- testing 'warn'
|
-- testing 'warn'
|
||||||
warn("@store")
|
warn("@store")
|
||||||
warn("@123", "456", "789")
|
warn("@123", "456", "789")
|
||||||
assert(_WARN == "@123456789")
|
assert(_WARN == "@123456789"); _WARN = nil
|
||||||
|
|
||||||
warn("zip", "", " ", "zap")
|
warn("zip", "", " ", "zap")
|
||||||
assert(_WARN == "zip zap")
|
assert(_WARN == "zip zap"); _WARN = nil
|
||||||
warn("ZIP", "", " ", "ZAP")
|
warn("ZIP", "", " ", "ZAP")
|
||||||
assert(_WARN == "ZIP ZAP")
|
assert(_WARN == "ZIP ZAP"); _WARN = nil
|
||||||
warn("@normal")
|
warn("@normal")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue