-- ROBLOX deviation: matchersObject annotated as { [string]: any } for now rather than { [string]: RawMatcherFn }
-- because we cannot currently express RawMatcherFn as tuple

type MatchersObject = { [string]: any }

local spyMatchers: MatchersObject = {
	lastCalledWith = createLastCalledWithMatcher("lastCalledWith"),
	lastReturnedWith = createLastReturnedMatcher("lastReturnedWith"),
	nthCalledWith = createNthCalledWithMatcher("nthCalledWith"),
	nthReturnedWith = createNthReturnedWithMatcher("nthReturnedWith"),
	toBeCalled = createToBeCalledMatcher("toBeCalled"),
	toBeCalledTimes = createToBeCalledTimesMatcher("toBeCalledTimes"),
	toBeCalledWith = createToBeCalledWithMatcher("toBeCalledWith"),
	toHaveBeenCalled = createToBeCalledMatcher("toHaveBeenCalled"),
	toHaveBeenCalledTimes = createToBeCalledTimesMatcher("toHaveBeenCalledTimes"),
	toHaveBeenCalledWith = createToBeCalledWithMatcher("toHaveBeenCalledWith"),
	toHaveBeenLastCalledWith = createLastCalledWithMatcher("toHaveBeenLastCalledWith"),
	toHaveBeenNthCalledWith = createNthCalledWithMatcher("toHaveBeenNthCalledWith"),
	toHaveLastReturnedWith = createLastReturnedMatcher("toHaveLastReturnedWith"),
	toHaveNthReturnedWith = createNthReturnedWithMatcher("toHaveNthReturnedWith"),
	toHaveReturned = createToReturnMatcher("toHaveReturned"),
	toHaveReturnedTimes = createToReturnTimesMatcher("toHaveReturnedTimes"),
	toHaveReturnedWith = createToReturnWithMatcher("toHaveReturnedWith"),
	toReturn = createToReturnMatcher("toReturn"),
	toReturnTimes = createToReturnTimesMatcher("toReturnTimes"),
	toReturnWith = createToReturnWithMatcher("toReturnWith"),
}

function isMock(received: any)
	return received ~= nil and typeof(received) == "table" and received._isMockFunction == true
end

function isSpy(received: any)
	return received ~= nil
		and typeof(received) == "table"
		and received.calls ~= nil
		and typeof(received.calls.all) == "function"
		and typeof(received.calls.count) == "function"
end
