local l=require((game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")).MockMemoryStore)return function()it("\083\104\111\117\108\100 \114\101\116\114\105\101\118\101 \116\104\101 \115\097\109\101 \113\117\101\117\101",function()local r=l:GetQueue("\084\101\115\116\081\117\101\117\101");(expect(r)).to.be.ok()local i=l:GetQueue("\084\101\115\116\081\117\101\117\101");(expect(i)).to.equal(r)end)it("\083\104\111\117\108\100 \100\111 \065\100\100\065\115\121\110\099",function()local r="\072\101\108\108\111\044 \087\111\114\108\100\033"local i=l:GetQueue("\084\101\115\116\081\117\101\117\101");(expect(i)).to.be.ok()i:AddAsync(r,60)local y,P,g=i:ReadAsync(1);(expect(y[1])).to.equal(r);(expect(i:GetRef(P))).to.be.ok()end)it("\083\104\111\117\108\100 \104\097\110\100\108\101 \105\110\118\105\115\084\105\109\101\111\117\116 \099\111\114\114\101\099\116\108\121",function()local r=l:GetQueue("\084\101\115\116\081\117\101\117\101\073\110\118\105\115\084\105\109\101\111\117\116",2)local i="\104\105 \116\104\101\114\101"r:AddAsync(i,60)local y,P,g=r:ReadAsync(1,true,10)print(y,P,g);(expect(y[1])).to.equal(i)local B=r:ReadAsync(1,false);(expect(#B)).to.equal(0)task.wait(2)local C=r:ReadAsync(1,false);(expect(#C)).to.equal(1)end)it("\083\104\111\117\108\100 \104\097\110\100\108\101 \112\114\105\111\114\105\116\105\101\115 \099\111\114\114\101\099\116\108\121",function()local r=l:GetQueue("\084\101\115\116\080\114\105\111\114\105\116\121\081\117\101\117\101",5)r:AddAsync("\079\110\101",60)r:AddAsync("\084\119\111",60)r:AddAsync("\084\104\114\101\101",60,5)r:AddAsync("\070\111\117\114",60,4)local i,y=r:ReadAsync(4,true);(expect(i[1])).to.equal("\084\104\114\101\101");(expect(i[2])).to.equal("\070\111\117\114");(expect(i[3])).to.equal("\084\119\111");(expect(i[4])).to.equal("\079\110\101")r:RemoveAsync(y)end)it("\083\104\111\117\108\100 \114\101\109\111\118\101 \101\120\112\105\114\101\100 \105\116\101\109\115 \099\111\114\114\101\099\116\108\121",function()local r=l:GetQueue("\084\101\115\116\069\120\112\105\114\097\116\105\111\110\081\117\101\117\101",0)r:AddAsync("\081\117\101\117\101 \086\097\108\117\101",2)task.wait(2)local i=r:ReadAsync(1,false,0);(expect(#i)).to.equal(0)end)it("\083\104\111\117\108\100 \104\097\110\100\108\101 \114\101\109\111\118\105\110\103 \105\116\101\109\115 \099\111\114\114\101\099\116\108\121",function()local r=l:GetQueue("\084\101\115\116\082\101\109\111\118\097\108\081\117\101\117\101",5)r:AddAsync("\079\110\101",60)r:AddAsync("\084\119\111",30)local i,y=r:ReadAsync(2,true,10);(expect(#i)).to.equal(2)r:RemoveAsync(y)task.wait(5)local P=r:ReadAsync(1);(expect(#P)).to.equal(0)end)end
local MockMemoryStoreService = require(game:GetService("ReplicatedStorage").MockMemoryStore)

return function ()
    it("Should retrieve the same queue", function()
        local TestQueue = MockMemoryStoreService:GetQueue("TestQueue")
        expect(TestQueue).to.be.ok()

        local TestQueue2 = MockMemoryStoreService:GetQueue("TestQueue")
        expect(TestQueue2).to.equal(TestQueue)
    end)

    it("Should do AddAsync", function()
        local TEST_VALUE = "Hello, World!"
        local TestQueue = MockMemoryStoreService:GetQueue("TestQueue")
        expect(TestQueue).to.be.ok()

        TestQueue:AddAsync(TEST_VALUE, 60)

        local topValues, ref, debugging = TestQueue:ReadAsync(1) -- read the last value

        -- Should have one value, at least.
        expect(topValues[1]).to.equal(TEST_VALUE)

        -- Should have a reference
        expect(TestQueue:GetRef(ref)).to.be.ok()
    end)

    it("Should handle invisTimeout correctly", function()
        local TestQueue = MockMemoryStoreService:GetQueue("TestQueueInvisTimeout", 2)
        local TEST_VALUE = "hi there"
        
        -- We're adding a value, it expires in 60 seconds
        TestQueue:AddAsync(TEST_VALUE, 60)

        -- The value in question here should be retrieved, and unaccessible for 2 seconds.
        local values1, ref, debug = TestQueue:ReadAsync(1, true, 10)
        print(values1, ref, debug)
        expect(values1[1]).to.equal(TEST_VALUE)

        -- This value shouldn't be retrievable.
        local values2 = TestQueue:ReadAsync(1, false)
        expect(#values2).to.equal(0)

        task.wait(2)
        -- It should be available again
        local values2 = TestQueue:ReadAsync(1, false)
        expect(#values2).to.equal(1)
    end)

    it("Should handle priorities correctly", function()
        local TestQueue = MockMemoryStoreService:GetQueue("TestPriorityQueue", 5)
        -- Queue priority default is 3, higher = front
        -- So order should be Three, Four, Two, One (Last two are based on order of insertion because they share priority)
        TestQueue:AddAsync("One", 60)
        TestQueue:AddAsync("Two", 60)
        TestQueue:AddAsync("Three", 60, 5)
        TestQueue:AddAsync("Four", 60, 4)

        local results, id = TestQueue:ReadAsync(4, true)
        expect(results[1]).to.equal("Three")
        expect(results[2]).to.equal("Four")
        expect(results[3]).to.equal("Two")
        expect(results[4]).to.equal("One")

        TestQueue:RemoveAsync(id)
    end)

    it("Should remove expired items correctly", function()
        local TestQueue = MockMemoryStoreService:GetQueue("TestExpirationQueue", 0)
        TestQueue:AddAsync("Queue Value", 2)
        task.wait(2)
        
        -- The item should've been removed after 2 seconds, so nmo items in the queue.
        local result = TestQueue:ReadAsync(1, false, 0)
        expect(#result).to.equal(0)
    end)

    it("Should handle removing items correctly", function()
        local TestQueue = MockMemoryStoreService:GetQueue("TestRemovalQueue", 5)
        TestQueue:AddAsync("One", 60)
        TestQueue:AddAsync("Two", 30)

        local results, id = TestQueue:ReadAsync(2, true, 10)
        expect(#results).to.equal(2)

        TestQueue:RemoveAsync(id)
        task.wait(5)

        local results2 = TestQueue:ReadAsync(1)
        expect(#results2).to.equal(0)
    end)
end