--- @classmod ProgrammableFn--- Creates an easily programmable function for testing purposes.-- Multiple behaviours can be defined.-- A behaviour consists of a set of arguments and a set of return values.-- If the function is called with these arguments it will return the programmed-- return values.
local ValueMatcher = require 'Module:Lua-mock/ValueMatcher'
local ProgrammableFn = ProgrammableFn.__index = ProgrammableFn
local function behaviourReturnValues(behaviour) local next = behaviour.nextReturnSet
local returnSet = behaviour.returnSets[next]
if next < #behaviour.returnSets then next = next + 1 else next = 1 end behaviour.nextReturnSet = next
return table.unpack(returnSet)end
function ProgrammableFn:__call(...) local behaviour = self:_findMatchingBehaviour if not behaviour then error('No matching behaviour for call.', 2) end return behaviourReturnValues(behaviour)end
function ProgrammableFn:_findMatchingBehaviour(arguments) for _,behaviour in ipairs(self.behaviours) do if ValueMatcher.matches(arguments, behaviour.arguments) then return behaviour end end return nilend
--- Creates a new behaviour entry or extends to one.---- @param specification-- The specification is a table, that contains the arguments that must match to-- trigger this behaviour and the values that will be returned then.-- Both are optional and can be passed like this:-- `whenCalled`function ProgrammableFn:whenCalled(specification) local arguments = specification.with or local returnSet = specification.thenReturn or
local behaviour = self:_findMatchingBehaviour(arguments) if behaviour then table.insert(behaviour.returnSets, returnSet) else behaviour = table.insert(self.behaviours, behaviour) end
return selfend
function ProgrammableFn:reset self.behaviours = return selfend
return function local self = return setmetatable(self, ProgrammableFn)end