util.async: Ensure runner is left in correct state after out-of-main-loop error (+tests)

This commit is contained in:
Matthew Wild 2018-03-16 22:26:15 +00:00
parent 2f1f98e1b5
commit 5c0a12d4d1
2 changed files with 29 additions and 1 deletions

View file

@ -35,9 +35,14 @@ describe("util.async", function()
describe("#errors", function ()
local last_processed_item, last_error;
local r;
local wait, done;
r = async.runner(function (item)
if item == "error" then
error({ e = "test error" });
elseif item == "wait" then
wait, done = async.waiter();
wait();
error({ e = "post wait error" });
end
last_processed_item = item;
end, {
@ -81,6 +86,24 @@ describe("util.async", function()
assert.equal(r.state, "ready");
assert.equal(last_processed_item, "world");
end);
it("should work despite a #waiter", function ()
-- This test covers an important case where a runner
-- throws an error while being executed outside of the
-- main loop. This happens when it was blocked ('waiting'),
-- and then released (via a call to done()).
last_error = nil;
r:run("wait");
assert.equal(r.state, "waiting");
done();
-- At this point an error happens (state goes error->ready)
assert.equal(r.state, "ready");
assert.is_table(last_error);
assert.equal(last_error.e, "post wait error");
last_error = nil;
r:run("hello again");
assert.equal(r.state, "ready");
assert.equal(last_processed_item, "hello again");
end);
end);
end);
describe("#waiter", function()