-- ROBLOX deviation: expected does not have string | RegExp type annotation

function formatReceived(
	label: string,
	thrown: Thrown, -- ROBLOX FIXME: narrowing | nil,
	key: string,
	expected: any -- ROBLOX FIXME: narrowing string | RegExp
)
	if thrown == nil then
		return ""
	end

	if key == "message" then
		local message = thrown.message

		if typeof(expected) == "string" then
			local index = message:find(expected)

			if index then
				return label .. printReceivedStringContainExpectedSubstring(message, index, #expected) .. "\n"
			end
		elseif getType(expected) == "regexp" then
			-- ROBLOX deviation: we don't check for expected.exec being a function
			-- since all RegExp polyfill instances have this function defined
			return label .. printReceivedStringContainExpectedResult(message, expected:exec(message)) .. "\n"
		end

		return label .. printReceived(message) .. "\n"
	end

	if key == "name" then
		if thrown.isError then
			return label .. printReceived(thrown.value.name) .. "\n"
		else
			return ""
		end
	end

	if key == "value" then
		if thrown.isError then
			return ""
		else
			return label .. printReceived(thrown.value) .. "\n"
		end
	end

	return ""
end

function formatStack(thrown: Thrown) -- ROBLOX FIXME: narrowing | nil)
	if thrown == nil or not thrown.isError then
		return ""
	else
		return formatStackTrace(thrown.value.stack)
	end
end

return {
	createMatcher = createMatcher,
	matchers = matchers,
}
