local l=require(script.Parent.assertDeepEqual)local function u(u)local k={callCount=0,values={};valuesLength=0}k.value=function(...)k.callCount=k.callCount+1 k.values={...}k.valuesLength=select("\035",...)if u~=nil then return u(...)end end k.assertCalledWith=function(l,...)local u=select("\035",...)if k.valuesLength~=u 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(k.valuesLength,u),2)end for l=1,u,1 do local u=select(l,...)assert(k.values[l]==u,"\118\097\108\117\101 \100\105\102\102\101\114\115")end end k.assertCalledWithDeepEqual=function(u,...)local T=select("\035",...)if k.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(k.valuesLength,T),2)end for u=1,T,1 do local T=select(u,...)l(k.values[u],T)end end k.captureValues=function(l,...)local u=select("\035",...)local T={}assert(k.valuesLength==u,"\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 l=1,u,1 do local u=select(l,...)T[u]=k.values[l]end return T end setmetatable(k,{__index=function(l,u)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(u))end})return k end return u


local assertDeepEqual = require(script.Parent.assertDeepEqual)

local function createSpy(inner)
	local self = {
		callCount = 0,
		values = {},
		valuesLength = 0,
	}

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

		if inner ~= nil then
			return inner(...)
		end
	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
