diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-08-18 17:29:46 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-08-18 17:29:46 -0300 |
commit | 9405472565cb4b0cb0c339d65babdef4d4cb7abd (patch) | |
tree | 386bcb066803310f7481b60e119748c85b13d618 | |
parent | 45948e7e55c753cf0e370b251ac1d4e7f3aabedd (diff) | |
download | lua-9405472565cb4b0cb0c339d65babdef4d4cb7abd.tar.gz lua-9405472565cb4b0cb0c339d65babdef4d4cb7abd.tar.bz2 lua-9405472565cb4b0cb0c339d65babdef4d4cb7abd.zip |
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.
-rw-r--r-- | ltests.c | 28 | ||||
-rw-r--r-- | testes/coroutine.lua | 11 | ||||
-rw-r--r-- | testes/gc.lua | 6 | ||||
-rw-r--r-- | testes/locals.lua | 35 | ||||
-rw-r--r-- | testes/main.lua | 6 |
5 files changed, 55 insertions, 31 deletions
@@ -62,8 +62,10 @@ static void pushobject (lua_State *L, const TValue *o) { | |||
62 | } | 62 | } |
63 | 63 | ||
64 | 64 | ||
65 | static void badexit (const char *fmt, const char *s) { | 65 | static void badexit (const char *fmt, const char *s1, const char *s2) { |
66 | fprintf(stderr, fmt, s); | 66 | fprintf(stderr, fmt, s1); |
67 | if (s2) | ||
68 | fprintf(stderr, "extra info: %s\n", s2); | ||
67 | /* avoid assertion failures when exiting */ | 69 | /* avoid assertion failures when exiting */ |
68 | l_memcontrol.numblocks = l_memcontrol.total = 0; | 70 | l_memcontrol.numblocks = l_memcontrol.total = 0; |
69 | exit(EXIT_FAILURE); | 71 | exit(EXIT_FAILURE); |
@@ -72,7 +74,7 @@ static void badexit (const char *fmt, const char *s) { | |||
72 | 74 | ||
73 | static int tpanic (lua_State *L) { | 75 | static int tpanic (lua_State *L) { |
74 | return (badexit("PANIC: unprotected error in call to Lua API (%s)\n", | 76 | return (badexit("PANIC: unprotected error in call to Lua API (%s)\n", |
75 | lua_tostring(L, -1)), | 77 | lua_tostring(L, -1), NULL), |
76 | 0); /* do not return to Lua */ | 78 | 0); /* do not return to Lua */ |
77 | } | 79 | } |
78 | 80 | ||
@@ -88,13 +90,14 @@ static int tpanic (lua_State *L) { | |||
88 | ** - 2.store: all warnings go to the global '_WARN'; | 90 | ** - 2.store: all warnings go to the global '_WARN'; |
89 | */ | 91 | */ |
90 | static void warnf (void *ud, const char *msg, int tocont) { | 92 | static void warnf (void *ud, const char *msg, int tocont) { |
93 | lua_State *L = cast(lua_State *, ud); | ||
91 | static char buff[200] = ""; /* should be enough for tests... */ | 94 | static char buff[200] = ""; /* should be enough for tests... */ |
92 | static int onoff = 1; | 95 | static int onoff = 1; |
93 | static int mode = 0; /* start in normal mode */ | 96 | static int mode = 0; /* start in normal mode */ |
94 | static int lasttocont = 0; | 97 | static int lasttocont = 0; |
95 | if (!lasttocont && !tocont && *msg == '@') { /* control message? */ | 98 | if (!lasttocont && !tocont && *msg == '@') { /* control message? */ |
96 | if (buff[0] != '\0') | 99 | if (buff[0] != '\0') |
97 | badexit("Control warning during warning: %s\naborting...\n", msg); | 100 | badexit("Control warning during warning: %s\naborting...\n", msg, buff); |
98 | if (strcmp(msg, "@off") == 0) | 101 | if (strcmp(msg, "@off") == 0) |
99 | onoff = 0; | 102 | onoff = 0; |
100 | else if (strcmp(msg, "@on") == 0) | 103 | else if (strcmp(msg, "@on") == 0) |
@@ -106,18 +109,28 @@ static void warnf (void *ud, const char *msg, int tocont) { | |||
106 | else if (strcmp(msg, "@store") == 0) | 109 | else if (strcmp(msg, "@store") == 0) |
107 | mode = 2; | 110 | mode = 2; |
108 | else | 111 | else |
109 | badexit("Invalid control warning in test mode: %s\naborting...\n", msg); | 112 | badexit("Invalid control warning in test mode: %s\naborting...\n", |
113 | msg, NULL); | ||
110 | return; | 114 | return; |
111 | } | 115 | } |
112 | lasttocont = tocont; | 116 | lasttocont = tocont; |
113 | if (strlen(msg) >= sizeof(buff) - strlen(buff)) | 117 | if (strlen(msg) >= sizeof(buff) - strlen(buff)) |
114 | badexit("%s", "warnf-buffer overflow"); | 118 | badexit("warnf-buffer overflow (%s)\n", msg, buff); |
115 | strcat(buff, msg); /* add new message to current warning */ | 119 | strcat(buff, msg); /* add new message to current warning */ |
116 | if (!tocont) { /* message finished? */ | 120 | if (!tocont) { /* message finished? */ |
121 | lua_unlock(L); | ||
122 | if (lua_getglobal(L, "_WARN") == LUA_TNIL) | ||
123 | lua_pop(L, 1); /* ok, no previous unexpected warning */ | ||
124 | else { | ||
125 | badexit("Unhandled warning in store mode: %s\naborting...\n", | ||
126 | lua_tostring(L, -1), buff); | ||
127 | } | ||
128 | lua_lock(L); | ||
117 | switch (mode) { | 129 | switch (mode) { |
118 | case 0: { /* normal */ | 130 | case 0: { /* normal */ |
119 | if (buff[0] != '#' && onoff) /* unexpected warning? */ | 131 | if (buff[0] != '#' && onoff) /* unexpected warning? */ |
120 | badexit("Unexpected warning in test mode: %s\naborting...\n", buff); | 132 | badexit("Unexpected warning in test mode: %s\naborting...\n", |
133 | buff, NULL); | ||
121 | /* else */ /* FALLTHROUGH */ | 134 | /* else */ /* FALLTHROUGH */ |
122 | } | 135 | } |
123 | case 1: { /* allow */ | 136 | case 1: { /* allow */ |
@@ -126,7 +139,6 @@ static void warnf (void *ud, const char *msg, int tocont) { | |||
126 | break; | 139 | break; |
127 | } | 140 | } |
128 | case 2: { /* store */ | 141 | case 2: { /* store */ |
129 | lua_State *L = cast(lua_State *, ud); | ||
130 | lua_unlock(L); | 142 | lua_unlock(L); |
131 | lua_pushstring(L, buff); | 143 | lua_pushstring(L, buff); |
132 | lua_setglobal(L, "_WARN"); /* assign message to global '_WARN' */ | 144 | lua_setglobal(L, "_WARN"); /* assign message to global '_WARN' */ |
diff --git a/testes/coroutine.lua b/testes/coroutine.lua index 79c72a9d..4fc23261 100644 --- a/testes/coroutine.lua +++ b/testes/coroutine.lua | |||
@@ -177,10 +177,15 @@ do | |||
177 | end) | 177 | end) |
178 | coroutine.resume(co) | 178 | coroutine.resume(co) |
179 | assert(x == 0) | 179 | assert(x == 0) |
180 | _WARN = nil; warn("@off"); warn("@store") | 180 | -- with test library, use 'store' mode to check warnings |
181 | warn(not T and "@off" or "@store") | ||
181 | local st, msg = coroutine.close(co) | 182 | local st, msg = coroutine.close(co) |
182 | warn("@on"); warn("@normal") | 183 | if not T then |
183 | assert(_WARN == nil or string.find(_WARN, "200")) | 184 | warn("@on") |
185 | else -- test library | ||
186 | assert(string.find(_WARN, "200")); _WARN = nil | ||
187 | warn("@normal") | ||
188 | end | ||
184 | assert(st == false and coroutine.status(co) == "dead" and msg == 111) | 189 | assert(st == false and coroutine.status(co) == "dead" and msg == 111) |
185 | assert(x == 200) | 190 | assert(x == 200) |
186 | 191 | ||
diff --git a/testes/gc.lua b/testes/gc.lua index 6bdc98ca..34854d6f 100644 --- a/testes/gc.lua +++ b/testes/gc.lua | |||
@@ -372,7 +372,7 @@ if T then | |||
372 | warn("@store") | 372 | warn("@store") |
373 | collectgarbage() | 373 | collectgarbage() |
374 | assert(string.find(_WARN, "error in __gc metamethod")) | 374 | assert(string.find(_WARN, "error in __gc metamethod")) |
375 | assert(string.match(_WARN, "@(.-)@") == "expected") | 375 | assert(string.match(_WARN, "@(.-)@") == "expected"); _WARN = nil |
376 | for i = 8, 10 do assert(s[i]) end | 376 | for i = 8, 10 do assert(s[i]) end |
377 | 377 | ||
378 | for i = 1, 5 do | 378 | for i = 1, 5 do |
@@ -481,6 +481,7 @@ if T then | |||
481 | u = setmetatable({}, {__gc = function () error "@expected error" end}) | 481 | u = setmetatable({}, {__gc = function () error "@expected error" end}) |
482 | u = nil | 482 | u = nil |
483 | collectgarbage() | 483 | collectgarbage() |
484 | assert(string.find(_WARN, "@expected error")); _WARN = nil | ||
484 | warn("@normal") | 485 | warn("@normal") |
485 | end | 486 | end |
486 | 487 | ||
@@ -663,9 +664,8 @@ if T then | |||
663 | else | 664 | else |
664 | assert(lastmsg == _WARN) -- subsequent error messages are equal | 665 | assert(lastmsg == _WARN) -- subsequent error messages are equal |
665 | end | 666 | end |
666 | warn("@store") | 667 | warn("@store"); _WARN = nil |
667 | error"@expected warning" | 668 | error"@expected warning" |
668 | warn("@normal") | ||
669 | end} | 669 | end} |
670 | for i = 10, 1, -1 do | 670 | for i = 10, 1, -1 do |
671 | -- create object and preserve it until the end | 671 | -- create object and preserve it until the end |
diff --git a/testes/locals.lua b/testes/locals.lua index 595e107a..b4de523d 100644 --- a/testes/locals.lua +++ b/testes/locals.lua | |||
@@ -288,9 +288,8 @@ end | |||
288 | 288 | ||
289 | -- auxiliary functions for testing warnings in '__close' | 289 | -- auxiliary functions for testing warnings in '__close' |
290 | local function prepwarn () | 290 | local function prepwarn () |
291 | warn("@off") -- do not show (lots of) warnings | 291 | if not T then -- no test library? |
292 | if not T then | 292 | warn("@off") -- do not show (lots of) warnings |
293 | _WARN = "OFF" -- signal that warnings are not being captured | ||
294 | else | 293 | else |
295 | warn("@store") -- to test the warnings | 294 | warn("@store") -- to test the warnings |
296 | end | 295 | end |
@@ -298,15 +297,20 @@ end | |||
298 | 297 | ||
299 | 298 | ||
300 | local function endwarn () | 299 | local function endwarn () |
301 | assert(T or _WARN == "OFF") | 300 | if not T then |
302 | warn("@on") -- back to normal | 301 | warn("@on") -- back to normal |
303 | warn("@normal") | 302 | else |
304 | _WARN = nil | 303 | assert(_WARN == nil) |
304 | warn("@normal") | ||
305 | end | ||
305 | end | 306 | end |
306 | 307 | ||
307 | 308 | ||
308 | local function checkwarn (msg) | 309 | local function checkwarn (msg) |
309 | assert(_WARN == "OFF" or string.find(_WARN, msg)) | 310 | if T then |
311 | assert(string.find(_WARN, msg)) | ||
312 | _WARN = nil -- reset variable to check next warning | ||
313 | end | ||
310 | end | 314 | end |
311 | 315 | ||
312 | 316 | ||
@@ -333,7 +337,8 @@ do print("testing errors in __close") | |||
333 | 337 | ||
334 | local y <close> = | 338 | local y <close> = |
335 | func2close(function (self, msg) | 339 | func2close(function (self, msg) |
336 | assert(string.find(msg, "@z")) -- error in 'z' | 340 | assert(string.find(msg, "@z")) -- first error in 'z' |
341 | checkwarn("@z") -- second error in 'z' generated a warning | ||
337 | error("@y") | 342 | error("@y") |
338 | end) | 343 | end) |
339 | 344 | ||
@@ -377,14 +382,14 @@ do print("testing errors in __close") | |||
377 | 382 | ||
378 | local y <close> = | 383 | local y <close> = |
379 | func2close(function (self, msg) | 384 | func2close(function (self, msg) |
380 | assert(msg == 4) -- error in body | 385 | assert(msg == 4) -- error in body |
386 | checkwarn("@z") | ||
381 | error("@y") | 387 | error("@y") |
382 | end) | 388 | end) |
383 | 389 | ||
384 | local first = true | 390 | local first = true |
385 | local z <close> = | 391 | local z <close> = |
386 | func2close(function (self, msg) | 392 | func2close(function (self, msg) |
387 | checkwarn("@z") | ||
388 | -- 'z' close is called once | 393 | -- 'z' close is called once |
389 | assert(first and msg == 4) | 394 | assert(first and msg == 4) |
390 | first = false | 395 | first = false |
@@ -418,16 +423,18 @@ do print("testing errors in __close") | |||
418 | local st, msg = xpcall(foo, debug.traceback) | 423 | local st, msg = xpcall(foo, debug.traceback) |
419 | assert(string.match(msg, "^[^ ]* @X")) | 424 | assert(string.match(msg, "^[^ ]* @X")) |
420 | assert(string.find(msg, "in metamethod 'close'")) | 425 | assert(string.find(msg, "in metamethod 'close'")) |
426 | checkwarn("@Y") | ||
421 | 427 | ||
422 | -- error in toclose in vararg function | 428 | -- error in toclose in vararg function |
423 | local function foo (...) | 429 | local function foo (...) |
424 | local x123 <close> = func2close(function () error("@X") end) | 430 | local x123 <close> = func2close(function () error("@x123") end) |
425 | end | 431 | end |
426 | 432 | ||
427 | local st, msg = xpcall(foo, debug.traceback) | 433 | local st, msg = xpcall(foo, debug.traceback) |
428 | assert(string.match(msg, "^[^ ]* @X")) | 434 | assert(string.match(msg, "^[^ ]* @x123")) |
429 | |||
430 | assert(string.find(msg, "in metamethod 'close'")) | 435 | assert(string.find(msg, "in metamethod 'close'")) |
436 | checkwarn("@x123") -- from second call to close 'x123' | ||
437 | |||
431 | endwarn() | 438 | endwarn() |
432 | end | 439 | end |
433 | 440 | ||
diff --git a/testes/main.lua b/testes/main.lua index 0ef4822d..36220362 100644 --- a/testes/main.lua +++ b/testes/main.lua | |||
@@ -379,12 +379,12 @@ if T then -- test library? | |||
379 | -- testing 'warn' | 379 | -- testing 'warn' |
380 | warn("@store") | 380 | warn("@store") |
381 | warn("@123", "456", "789") | 381 | warn("@123", "456", "789") |
382 | assert(_WARN == "@123456789") | 382 | assert(_WARN == "@123456789"); _WARN = nil |
383 | 383 | ||
384 | warn("zip", "", " ", "zap") | 384 | warn("zip", "", " ", "zap") |
385 | assert(_WARN == "zip zap") | 385 | assert(_WARN == "zip zap"); _WARN = nil |
386 | warn("ZIP", "", " ", "ZAP") | 386 | warn("ZIP", "", " ", "ZAP") |
387 | assert(_WARN == "ZIP ZAP") | 387 | assert(_WARN == "ZIP ZAP"); _WARN = nil |
388 | warn("@normal") | 388 | warn("@normal") |
389 | end | 389 | end |
390 | 390 | ||