local l=game:GetService("\084\101\115\116\083\101\114\118\105\099\101")local E=require(script.Parent.Parent.TestEnum)local W=(" "):rep(3)local G={[E.TestStatus.Success]="\043",[E.TestStatus.Failure]="-",[E.TestStatus.Skipped]="~"}local h="\063"local C={}local function S(l,E)return l.planNode.phrase:lower()<E.planNode.phrase:lower()end local function t(l,C,V)C=C or{}V=V or 0 if l.status==E.TestStatus.Skipped then return C end local o if l.status then local E=G[l.status]or h o=("\037\115\091\037\115\093 \037\115"):format(W:rep(V),E,l.planNode.phrase)else o=("\037\115\037\115"):format(W:rep(V),l.planNode.phrase)end table.insert(C,o)table.sort(l.children,S)for l,E in ipairs(l.children)do t(E,C,V+1)end return C end local function V(l)local E={}table.sort(l.children,S)for l,W in ipairs(l.children)do t(W,E,0)end return E end local function o(l)local E=V(l)return table.concat(E,"\n")end function C.report(E)local W={"\084\101\115\116 \114\101\115\117\108\116\115\058",o(E);("\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(E.successCount,E.failureCount,E.skippedCount)}print(table.concat(W,"\n"))if E.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(E.failureCount))end if#E.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 E,W in ipairs(E.errors)do l:Error(W)print("")end end end return C
--[[
	The TextReporter uses the results from a completed test to output text to
	standard output and TestService.
]]

local TestService = game:GetService("TestService")

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

local INDENT = (" "):rep(3)
local STATUS_SYMBOLS = {
	[TestEnum.TestStatus.Success] = "+",
	[TestEnum.TestStatus.Failure] = "-",
	[TestEnum.TestStatus.Skipped] = "~"
}
local UNKNOWN_STATUS_SYMBOL = "?"

local TextReporter = {}

local function compareNodes(a, b)
	return a.planNode.phrase:lower() < b.planNode.phrase:lower()
end

local function reportNode(node, buffer, level)
	buffer = buffer or {}
	level = level or 0

	if node.status == TestEnum.TestStatus.Skipped then
		return buffer
	end

	local line

	if node.status then
		local symbol = STATUS_SYMBOLS[node.status] or UNKNOWN_STATUS_SYMBOL

		line = ("%s[%s] %s"):format(
			INDENT:rep(level),
			symbol,
			node.planNode.phrase
		)
	else
		line = ("%s%s"):format(
			INDENT:rep(level),
			node.planNode.phrase
		)
	end

	table.insert(buffer, line)
	table.sort(node.children, compareNodes)

	for _, child in ipairs(node.children) do
		reportNode(child, buffer, level + 1)
	end

	return buffer
end

local function reportRoot(node)
	local buffer = {}
	table.sort(node.children, compareNodes)

	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 TextReporter.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 TextReporter