This commit is contained in:
lx
2026-07-06 14:01:11 -04:00
commit c4f97d729d
16468 changed files with 935321 additions and 0 deletions
@@ -0,0 +1,5 @@
# Generated by Rotriever. Format subject to change in future releases.
name = "jtaylor/mock"
version = "0.1.0"
commit = "d2c4005c863fd2f9fa74b7391ada64906d242847"
source = "git+https://github.com/roblox/mock#master"
@@ -0,0 +1,50 @@
-- Functions to check if a mock was ever called with given arguments.
local getCalls = require(script.Parent.getCalls)
local cmpLiteralArgs = require(script.Parent.cmpLiteralArgs)
local cmpPredicateArgs = require(script.Parent.cmpPredicateArgs)
local fmtArgs = require(script.Parent.fmtArgs)
local AnyCallMatches = {}
function AnyCallMatches.args(mock, test)
local callList = getCalls(mock)
local size = #callList
if size == 0 then
return false, "mock was not called"
end
local msg
for i = 1, size do
local result
result, msg = test(callList[i].args)
if result then
return true
end
end
if not msg then
msg = fmtArgs(callList[size].args) .. " did not match"
end
if size > 1 then
msg = msg .. " (+" .. (size - 1) .. " other calls)"
end
return false, msg
end
function AnyCallMatches.literals(mock, ...)
local expected = table.pack(...)
return AnyCallMatches.args(mock, function(actual)
return cmpLiteralArgs(expected, actual)
end)
end
function AnyCallMatches.predicates(mock, ...)
local predicates = table.pack(...)
return AnyCallMatches.args(mock, function(actual)
return cmpPredicateArgs(predicates, actual)
end)
end
return AnyCallMatches
@@ -0,0 +1,76 @@
local symbols = require(script.Parent.symbols)
local Spy = require(script.Parent.Spy)
local MagicMock = {}
local MetaMock = {}
function MetaMock:__index(key)
-- Any access to an undefined member will return a new MagicMock.
local meta = getmetatable(self)
local child = meta[symbols.Children][key]
if child == nil then
child = MagicMock.new()
meta[symbols.Children][key] = child
return child
elseif child == symbols.None then
return nil
else
return child
end
end
function MetaMock:__newindex(key, value)
-- Store any assigned values for later recall.
local meta = getmetatable(self)
if type(value) == "function" then
local _, wrapper = Spy.new(value)
value = wrapper
elseif value == nil then
value = symbols.None
end
if key == symbols.ReturnValue then
meta[symbols.ReturnValue] = { value, n=1 }
else
meta[symbols.Children][key] = value
end
end
function MetaMock:__call(...)
-- Any call to a MagicMock will store the args and then return the
-- ReturnValue (or call that if it's a function). If no return
-- value was set, this will create a new MagicMock.
local meta = getmetatable(self)
local call = {
args = table.pack(...),
result = meta[symbols.ReturnValue],
}
if call.result == nil then
local child = MagicMock.new()
call.result = { child, n=1 }
meta[symbols.ReturnValue] = call.result
elseif call.result == symbols.None then
call.result = { n=1 }
end
table.insert(meta[symbols.Calls], call)
return table.unpack(call.result)
end
function MagicMock.new(lock)
local mock = {
[symbols.Calls] = {},
[symbols.Children] = {},
[symbols.Lock] = lock,
[symbols.ReturnValue] = nil,
}
-- Copy the Meta functions from MetaMock
for k, v in pairs(MetaMock) do
mock[k] = v
end
return setmetatable({}, mock)
end
return MagicMock
@@ -0,0 +1,37 @@
-- Create a wrapper around a function to capture what arguments it was called
-- with.
local symbols = require(script.Parent.symbols)
local Spy = {}
Spy.__index = Spy
local spyLookup = {}
setmetatable(spyLookup, {__mode = "kv"})
function Spy.new(inner)
local spy = {
[symbols.Calls] = {}
}
setmetatable(spy, Spy)
local wrapper = function(...)
local call = {
args = table.pack(...),
result = table.pack(inner(...)),
}
table.insert(spy[symbols.Calls], call)
return table.unpack(call.result)
end
spy.inner = wrapper
spyLookup[wrapper] = spy
return spy, wrapper
end
function Spy.lookup(wrapper)
return spyLookup[wrapper]
end
return Spy
@@ -0,0 +1,17 @@
-- Compare two packed tables for shallow equality.
local fmtArgs = require(script.Parent.fmtArgs)
return function(e, a)
if e.n ~= a.n then
local msg = "number of literals in " .. fmtArgs(e) .. " does not match number of args in " .. fmtArgs(a)
return false, msg
end
for i = 1, e.n do
if e[i] ~= a[i] then
local msg = "expected " .. fmtArgs(e) .. ", got " .. fmtArgs(a)
return false, msg
end
end
return true
end
@@ -0,0 +1,17 @@
-- Compare a packed table with a packed table of predicates.
local fmtArgs = require(script.Parent.fmtArgs)
return function(p, x)
if p.n ~= x.n then
local msg = "number of args in " .. fmtArgs(x) .. " does not match number of predicates"
return false, msg
end
for i = 1, x.n do
if not p[i](x[i]) then
local msg = fmtArgs(x) .. " does not match predicates at position " .. i
return false, msg
end
end
return true
end
@@ -0,0 +1,11 @@
return function(args)
local msg = {}
for i = 1, args.n do
if type(args[i]) == "string" then
table.insert(msg, '"' .. args[i] .. '"')
else
table.insert(msg, tostring(args[i]))
end
end
return "{" .. table.concat(msg, ", ") .. "}"
end
@@ -0,0 +1,29 @@
local symbols = require(script.Parent.symbols)
local Spy = require(script.Parent.Spy)
return function(mock)
-- To support the usecase of invoking getCalls on a function
-- wrapped with a spy
if type(mock) == "function" then
local spy = Spy.lookup(mock)
if spy then
return spy[symbols.Calls]
end
error("Calling getCalls on a non-spy function")
end
-- To support the usecase of invoking getCalls on spy itself
local argsList = rawget(mock, symbols.Calls)
-- To support the usecase of invoking getCalls on MagicMock
if argsList == nil then
local meta = getmetatable(mock)
argsList = meta[symbols.Calls]
end
if argsList == nil then
error("Calling getCalls on a non-mock")
end
return argsList
end
@@ -0,0 +1,8 @@
local symbols = require(script.symbols)
return {
MagicMock = require(script.MagicMock),
AnyCallMatches = require(script.AnyCallMatches),
getCalls = require(script.getCalls),
Spy = require(script.Spy),
}
@@ -0,0 +1,16 @@
local function newSymbol(name)
local symbol = newproxy(true)
name = ("Mocks.%s"):format(name)
getmetatable(symbol).__tostring = function()
return name
end
return symbol
end
return {
Calls = newSymbol("Calls"),
Children = newSymbol("Children"),
Lock = newSymbol("Lock"),
None = newSymbol("None"),
ReturnValue = newSymbol("ReturnValue"),
}