From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id F2C5D28AF3 for ; Sat, 18 Aug 2018 08:36:26 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7R8dkbM-ZBxt for ; Sat, 18 Aug 2018 08:36:26 -0400 (EDT) Received: from smtp39.i.mail.ru (smtp39.i.mail.ru [94.100.177.99]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id 3886628AE8 for ; Sat, 18 Aug 2018 08:36:24 -0400 (EDT) From: Alexander Turenko Subject: [tarantool-patches] [PATCH] lua: show locals when a tap test fails Date: Sat, 18 Aug 2018 15:36:24 +0300 Message-Id: <84509c8ab6e29159082ff27a5d72c9228adc1c21.1534595542.git.alexander.turenko@tarantool.org> Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-help: List-unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-subscribe: List-owner: List-post: List-archive: To: Vladislav Shpilevoy , Eugine Blikh Cc: Alexander Turenko , tarantool-patches@freelists.org Fixes #3627. --- branch: Totktonada/gh-3627-tap-show-local-variables travis-ci: https://travis-ci.org/tarantool/tarantool/builds/417616160 issue: https://github.com/tarantool/tarantool/issues/3627 src/lua/tap.lua | 45 ++++++++++++++++++++++++++++++++++----- test/app-tap/tap.result | 26 ++++++++++++++++++++-- test/app-tap/tap.test.lua | 21 +++++++++++++++--- 3 files changed, 82 insertions(+), 10 deletions(-) diff --git a/src/lua/tap.lua b/src/lua/tap.lua index edc9f2211..9dd531422 100644 --- a/src/lua/tap.lua +++ b/src/lua/tap.lua @@ -1,6 +1,6 @@ --- tap.lua internal file --- ---- The Test Anything Protocol vesion 13 producer +--- The Test Anything Protocol version 13 producer --- -- yaml formatter must be able to encode any Lua variable @@ -36,12 +36,43 @@ local function traceback(level) return trace end +local function locals(test, level) + level = level or 3 + local variables = {} + local idx = 1 + while true do + local name, value = debug.getlocal(level, idx) + if name ~= nil then + -- compare a table with a tuple raises an error, so we check types + -- first + local eq = type(value) == type(test) and value == test + -- temporary values start with '(' + if not name:startswith('(') and not eq then + variables[name] = value + end + else + break + end + idx = 1 + idx + end + return variables +end + local function diag(test, fmt, ...) io.write(string.rep(' ', 4 * test.level), "# ", string.format(fmt, ...), "\n") end -local function ok(test, cond, message, extra) +local function ok(test, cond, message, extra, opts) + opts = opts or {} + local show_locals + if opts.locals ~= nil then + show_locals = opts.locals + elseif test.locals ~= nil then + show_locals = test.locals + else + show_locals = true + end test.total = test.total + 1 io.write(string.rep(' ', 4 * test.level)) if cond then @@ -58,6 +89,9 @@ local function ok(test, cond, message, extra) extra.filename = extra.trace[#extra.trace].filename extra.line = extra.trace[#extra.trace].line end + if show_locals then + extra.locals = locals(test) + end if next(extra) == nil then return false -- don't have extra information end @@ -221,6 +255,7 @@ local function test(parent, name, fun, ...) failed = 0; planned = 0; trace = parent == nil and true or parent.trace; + locals = parent == nil and true or parent.locals; }, test_mt) if fun ~= nil then test:diag('%s', test.name) @@ -245,7 +280,7 @@ local function check(test) if test.planned ~= test.total then if test.parent ~= nil then ok(test.parent, false, "bad plan", { planned = test.planned; - run = test.total}) + run = test.total}, {locals = false}) else diag(test, string.format("bad plan: planned %d run %d", test.planned, test.total)) @@ -255,13 +290,13 @@ local function check(test) ok(test.parent, false, "failed subtests", { failed = test.failed; planned = test.planned; - }) + }, {locals = false}) else diag(test, "failed subtest: %d", test.failed) end else if test.parent ~= nil then - ok(test.parent, true, test.name) + ok(test.parent, true, test.name, {locals = false}) end end return test.planned == test.total and test.failed == 0 diff --git a/test/app-tap/tap.result b/test/app-tap/tap.result index 3e7882331..36caa3023 100644 --- a/test/app-tap/tap.result +++ b/test/app-tap/tap.result @@ -1,5 +1,5 @@ TAP version 13 -1..32 +1..33 ok - true ok - extra information is not printed on success not ok - extra printed using yaml only on failure @@ -148,4 +148,26 @@ not ok - failed subtests ok - unlike(abcde, acd) # like: end ok - like -# failed subtest: 15 + # locals + 1..1 + # locals nested + 1..2 + ok - locals are not printed in case of success + not ok - locals are printed in case of fail + --- + locals: + a: 42 + ... + # locals nested: end + not ok - failed subtests + --- + planned: 2 + failed: 1 + ... + # locals: end +not ok - failed subtests + --- + planned: 1 + failed: 1 + ... +# failed subtest: 16 diff --git a/test/app-tap/tap.test.lua b/test/app-tap/tap.test.lua index 0e1de7f1c..29dc0b100 100755 --- a/test/app-tap/tap.test.lua +++ b/test/app-tap/tap.test.lua @@ -12,15 +12,16 @@ local tap = require "tap" -- Create a root test -- test = tap.test("root test") --- Disable stack traces for this test because Tarantool test system also --- checks test output. +-- Disable stack traces and locals for this test because Tarantool test system +-- also checks test output. test.trace = false +test.locals = false -- -- ok, fail and skip predicates -- -test:plan(32) -- plan to run 3 test +test:plan(33) -- plan to run 3 test test:ok(true, 'true') -- basic function local extra = { state = 'some userful information to debug on failure', details = 'a table argument formatted using yaml.encode()' } @@ -136,6 +137,20 @@ test:test('like', function(t) t:unlike('abcde', 'acd', 'unlike(abcde, acd)') end) +-- The test case implicitly checks that locals will not be printed while +-- checking the plan. +test:test('locals', function(t) + t.locals = true + t:plan(1) + t:test('locals nested', function(t) + local a = 42 + local tuple = box.tuple.new({}) + t:plan(2) + t:ok(true, 'locals are not printed in case of success') + t:fail('locals are printed in case of fail') + end) +end) + -- -- Finish root test. Since we used non-callback variant, we have to -- call check explicitly. -- 2.17.1