return function()local e=require(script.Parent)local function W(e)local W=typeof(e)if W=="\116\097\098\108\101"then local W=getmetatable(e)if type(W)=="\116\097\098\108\101"then local e=W.__type or W.ClassName if e then return e end end end return W end local w={}w.ClassName="\084\104\114\111\119\097\119\097\121\067\108\097\115\115"w.__index=w function w.new()return setmetatable({},w)end function w.__tostring(e)return"\084\104\114\111\119\097\119\097\121\067\108\097\115\115"end describe("\081\117\101\117\101\046\110\101\119",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \097 \081\117\101\117\101",function()(expect(W(e.new()))).to.equal("\081\117\101\117\101")end)end)describe("\081\117\101\117\101\046\073\115",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \116\114\117\101 \102\111\114 \081\117\101\117\101\115\044 \102\097\108\115\101 \102\111\114 \097\110\121\116\104\105\110\103 \101\108\115\101",function()(expect(e.Is(e.new()))).to.equal(true);(expect(e.Is(w.new()))).to.equal(false);(expect(e.Is(1))).to.equal(false)end)end)describe("\081\117\101\117\101\058\080\117\115\104",function()it("\115\104\111\117\108\100 \116\104\114\111\119 \105\102 \116\104\101 \112\097\115\115\101\100 \118\097\108\117\101 \105\115 \110\105\108",function()(expect(function()(e.new()):Push(nil)end)).to.throw()end)it("\115\104\111\117\108\100 \114\101\116\117\114\110 \116\104\101 \112\111\115\105\116\105\111\110",function()local W=e.new();(expect(W:Push(1))).to.equal(1);(expect(W:Push(2))).to.equal(2)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 \113\117\101\117\101",function()local W=e.new()W:Push(1)W:Push(2);(expect(W[W.Length])).to.equal(2)end)end)describe("\081\117\101\117\101\058\080\111\112",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \110\105\108 \105\102 \116\104\101 \113\117\101\117\101 \105\115 \101\109\112\116\121",function()(expect((e.new()):Pop())).to.equal(nil)end)it("\115\104\111\117\108\100 \114\101\109\111\118\101 \097\110\100 \114\101\116\117\114\110 \116\104\101 \102\105\114\115\116 \118\097\108\117\101",function()local W=e.new()W:Push(1)W:Push(2)W:Push(3);(expect(W[1])).to.equal(1);(expect(W:Pop())).to.equal(1)end)end)describe("\081\117\101\117\101\058\070\114\111\110\116",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \116\104\101 \102\105\114\115\116 \118\097\108\117\101",function()local W=e.new()W:Push(1)W:Push(2);(expect(W:Front())).to.equal(1)end)end)describe("\081\117\101\117\101\058\066\097\099\107",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \116\104\101 \108\097\115\116 \118\097\108\117\101",function()local W=e.new()W:Push(1)W:Push(2);(expect(W:Back())).to.equal(2)end)end)describe("\081\117\101\117\101\058\073\115\069\109\112\116\121",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \116\114\117\101 \105\102\102 \116\104\101 \113\117\101\117\101 \105\115 \101\109\112\116\121",function()local W=e.new();(expect(W:IsEmpty())).to.equal(true)W:Push(1);(expect(W:IsEmpty())).to.equal(false)end)end)describe("\081\117\101\117\101\058\073\116\101\114\097\116\111\114",function()it("\115\104\111\117\108\100 \114\101\116\117\114\110 \097\110 \105\116\101\114\097\116\111\114",function()(expect((e.new()):Iterator())).to.be.a("\102\117\110\099\116\105\111\110")end)it("\115\104\111\117\108\100 \114\101\116\117\114\110 \116\104\101 \105\110\100\101\120 \097\110\100 \118\097\108\117\101",function()local W=e.new()W:Push(4)W:Push(3)W:Push(2)W:Push(1)local w=table.create(W.Length)for e,W in W:Iterator()do table.insert(w,string.format("\091\037\100\044\037\100\093",e,W))end;(expect(table.concat(w,"\044 "))).to.equal("\091\049\044\052\093\044 \091\050\044\051\093\044 \091\051\044\050\093\044 \091\052\044\049\093")end)end)end
return function()
	local Queue = 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
				end
			end
		end

		return ValueType
	end

	local ThrowawayClass = {}
	ThrowawayClass.ClassName = "ThrowawayClass"
	ThrowawayClass.__index = ThrowawayClass

	function ThrowawayClass.new()
		return setmetatable({}, ThrowawayClass)
	end

	function ThrowawayClass:__tostring()
		return "ThrowawayClass"
	end

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

	describe("Queue.Is", function()
		it("should return true for Queues, false for anything else", function()
			expect(Queue.Is(Queue.new())).to.equal(true)
			expect(Queue.Is(ThrowawayClass.new())).to.equal(false)
			expect(Queue.Is(1)).to.equal(false)
		end)
	end)

	describe("Queue:Push", function()
		it("should throw if the passed value is nil", function()
			expect(function()
				Queue.new():Push(nil)
			end).to.throw()
		end)

		it("should return the position", function()
			local TestQueue = Queue.new()
			expect(TestQueue:Push(1)).to.equal(1)
			expect(TestQueue:Push(2)).to.equal(2)
		end)

		it("should push to the end of the queue", function()
			local TestQueue = Queue.new()
			TestQueue:Push(1)
			TestQueue:Push(2)
			expect(TestQueue[TestQueue.Length]).to.equal(2)
		end)
	end)

	describe("Queue:Pop", function()
		it("should return nil if the queue is empty", function()
			expect(Queue.new():Pop()).to.equal(nil)
		end)

		it("should remove and return the first value", function()
			local TestQueue = Queue.new()
			TestQueue:Push(1)
			TestQueue:Push(2)
			TestQueue:Push(3)

			expect(TestQueue[1]).to.equal(1)
			expect(TestQueue:Pop()).to.equal(1)
		end)
	end)

	describe("Queue:Front", function()
		it("should return the first value", function()
			local TestQueue = Queue.new()
			TestQueue:Push(1)
			TestQueue:Push(2)
			expect(TestQueue:Front()).to.equal(1)
		end)
	end)

	describe("Queue:Back", function()
		it("should return the last value", function()
			local TestQueue = Queue.new()
			TestQueue:Push(1)
			TestQueue:Push(2)
			expect(TestQueue:Back()).to.equal(2)
		end)
	end)

	describe("Queue:IsEmpty", function()
		it("should return true iff the queue is empty", function()
			local TestQueue = Queue.new()
			expect(TestQueue:IsEmpty()).to.equal(true)
			TestQueue:Push(1)
			expect(TestQueue:IsEmpty()).to.equal(false)
		end)
	end)

	describe("Queue:Iterator", function()
		it("should return an iterator", function()
			expect(Queue.new():Iterator()).to.be.a("function")
		end)

		-- how do I even test this
		it("should return the index and value", function()
			local TestQueue = Queue.new()
			TestQueue:Push(4)
			TestQueue:Push(3)
			TestQueue:Push(2)
			TestQueue:Push(1)

			local Array = table.create(TestQueue.Length)
			for Index, Value in TestQueue:Iterator() do
				table.insert(Array, string.format("[%d,%d]", Index, Value))
			end

			expect(table.concat(Array, ", ")).to.equal("[1,4], [2,3], [3,2], [4,1]")
		end)
	end)
end
