Improve robustness of Promise.all tests

This commit is contained in:
Lucien Greathouse 2018-09-14 11:31:24 -07:00
parent 371f08598c
commit 40acffb2f0
2 changed files with 45 additions and 19 deletions

View file

@ -167,7 +167,7 @@ end
]] ]]
function Promise.all(promises) function Promise.all(promises)
if type(promises) ~= "table" then if type(promises) ~= "table" then
error("Please pass an array of promises or values to Promise.all", 2) error("Please pass a list of promises to Promise.all", 2)
end end
-- If there are no values then return an already resolved promise. -- If there are no values then return an already resolved promise.
@ -208,15 +208,16 @@ function Promise.all(promises)
-- We can assume the values inside `promises` are all promises since we checked above. -- We can assume the values inside `promises` are all promises since we checked above.
for i = 1, #promises do for i = 1, #promises do
promises[i]:andThen(function(...) promises[i]:andThen(
function(...)
resolveOne(i, ...) resolveOne(i, ...)
end) end,
:catch(function(...) function(...)
-- Only reject if this promise is unrejected.
if not rejected then if not rejected then
reject(...) reject(...)
end end
end) end
)
end end
end) end)
end end
@ -314,6 +315,23 @@ function Promise:await()
end end
end end
--[[
Intended for use in tests.
Similar to await(), but instead of yielding if the promise is unresolved,
_unwrap will throw. This indicates an assumption that a promise has
resolved.
]]
function Promise:_unwrap()
if self._status == Promise.Status.Started then
error("Promise has not resolved or rejected.", 2)
end
local success = self._status == Promise.Status.Resolved
return success, unpack(self._values, 1, self._valuesLength)
end
function Promise:_resolve(...) function Promise:_resolve(...)
if self._status ~= Promise.Status.Started then if self._status ~= Promise.Status.Started then
return return

View file

@ -272,14 +272,14 @@ return function()
end).to.throw() end).to.throw()
end) end)
it("should resolve instantly with an empty table if given no values", function() it("should resolve instantly with an empty table if given no promises", function()
local promise = Promise.all({}) local promise = Promise.all({})
local success, value = promise:await() local success, value = promise:_unwrap()
expect(success).to.equal(true) expect(success).to.equal(true)
expect(promise:getStatus()).to.equal(Promise.Status.Resolved) expect(promise:getStatus()).to.equal(Promise.Status.Resolved)
expect(value).to.be.a("table") expect(value).to.be.a("table")
expect(#value).to.equal(0) expect(next(value)).to.equal(nil)
end) end)
it("should error if given non-promise values", function() it("should error if given non-promise values", function()
@ -289,23 +289,31 @@ return function()
end) end)
it("should wait for all promises to be resolved and return their values", function() it("should wait for all promises to be resolved and return their values", function()
local resolveFunctions = {}
local promises = { local promises = {
Promise.new(function(resolve) Promise.new(function(resolve)
resolve(1) table.insert(resolveFunctions, {resolve, 1})
end), end),
Promise.new(function(resolve) Promise.new(function(resolve)
resolve("A string") table.insert(resolveFunctions, {resolve, "A string"})
end), end),
Promise.new(function(resolve) Promise.new(function(resolve)
resolve(nil) table.insert(resolveFunctions, {resolve, nil})
end), end),
Promise.new(function(resolve) Promise.new(function(resolve)
resolve(false) table.insert(resolveFunctions, {resolve, false})
end) end),
} }
local promise = Promise.all(promises) local combinedPromise = Promise.all(promises)
local success, resolved = promise:await()
for _, resolve in ipairs(resolveFunctions) do
expect(combinedPromise:getStatus()).to.equal(Promise.Status.Started)
resolve[1](resolve[2])
end
local success, resolved = combinedPromise:_unwrap()
expect(success).to.equal(true) expect(success).to.equal(true)
expect(resolved).to.be.a("table") expect(resolved).to.be.a("table")