Add testActionQueue

This commit is contained in:
Sage Vaillancourt 2025-02-24 11:34:28 -05:00
parent 19ddae6273
commit 51c80fa427
3 changed files with 103 additions and 1 deletions

View File

@ -1,5 +1,6 @@
---@class ActionQueue
---@field queue table<any, { coroutine: thread, expireTimeMs: number }>
actionQueue = {
---@type table<any, { coroutine: thread, expireTimeMs: number }>
queue = {},
}
@ -52,3 +53,8 @@ function actionQueue:runWaiting(deltaSeconds)
end
end
end
-- luacheck: ignore
if not playdate or playdate.TEST_MODE then
return actionQueue
end

View File

@ -1,7 +1,16 @@
utils = require("utils")
local currentTimeMs = 0
local mockPlaydate = {
TEST_MODE = true,
skipMs = function(skip)
currentTimeMs = currentTimeMs + skip
end,
getCurrentTimeMilliseconds = function()
currentTimeMs = currentTimeMs + 1
return currentTimeMs
end,
timer = {
new = function(_, callback)
return {

View File

@ -0,0 +1,87 @@
require("test/setup")
require("action-queue")
function testActionQueueRunsToCompletion()
actionQueue.queue = {}
local invokeTotalSec = 0
local hasYielded = false
actionQueue:upsert("testAction", 9999999999, function(delta)
while invokeTotalSec < 5 do
invokeTotalSec = invokeTotalSec + delta
hasYielded = true
coroutine.yield()
end
end)
luaunit.assertIsFalse(hasYielded, "Should not have been invoked yet.")
for _ = 1, 10 do
actionQueue:runWaiting(1)
luaunit.assertIsTrue(hasYielded, "Should have been invoked.")
end
luaunit.assertEquals(5, invokeTotalSec, "Should have run five times and stopped itself")
end
function testActionQueueExpiration()
actionQueue.queue = {}
local yieldCount = 0
actionQueue:upsert("testAction", 2000, function(delta)
while true do
yieldCount = yieldCount + 1
coroutine.yield()
end
end)
local skipSec = 60
playdate.skipMs(60 * 1000)
actionQueue:runWaiting(skipSec)
luaunit.assertEquals(1, yieldCount, "Should always be invoked at least once")
playdate.skipMs(1000)
actionQueue:runWaiting(1)
luaunit.assertEquals(1, yieldCount, "Should not be invoked again after expiry")
end
function testDuplicateUpsertsShouldOnlyRunOnce()
actionQueue.queue = {}
local yieldCount = 0
local yieldId
local action = function(id)
return function()
while true do
yieldCount = yieldCount + 1
yieldId = id
coroutine.yield()
end
end
end
for i = 1, 10 do
actionQueue:upsert("testAction", 9999999999, action(i))
end
actionQueue:runWaiting(1)
luaunit.assertEquals(1, yieldCount, "Duplicate upserts should result in only one invocation.")
luaunit.assertEquals(10, yieldId, "Most recent upsert should take precedence.")
end
function testNewOnlyActionsShouldNotReplaceExistingActions()
actionQueue.queue = {}
local yieldCount = 0
local yieldId
local action = function(id)
return function()
while true do
yieldCount = yieldCount + 1
yieldId = id
coroutine.yield()
end
end
end
for i = 1, 10 do
actionQueue:newOnly("testAction", 9999999999, action(i))
end
actionQueue:runWaiting(1)
luaunit.assertEquals(1, yieldCount, "Duplicate newOnly should result in only one invocation.")
luaunit.assertEquals(1, yieldId, "The first newOnly should take precedence.")
end
os.exit(luaunit.LuaUnit.run())