print("\076\101\109\117\114\082\117\110\110\101\114\058 \076\111\097\100\105\110\103 \100\101\112\101\110\100\101\110\099\105\101\115\046\046\046")package.path=package.path.."\059\063\047\105\110\105\116\046\108\117\097"local R=require("\108\101\109\117\114")local s=R.Habitat.new()print("\076\101\109\117\114\082\117\110\110\101\114\058 \073\110\105\116\105\097\108\105\122\105\110\103 \099\111\110\115\116\097\110\116\115\046\046\046")local t={{"\067\108\105\101\110\116","\083\116\097\114\116\101\114\080\108\097\121\101\114\046\083\116\097\114\116\101\114\080\108\097\121\101\114\083\099\114\105\112\116\115"},{"\076\111\097\100\105\110\103";"\082\101\112\108\105\099\097\116\101\100\070\105\114\115\116\046\083\099\114\105\112\116\115"},{"\083\101\114\118\101\114";"\083\101\114\118\101\114\083\099\114\105\112\116\083\101\114\118\105\099\101"};{"\083\104\097\114\101\100","\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101\046\083\099\114\105\112\116\115"},{"\084\101\115\116\115";"\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101\046\084\101\115\116\115"};{"\077\111\100\117\108\101\115\047\084\101\115\116\069\090\047\115\114\099","\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101\046\084\101\115\116\115\046\084\101\115\116\069\090"}}print("\076\101\109\117\114\082\117\110\110\101\114\058 \067\111\110\115\116\114\117\099\116\105\110\103 \102\117\110\099\116\105\111\110\115\046\046\046")local function W(R)local s={}for R in string.gmatch(R,"\091\094\037\046\093\043")do table.insert(s,R)end return s end print("\076\101\109\117\114\082\117\110\110\101\114\058 \082\117\110\110\105\110\103\046\046\046")for R,t in ipairs(t)do local V=s:loadFromFs(t[1])local H=W(t[2])local Y=s.game:GetService(H[1])local k=false if#H==1 then k=true else for R=2,#H-1,1 do Y=Y:FindFirstChild(H[R])end local R=Y:FindFirstChild(H[#H])if R then Y=R k=true end end if k then for R,s in ipairs(V:GetChildren())do s.Parent=Y end V:Destroy()else V.Name=H[#H]V.Parent=Y end end local V=s.game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local H=s:require((V:WaitForChild("\084\101\115\116\115")):WaitForChild("\084\101\115\116\115"))local Y={V.Tests}local k,O=H(Y)local p=0 if k then if not O then print("\084\101\115\116\115 \104\097\118\101 \102\097\105\108\101\100\046")p=1 end else print(O)p=2 end print("\076\101\109\117\114\082\117\110\110\101\114\058 \068\111\110\101\046")os.exit(p)
--- The Lemur test runner script.
-- This script can run with Lemur to perform automated tests.
--
-- @author LastTalon
-- @version 0.1.0, 2020-10-15
-- @since 0.2
--
-- @module LemurTestRunner
-- @throws when the tests fail

-- Dependencies --
print("LemurRunner: Loading dependencies...")

-- Add init.lua to path allowing Lemur (and other dependencies to load)
package.path = package.path .. ";?/init.lua"

local Lemur = require("lemur")
local Habitat = Lemur.Habitat.new()

-- Constants --
print("LemurRunner: Initializing constants...")

--- The source locations to load in lemur
local Source = { -- This can potentially be loaded from a project.json
	{"Client", "StarterPlayer.StarterPlayerScripts"},
	{"Loading", "ReplicatedFirst.Scripts"},
	{"Server", "ServerScriptService"},
	{"Shared", "ReplicatedStorage.Scripts"},
	{"Tests", "ReplicatedStorage.Tests"},
	{"Modules/TestEZ/src", "ReplicatedStorage.Tests.TestEZ"}
}

-- Functions --
print("LemurRunner: Constructing functions...")

--- Tokenizes a habitat path.
-- @param path the path to tokenize
-- @return a table of the tokens
local function tokenizePath(path)
	local tokens = {}
	for token in string.gmatch(path, "[^%.]+") do
		table.insert(tokens, token)
	end
	return tokens
end

-- Main --
print("LemurRunner: Running...")

-- Build the project in Lemur
for _, pair in ipairs(Source) do
	local source = Habitat:loadFromFs(pair[1])
	local tokens = tokenizePath(pair[2])
	local container = Habitat.game:GetService(tokens[1])
	local containerExists = false

	-- Find the object we're placing this source in
	if #tokens == 1 then
		containerExists = true
	else
		for i = 2, #tokens - 1 do
			container = container:FindFirstChild(tokens[i])
		end
		local object = container:FindFirstChild(tokens[#tokens])
		if object then
			container = object
			containerExists = true
		end
	end

	-- If the final container exists place everything inside.
	if containerExists then
		for _, object in ipairs(source:GetChildren()) do
			object.Parent = container
		end
		source:Destroy()
	else -- If it doesn't, replace it
		source.Name = tokens[#tokens]
		source.Parent = container
	end
end

-- Load variables dependent on the build
local ReplicatedStorage = Habitat.game:GetService("ReplicatedStorage")
local Tests = Habitat:require(ReplicatedStorage:WaitForChild("Tests"):WaitForChild("Tests"))
local Roots = {ReplicatedStorage.Tests}

-- Run tests and set up exit status
local completed, result = Tests(Roots)
local status = 0

-- Determine and report results
if completed then
	if not result then
		print("Tests have failed.")
		status = 1
	end
else
	print(result)
	status = 2
end

-- End --
print("LemurRunner: Done.")

os.exit(status)
