return function()local z=require(script.Parent)local function p(z)local p=typeof(z)if p=="\116\097\098\108\101"then local K=getmetatable(z)if type(K)=="\116\097\098\108\101"then local z=K.__type or K.ClassName if z then return z else return p end else return p end else return p end end describe("\076\105\110\107\101\100\076\105\115\116\046\110\101\119",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \097 \076\105\110\107\101\100\076\105\115\116",function()(expect(p(z.new()))).to.equal("\076\105\110\107\101\100\076\105\115\116")end)it("\115\104\111\117\108\100 \097\108\108\111\119 \097\110 \097\114\114\097\121 \116\111 \098\101 \112\097\115\115\101\100",function()local K=z.new({1;2,3,4});(expect(p(K))).to.equal("\076\105\110\107\101\100\076\105\115\116");(expect(K.Length)).to.equal(4);(expect(tostring(K))).to.equal("\076\105\110\107\101\100\076\105\115\116\060\091\049\044 \050\044 \051\044 \052\093\062")end)it("\115\104\111\117\108\100 \116\104\114\111\119 \105\102 \097\110\121\116\104\105\110\103 \098\117\116 \097\110 \097\114\114\097\121 \111\114 \110\105\108 \105\115 \112\097\115\115\101\100",function()(expect(function()z.new(5)end)).to.throw()end)end)describe("\076\105\110\107\101\100\076\105\115\116\058\080\117\115\104",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \097 \076\105\115\116\078\111\100\101",function()(expect(p((z.new()):Push(1)))).to.equal("\076\105\115\116\078\111\100\101")end)it("\115\104\111\117\108\100 \112\117\115\104 \116\111 \116\104\101 \101\110\100 \111\102 \116\104\101 \108\105\115\116",function()local p=z.new({1,2,3})p:Push(4);(expect(p.Length)).to.equal(4);(expect(tostring(p))).to.equal("\076\105\110\107\101\100\076\105\115\116\060\091\049\044 \050\044 \051\044 \052\093\062")end)it("\115\104\111\117\108\100 \116\104\114\111\119 \105\102 \110\105\108 \105\115 \112\097\115\115\101\100",function()(expect(function()(z.new()):Push(nil)end)).to.throw()end)end)describe("\076\105\110\107\101\100\076\105\115\116\058\065\112\112\101\110\100",function()it("\115\104\111\117\108\100 \116\104\114\111\119 \105\102 \116\104\101 \097\114\103\117\109\101\110\116 \112\097\115\115\101\100 \105\115 \110\111\116 \097 \076\105\110\107\101\100\076\105\115\116",function()(expect(function()(z.new()):Append(1)end)).to.throw()end)it("\115\104\111\117\108\100 \112\117\115\104 \097 \076\105\110\107\101\100\076\105\115\116 \116\111 \116\104\101 \101\110\100 \111\102 \116\104\101 \108\105\115\116",function()local p=z.new({1,2})p:Append(z.new({3;4}));(expect(p.Length)).to.equal(4);(expect(tostring(p))).to.equal("\076\105\110\107\101\100\076\105\115\116\060\091\049\044 \050\044 \051\044 \052\093\062")end)end)describe("\076\105\110\107\101\100\076\105\115\116\058\080\117\115\104\070\114\111\110\116",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \097 \076\105\115\116\078\111\100\101",function()(expect(p((z.new()):PushFront(1)))).to.equal("\076\105\115\116\078\111\100\101")end)it("\115\104\111\117\108\100 \112\117\115\104 \116\111 \116\104\101 \102\114\111\110\116 \111\102 \116\104\101 \108\105\115\116",function()local p=z.new({2,3;4})p:PushFront(1);(expect(p.Length)).to.equal(4);(expect(tostring(p))).to.equal("\076\105\110\107\101\100\076\105\115\116\060\091\049\044 \050\044 \051\044 \052\093\062")end)it("\115\104\111\117\108\100 \116\104\114\111\119 \105\102 \110\105\108 \105\115 \112\097\115\115\101\100",function()(expect(function()(z.new()):PushFront(nil)end)).to.throw()end)end)describe("\076\105\110\107\101\100\076\105\115\116\058\080\114\101\112\101\110\100",function()it("\115\104\111\117\108\100 \116\104\114\111\119 \105\102 \116\104\101 \097\114\103\117\109\101\110\116 \112\097\115\115\101\100 \105\115 \110\111\116 \097 \076\105\110\107\101\100\076\105\115\116",function()(expect(function()(z.new()):Prepend(1)end)).to.throw()end)it("\115\104\111\117\108\100 \112\117\115\104 \097 \076\105\110\107\101\100\076\105\115\116 \116\111 \116\104\101 \115\116\097\114\116 \111\102 \116\104\101 \108\105\115\116",function()local p=z.new({3;4})p:Prepend(z.new({1;2}));(expect(p.Length)).to.equal(4);(expect(tostring(p))).to.equal("\076\105\110\107\101\100\076\105\115\116\060\091\049\044 \050\044 \051\044 \052\093\062")end)end)describe("\076\105\110\107\101\100\076\105\115\116\058\080\111\112",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \097 \076\105\115\116\078\111\100\101",function()(expect(p((z.new({1,2;3})):Pop()))).to.equal("\076\105\115\116\078\111\100\101")end)it("\115\104\111\117\108\100 \114\101\109\111\118\101 \116\104\101 \102\105\114\115\116 \118\097\108\117\101",function()local p=z.new({1;2,3,4});(expect((p:Pop()).Value)).to.equal(1);(expect(p.Length)).to.equal(3);(expect(tostring(p))).to.equal("\076\105\110\107\101\100\076\105\115\116\060\091\050\044 \051\044 \052\093\062")end)end)describe("\076\105\110\107\101\100\076\105\115\116\058\080\111\112\066\097\099\107",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \097 \076\105\115\116\078\111\100\101",function()(expect(p((z.new({1;2;3})):PopBack()))).to.equal("\076\105\115\116\078\111\100\101")end)it("\115\104\111\117\108\100 \114\101\109\111\118\101 \116\104\101 \108\097\115\116 \118\097\108\117\101",function()local p=z.new({1;2,3;4});(expect((p:PopBack()).Value)).to.equal(4);(expect(p.Length)).to.equal(3);(expect(tostring(p))).to.equal("\076\105\110\107\101\100\076\105\115\116\060\091\049\044 \050\044 \051\093\062")end)end)describe("\076\105\110\107\101\100\076\105\115\116\058\073\115\069\109\112\116\121",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \097 \098\111\111\108\101\097\110",function()(expect((z.new()):IsEmpty())).to.be.a("\098\111\111\108\101\097\110")end)it("\115\104\111\117\108\100 \114\101\116\117\114\110 \116\104\101 \099\111\114\114\101\099\116 \118\097\108\117\101",function()(expect((z.new()):IsEmpty())).to.equal(true);(expect((z.new(table.create(1,1))):IsEmpty())).to.equal(false)end)end)describe("\076\105\110\107\101\100\076\105\115\116\058\067\108\101\097\114",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \097 \076\105\110\107\101\100\076\105\115\116",function()(expect(p((z.new(table.create(4,1))):Clear()))).to.equal("\076\105\110\107\101\100\076\105\115\116")end)it("\115\104\111\117\108\100 \114\101\109\111\118\101 \101\118\101\114\121\116\104\105\110\103",function()local p=(z.new(table.create(4,1))):Clear();(expect(p:IsEmpty())).to.equal(true);(expect(p.Length)).to.equal(0);(expect(tostring(p))).to.equal("\076\105\110\107\101\100\076\105\115\116\060\091\093\062")end)end)end
return function()
	local LinkedList = require(script.Parent)

	local function TypeOf(Value)
		local ValueType = typeof(Value)
		if ValueType == "table" then
			local Metatable = getmetatable(Value)
			if type(Metatable) == "table" then
				local CustomType = Metatable.__type or Metatable.ClassName
				if CustomType then
					return CustomType
				else
					return ValueType
				end
			else
				return ValueType
			end
		else
			return ValueType
		end
	end

	describe("LinkedList.new", function()
		it("should return a LinkedList", function()
			expect(TypeOf(LinkedList.new())).to.equal("LinkedList")
		end)

		it("should allow an array to be passed", function()
			local List = LinkedList.new({1, 2, 3, 4})
			expect(TypeOf(List)).to.equal("LinkedList")
			expect(List.Length).to.equal(4)
			expect(tostring(List)).to.equal("LinkedList<[1, 2, 3, 4]>")
		end)

		it("should throw if anything but an array or nil is passed", function()
			expect(function()
				LinkedList.new(5)
			end).to.throw()
		end)
	end)

	describe("LinkedList:Push", function()
		it("should return a ListNode", function()
			expect(TypeOf(LinkedList.new():Push(1))).to.equal("ListNode")
		end)

		it("should push to the end of the list", function()
			local List = LinkedList.new({1, 2, 3})
			List:Push(4)
			expect(List.Length).to.equal(4)
			expect(tostring(List)).to.equal("LinkedList<[1, 2, 3, 4]>")
		end)

		it("should throw if nil is passed", function()
			expect(function()
				LinkedList.new():Push(nil)
			end).to.throw()
		end)
	end)

	describe("LinkedList:Append", function()
		it("should throw if the argument passed is not a LinkedList", function()
			expect(function()
				LinkedList.new():Append(1)
			end).to.throw()
		end)

		it("should push a LinkedList to the end of the list", function()
			local List = LinkedList.new({1, 2})
			List:Append(LinkedList.new({3, 4}))
			expect(List.Length).to.equal(4)
			expect(tostring(List)).to.equal("LinkedList<[1, 2, 3, 4]>")
		end)
	end)

	describe("LinkedList:PushFront", function()
		it("should return a ListNode", function()
			expect(TypeOf(LinkedList.new():PushFront(1))).to.equal("ListNode")
		end)

		it("should push to the front of the list", function()
			local List = LinkedList.new({2, 3, 4})
			List:PushFront(1)
			expect(List.Length).to.equal(4)
			expect(tostring(List)).to.equal("LinkedList<[1, 2, 3, 4]>")
		end)

		it("should throw if nil is passed", function()
			expect(function()
				LinkedList.new():PushFront(nil)
			end).to.throw()
		end)
	end)

	describe("LinkedList:Prepend", function()
		it("should throw if the argument passed is not a LinkedList", function()
			expect(function()
				LinkedList.new():Prepend(1)
			end).to.throw()
		end)

		it("should push a LinkedList to the start of the list", function()
			local List = LinkedList.new({3, 4})
			List:Prepend(LinkedList.new({1, 2}))
			expect(List.Length).to.equal(4)
			expect(tostring(List)).to.equal("LinkedList<[1, 2, 3, 4]>")
		end)
	end)

	describe("LinkedList:Pop", function()
		it("should return a ListNode", function()
			expect(TypeOf(LinkedList.new({1, 2, 3}):Pop())).to.equal("ListNode")
		end)

		it("should remove the first value", function()
			local List = LinkedList.new({1, 2, 3, 4})
			expect(List:Pop().Value).to.equal(1)
			expect(List.Length).to.equal(3)
			expect(tostring(List)).to.equal("LinkedList<[2, 3, 4]>")
		end)
	end)

	describe("LinkedList:PopBack", function()
		it("should return a ListNode", function()
			expect(TypeOf(LinkedList.new({1, 2, 3}):PopBack())).to.equal("ListNode")
		end)

		it("should remove the last value", function()
			local List = LinkedList.new({1, 2, 3, 4})
			expect(List:PopBack().Value).to.equal(4)
			expect(List.Length).to.equal(3)
			expect(tostring(List)).to.equal("LinkedList<[1, 2, 3]>")
		end)
	end)

	describe("LinkedList:IsEmpty", function()
		it("should return a boolean", function()
			expect(LinkedList.new():IsEmpty()).to.be.a("boolean")
		end)

		it("should return the correct value", function()
			expect(LinkedList.new():IsEmpty()).to.equal(true)
			expect(LinkedList.new(table.create(1, 1)):IsEmpty()).to.equal(false)
		end)
	end)

	describe("LinkedList:Clear", function()
		it("should return a LinkedList", function()
			expect(TypeOf(LinkedList.new(table.create(4, 1)):Clear())).to.equal("LinkedList")
		end)

		it("should remove everything", function()
			local List = LinkedList.new(table.create(4, 1)):Clear()
			expect(List:IsEmpty()).to.equal(true)
			expect(List.Length).to.equal(0)
			expect(tostring(List)).to.equal("LinkedList<[]>")
		end)
	end)
end
