luau-promise/lib/init.spec.lua

328 lines
8.5 KiB
Lua
Raw Normal View History

2018-04-11 22:26:54 +00:00
return function()
local Promise = require(script.Parent)
describe("Promise.new", function()
it("should instantiate with a callback", function()
local promise = Promise.new(function() end)
expect(promise).to.be.ok()
end)
it("should invoke the given callback with resolve and reject", function()
local callCount = 0
local resolveArg
local rejectArg
local promise = Promise.new(function(resolve, reject)
callCount = callCount + 1
resolveArg = resolve
rejectArg = reject
end)
expect(promise).to.be.ok()
expect(callCount).to.equal(1)
expect(resolveArg).to.be.a("function")
expect(rejectArg).to.be.a("function")
expect(promise:getStatus()).to.equal(Promise.Status.Started)
2018-04-11 22:26:54 +00:00
end)
it("should resolve promises on resolve()", function()
local callCount = 0
local promise = Promise.new(function(resolve)
callCount = callCount + 1
resolve()
end)
expect(promise).to.be.ok()
expect(callCount).to.equal(1)
expect(promise:getStatus()).to.equal(Promise.Status.Resolved)
2018-04-11 22:26:54 +00:00
end)
it("should reject promises on reject()", function()
local callCount = 0
local promise = Promise.new(function(resolve, reject)
callCount = callCount + 1
reject()
end)
expect(promise).to.be.ok()
expect(callCount).to.equal(1)
expect(promise:getStatus()).to.equal(Promise.Status.Rejected)
2018-04-11 22:26:54 +00:00
end)
it("should reject on error in callback", function()
local callCount = 0
local promise = Promise.new(function()
callCount = callCount + 1
error("hahah")
end)
expect(promise).to.be.ok()
expect(callCount).to.equal(1)
expect(promise:getStatus()).to.equal(Promise.Status.Rejected)
expect(promise._values[1]:find("hahah")).to.be.ok()
-- Loosely check for the pieces of the stack trace we expect
expect(promise._values[1]:find("init.spec")).to.be.ok()
expect(promise._values[1]:find("new")).to.be.ok()
expect(promise._values[1]:find("error")).to.be.ok()
2018-04-11 22:26:54 +00:00
end)
end)
describe("Promise.resolve", function()
it("should immediately resolve with a value", function()
local promise = Promise.resolve(5)
expect(promise).to.be.ok()
expect(promise:getStatus()).to.equal(Promise.Status.Resolved)
expect(promise._values[1]).to.equal(5)
2018-04-11 22:26:54 +00:00
end)
it("should chain onto passed promises", function()
local promise = Promise.resolve(Promise.new(function(_, reject)
reject(7)
end))
expect(promise).to.be.ok()
expect(promise:getStatus()).to.equal(Promise.Status.Rejected)
expect(promise._values[1]).to.equal(7)
2018-04-11 22:26:54 +00:00
end)
end)
describe("Promise.reject", function()
it("should immediately reject with a value", function()
local promise = Promise.reject(6)
expect(promise).to.be.ok()
expect(promise:getStatus()).to.equal(Promise.Status.Rejected)
expect(promise._values[1]).to.equal(6)
2018-04-11 22:26:54 +00:00
end)
it("should pass a promise as-is as an error", function()
local innerPromise = Promise.new(function(resolve)
resolve(6)
end)
local promise = Promise.reject(innerPromise)
expect(promise).to.be.ok()
expect(promise:getStatus()).to.equal(Promise.Status.Rejected)
expect(promise._values[1]).to.equal(innerPromise)
2018-04-11 22:26:54 +00:00
end)
end)
describe("Promise:andThen", function()
it("should chain onto resolved promises", function()
local args
local argsLength
local callCount = 0
local badCallCount = 0
local promise = Promise.resolve(5)
local chained = promise
:andThen(function(...)
args = {...}
argsLength = select("#", ...)
callCount = callCount + 1
end, function()
badCallCount = badCallCount + 1
end)
expect(badCallCount).to.equal(0)
expect(callCount).to.equal(1)
expect(argsLength).to.equal(1)
expect(args[1]).to.equal(5)
expect(promise).to.be.ok()
expect(promise:getStatus()).to.equal(Promise.Status.Resolved)
expect(promise._values[1]).to.equal(5)
2018-04-11 22:26:54 +00:00
expect(chained).to.be.ok()
expect(chained).never.to.equal(promise)
expect(chained:getStatus()).to.equal(Promise.Status.Resolved)
expect(#chained._values).to.equal(0)
2018-04-11 22:26:54 +00:00
end)
it("should chain onto rejected promises", function()
local args
local argsLength
local callCount = 0
local badCallCount = 0
local promise = Promise.reject(5)
local chained = promise
:andThen(function(...)
badCallCount = badCallCount + 1
end, function(...)
args = {...}
argsLength = select("#", ...)
callCount = callCount + 1
end)
expect(badCallCount).to.equal(0)
expect(callCount).to.equal(1)
expect(argsLength).to.equal(1)
expect(args[1]).to.equal(5)
expect(promise).to.be.ok()
expect(promise:getStatus()).to.equal(Promise.Status.Rejected)
expect(promise._values[1]).to.equal(5)
2018-04-11 22:26:54 +00:00
expect(chained).to.be.ok()
expect(chained).never.to.equal(promise)
expect(chained:getStatus()).to.equal(Promise.Status.Resolved)
expect(#chained._values).to.equal(0)
2018-04-11 22:26:54 +00:00
end)
it("should chain onto asynchronously resolved promises", function()
local args
local argsLength
local callCount = 0
local badCallCount = 0
local startResolution
local promise = Promise.new(function(resolve)
startResolution = resolve
end)
local chained = promise
:andThen(function(...)
args = {...}
argsLength = select("#", ...)
callCount = callCount + 1
end, function()
badCallCount = badCallCount + 1
end)
expect(callCount).to.equal(0)
expect(badCallCount).to.equal(0)
startResolution(6)
expect(badCallCount).to.equal(0)
expect(callCount).to.equal(1)
expect(argsLength).to.equal(1)
expect(args[1]).to.equal(6)
expect(promise).to.be.ok()
expect(promise:getStatus()).to.equal(Promise.Status.Resolved)
expect(promise._values[1]).to.equal(6)
2018-04-11 22:26:54 +00:00
expect(chained).to.be.ok()
expect(chained).never.to.equal(promise)
expect(chained:getStatus()).to.equal(Promise.Status.Resolved)
expect(#chained._values).to.equal(0)
2018-04-11 22:26:54 +00:00
end)
it("should chain onto asynchronously rejected promises", function()
local args
local argsLength
local callCount = 0
local badCallCount = 0
local startResolution
local promise = Promise.new(function(_, reject)
startResolution = reject
end)
local chained = promise
:andThen(function()
badCallCount = badCallCount + 1
end, function(...)
args = {...}
argsLength = select("#", ...)
callCount = callCount + 1
end)
expect(callCount).to.equal(0)
expect(badCallCount).to.equal(0)
startResolution(6)
expect(badCallCount).to.equal(0)
expect(callCount).to.equal(1)
expect(argsLength).to.equal(1)
expect(args[1]).to.equal(6)
expect(promise).to.be.ok()
expect(promise:getStatus()).to.equal(Promise.Status.Rejected)
expect(promise._values[1]).to.equal(6)
2018-04-11 22:26:54 +00:00
expect(chained).to.be.ok()
expect(chained).never.to.equal(promise)
expect(chained:getStatus()).to.equal(Promise.Status.Resolved)
expect(#chained._values).to.equal(0)
2018-04-11 22:26:54 +00:00
end)
end)
2018-09-14 18:17:06 +00:00
describe("Promise.all", function()
it("should error if given something other than a table", function()
expect(function()
Promise.all(1)
end).to.throw()
end)
it("should resolve instantly with an empty table if given no promises", function()
2018-09-14 18:17:06 +00:00
local promise = Promise.all({})
local success, value = promise:_unwrap()
2018-09-14 18:17:06 +00:00
expect(success).to.equal(true)
expect(promise:getStatus()).to.equal(Promise.Status.Resolved)
expect(value).to.be.a("table")
expect(next(value)).to.equal(nil)
2018-09-14 18:17:06 +00:00
end)
it("should error if given non-promise values", function()
expect(function()
Promise.all({{}, {}, {}})
end).to.throw()
end)
it("should wait for all promises to be resolved and return their values", function()
local resolveFunctions = {}
2018-09-14 18:17:06 +00:00
local promises = {
Promise.new(function(resolve)
table.insert(resolveFunctions, {resolve, 1})
2018-09-14 18:17:06 +00:00
end),
Promise.new(function(resolve)
table.insert(resolveFunctions, {resolve, "A string"})
2018-09-14 18:17:06 +00:00
end),
Promise.new(function(resolve)
table.insert(resolveFunctions, {resolve, nil})
2018-09-14 18:17:06 +00:00
end),
Promise.new(function(resolve)
table.insert(resolveFunctions, {resolve, false})
end),
2018-09-14 18:17:06 +00:00
}
local combinedPromise = Promise.all(promises)
for _, resolve in ipairs(resolveFunctions) do
expect(combinedPromise:getStatus()).to.equal(Promise.Status.Started)
resolve[1](resolve[2])
end
local success, resolved = combinedPromise:_unwrap()
2018-09-14 18:17:06 +00:00
expect(success).to.equal(true)
expect(resolved).to.be.a("table")
expect(#resolved).to.equal(4)
expect(resolved[1]).to.equal(1)
expect(resolved[2]).to.equal("A string")
expect(resolved[3]).to.equal(nil)
expect(resolved[4]).to.equal(false)
end)
end)
2018-04-11 22:26:54 +00:00
end