local C=require(script.Parent.component)local J=(require(script.Parent.immutable)).None local E=C.newComponent local l=C.assertValidComponentInstance local f=C.assertValidComponent return function()describe("\067\111\109\112\111\110\101\110\116",function()it("\115\104\111\117\108\100 \099\114\101\097\116\101 \099\111\109\112\111\110\101\110\116\115",function()local C=E()local J=E();(expect(getmetatable(C))).to.be.ok();(expect(getmetatable(C))).to.never.equal(getmetatable(J));(expect(typeof(C.new))).to.equal("\102\117\110\099\116\105\111\110")end)it("\115\104\111\117\108\100 \097\108\108\111\119 \099\097\108\108\105\110\103 \116\104\101 \116\097\098\108\101 \116\111 \099\111\110\115\116\114\117\099\116",function()local C=E();(expect(getmetatable(C()))).to.equal(getmetatable(C.new()))end)it("\115\104\111\117\108\100 \097\108\108\111\119 \112\097\116\099\104\105\110\103 \105\110\116\111 \097 \110\101\119 \099\111\109\112\111\110\101\110\116",function()local C=E()local l=C({foo="\098\097\114",unset=true})local f=l:patch({baz="\113\117\120";unset=J});(expect(f.foo)).to.equal("\098\097\114");(expect(f.unset)).to.equal(nil);(expect(f.baz)).to.equal("\113\117\120")end)it("\115\104\111\117\108\100 \097\108\108\111\119 \115\112\101\099\105\102\121\105\110\103 \100\101\102\097\117\108\116 \100\097\116\097",function()local C=E("\070\111\111",{a=53})local J=C();(expect(J.a)).to.equal(53)local l=C({a=42,b=54});(expect(l.a)).to.equal(42);(expect(l.b)).to.equal(54)local f=C({b=100});(expect(f.a)).to.equal(53);(expect(f.b)).to.equal(100)end)end)describe("\097\115\115\101\114\116\086\097\108\105\100\067\111\109\112\111\110\101\110\116\073\110\115\116\097\110\099\101",function()it("\115\104\111\117\108\100 \116\104\114\111\119 \111\110 \105\110\118\097\108\105\100 \099\111\109\112\111\110\101\110\116\115",function()(expect(function()l({})end)).to.throw();(expect(function()l(55)end)).to.throw();(expect(function()l(E())end)).to.throw();(expect(function()l((E()).new())end)).never.to.throw()end)end)describe("\097\115\115\101\114\116\086\097\108\105\100\067\111\109\112\111\110\101\110\116",function()it("\115\104\111\117\108\100 \116\104\114\111\119 \111\110 \105\110\118\097\108\105\100 \099\111\109\112\111\110\101\110\116\115",function()(expect(function()f((E()).new())end)).to.throw();(expect(function()f(55)end)).to.throw();(expect(function()f(E())end)).never.to.throw()end)end)end
local Component = require(script.Parent.component)
local None = require(script.Parent.immutable).None
local component = Component.newComponent
local assertValidComponentInstance = Component.assertValidComponentInstance
local assertValidComponent = Component.assertValidComponent

return function()
	describe("Component", function()
		it("should create components", function()
			local a = component()
			local b = component()

			expect(getmetatable(a)).to.be.ok()

			expect(getmetatable(a)).to.never.equal(getmetatable(b))

			expect(typeof(a.new)).to.equal("function")
		end)

		it("should allow calling the table to construct", function()
			local a = component()

			expect(getmetatable(a())).to.equal(getmetatable(a.new()))
		end)

		it("should allow patching into a new component", function()
			local A = component()

			local a = A({
				foo = "bar",
				unset = true,
			})

			local a2 = a:patch({
				baz = "qux",
				unset = None,
			})

			expect(a2.foo).to.equal("bar")
			expect(a2.unset).to.equal(nil)
			expect(a2.baz).to.equal("qux")
		end)

		it("should allow specifying default data", function()
			local Foo = component("Foo", {
				a = 53,
			})

			local foo = Foo()

			expect(foo.a).to.equal(53)

			local bar = Foo({
				a = 42,
				b = 54,
			})

			expect(bar.a).to.equal(42)
			expect(bar.b).to.equal(54)

			local baz = Foo({
				b = 100,
			})

			expect(baz.a).to.equal(53)
			expect(baz.b).to.equal(100)
		end)
	end)

	describe("assertValidComponentInstance", function()
		it("should throw on invalid components", function()
			expect(function()
				assertValidComponentInstance({})
			end).to.throw()

			expect(function()
				assertValidComponentInstance(55)
			end).to.throw()

			expect(function()
				assertValidComponentInstance(component())
			end).to.throw()

			expect(function()
				assertValidComponentInstance(component().new())
			end).never.to.throw()
		end)
	end)

	describe("assertValidComponent", function()
		it("should throw on invalid components", function()
			expect(function()
				assertValidComponent(component().new())
			end).to.throw()

			expect(function()
				assertValidComponent(55)
			end).to.throw()

			expect(function()
				assertValidComponent(component())
			end).never.to.throw()
		end)
	end)
end
