local ok, task = pcall(require, "lb:task") if not ok then return end describe("spawn", function() test("callback receives args", function() spawn(function(...) assert(select("#", ...) == 0) end):await() spawn(function(...) assert(select("#", ...) == 1) assert((...) == nil) end, nil):await() spawn(function(...) assert(select("#", ...) == 4) local args = table.pack(...) assert(args[1] == 1 and args[2] == 2 and args[3] == nil and args[4] == 3) end, 1, 2, nil, 3):await() end) test("await returns callback results", function() local res = table.pack(spawn(function() -- no returns end):await()) assert(res.n == 0) local res = table.pack(spawn(function() return nil end):await()) assert(res.n == 1 and res[1] == nil) local res = table.pack(spawn(function() return 1, 2, nil, 3 end):await()) assert(res.n == 4 and res[1] == 1 and res[2] == 2 and res[3] == nil and res[4] == 3) end) test("callback args and results", function() local res = table.pack(spawn(function(...) assert(select("#", ...) == 5) local args = table.pack(...) assert(args[1] == 5 and args[2] == 4 and args[3] == nil and args[4] == 3, args[5] == nil) return 1, 3, nil end, 5, 4, nil, 3, nil):await()) assert(res.n == 3 and res[1] == 1 and res[2] == 3 and res[3] == nil) end) test("order is consistent", function() -- all tasks spawned in one batch should be resumed in the spawn order local tasks, nums = {}, {} for i = 1, 10 do table.insert( tasks, spawn(function() table.insert(nums, i) end) ) end for i = 10, 1, -1 do tasks[i]:await() end assert(#nums == 10) for i = 1, 10 do assert(nums[i] == i) end end) end) describe("sleep", function() test("sleep is asynchronous", function() local value spawn(function() value = "value" end) assert(value == nil) task:sleep(100) -- implicit await: if it's synchronous, value wouldn't change assert(value == "value") end) end) describe("task", function() test("properly unrefs arg and ret table", function() local registry = debug.getregistry() local ref, t local cb = function() return "my ret" end do local task = spawn(cb, "my arg") ref = task.__ref t = registry[ref] assert(type(t) == "table") assert(t[1] == cb) assert(t[2] == "my arg") task:await() assert(registry[task.__ref] == t) assert(t[1] == "my ret") end collectgarbage() assert(registry[ref] ~= t) -- if task unref'ed it, it should be either nil or the next freelist number end) end)