/usr/share/lua/5.1/luassert/state.lua is in lua-luassert 1.7.9-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | -- maintains a state of the assert engine in a linked-list fashion
-- records; formatters, parameters, spies and stubs
local state_mt = {
__call = function(self)
self:revert()
end
}
local spies_mt = { __mode = "kv" }
local nilvalue = {} -- unique ID to refer to nil values for parameters
-- will hold the current state
local current
-- exported module table
local state = {}
------------------------------------------------------
-- Reverts to a (specific) snapshot.
-- @param self (optional) the snapshot to revert to. If not provided, it will revert to the last snapshot.
state.revert = function(self)
if not self then
-- no snapshot given, so move 1 up
self = current
if not self.previous then
-- top of list, no previous one, nothing to do
return
end
end
if getmetatable(self) ~= state_mt then error("Value provided is not a valid snapshot", 2) end
if self.next then
self.next:revert()
end
-- revert formatters in 'last'
self.formatters = {}
-- revert parameters in 'last'
self.parameters = {}
-- revert spies/stubs in 'last'
for s,_ in pairs(self.spies) do
self.spies[s] = nil
s:revert()
end
setmetatable(self, nil) -- invalidate as a snapshot
current = self.previous
current.next = nil
end
------------------------------------------------------
-- Creates a new snapshot.
-- @return snapshot table
state.snapshot = function()
local s = current
local new = setmetatable ({
formatters = {},
parameters = {},
spies = setmetatable({}, spies_mt),
previous = current,
revert = state.revert,
}, state_mt)
if current then current.next = new end
current = new
return current
end
-- FORMATTERS
state.add_formatter = function(callback)
table.insert(current.formatters, 1, callback)
end
state.remove_formatter = function(callback, s)
s = s or current
for i, v in ipairs(s.formatters) do
if v == callback then
table.remove(s.formatters, i)
break
end
end
-- wasn't found, so traverse up 1 state
if s.previous then
state.remove_formatter(callback, s.previous)
end
end
state.format_argument = function(val, s, fmtargs)
s = s or current
for _, fmt in ipairs(s.formatters) do
local valfmt = fmt(val, fmtargs)
if valfmt ~= nil then return valfmt end
end
-- nothing found, check snapshot 1 up in list
if s.previous then
return state.format_argument(val, s.previous, fmtargs)
end
return nil -- end of list, couldn't format
end
-- PARAMETERS
state.set_parameter = function(name, value)
if value == nil then value = nilvalue end
current.parameters[name] = value
end
state.get_parameter = function(name, s)
s = s or current
local val = s.parameters[name]
if val == nil and s.previous then
-- not found, so check 1 up in list
return state.get_parameter(name, s.previous)
end
if val ~= nilvalue then
return val
end
return nil
end
-- SPIES / STUBS
state.add_spy = function(spy)
current.spies[spy] = true
end
state.snapshot() -- create initial state
return state
|