local E=game:GetService("\084\101\115\116\083\101\114\118\105\099\101")local p=require(script.Parent.Parent.TestEnum)local n={}local function h(E)E=string.gsub(E,"\040\091\093\124\'\091\093\041","\124\037\049")E=string.gsub(E,"\r","\124\114")E=string.gsub(E,"\n","\124\110")return E end local function f(E)return string.format("\035\035\116\101\097\109\099\105\116\121\091\116\101\115\116\083\117\105\116\101\083\116\097\114\116\101\100 \110\097\109\101\061\'\037\115\'\093",h(E))end local function M(E)return string.format("\035\035\116\101\097\109\099\105\116\121\091\116\101\115\116\083\117\105\116\101\070\105\110\105\115\104\101\100 \110\097\109\101\061\'\037\115\'\093",h(E))end local function c(E)return string.format("\035\035\116\101\097\109\099\105\116\121\091\116\101\115\116\083\116\097\114\116\101\100 \110\097\109\101\061\'\037\115\'\093",h(E))end local function m(E)return string.format("\035\035\116\101\097\109\099\105\116\121\091\116\101\115\116\070\105\110\105\115\104\101\100 \110\097\109\101\061\'\037\115\'\093",h(E))end local function T(E,p)return string.format("\035\035\116\101\097\109\099\105\116\121\091\116\101\115\116\070\097\105\108\101\100 \110\097\109\101\061\'\037\115\' \109\101\115\115\097\103\101\061\'\037\115\'\093",h(E),h(p))end local function a(E,n,h)n=n or{}h=h or 0 if E.status==p.TestStatus.Skipped then return n end if E.planNode.type==p.NodeType.Describe then table.insert(n,f(E.planNode.phrase))for E,p in ipairs(E.children)do a(p,n,h+1)end table.insert(n,M(E.planNode.phrase))else table.insert(n,c(E.planNode.phrase))if E.status==p.TestStatus.Failure then table.insert(n,T(E.planNode.phrase,table.concat(E.errors,"\n")))end table.insert(n,m(E.planNode.phrase))end end local function r(E)local p={}for E,n in ipairs(E.children)do a(n,p,0)end return p end local function y(E)local p=r(E)return table.concat(p,"\n")end function n.report(p)local n={"\084\101\115\116 \114\101\115\117\108\116\115\058",y(p),("\037\100 \112\097\115\115\101\100\044 \037\100 \102\097\105\108\101\100\044 \037\100 \115\107\105\112\112\101\100"):format(p.successCount,p.failureCount,p.skippedCount)}print(table.concat(n,"\n"))if p.failureCount>0 then print(("\037\100 \116\101\115\116 \110\111\100\101\115 \114\101\112\111\114\116\101\100 \102\097\105\108\117\114\101\115\046"):format(p.failureCount))end if#p.errors>0 then print("\069\114\114\111\114\115 \114\101\112\111\114\116\101\100 \098\121 \116\101\115\116\115\058")print("")for p,n in ipairs(p.errors)do E:Error(n)print("")end end end return n
local TestService = game:GetService("TestService")

local TestEnum = require(script.Parent.Parent.TestEnum)

local TeamCityReporter = {}

local function teamCityEscape(str)
	str = string.gsub(str, "([]|'[])","|%1")
	str = string.gsub(str, "\r", "|r")
	str = string.gsub(str, "\n", "|n")
	return str
end

local function teamCityEnterSuite(suiteName)
	return string.format("##teamcity[testSuiteStarted name='%s']", teamCityEscape(suiteName))
end

local function teamCityLeaveSuite(suiteName)
	return string.format("##teamcity[testSuiteFinished name='%s']", teamCityEscape(suiteName))
end

local function teamCityEnterCase(caseName)
	return string.format("##teamcity[testStarted name='%s']", teamCityEscape(caseName))
end

local function teamCityLeaveCase(caseName)
	return string.format("##teamcity[testFinished name='%s']", teamCityEscape(caseName))
end

local function teamCityFailCase(caseName, errorMessage)
	return string.format("##teamcity[testFailed name='%s' message='%s']",
		teamCityEscape(caseName), teamCityEscape(errorMessage))
end

local function reportNode(node, buffer, level)
	buffer = buffer or {}
	level = level or 0
	if node.status == TestEnum.TestStatus.Skipped then
		return buffer
	end
	if node.planNode.type == TestEnum.NodeType.Describe then
		table.insert(buffer, teamCityEnterSuite(node.planNode.phrase))
		for _, child in ipairs(node.children) do
			reportNode(child, buffer, level + 1)
		end
		table.insert(buffer, teamCityLeaveSuite(node.planNode.phrase))
	else
		table.insert(buffer, teamCityEnterCase(node.planNode.phrase))
		if node.status == TestEnum.TestStatus.Failure then
			table.insert(buffer, teamCityFailCase(node.planNode.phrase, table.concat(node.errors,"\n")))
		end
		table.insert(buffer, teamCityLeaveCase(node.planNode.phrase))
	end
end

local function reportRoot(node)
	local buffer = {}

	for _, child in ipairs(node.children) do
		reportNode(child, buffer, 0)
	end

	return buffer
end

local function report(root)
	local buffer = reportRoot(root)

	return table.concat(buffer, "\n")
end

function TeamCityReporter.report(results)
	local resultBuffer = {
		"Test results:",
		report(results),
		("%d passed, %d failed, %d skipped"):format(
			results.successCount,
			results.failureCount,
			results.skippedCount
		)
	}

	print(table.concat(resultBuffer, "\n"))

	if results.failureCount > 0 then
		print(("%d test nodes reported failures."):format(results.failureCount))
	end

	if #results.errors > 0 then
		print("Errors reported by tests:")
		print("")

		for _, message in ipairs(results.errors) do
			TestService:Error(message)

			-- Insert a blank line after each error
			print("")
		end
	end
end

return TeamCityReporter