-- ROBLOX deviation: expected does not have Error type annotation

function toThrowExpectedObject(
	matcherName: string,
	options: JestMatcherUtils.MatcherHintOptions,
	thrown: Thrown | nil,
	expected: Error
): SyncExpectationResult
	local pass = thrown ~= nil and thrown.message == expected.message

	local message
	if pass then
		message = function()
			local retval = matcherHint(matcherName, nil, nil, options)
				.. "\n\n"
				.. formatExpected("Expected message: never ", expected.message)

			if thrown ~= nil and thrown.hasMessage and not thrown.value["$$robloxInternalJestError"] then
				retval = retval .. formatStack(thrown)
			else
				retval = retval .. formatReceived("Received value:         ", thrown, "message") .. formatStack(thrown)
			end

			return retval
		end
	else
		message = function()
			local retval = matcherHint(matcherName, nil, nil, options) .. "\n\n"

			if thrown == nil then
				retval = retval .. formatExpected("Expected message: ", expected.message) .. "\n" .. DID_NOT_THROW
			else
				if thrown.hasMessage and not thrown.value["$$robloxInternalJestError"] then
					retval = retval
						.. printDiffOrStringify(
							expected.message,
							thrown.message,
							"Expected message",
							"Received message",
							true
						)
						.. "\n"
						.. formatStack(thrown)
				else
					retval = retval
						.. formatExpected("Expected message: ", expected.message)
						.. formatReceived("Received value:   ", thrown, "message")
						.. formatStack(thrown)
				end
			end

			return retval
		end
	end

	return { message = message, pass = pass }
end
