diff options
Diffstat (limited to 'extras/luacov/src/luacov.lua')
-rw-r--r-- | extras/luacov/src/luacov.lua | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/extras/luacov/src/luacov.lua b/extras/luacov/src/luacov.lua new file mode 100644 index 0000000..a44333a --- /dev/null +++ b/extras/luacov/src/luacov.lua @@ -0,0 +1,95 @@ + +local M = {} + +local stats = require("luacov.stats") +local data = stats.load() +local statsfile = stats.start() +M.statsfile = statsfile + +local tick = package.loaded["luacov.tick"] +local ctr = 0 +local luacovlock = os.tmpname() + +local booting = true +local skip = {} +M.skip = skip + +local function on_line(_, line_nr) + if tick then + ctr = ctr + 1 + if ctr == 100 then + ctr = 0 + stats.save(data, statsfile) + end + end + + -- get name of processed file; ignore Lua code loaded from raw strings + local name = debug.getinfo(2, "S").source + if not name:match("^@") then + return + end + name = name:sub(2) + + -- skip 'luacov.lua' in coverage report + if booting then + skip[name] = true + booting = false + end + + if skip[name] then + return + end + + local file = data[name] + if not file then + file = {max=0} + data[name] = file + end + if line_nr > file.max then + file.max = line_nr + end + file[line_nr] = (file[line_nr] or 0) + 1 +end + +local function on_exit() + os.remove(luacovlock) + stats.save(data, statsfile) + stats.stop(statsfile) +end + +local function init() + if not tick then + M.on_exit_trick = io.open(luacovlock, "w") + debug.setmetatable(M.on_exit_trick, { __gc = on_exit } ) + end + + debug.sethook(on_line, "l") + + local rawcoroutinecreate = coroutine.create + coroutine.create = function(...) + local co = rawcoroutinecreate(...) + debug.sethook(co, on_line, "l") + return co + end + coroutine.wrap = function(...) + local co = rawcoroutinecreate(...) + debug.sethook(co, on_line, "l") + return function() + local r = { coroutine.resume(co) } + if not r[1] then + error(r[2]) + end + return unpack(r, 2) + end + end + + local rawexit = os.exit + os.exit = function(...) + on_exit() + rawexit(...) + end +end + +init() + +return M
|