local Y=require(script.Parent.assertDeepEqual)local function Q(Q)local c={}c.callCount=0 c.values={}c.valuesLength=0 c.value=function(...)c.callCount=c.callCount+1 c.values={...}c.valuesLength=select("\035",...)if Q~=nil then return Q(...)end return nil end c.assertCalledWith=function(Y,...)local Q=select("\035",...)if c.valuesLength~=Q then error(("\069\120\112\101\099\116\101\100 \037\100 \097\114\103\117\109\101\110\116\115\044 \098\117\116 \119\097\115 \099\097\108\108\101\100 \119\105\116\104 \037\100 \097\114\103\117\109\101\110\116\115"):format(c.valuesLength,Q),2)end for Y=1,Q,1 do local Q=select(Y,...)assert(c.values[Y]==Q,"\118\097\108\117\101 \100\105\102\102\101\114\115")end end c.assertCalledWithDeepEqual=function(Q,...)local T=select("\035",...)if c.valuesLength~=T then error(("\069\120\112\101\099\116\101\100 \037\100 \097\114\103\117\109\101\110\116\115\044 \098\117\116 \119\097\115 \099\097\108\108\101\100 \119\105\116\104 \037\100 \097\114\103\117\109\101\110\116\115"):format(c.valuesLength,T),2)end for Q=1,T,1 do local T=select(Q,...)Y(c.values[Q],T)end end c.captureValues=function(Y,...)local Q=select("\035",...)local T={}assert(c.valuesLength==Q,"\108\101\110\103\116\104 \111\102 \101\120\112\101\099\116\101\100 \118\097\108\117\101\115 \100\105\102\102\101\114\115 \102\114\111\109 \115\116\111\114\101\100 \118\097\108\117\101\115")for Y=1,Q,1 do local Q=select(Y,...)T[Q]=c.values[Y]end return T end setmetatable(c,{__index=function(Y,Q)error(("\037\113 \105\115 \110\111\116 \097 \118\097\108\105\100 \109\101\109\098\101\114 \111\102 \115\112\121"):format(Q))end})return c end return Q


local assertDeepEqual = require(script.Parent.assertDeepEqual)

local function createSpy(inner)
	local self = {}
	self.callCount = 0
	self.values = {}
	self.valuesLength = 0
	self.value = function(...)
		self.callCount = self.callCount + 1
		self.values = { ... }
		self.valuesLength = select("#", ...)

		if inner ~= nil then
			return inner(...)
		end
		return nil
	end

	self.assertCalledWith = function(_, ...)
		local len = select("#", ...)

		if self.valuesLength ~= len then
			error(("Expected %d arguments, but was called with %d arguments"):format(self.valuesLength, len), 2)
		end

		for i = 1, len do
			local expected = select(i, ...)

			assert(self.values[i] == expected, "value differs")
		end
	end

	self.assertCalledWithDeepEqual = function(_, ...)
		local len = select("#", ...)

		if self.valuesLength ~= len then
			error(("Expected %d arguments, but was called with %d arguments"):format(self.valuesLength, len), 2)
		end

		for i = 1, len do
			local expected = select(i, ...)

			assertDeepEqual(self.values[i], expected)
		end
	end

	self.captureValues = function(_, ...)
		local len = select("#", ...)
		local result = {}

		assert(self.valuesLength == len, "length of expected values differs from stored values")

		for i = 1, len do
			local key = select(i, ...)
			result[key] = self.values[i]
		end

		return result
	end

	setmetatable(self, {
		__index = function(_, key)
			error(("%q is not a valid member of spy"):format(key))
		end,
	})

	return self
end

return createSpy
