return function()local g=require(script.Parent.watchDatamodel)local function r(g,r)return g[r]~=nil end describe("\114\101\116\117\114\110 \118\097\108\117\101",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \097 \116\097\098\108\101",function()(expect(g)).to.be.ok();(expect(type(g))).to.equal("\116\097\098\108\101")end)end)describe("\110\101\119",function()it("\115\104\111\117\108\100 \114\101\113\117\105\114\101 \097 \114\111\111\116",function()(expect(function()g.new()end)).to.throw();(expect(function()g.new({})end)).to.never.throw()end)end)describe("\119\105\116\104\083\105\103\110\097\108",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \116\104\101 \111\114\105\103\105\110\097\108 \111\098\106\101\099\116",function()local r=g.new({});(expect(r:withSignal())).to.equal(r)end)end)describe("\102\105\110\100\079\108\100\083\099\114\105\112\116\115",function()it("\115\104\111\117\108\100 \115\099\097\110 \097 \108\105\115\116 \111\102 \115\099\114\105\112\116 \111\098\106\101\099\116\115 \103\105\118\101\110 \114\111\111\116\115",function()local r=Instance.new("\070\111\108\100\101\114")local m=g.new({r})m:findOldScripts();(expect(m)).to.be.ok()m:destruct()r:Destroy()end)it("\115\104\111\117\108\100 \103\097\116\104\101\114 \109\111\100\117\108\101 \115\099\114\105\112\116\115 \111\110\108\121",function()local m=Instance.new("\070\111\108\100\101\114")local H=Instance.new("\077\111\100\117\108\101\083\099\114\105\112\116",m)local n=Instance.new("\070\111\108\100\101\114",m)local S=Instance.new("\076\111\099\097\108\083\099\114\105\112\116",m)local N=g.new({m})N:findOldScripts();(expect(N)).to.be.ok();(expect(r(N:getModuleCache(),H))).to.equal(true);(expect(r(N:getModuleCache(),n))).to.equal(false);(expect(r(N:getModuleCache(),S))).to.equal(false)N:destruct()m:Destroy()S:Destroy()n:Destroy()H:Destroy()end)end)describe("\119\097\116\099\104\070\111\114\078\101\119\083\099\114\105\112\116\115",function()it("\115\104\111\117\108\100 \102\105\114\101 \119\104\101\110 \097 \110\101\119 \115\099\114\105\112\116 \105\115 \097\100\100\101\100 \116\111 \097 \114\111\111\116",function()local m=Instance.new("\070\111\108\100\101\114")local H=g.new({m})H:watchForNewScripts()local n=Instance.new("\070\111\108\100\101\114",m);(expect(r(H:getModuleCache(),n))).to.equal(false)local S=Instance.new("\077\111\100\117\108\101\083\099\114\105\112\116",m);(expect(r(H:getModuleCache(),S))).to.equal(true)H:destruct()m:Destroy()n:Destroy()S:Destroy()end)end)describe("\115\116\097\114\116",function()it("\115\104\111\117\108\100 \101\120\101\099\117\116\101 \119\105\116\104\111\117\116 \105\115\115\117\101",function()local r=Instance.new("\070\111\108\100\101\114")local m=g.new({r})m:start()r:Destroy()m:destruct()end)it("\115\104\111\117\108\100 \097\100\100 \097 \110\101\119 \115\099\114\105\112\116 \116\111 \099\097\099\104\101 \097\110\100 \102\105\114\101 \119\104\101\110 \116\104\101 \115\111\117\114\099\101 \099\104\097\110\103\101\115",function()local m=Instance.new("\070\111\108\100\101\114")local H=Instance.new("\066\105\110\100\097\098\108\101\069\118\101\110\116")local n=(g.new({m})):withSignal(H)local S=0 H.Event:Connect(function()S=S+1 end)n:start();(expect(S)).to.equal(0)local N=Instance.new("\077\111\100\117\108\101\083\099\114\105\112\116",m);(expect(S)).to.equal(0);(expect(r(n:getModuleCache(),N))).to.equal(true)N.Source="\114\101\116\117\114\110 \116\114\117\101";(expect(S)).to.equal(1)N.Source="\114\101\116\117\114\110 \102\097\108\115\101";(expect(S)).to.equal(2)H:Destroy()m:Destroy()n:destruct()end)end)end
return function()
	local watchDatamodel = require(script.Parent.watchDatamodel)

	local function find(table, value)
		return table[value] ~= nil
	end

	describe("return value", function()
		it("should return a table", function()
			expect(watchDatamodel).to.be.ok()
			expect(type(watchDatamodel)).to.equal("table")
		end)
	end)

	describe("new", function()
		it("should require a root", function()
			expect(function()
				watchDatamodel.new()
			end).to.throw()

			expect(function()
				watchDatamodel.new({})
			end).to.never.throw()
		end)
	end)

	describe("withSignal", function()
		it("should return the original object", function()
			local watcher = watchDatamodel.new({})
			expect(watcher:withSignal()).to.equal(watcher)
		end)
	end)

	describe("findOldScripts", function()
		it("should scan a list of script objects given roots", function()
			local folder = Instance.new("Folder")
			local watcher = watchDatamodel.new({folder})
			watcher:findOldScripts()

			expect(watcher).to.be.ok()
			watcher:destruct()
			folder:Destroy()
		end)

		it("should gather module scripts only", function()
			local folder = Instance.new("Folder")
			local module1 = Instance.new("ModuleScript", folder)
			local folder2 = Instance.new("Folder", folder)
			local script1 = Instance.new("LocalScript", folder)
			local watcher = watchDatamodel.new({folder})
			watcher:findOldScripts()

			expect(watcher).to.be.ok()
			expect(find(watcher:getModuleCache(), module1)).to.equal(true)
			expect(find(watcher:getModuleCache(), folder2)).to.equal(false)
			expect(find(watcher:getModuleCache(), script1)).to.equal(false)
			watcher:destruct()
			folder:Destroy()
			script1:Destroy()
			folder2:Destroy()
			module1:Destroy()
		end)
	end)

	describe("watchForNewScripts", function()
		it("should fire when a new script is added to a root", function()
			local folder = Instance.new("Folder")
			local watcher = watchDatamodel.new({folder})

			watcher:watchForNewScripts()
			local folder2 = Instance.new("Folder", folder)
			expect(find(watcher:getModuleCache(), folder2)).to.equal(false)

			local module = Instance.new("ModuleScript", folder)
			expect(find(watcher:getModuleCache(), module)).to.equal(true)

			watcher:destruct()
			folder:Destroy()
			folder2:Destroy()
			module:Destroy()
		end)
	end)

	describe("start", function()
		it("should execute without issue", function()
			local folder = Instance.new("Folder")
			local watcher = watchDatamodel.new({folder})

			watcher:start()

			folder:Destroy()
			watcher:destruct()
		end)

		it("should add a new script to cache and fire when the source changes", function()
			local folder = Instance.new("Folder")
			local signal = Instance.new("BindableEvent")
			local watcher = watchDatamodel.new({folder}):withSignal(signal)

			local sum = 0
			signal.Event:Connect(function()
				sum = sum + 1
			end)

			watcher:start()
			expect(sum).to.equal(0)
			local module = Instance.new("ModuleScript", folder)
			expect(sum).to.equal(0)
			expect(find(watcher:getModuleCache(), module)).to.equal(true)
			module.Source = "return true"
			expect(sum).to.equal(1)
			module.Source = "return false"
			expect(sum).to.equal(2)

			signal:Destroy()
			folder:Destroy()
			watcher:destruct()
		end)
	end)
end