Diff

spec/util_async_spec.lua @ 11962:9a70a543c727

util.async: Add next-tick configuration Running woken runners in the next iteration of the event loop prevents unexpected recursion, unexpected tracebacks, and is generally more predictable. The pattern is borrowed from util.promise, where we're now doing the same.
author Matthew Wild <mwild1@gmail.com>
date Mon, 29 Nov 2021 14:14:30 +0000
parent 11961:542a9a503073
child 11964:563ee7969f6c
line wrap: on
line diff
--- a/spec/util_async_spec.lua	Mon Nov 29 14:11:24 2021 +0000
+++ b/spec/util_async_spec.lua	Mon Nov 29 14:14:30 2021 +0000
@@ -669,4 +669,50 @@
 			assert.spy(r.watchers.ready).was.called();
 		end);
 	end);
+
+	describe("#set_nexttick()", function ()
+		after_each(function ()
+			-- Restore to default
+			async.set_nexttick(nil);
+		end);
+		it("should work", function ()
+			local queue = {};
+			local nexttick = spy.new(function (f)
+				assert.is_function(f);
+				table.insert(queue, f);
+			end);
+			async.set_nexttick(nexttick);
+
+			local processed_item;
+			local wait, done;
+			local r = new(function (item)
+				wait, done = async.waiter();
+				wait();
+				processed_item = item;
+			end);
+			r:run("test");
+
+			-- Nothing happened, because the runner is waiting
+			assert.is_nil(processed_item);
+			assert.equal(r.state, "waiting");
+			assert.spy(nexttick).was_called(0);
+			assert.spy(r.watchers.waiting).was.called();
+			assert.spy(r.watchers.ready).was_not.called();
+
+			-- Mark the runner as ready, it should be scheduled for
+			-- the next tick
+			done();
+
+			assert.spy(nexttick).was_called(1);
+			assert.spy(nexttick).was_called_with(match.is_function());
+			assert.equal(1, #queue);
+
+			-- Pretend it's the next tick - call the pending function
+			queue[1]();
+
+			assert.equal(processed_item, "test");
+			assert.equal(r.state, "ready");
+			assert.spy(r.watchers.ready).was.called();
+		end);
+	end);
 end);