This file is indexed.

/usr/share/lua/5.1/luassert/spy.lua is in lua-luassert 1.7.10-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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
-- module will return spy table, and register its assertions with the main assert engine
local assert = require('luassert.assert')
local util = require('luassert.util')

-- Spy metatable
local spy_mt = {
  __call = function(self, ...)
    local arguments = {...}
    arguments.n = select('#',...)  -- add argument count for trailing nils
    table.insert(self.calls, util.copyargs(arguments))
    local function get_returns(...)
      local returnvals = {...}
      returnvals.n = select('#',...)  -- add argument count for trailing nils
      table.insert(self.returnvals, util.copyargs(returnvals))
      return ...
    end
    return get_returns(self.callback(...))
  end
}

local spy   -- must make local before defining table, because table contents refers to the table (recursion)
spy = {
  new = function(callback)
    if not util.callable(callback) then
      error("Cannot spy on type '" .. type(callback) .. "', only on functions or callable elements", util.errorlevel())
    end
    local s = setmetatable({
      calls = {},
      returnvals = {},
      callback = callback,

      target_table = nil, -- these will be set when using 'spy.on'
      target_key = nil,

      revert = function(self)
        if not self.reverted then
          if self.target_table and self.target_key then
            self.target_table[self.target_key] = self.callback
          end
          self.reverted = true
        end
        return self.callback
      end,

      clear = function(self)
        self.calls = {}
        self.returnvals = {}
        return self
      end,

      called = function(self, times, compare)
        if times or compare then
          local compare = compare or function(count, expected) return count == expected end
          return compare(#self.calls, times), #self.calls
        end

        return (#self.calls > 0), #self.calls
      end,

      called_with = function(self, args)
        return util.matchargs(self.calls, args) ~= nil
      end,

      returned_with = function(self, args)
        return util.matchargs(self.returnvals, args) ~= nil
      end
    }, spy_mt)
    assert:add_spy(s)  -- register with the current state
    return s
  end,

  is_spy = function(object)
    return type(object) == "table" and getmetatable(object) == spy_mt
  end,

  on = function(target_table, target_key)
    local s = spy.new(target_table[target_key])
    target_table[target_key] = s
    -- store original data
    s.target_table = target_table
    s.target_key = target_key

    return s
  end
}

local function set_spy(state, arguments, level)
  state.payload = arguments[1]
  if arguments[2] ~= nil then
    state.failure_message = arguments[2]
  end
end

local function returned_with(state, arguments, level)
  local level = (level or 1) + 1
  local payload = rawget(state, "payload")
  if payload and payload.returned_with then
    return state.payload:returned_with(arguments)
  else
    error("'returned_with' must be chained after 'spy(aspy)'", level)
  end
end

local function called_with(state, arguments, level)
  local level = (level or 1) + 1
  local payload = rawget(state, "payload")
  if payload and payload.called_with then
    return state.payload:called_with(arguments)
  else
    error("'called_with' must be chained after 'spy(aspy)'", level)
  end
end

local function called(state, arguments, level, compare)
  local level = (level or 1) + 1
  local num_times = arguments[1]
  if not num_times and not state.mod then
    state.mod = true
    num_times = 0
  end
  local payload = rawget(state, "payload")
  if payload and type(payload) == "table" and payload.called then
    local result, count = state.payload:called(num_times, compare)
    arguments[1] = tostring(num_times or ">0")
    util.tinsert(arguments, 2, tostring(count))
    arguments.nofmt = arguments.nofmt or {}
    arguments.nofmt[1] = true
    arguments.nofmt[2] = true
    return result
  elseif payload and type(payload) == "function" then
    error("When calling 'spy(aspy)', 'aspy' must not be the original function, but the spy function replacing the original", level)
  else
    error("'called' must be chained after 'spy(aspy)'", level)
  end
end

local function called_at_least(state, arguments, level)
  local level = (level or 1) + 1
  return called(state, arguments, level, function(count, expected) return count >= expected end)
end

local function called_at_most(state, arguments, level)
  local level = (level or 1) + 1
  return called(state, arguments, level, function(count, expected) return count <= expected end)
end

local function called_more_than(state, arguments, level)
  local level = (level or 1) + 1
  return called(state, arguments, level, function(count, expected) return count > expected end)
end

local function called_less_than(state, arguments, level)
  local level = (level or 1) + 1
  return called(state, arguments, level, function(count, expected) return count < expected end)
end

assert:register("modifier", "spy", set_spy)
assert:register("assertion", "returned_with", returned_with, "assertion.returned_with.positive", "assertion.returned_with.negative")
assert:register("assertion", "called_with", called_with, "assertion.called_with.positive", "assertion.called_with.negative")
assert:register("assertion", "called", called, "assertion.called.positive", "assertion.called.negative")
assert:register("assertion", "called_at_least", called_at_least, "assertion.called_at_least.positive", "assertion.called_less_than.positive")
assert:register("assertion", "called_at_most", called_at_most, "assertion.called_at_most.positive", "assertion.called_more_than.positive")
assert:register("assertion", "called_more_than", called_more_than, "assertion.called_more_than.positive", "assertion.called_at_most.positive")
assert:register("assertion", "called_less_than", called_less_than, "assertion.called_less_than.positive", "assertion.called_at_least.positive")

return setmetatable(spy, {
  __call = function(self, ...)
    return spy.new(...)
  end
})