diff --git a/.vscode/launch.json b/.vscode/launch.json
index 5766dd9..972dae5 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -6,6 +6,9 @@
"type": "brightscript",
"request": "launch",
"rootDir": "${workspaceFolder}/dist",
+ "files": [
+ "**/*"
+ ],
"preLaunchTask": "build-tests",
"enableDebuggerAutoRecovery": true,
"stopDebuggerOnAppExit": true,
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 918ce9a..553d66e 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -24,5 +24,9 @@
"typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false,
"files.insertFinalNewline": true,
"files.trimTrailingWhitespace": true,
- "brightscript.bsdk": "./node_modules/brighterscript"
+ "brightscript.bsdk": "./node_modules/brighterscript",
+ "brightscript.projects": [
+ "bsconfig.json",
+ "bsconfig.tests.json"
+ ]
}
diff --git a/bsconfig.json b/bsconfig.json
index 1c47c3a..1722651 100644
--- a/bsconfig.json
+++ b/bsconfig.json
@@ -1,7 +1,7 @@
{
"files": [
"**/*",
- "!**/*.spec.bs"
+ "!**/*.spec.*"
],
"plugins": [
"@rokucommunity/bslint"
diff --git a/bsconfig.tests.json b/bsconfig.tests.json
index 64ba4b4..45555df 100644
--- a/bsconfig.tests.json
+++ b/bsconfig.tests.json
@@ -1,31 +1,34 @@
{
- "stagingDir": "./dist",
- "extends": "./bsconfig.json",
- "retainStagingDir": true,
- "createPackage": false,
- "files": [
- "**/*"
- ],
- "plugins": [
- "rooibos-roku"
- ],
- "rooibos": {
- "isRecordingCodeCoverage": false,
- "isGlobalMethodMockingEnabled": true,
- "testsFilePattern": null,
- "tags": [
- "!integration",
- "!deprecated",
- "!fixme"
- ],
- "showOnlyFailures": true,
- "catchCrashes": true,
- "lineWidth": 70,
- "failFast": false,
- "sendHomeOnFinish": false,
- "colorizeOutput": true,
- "reporters": [
- "mocha"
- ]
- }
-}
\ No newline at end of file
+ "files": [
+ "**/*"
+ ],
+ "rootDir": "./src",
+ "stagingDir": "./dist",
+ "emitDefinitions": true,
+ "sourceMap": true,
+ "autoImportComponentScript": true,
+ "retainStagingDir": true,
+ "createPackage": false,
+ "plugins": [
+ "rooibos-roku"
+ ],
+ "rooibos": {
+ "isRecordingCodeCoverage": false,
+ "isGlobalMethodMockingEnabled": true,
+ "testsFilePattern": null,
+ "tags": [
+ "!integration",
+ "!deprecated",
+ "!fixme"
+ ],
+ "showOnlyFailures": true,
+ "catchCrashes": true,
+ "lineWidth": 70,
+ "failFast": false,
+ "sendHomeOnFinish": false,
+ "colorizeOutput": true,
+ "reporters": [
+ "mocha"
+ ]
+ }
+}
diff --git a/demos/simple-brightscript/components/MainScene.bs b/demos/simple-brightscript/components/MainScene.bs
index 38f9566..0b215bf 100644
--- a/demos/simple-brightscript/components/MainScene.bs
+++ b/demos/simple-brightscript/components/MainScene.bs
@@ -6,11 +6,11 @@ sub init()
'Uncomment the example below to run...
- 'Simple network request example (passing in the `m` scope as context)
+ 'Simple network request example
' promise = networkRequest("http://ip-api.com/json/", "GET")
- ' promises_onThen(promise, sub(response as object, context = {} as dynamic)
+ ' promises_onThen(promise, sub(response as object)
' print "Your timezone is " + response.timezone
- ' end sub, m)
+ ' end sub)
'Simple single request using method
' separateCallbacksExample("http://ip-api.com/json/")
@@ -23,6 +23,19 @@ sub init()
'Simple single request using method with error handling
' separateCallbacksExample("http://invalid--url.com")
+
+ runTaskWithInternalPromises()
+end sub
+
+function runTaskWithInternalPromises()
+ task = createObject("roSGNode", "TaskWithInternalPromises")
+ task.observeFieldScoped("response", "onTaskWithInternalPromisesResponseChange")
+ task.control = "RUN"
+end function
+
+sub onTaskWithInternalPromisesResponseChange(event as object)
+ print "onTaskWithInternalPromisesResponseChange:"
+ print event.getData()
end sub
function networkRequest(url as string, method = "GET" as string, body = {} as object) as object
@@ -74,7 +87,7 @@ sub chainExample()
promises_chain(promise, context).then(function(ipApiData, context)
if (ipApiData.error = invalid)
print "Promises chain first call completed!!!"
- return getTimeApiTimeToFiji(ipApiData.timezone)
+ return validateTimezoneInformation(ipApiData.timezone)
else
print "Promises chain first call failed!!!"
return {
@@ -94,12 +107,11 @@ sub chainExample()
end if
m.top.chainResult = context
-
end function).catch(function(error, context)
print "Caught an error with the chain promise!!!", error
- end function).finally(function(error, context)
- print "Chain promise completed!!!", error
+ end function).finally(function(context)
+ print "Chain promise completed!!!", context
end function)
end sub
@@ -158,18 +170,11 @@ function getIpApiTimeZoneByDomain(domain as string) as object
return networkRequest(url)
end function
-function getTimeApiTimeToFiji(fromTimeZone as object) as object
+function validateTimezoneInformation(fromTimeZone as object) as object
print "Your timezone is " + fromTimeZone
- url = "https://timeapi.io/api/Conversion/ConvertTimeZone"
- method = "POST"
-
- body = {
- "fromTimeZone": fromTimeZone
- "dateTime": getFullDate() + " 00:00:00"
- "toTimeZone": "Pacific/Fiji"
- "dstAmbiguity": ""
- }
- return networkRequest(url, method, body)
+ url = "http://worldtimeapi.org/api/timezone/" + fromTimeZone
+ method = "GET"
+ return networkRequest(url, method)
end function
function getFullDate() as string
@@ -190,12 +195,9 @@ function getFullDate() as string
end function
function getChainResultString(data as object) as object
- currentDay = 25
- fijiDay = data.conversionResult.day
- fijiHour = data.conversionResult.hour
- aheadOrBehind = "ahead"
- if (fijiDay > currentDay) then aheadOrBehind = "behind"
- return "Fiji is " + fijiHour.toStr() + " hours " + aheadOrBehind + " of your timezone!"
+ timezone = data.timezone
+ doy = data.day_of_year
+ return "Confirming your timezone is is " + timezone + " and the day of year is " + doy.toStr() + "!"
end function
sub initOnscreenImage()
diff --git a/demos/simple-brightscript/components/TaskWithInternalPromises.bs b/demos/simple-brightscript/components/TaskWithInternalPromises.bs
new file mode 100644
index 0000000..21728d3
--- /dev/null
+++ b/demos/simple-brightscript/components/TaskWithInternalPromises.bs
@@ -0,0 +1,27 @@
+sub init()
+ m.port = CreateObject("roMessagePort")
+ m.top.functionName = "startTask"
+end sub
+
+sub startTask()
+ promises.initTaskFunctionality(m.port)
+ promise = doNetworkRequest("http://ip-api.com/json/", "GET", {})
+ promises.chain(promise).then(function(response)
+ m.top.response = response
+ end function).catch(function(error)
+ print "Error in TaskWithInternalPromises:", error
+ end function)
+
+ promises.runEventLoop(m.port, sub(message)
+ print "Task with internal promises received message:", message
+ end sub)
+end sub
+
+
+function doNetworkRequest(url as string, method as string, body as object) as object
+ promise = promises.create()
+ promises.resolve({
+ "something": "OF VALUE"
+ }, promise)
+ return promise
+end function
diff --git a/demos/simple-brightscript/components/TaskWithInternalPromises.xml b/demos/simple-brightscript/components/TaskWithInternalPromises.xml
new file mode 100644
index 0000000..87160c9
--- /dev/null
+++ b/demos/simple-brightscript/components/TaskWithInternalPromises.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/package-lock.json b/package-lock.json
index ce25941..e24377e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,7 +12,7 @@
"@rokucommunity/bslint": "^0.8.38",
"@types/fs-extra": "^11.0.1",
"@types/node": "^20.6.0",
- "brighterscript": "0.69.10",
+ "brighterscript": "0.69.11",
"dotenv": "^16.3.1",
"fs-extra": "^11.1.1",
"roku-deploy": "^3.14.4",
@@ -805,9 +805,9 @@
}
},
"node_modules/brighterscript": {
- "version": "0.69.10",
- "resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.69.10.tgz",
- "integrity": "sha512-E8QCzN5bueG+SYJUdQ+1vw/frIV3WrpvoLgbNkAhYLOC6bSwoqmETwmgaiXpnY66Qe2zeAapXCbBcWVVIA7AQA==",
+ "version": "0.69.11",
+ "resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.69.11.tgz",
+ "integrity": "sha512-Iq8lcCERkk6QwSn5Y+tAFZSEQbCZX6rDGpQkVPzNHzR/BtHTYsP/wSmbSIvghGQly+PihoBftR9i1txd6DD3lA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4412,9 +4412,9 @@
}
},
"brighterscript": {
- "version": "0.69.10",
- "resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.69.10.tgz",
- "integrity": "sha512-E8QCzN5bueG+SYJUdQ+1vw/frIV3WrpvoLgbNkAhYLOC6bSwoqmETwmgaiXpnY66Qe2zeAapXCbBcWVVIA7AQA==",
+ "version": "0.69.11",
+ "resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.69.11.tgz",
+ "integrity": "sha512-Iq8lcCERkk6QwSn5Y+tAFZSEQbCZX6rDGpQkVPzNHzR/BtHTYsP/wSmbSIvghGQly+PihoBftR9i1txd6DD3lA==",
"dev": true,
"requires": {
"@rokucommunity/bslib": "^0.1.1",
diff --git a/package.json b/package.json
index 60e843b..01b1f3d 100644
--- a/package.json
+++ b/package.json
@@ -17,7 +17,7 @@
"@rokucommunity/bslint": "^0.8.38",
"@types/fs-extra": "^11.0.1",
"@types/node": "^20.6.0",
- "brighterscript": "0.69.10",
+ "brighterscript": "0.69.11",
"dotenv": "^16.3.1",
"fs-extra": "^11.1.1",
"roku-deploy": "^3.14.4",
diff --git a/src/components/Test.spec.xml b/src/components/Test.spec.xml
new file mode 100644
index 0000000..4751e10
--- /dev/null
+++ b/src/components/Test.spec.xml
@@ -0,0 +1 @@
+
diff --git a/src/components/TestTask.spec.bs b/src/components/TestTask.spec.bs
new file mode 100644
index 0000000..4965abf
--- /dev/null
+++ b/src/components/TestTask.spec.bs
@@ -0,0 +1,69 @@
+import "pkg:/source/promises.bs"
+
+function doAction(actionName as string) as dynamic
+ m.port = createObject("roMessagePort")
+ m.top.promise = promises.create()
+ m.top.functionName = actionName
+ m.top.control = "RUN"
+ return m.top.promise
+end function
+
+sub test1()
+ promises.setMessagePort(m.port)
+ promises.chain(promises.resolve(true)).then(sub(response as object)
+ promises.resolve("task completed", m.top.promise)
+ end sub).finally(sub(response as object)
+ m.top.control = "STOP"
+ end sub)
+
+ while true
+ message = promises.wait2(20, m.port)
+ end while
+end sub
+
+sub test2()
+ promises.setMessagePort(m.port)
+ promises.chain(promises.resolve(true)).then(function(response as object) as dynamic
+ return doNetworkRequest("http://ip-api.com/json/")
+ end function).then(sub(response as object)
+ promises.resolve(response, m.top.promise)
+ end sub).finally(sub()
+ m.top.control = "STOP"
+ end sub)
+
+ m.top.observeField("request", m.port)
+ while true
+ message = promises.wait2(0, m.port)
+ if type(message) = "roSGNodeEvent" then
+ requestId = message.getData()
+ promises.resolve({ ipInfo: "hello" }, m.requestStorage[requestId].promise)
+ end if
+ end while
+end sub
+
+sub test3()
+ promises.setMessagePort(m.port)
+ promises.chain(promises.resolve(true), {}).then(sub(response as object, context as object) as dynamic
+ promises.reject("Simulated error", m.top.promise)
+ end sub).finally(sub(context as object)
+ m.top.control = "STOP"
+ end sub)
+
+ while true
+ message = promises.wait2(20, m.port)
+ end while
+end sub
+
+function doNetworkRequest(url as string) as dynamic
+ promise = promises.create()
+ if m.requestStorage = invalid then
+ m.requestStorage = {}
+ end if
+
+ m.requestStorage[url] = {
+ promise: promise
+ }
+
+ m.top.request = url
+ return promise
+end function
diff --git a/src/components/TestTask.spec.xml b/src/components/TestTask.spec.xml
new file mode 100644
index 0000000..359c945
--- /dev/null
+++ b/src/components/TestTask.spec.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/src/components/test.spec.xml b/src/components/test.spec.xml
deleted file mode 100644
index 90955eb..0000000
--- a/src/components/test.spec.xml
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/source/promises.bs b/src/source/promises.bs
index e75346b..b0db8fe 100644
--- a/src/source/promises.bs
+++ b/src/source/promises.bs
@@ -494,6 +494,124 @@ namespace promises
}
end function
+ sub setMessagePort(port as dynamic)
+ m.__promises__promisesPort = port
+ end sub
+
+ function getMessagePort() as dynamic
+ return m.__promises__promisesPort
+ end function
+
+ ' First, consume and process all promise events from the front of the queue.
+ ' This method is similar to the GetMessage() method, but the returned object (if not invalid) remains in the message queue.
+ ' A later call to WaitMessage(), GetMessage() or PeekMessage() will return the same message.
+ function peekMessage(port as dynamic) as dynamic
+ while true
+ message = port.peekMessage()
+
+ 'if this is a promise event, process it and peek again
+ if promises.isPromiseEvent(message) then
+ 'remove the message from the queue and process it
+ message = port.getMessage()
+ promises.internal.notifyListeners(message)
+ continue while
+ end if
+
+ return message
+ end while
+ return invalid
+ end function
+
+
+ ' First, consume and process all promise events from the front of the queue.
+ ' Then, if an event object is available, it is returned. Otherwise `invalid` is returned. The method returns immediately in either case and does not wait.
+ function getMessage(port as dynamic) as dynamic
+ if promises.peekMessage(port) <> invalid then
+ return port.getMessage()
+ end if
+
+ return invalid
+ end function
+
+
+ ' Same capabilities as the native `wait()` function, except that promise events are automatically processed and removed from its registered `roMessagePort` provided in `promises.setMessagePort()`.
+ function wait2(timeoutMilliseconds as dynamic, port as dynamic) as dynamic
+ promisesPort = promises.getMessagePort()
+ 'bs:disable-next-line
+ utils = createObject("roUtils") '
+ portIsPromisesPort = false
+
+ ' if the promise port is the same as the supplied port (and we can actually use roUtils to compare same-ness)
+ if utils <> invalid and utils.isSameObject(port, promisesPort) then
+ portIsPromisesPort = true
+ end if
+
+ timespan = createObject("roTimeSpan")
+
+ while true
+ currentDuration = timespan.TotalMilliseconds()
+ 'if we are not waiting indefinitely
+ if timeoutMilliseconds > 0 then
+ ' if the duration has exceeded the wait time, exit and return invalid
+ if currentDuration >= timeoutMilliseconds then
+ return invalid
+
+ 'the duration has not exceeded the wait time. compute how much time we have left
+ else
+ thisTickTimeout = timeoutMilliseconds - currentDuration
+ end if
+ else
+ thisTickTimeout = timeoutMilliseconds
+ end if
+ 'ensure we don't wait too long in a single tick (so promises still have time to resolve)
+ if thisTickTimeout = 0 or thisTickTimeout > 200 then
+ thisTickTimeout = 200
+ else
+ thisTickTimeout = timeoutMilliseconds
+ end if
+
+ 'if the port we're waiting on is the promises port, then no need for the double-latch
+ if portIsPromisesPort then
+ event = wait(timeoutMilliseconds, port)
+ if promises.isPromiseEvent(event) then
+ promises.internal.notifyListeners(event)
+ continue while
+ end if
+ return event
+ else
+ 'flush all pending promises on the promise port
+ promises.peekMessage(promises.getMessagePort())
+
+ 'wait a little bit for an event on the supplied port
+ event = wait(thisTickTimeout, port)
+
+ 'if the message was a promise event, handle it
+ if promises.isPromiseEvent(event) then
+ promises.internal.notifyListeners(event)
+ continue while
+ else
+ 'it's not a promise event! return it
+ return event
+ end if
+ end if
+ end while
+ return invalid
+ end function
+
+ ' function closeAllTheThings() as dynamic
+ ' unhandledMessages = []
+ ' while true
+ ' message = wait(timeout, port)
+ ' if promises.isPromiseEvent(message) then
+ ' promises.internal.notifyListeners(message)
+ ' continue while
+ ' else
+ ' unhandledMessages.push(message)
+ ' end if
+ ' end while
+ ' return unhandledMessages
+ ' end function
+
' Makes sure the value supplied is a promise
function ensurePromise(value as object) as object
if promises.isPromise(value) then return value
@@ -578,15 +696,18 @@ namespace promises.internal
' Only create storage and register observers if it does not exist
if storage = invalid then
- ' unregister any observers on the promise to prevent multiple callbacks
- promises.internal.unobserveFieldScoped(promise, promises.internal.PromiseField.promiseState)
- promises.internal.observeFieldScoped(promise, promises.internal.PromiseField.promiseState, sub(event as dynamic)
- 'run the notification nexttick to prevent stackoverflow due to cascading promises all resolving in sequence
- promises.internal.delay(sub(context as dynamic)
- promises.internal.notifyListeners(context.event)
- end sub, { event: event })
- end sub, [promises.internal.PromiseField.promiseResult])
-
+ if m.__promises__promisesPort <> invalid then
+ promise.observeFieldScoped(promises.internal.PromiseField.promiseState, m.__promises__promisesPort, [promises.internal.PromiseField.promiseResult])
+ else
+ ' unregister any observers on the promise to prevent multiple callbacks
+ promises.internal.unobserveFieldScoped(promise, promises.internal.PromiseField.promiseState)
+ promises.internal.observeFieldScoped(promise, promises.internal.PromiseField.promiseState, sub(event as dynamic)
+ 'run the notification nexttick to prevent stackoverflow due to cascading promises all resolving in sequence
+ promises.internal.delay(sub(context as dynamic)
+ promises.internal.notifyListeners(context.event)
+ end sub, { event: event })
+ end sub, [promises.internal.PromiseField.promiseResult])
+ end if
storage = {
promise: promise
thenListeners: []
@@ -626,9 +747,13 @@ namespace promises.internal
promiseState = promise.promiseState
'trigger a change if the promise is already resolved
if promiseState = promises.PromiseState.resolved or promiseState = promises.PromiseState.rejected then
- promises.internal.delay(sub (details as object)
- details.promise.promiseState = details.promiseState
- end sub, { promise: promise, promiseState: promiseState })
+ if m.__promises__promisesPort <> invalid then
+ promise.promiseState = promiseState
+ else
+ promises.internal.delay(sub (details as object)
+ details.promise.promiseState = details.promiseState
+ end sub, { promise: promise, promiseState: promiseState })
+ end if
end if
#if PROMISES_DEBUG
print "[promises.watch]", newPromise.id, "is watching", promise.id, eventName
@@ -691,9 +816,13 @@ namespace promises.internal
if promises.internal.hasStorage(originalPromise) then
' There were listeners added as a result of some of the callback notifications
' Re-trigger the notification process for the new listeners
- promises.internal.delay(sub (event as object)
+ if m.__promises__promisesPort <> invalid then
promises.internal.notifyListeners(event)
- end sub, event)
+ else
+ promises.internal.delay(sub (event as object)
+ promises.internal.notifyListeners(event)
+ end sub, event)
+ end if
end if
end if
end sub
@@ -752,7 +881,23 @@ namespace promises.internal
end if
end try
else
- callbackResult = callback(promiseValue)
+ try
+ lineNumber = LINE_NUM + 1
+ callbackResult = callback(promiseValue)
+ catch error
+ file = error.backtrace.peek()
+ if error.number = 241 and file.filename = promises.internal.getLibPath() and file.line_number = lineNumber then
+ #if PROMISES_SAVE_LISTENER_REGISTRATION_LOCATION
+ print "[promises.error]: " promises.internal.formatStackTrace(storageItem.registrationLocation, promises.internal.wrongNumberOfParametersMessage)
+ #else
+ print "[promises.error]: " promises.internal.formatStackTrace(error, promises.internal.wrongNumberOfParametersMessage)
+ #end if
+ callbackResult = callback(promiseValue, 0) ' 0 is the safest default value to pass in case of wrong number of parameters
+ else
+ promises.internal.logCrashIfEnabled(error)
+ callbackResult = promises.reject(error)
+ end if
+ end try
end if
'.finally callback takes 1 optional parameter (`context`)
@@ -777,7 +922,23 @@ namespace promises.internal
end if
end try
else
- callbackResult = callback()
+ try
+ lineNumber = LINE_NUM + 1
+ callbackResult = callback()
+ catch error
+ file = error.backtrace.peek()
+ if error.number = 241 and file.filename = promises.internal.getLibPath() and file.line_number = lineNumber then
+ #if PROMISES_SAVE_LISTENER_REGISTRATION_LOCATION
+ print "[promises.error]: " promises.internal.formatStackTrace(storageItem.registrationLocation, promises.internal.wrongNumberOfParametersMessage)
+ #else
+ print "[promises.error]: " promises.internal.formatStackTrace(error, promises.internal.wrongNumberOfParametersMessage)
+ #end if
+ callbackResult = callback(0) ' 0 is the safest default value to pass in case of wrong number of parameters
+ else
+ promises.internal.logCrashIfEnabled(error)
+ callbackResult = promises.reject(error)
+ end if
+ end try
end if
end if
catch e
diff --git a/src/source/promises.spec.bs b/src/source/promises.spec.bs
index c3f3c84..1f692b3 100644
--- a/src/source/promises.spec.bs
+++ b/src/source/promises.spec.bs
@@ -1,2323 +1,2365 @@
import "pkg:/source/promises.bs"
namespace tests
- @SGNode("test")
- @suite
- class PromisesTests extends rooibos.BaseTestSuite
-
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @describe("promises.create()")
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- @it("create promise")
- sub _()
- promise = promises.create()
- m.assertTrue(promises.isPromise(promise))
- end sub
-
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @describe("promises.isPromise()")
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- @it("promise validation")
- sub _()
- m.assertTrue(promises.isPromise(promises.create()))
- promiseNode = createNode("node", { promiseState: 0 })
- m.assertTrue(promises.isPromise(promiseNode))
- notPromise = createNode()
- m.assertFalse(promises.isPromise(notPromise))
- m.assertFalse(promises.isPromise(invalid))
- end sub
-
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @describe("promises.isComplete()")
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- @it("promise settlement check")
- sub _()
- m.assertFalse(promises.isComplete(promises.create()))
- m.assertTrue(promises.isComplete(promises.resolve({})))
- m.assertTrue(promises.isComplete(promises.reject({})))
- m.assertFalse(promises.isComplete(createNode()))
- m.assertFalse(promises.isComplete(invalid))
- end sub
-
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @describe("promises.chain()")
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- @it("promise chain follows happy path")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- finallyCount: 0
- result: ""
- }
-
- results = promises.chain(promises.resolve(1), context).then(sub(result, context)
- context.thenCount++
- context.result = result
- end sub).catch(sub(error, context)
- context.catchCount++
- end sub).finally(sub(context)
- context.finallyCount++
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 1
- catchCount: 0
- finallyCount: 1
- result: 1
- })
- end sub, context)
- end function
-
- @it("handles default then identify passthrough calls")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- finallyCount: 0
- result: []
- }
-
- results = promises.chain(promises.resolve(1), context).then(function(result, context)
- context.thenCount++
- context.result.push(result)
- return 2
- end function).then().then().then(function(result, context)
- context.thenCount++
- context.result.push(result)
- end function).catch(sub(error, context)
- context.catchCount++
- end sub).finally(sub(context)
- context.finallyCount++
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 2
- catchCount: 0
- finallyCount: 1
- result: [1, 2]
- })
- end sub, context)
- end function
-
- @it("calls thens in order")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- finallyCount: 0
- result: []
- }
-
- results = promises.chain(promises.resolve(1), context).then(function(result, context)
- context.thenCount++
- context.result.push(result)
- return 2
- end function).then(function(result, context)
- context.thenCount++
- context.result.push(result)
- return 3
- end function).then(function(result, context)
- context.thenCount++
- context.result.push(result)
- return 4
- end function).then(function(result, context)
- context.thenCount++
- context.result.push(result)
- end function).catch(sub(error, context)
- context.catchCount++
- end sub).finally(sub(context)
- context.finallyCount++
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 4
- catchCount: 0
- finallyCount: 1
- result: [1, 2, 3, 4]
- })
- end sub, context)
- end function
-
- @it("calls catches in order")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- finallyCount: 0
- result: []
- }
-
- results = promises.chain(promises.reject(1), context).then(function(result, context)
- context.thenCount++
- context.result.push(invalid)
- end function).catch(function(result, context)
- context.catchCount++
- context.result.push(result)
- return promises.reject(2)
- end function).catch(function(result, context)
- context.catchCount++
- context.result.push(result)
- return promises.reject(3)
- end function).catch(function(result, context)
- context.catchCount++
- context.result.push(result)
- return promises.reject(4)
- end function).catch(function(result, context)
- context.catchCount++
- context.result.push(result)
- end function).finally(sub(context)
- context.finallyCount++
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 0
- catchCount: 4
- finallyCount: 1
- result: [1, 2, 3, 4]
- })
- end sub, context)
- end function
-
- @it("handles default then thrower passthrough calls")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- finallyCount: 0
- result: []
- }
-
- results = promises.chain(promises.reject(1), context).then(function(result, context)
- context.thenCount++
- context.result.push(invalid)
- end function).catch(function(result, context)
- context.catchCount++
- context.result.push(result)
- return promises.reject(2)
- end function).catch().catch().catch(function(result, context)
- context.catchCount++
- context.result.push(result)
- end function).finally(sub(context)
- context.finallyCount++
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 0
- catchCount: 2
- finallyCount: 1
- result: [1, 2]
- })
- end sub, context)
- end function
-
- @it("calls finally in order")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- finallyCount: 0
- result: []
- }
-
- results = promises.chain(promises.resolve(1), context).then(function(result, context)
- context.thenCount++
- context.result.push(result)
- return 2
- end function).then(function(result, context)
- context.thenCount++
- context.result.push(result)
- return 3
- end function).then(function(result, context)
- context.thenCount++
- context.result.push(result)
- return 4
- end function).then(function(result, context)
- context.thenCount++
- context.result.push(result)
- end function).catch(sub(error, context)
- context.catchCount++
- end sub).finally(function(context)
- context.finallyCount++
- end function).finally(function(context)
- context.finallyCount++
- end function).finally(function(context)
- context.finallyCount++
- end function).finally(function(context)
- context.finallyCount++
- end function).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 4
- catchCount: 0
- finallyCount: 4
- result: [1, 2, 3, 4]
- })
- end sub, context)
- end function
-
- @it("handles default finally passthrough calls")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- finallyCount: 0
- result: []
- }
-
- results = promises.chain(promises.resolve(1), context).then(function(result, context)
- context.thenCount++
- context.result.push(result)
- return 2
- end function).then(function(result, context)
- context.thenCount++
- context.result.push(result)
- return 3
- end function).then(function(result, context)
- context.thenCount++
- context.result.push(result)
- return 4
- end function).then(function(result, context)
- context.thenCount++
- context.result.push(result)
- end function).catch(sub(error, context)
- context.catchCount++
- end sub).finally(function(context)
- context.finallyCount++
- end function).finally().finally().finally(function(context)
- context.finallyCount++
- end function).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 4
- catchCount: 0
- finallyCount: 2
- result: [1, 2, 3, 4]
- })
- end sub, context)
- end function
-
- @it("skips thens when promise is rejected")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- finallyCount: 0
- result: []
- error: ""
- }
-
- results = promises.chain(promises.resolve(1), context).then(function(result, context)
- context.thenCount++
- context.result.push(result)
- return promises.reject("rejected")
- end function).then(function(result, context)
- context.thenCount++
- context.result.push(invalid)
- end function).then(function(result, context)
- context.thenCount++
- context.result.push(invalid)
- end function).then(function(result, context)
- context.thenCount++
- context.result.push(invalid)
- end function).catch(sub(error, context)
- context.catchCount++
- context.error = error
- end sub).finally(sub(context)
- context.finallyCount++
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 1
- catchCount: 1
- finallyCount: 1
- result: [1]
- error: "rejected"
- })
- end sub, context)
- end function
-
- @it("ignores return value from finally when not crash or rejected promise")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- finallyCount: 0
- result: ""
- }
-
- results = promises.chain(promises.resolve("I am happy"), context).finally(function(context)
- context.finallyCount++
- return "I am sad"
- end function).then(sub(result as dynamic, context as dynamic)
- context.thenCount++
- context.result = result
- end sub).catch(sub(result as dynamic, context as dynamic)
- context.catchCount++
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 1
- catchCount: 0
- finallyCount: 1
- result: "I am happy"
- })
- end sub, context)
- end function
-
- @it("finally does not prevent rejection from propagating down the chain")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- finallyCount: 0
- errorMessage: ""
- }
-
- results = promises.chain(promises.reject("Crash"), context).finally(sub(context)
- context.finallyCount++
- end sub).then(sub(result as dynamic, context as dynamic)
- context.thenCount++
- end sub).catch(sub(result as dynamic, context as dynamic)
- context.catchCount++
- context.errorMessage = result
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 0
- catchCount: 1
- finallyCount: 1
- errorMessage: "Crash"
- })
- end sub, context)
- end function
-
- @it("finally that returns resolved promises does not prevent rejection from propagating down the chain")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- finallyCount: 0
- errorMessage: ""
- }
-
- results = promises.chain(promises.reject("Crash"), context).finally(function(context)
- context.finallyCount++
- return promises.resolve(true)
- end function).then(sub(result as dynamic, context as dynamic)
- context.thenCount++
- end sub).catch(sub(result as dynamic, context as dynamic)
- context.catchCount++
- context.errorMessage = result
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 0
- catchCount: 1
- finallyCount: 1
- errorMessage: "Crash"
- })
- end sub, context)
- end function
-
- @it("finally that returns value does not prevent rejection from propagating down the chain")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- finallyCount: 0
- errorMessage: ""
- }
-
- results = promises.chain(promises.reject("Crash"), context).finally(function(context)
- context.finallyCount++
- return true
- end function).then(sub(result as dynamic, context as dynamic)
- context.thenCount++
- end sub).catch(sub(result as dynamic, context as dynamic)
- context.catchCount++
- context.errorMessage = result
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 0
- catchCount: 1
- finallyCount: 1
- errorMessage: "Crash"
- })
- end sub, context)
- end function
-
- @it("returned rejection in finally is propagated down the chain")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- finallyCount: 0
- errorMessage: ""
- }
-
- results = promises.chain(promises.reject("Crash"), context).finally(function(context)
- context.finallyCount++
- return promises.reject("error in finally")
- end function).then(sub(result as dynamic, context as dynamic)
- context.thenCount++
- end sub).catch(sub(result as dynamic, context as dynamic)
- context.catchCount++
- context.errorMessage = result
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 0
- catchCount: 1
- finallyCount: 1
- errorMessage: "error in finally"
- })
- end sub, context)
- end function
-
- @it("crash in finally is propagated down the chain")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- finallyCount: 0
- errorMessage: ""
- }
-
- results = promises.chain(promises.reject("Crash"), context).finally(function(context)
- context.finallyCount++
- throw "error in finally"
- end function).then(sub(result as dynamic, context as dynamic)
- context.thenCount++
- end sub).catch(sub(result as dynamic, context as dynamic)
- context.catchCount++
- context.errorMessage = result.message
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 0
- catchCount: 1
- finallyCount: 1
- errorMessage: "error in finally"
- })
- end sub, context)
- end function
-
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @describe("promises.all()")
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- @it("handled non-array")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- errorMessage: ""
- backtrace: invalid
- }
-
- results = promises.chain(promises.all(invalid), context).then(sub(result, context)
- context.thenCount++
- end sub).catch(function(error, context)
- context.catchCount++
- context.errorMessage = error.message
- context.backtrace = error.backtrace
- return true
- end function).toPromise()
-
- return promises.onFinally(results, sub(context)
- backtrace = context.backtrace
- context.delete("backtrace")
- m.testSuite.assertEqual(context, {
- thenCount: 0
- catchCount: 1
- errorMessage: "Did not supply an array"
- })
- m.testSuite.assertNotInvalid(backtrace)
- end sub, context)
- end function
-
- @it("handled empty array")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- result: invalid
- }
-
- results = promises.chain(promises.all([]), context).then(sub(result, context)
- context.thenCount++
- context.result = result
- end sub).catch(sub(_, context)
- context.catchCount++
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 1
- catchCount: 0
- result: []
- })
- end sub, context)
- end function
-
- @it("resolving all promises")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- result: invalid
- }
-
- results = promises.chain(promises.all([
- promises.resolve(1)
- promises.resolve(2)
- promises.resolve(3)
- ]), context).then(sub(result, context)
- context.thenCount++
- context.result = result
- end sub).catch(sub(_, context)
- context.catchCount++
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 1
- catchCount: 0
- result: [1, 2, 3]
- })
- end sub, context)
- end function
-
- @it("resolving works with non-promise entire all promises")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- result: invalid
- }
-
- results = promises.chain(promises.all([
- promises.resolve(1)
- 2
- promises.resolve(3)
- ]), context).then(sub(result, context)
- context.thenCount++
- context.result = result
- end sub).catch(sub(_, context)
- context.catchCount++
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 1
- catchCount: 0
- result: [1, 2, 3]
- })
- end sub, context)
- end function
-
- @it("resolving works with all non-promise entires all promises")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- result: invalid
- }
-
- results = promises.chain(promises.all([
- 1
- 2
- 3
- ]), context).then(sub(result, context)
- context.thenCount++
- context.result = result
- end sub).catch(sub(_, context)
- context.catchCount++
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 1
- catchCount: 0
- result: [1, 2, 3]
- })
- end sub, context)
- end function
-
- @it("rejecting all promises")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- result: ""
- }
-
- results = promises.chain(promises.all([
- promises.resolve(1)
- promises.reject(2)
- promises.resolve(3)
- ]), context).then(sub(_, context)
- context.thenCount++
- end sub).catch(sub(error, context)
- context.catchCount++
- context.result = error
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 0
- catchCount: 1
- result: 2
- })
- end sub, context)
- end function
-
-
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @describe("promises.allSettled()")
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- @it("handled non-array")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- errorMessage: ""
- backtrace: invalid
- }
-
- results = promises.chain(promises.allSettled(invalid), context).then(sub(_, context)
- context.thenCount++
- end sub).catch(function(error, context)
- context.catchCount++
- context.errorMessage = error.message
- context.backtrace = error.backtrace
- end function).toPromise()
-
- return promises.onFinally(results, sub(context)
- backtrace = context.backtrace
- context.delete("backtrace")
- m.testSuite.assertEqual(context, {
- thenCount: 0
- catchCount: 1
- errorMessage: "Did not supply an array"
- })
- m.testSuite.assertNotInvalid(backtrace)
- end sub, context)
- end function
-
- @it("handled empty array")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- result: invalid
- }
-
- results = promises.chain(promises.allSettled([]), context).then(sub(result, context)
- context.thenCount++
- context.result = result
- end sub).catch(sub(_, context)
- context.catchCount++
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 1
- catchCount: 0
- result: []
- })
- end sub, context)
- end function
-
- @it("resolving all promises in allSettled")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- result: invalid
- }
-
- results = promises.chain(promises.allSettled([
- promises.resolve(1)
- promises.resolve(2)
- promises.resolve(3)
- ]), context).then(sub(result, context)
- context.thenCount++
- context.result = result
- end sub).catch(sub(_, context)
- context.catchCount++
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 1
- catchCount: 0
- result: [
- { status: promises.PromiseState.resolved, value: 1 }
- { status: promises.PromiseState.resolved, value: 2 }
- { status: promises.PromiseState.resolved, value: 3 }
- ]
- })
- end sub, context)
- end function
-
- @it("resolving works with non-promise entire in allSettled")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- result: invalid
- }
-
- results = promises.chain(promises.allSettled([
- promises.resolve(1)
- 2
- promises.resolve(3)
- ]), context).then(sub(result, context)
- context.thenCount++
- context.result = result
- end sub).catch(sub(_, context)
- context.catchCount++
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 1
- catchCount: 0
- result: [
- { status: promises.PromiseState.resolved, value: 1 }
- { status: promises.PromiseState.resolved, value: 2 }
- { status: promises.PromiseState.resolved, value: 3 }
- ]
- })
- end sub, context)
- end function
-
- @it("resolving works with all non-promise entire in allSettled")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- result: invalid
- }
-
- results = promises.chain(promises.allSettled([
- 1
- 2
- 3
- ]), context).then(sub(result, context)
- context.thenCount++
- context.result = result
- end sub).catch(sub(_)
- context.catchCount++
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 1
- catchCount: 0
- result: [
- { status: promises.PromiseState.resolved, value: 1 }
- { status: promises.PromiseState.resolved, value: 2 }
- { status: promises.PromiseState.resolved, value: 3 }
- ]
- })
- end sub, context)
- end function
-
- @it("rejecting a promise in allSettled")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- result: invalid
- }
-
- results = promises.chain(promises.allSettled([
- promises.resolve(1)
- promises.reject(2)
- promises.resolve(3)
- ]), context).then(sub(result, context)
- context.thenCount++
- context.result = result
- end sub).catch(sub(_)
- context.catchCount++
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 1
- catchCount: 0
- result: [
- { status: promises.PromiseState.resolved, value: 1 }
- { status: promises.PromiseState.rejected, reason: 2 }
- { status: promises.PromiseState.resolved, value: 3 }
- ]
- })
- end sub, context)
- end function
-
- @it("rejecting all promises in allSettled")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- result: invalid
- }
-
- results = promises.chain(promises.allSettled([
- promises.reject(1)
- promises.reject(2)
- promises.reject(3)
- ]), context).then(sub(result, context)
- context.thenCount++
- context.result = result
- end sub).catch(sub(_)
- context.catchCount++
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- m.testSuite.assertEqual(context, {
- thenCount: 1
- catchCount: 0
- result: [
- { status: promises.PromiseState.rejected, reason: 1 }
- { status: promises.PromiseState.rejected, reason: 2 }
- { status: promises.PromiseState.rejected, reason: 3 }
- ]
- })
- end sub, context)
- end function
-
-
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @describe("promises.any()")
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- @it("handled non-array")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- errors: invalid
- errorMessage: ""
- backtrace: invalid
- }
-
- results = promises.chain(promises.any(invalid), context).then(sub(_, context)
- context.thenCount++
- end sub).catch(sub(error, context)
- context.catchCount++
- context.errors = error.errors
- context.errorMessage = error.message
- context.backtrace = error.backtrace
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- backtrace = context.backtrace
- context.delete("backtrace")
- m.testSuite.assertEqual(context, {
- thenCount: 0
- catchCount: 1
- errors: []
- errorMessage: "All promises were rejected"
- })
- m.testSuite.assertNotInvalid(backtrace)
- end sub, context)
- end function
-
- @it("handled empty array")
- function _()
- context = {
- thenCount: 0
- catchCount: 0
- errors: invalid
- errorMessage: ""
- backtrace: invalid
- }
-
- results = promises.chain(promises.any([]), context).then(sub(_, context)
- context.thenCount++
- end sub).catch(sub(error, context)
- context.catchCount++
- context.errors = error.errors
- context.errorMessage = error.message
- context.backtrace = error.backtrace
- end sub).toPromise()
-
- return promises.onFinally(results, sub(context)
- backtrace = context.backtrace
- context.delete("backtrace")
- m.testSuite.assertEqual(context, {
- thenCount: 0
- catchCount: 1
- errors: []
- errorMessage: "All promises were rejected"
- })
- m.testSuite.assertNotInvalid(backtrace)
- end sub, context)
- end function
-
- @async
- @it("handled a promise that resolves")
- sub _()
- promiseArray = [
- promises.create()
- promises.create()
- promises.create()
- ]
-
- promises.chain(promises.any(promiseArray), promiseArray).then(sub(result, promiseArray)
- m.testSuite.assertEqual(result, 2)
- end sub).catch(sub(_, promiseArray)
- m.testSuite.fail("should not get here")
- end sub).finally(sub(promiseArray)
- promises.resolve(invalid, promiseArray[0])
- promises.resolve(invalid, promiseArray[2])
-
- m.testSuite.done()
- end sub)
-
- promises.resolve(2, promiseArray[1])
- end sub
-
- @it("handles a pre-resolved promise")
- function _()
- promiseArray = [
- promises.create()
- promises.resolve(2)
- promises.create()
- ]
-
- return promises.chain(promises.any(promiseArray), promiseArray).then(sub(result, promiseArray)
- m.testSuite.assertEqual(result, 2)
- end sub).catch(sub(_, promiseArray)
- m.testSuite.fail("should not get here")
- end sub).finally(sub(promiseArray)
- promises.resolve(invalid, promiseArray[0])
- promises.resolve(invalid, promiseArray[2])
- end sub).toPromise()
- end function
-
- @it("handles a non-promise value amongst pending promises")
- function _()
- promiseArray = [
- promises.create()
- 2
- promises.create()
- ]
-
- return promises.chain(promises.any(promiseArray), promiseArray).then(sub(result, promiseArray)
- m.testSuite.assertEqual(result, 2)
- end sub).catch(sub(_, promiseArray)
- m.testSuite.fail("should not get here")
- end sub).finally(sub(promiseArray)
- promises.resolve(invalid, promiseArray[0])
- promises.resolve(invalid, promiseArray[2])
- end sub).toPromise()
- end function
-
- @it("handles a non-promise value amongst rejected promises")
- function _()
- promiseArray = [
- promises.reject(1)
- 2
- promises.reject(2)
- ]
-
- return promises.chain(promises.any(promiseArray), promiseArray).then(sub(result, promiseArray)
- m.testSuite.assertEqual(result, 2)
- end sub).catch(sub(_, promiseArray)
- m.testSuite.fail("should not get here")
- end sub).toPromise()
- end function
-
- @it("handles a first pre-resolved promise")
- function _()
- promiseArray = [
- promises.resolve(1)
- promises.resolve(2)
- promises.resolve(2)
- ]
-
- return promises.chain(promises.any(promiseArray), promiseArray).then(sub(result, promiseArray)
- m.testSuite.assertEqual(result, 1)
- end sub).catch(sub(_, promiseArray)
- m.testSuite.fail("should not get here")
- end sub).toPromise()
- end function
-
- @async
- @it("handles first pre-resolved promise along with a non-promise value")
- function _()
- promiseArray = [
- promises.resolve(1)
- 2
- promises.resolve(2)
- ]
-
- return promises.chain(promises.any(promiseArray), promiseArray).then(sub(result, promiseArray)
- m.testSuite.assertEqual(result, 1)
- end sub).catch(sub(_, promiseArray)
- m.testSuite.fail("should not get here")
- end sub).toPromise()
- end function
-
- @it("handles all promises being pre-rejected")
- function _()
- promiseArray = [
- promises.reject("1")
- promises.reject("2")
- promises.reject("3")
- ]
-
- return promises.chain(promises.any(promiseArray), promiseArray).then(sub(result, promiseArray)
- m.testSuite.fail("should not get here")
- end sub).catch(sub(error, promiseArray)
- m.testSuite.assertEqual(error.message, "All promises were rejected")
- m.testSuite.assertEqual(error.errors, ["1", "2", "3"])
- m.testSuite.assertNotInvalid(error.backtrace)
- end sub).toPromise()
- end function
-
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @describe("promises.race()")
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- @it("handled non-array")
- function _()
- return promises.chain(promises.race(invalid)).then(sub(result)
- m.testSuite.fail("should not get here")
- end sub).catch(sub(error)
- m.testSuite.assertEqual(error.message, "All promises were rejected")
- m.testSuite.assertEqual(error.errors, [])
- m.testSuite.assertNotInvalid(error.backtrace)
- end sub).toPromise()
- end function
-
- @it("handled empty array")
- function _()
- return promises.chain(promises.race([])).then(sub(result)
- m.testSuite.fail("should not get here")
- end sub).catch(sub(error)
- m.testSuite.assertEqual(error.message, "All promises were rejected")
- m.testSuite.assertEqual(error.errors, [])
- m.testSuite.assertNotInvalid(error.backtrace)
- end sub).toPromise()
- end function
-
- @async
- @it("handled a promise that resolves")
- sub _()
- promiseArray = [
- promises.create()
- promises.create()
- promises.create()
- ]
-
- promises.chain(promises.race(promiseArray), promiseArray).then(sub(result, promiseArray)
- m.testSuite.assertEqual(result, 2)
- end sub).catch(sub(_, promiseArray)
- m.testSuite.fail("should not get here")
- end sub).finally(sub(promiseArray)
- promises.resolve(invalid, promiseArray[0])
- promises.resolve(invalid, promiseArray[2])
-
- m.testSuite.done()
- end sub)
-
- promises.resolve(2, promiseArray[1])
- end sub
-
- @it("handles a pre-resolved promise")
- function _()
- promiseArray = [
- promises.create()
- promises.resolve(2)
- promises.create()
- ]
-
- return promises.chain(promises.race(promiseArray), promiseArray).then(sub(result, promiseArray)
- m.testSuite.assertEqual(result, 2)
- end sub).catch(sub(_, promiseArray)
- m.testSuite.fail("should not get here")
- end sub).finally(sub(promiseArray)
- promises.resolve(invalid, promiseArray[0])
- promises.resolve(invalid, promiseArray[2])
- end sub).toPromise()
- end function
-
- @it("handles a non-promise value amongst pending promises")
- function _()
- promiseArray = [
- promises.create()
- 2
- promises.create()
- ]
-
- promises.chain(promises.race(promiseArray), promiseArray).then(sub(result, promiseArray)
- m.testSuite.assertEqual(result, 2)
- end sub).catch(sub(_, promiseArray)
- m.testSuite.fail("should not get here")
- end sub).finally(sub(promiseArray)
- promises.resolve(invalid, promiseArray[0])
- promises.resolve(invalid, promiseArray[2])
- end sub).toPromise()
- end function
-
- @it("handles a non-promise value amongst rejected promises")
- function _()
- promiseArray = [
- promises.reject(1)
- 2
- promises.reject(3)
- ]
-
- return promises.chain(promises.race(promiseArray), promiseArray).then(sub(result, promiseArray)
- m.testSuite.fail("should not get here")
- end sub).catch(sub(error, promiseArray)
- m.testSuite.assertEqual(error, 1)
- end sub).toPromise()
- end function
-
- @it("handles a first pre-resolved promise")
- function _()
- promiseArray = [
- promises.resolve(1)
- promises.resolve(2)
- promises.resolve(3)
- ]
-
- return promises.chain(promises.race(promiseArray), promiseArray).then(sub(result, promiseArray)
- m.testSuite.assertEqual(result, 1)
- end sub).catch(sub(_, promiseArray)
- m.testSuite.fail("should not get here")
- end sub).toPromise()
- end function
-
- @it("handles first pre-resolved promise along with a non-promise value")
- function _()
- promiseArray = [
- promises.resolve(1)
- 2
- promises.resolve(3)
- ]
-
- return promises.chain(promises.race(promiseArray), promiseArray).then(sub(result, promiseArray)
- m.testSuite.assertEqual(result, 1)
- end sub).catch(sub(_, promiseArray)
- m.testSuite.fail("should not get here")
- end sub).toPromise()
- end function
-
- @it("handles all promises being pre-rejected")
- function _()
- promiseArray = [
- promises.reject("1")
- promises.reject("2")
- promises.reject("3")
- ]
-
- return promises.chain(promises.race(promiseArray), promiseArray).then(sub(result, promiseArray)
- m.testSuite.fail("should not get here")
- end sub).catch(sub(error, promiseArray)
- m.testSuite.assertEqual(error, "1")
- end sub).toPromise()
- end function
-
- @it("handled a the first promise to resolve")
- function _()
- promiseArray = [
- toPromiseWithDelay(0.3, 1)
- toPromiseWithDelay(0.2, 2)
- toPromiseWithDelay(0.1, 3)
- ]
-
- promises.chain(promises.race(promiseArray), promiseArray).then(sub(result, promiseArray)
- m.testSuite.assertEqual(result, 3)
- end sub).catch(sub(_, promiseArray)
- m.testSuite.fail("should not get here")
- end sub).toPromise()
- end function
-
- @it("handled a the first promise to reject")
- function _()
- promiseArray = [
- toPromiseWithDelay(0.2, 1)
- toPromiseWithDelay(0.1, 2, false)
- toPromiseWithDelay(0.3, 3)
- ]
-
- promises.chain(promises.race(promiseArray), promiseArray).then(sub(result, promiseArray)
- m.testSuite.fail("should not get here")
- end sub).catch(sub(error, promiseArray)
- m.testSuite.assertEqual(error, 2)
- end sub).toPromise()
- end function
-
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @describe("promises.onThen()")
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- @async
- @it("catches resolved promises")
- sub _()
- promises.onThen(promises.resolve("resolved"), sub(value)
- m.testSuite.assertEqual(value, "resolved")
- m.testSuite.done()
- end sub)
- end sub
-
- @async
- @it("recovered on wrong num of callback args")
- sub _()
- context = {}
- promises.onThen(promises.resolve("resolved"), sub(value)
- m.testSuite.assertEqual(value, "resolved")
- m.testSuite.done()
- end sub, context)
- end sub
-
- @async
- @it("handles empty callbacks")
- sub _()
- promises.onThen(promises.onThen(promises.resolve("resolved")), sub(value)
- m.testSuite.assertEqual(value, "resolved")
- m.testSuite.done()
- end sub)
- end sub
-
- @async
- @it("does not response to rejected promises")
- sub _()
- context = { thenCount: 0 }
-
- promise = promises.onThen(promises.reject("rejected"), sub(value, context)
- context.thenCount++
- end sub, context)
-
- promises.onFinally(promise, sub(context)
- m.testSuite.assertEqual(context, { thenCount: 0 })
- m.testSuite.done()
- end sub, context)
- end sub
-
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @describe("promises.onCatch()")
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- @async
- @it("catches rejected promises")
- sub _()
- promises.onCatch(promises.reject("rejected"), sub(value)
- m.testSuite.assertEqual(value, "rejected")
- m.testSuite.done()
- end sub)
- end sub
-
- @async
- @it("recovered on wrong num of callback args")
- sub _()
- context = {}
- promises.onCatch(promises.reject("rejected"), sub(value)
- m.testSuite.assertEqual(value, "rejected")
- m.testSuite.done()
- end sub, context)
- end sub
-
- @async
- @it("handles empty callbacks")
- sub _()
- promises.onCatch(promises.onCatch(promises.reject("rejected")), sub(value)
- m.testSuite.assertEqual(value, "rejected")
- m.testSuite.done()
- end sub)
- end sub
-
- @async
- @it("does not response to resolved promises")
- sub _()
- context = { catchCount: 0 }
-
- promise = promises.onCatch(promises.resolve("resolved"), sub(value, context)
- context.catchCount++
- end sub, context)
-
- promises.onFinally(promise, sub(context)
- m.testSuite.assertEqual(context, { catchCount: 0 })
- m.testSuite.done()
- end sub, context)
- end sub
-
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @describe("promises.onFinally()")
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- @async
- @it("handles resolved promise")
- sub _()
- promise = promises.onFinally(promises.resolve("resolved"), sub()
- end sub)
-
- promises.onThen(promise, sub(value)
- m.testSuite.assertEqual(value, "resolved")
- m.testSuite.done()
- end sub)
- end sub
-
- @async
- @it("recovered on wrong num of callback args")
- sub _()
- context = {}
- promises.onFinally(promises.resolve("resolved"), sub()
- m.testSuite.done()
- end sub, context)
- end sub
-
- @async
- @it("handles resolved promise with empty callback")
- sub _()
- promise = promises.onFinally(promises.onFinally(promises.resolve("resolved")), sub()
- end sub)
-
- promises.onThen(promise, sub(value)
- m.testSuite.assertEqual(value, "resolved")
- m.testSuite.done()
- end sub)
- end sub
-
- @async
- @it("handles rejected promise")
- sub _()
- promise = promises.onFinally(promises.reject("rejected"), sub()
- end sub)
-
- promises.onCatch(promise, sub(value)
- m.testSuite.assertEqual(value, "rejected")
- m.testSuite.done()
- end sub)
- end sub
-
- @async
- @it("handles rejected promise with empty callback")
- sub _()
- promise = promises.onFinally(promises.onFinally(promises.reject("rejected")), sub()
- end sub)
-
- promises.onCatch(promise, sub(value)
- m.testSuite.assertEqual(value, "rejected")
- m.testSuite.done()
- end sub)
- end sub
-
- @async
- @it("handles returning as rejected promise from the finally")
- sub _()
- promise = promises.onFinally(promises.reject("rejected"), function()
- return promises.reject("new rejected promise")
- end function)
-
- promises.onCatch(promise, sub(value)
- m.testSuite.assertEqual(value, "new rejected promise")
- m.testSuite.done()
- end sub)
- end sub
-
- @async
- @it("handles rejecting with a crash in the finally")
- sub _()
- promise = promises.onFinally(promises.reject("rejected"), sub()
- throw "new rejected promise"
- end sub)
-
- promises.onCatch(promise, sub(value)
- m.testSuite.assertEqual(value.message, "new rejected promise")
- m.testSuite.assertNotInvalid(value.backtrace)
- m.testSuite.done()
- end sub)
- end sub
-
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @describe("promises.enableCrashLogging()")
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- @beforeEach
- sub beforeEachenableCrashLogging()
- m.global.removeField("__promises__crashLoggingEnabled")
- m.node.delete("formatStackTraceCalled")
- end sub
-
- @afterEach
- sub afterEachenableCrashLogging()
- m.global.removeField("__promises__crashLoggingEnabled")
- m.node.delete("formatStackTraceCalled")
- end sub
-
- @it("properly adds and removes the setting from global")
- function _()
- m.assertFalse(m.global.hasField("__promises__crashLoggingEnabled"))
- promises.configuration.enableCrashLogging(true)
- m.assertNodeContainsFields(m.global, { "__promises__crashLoggingEnabled": true })
- promises.configuration.enableCrashLogging(false)
- m.assertFalse(m.global.hasField("__promises__crashLoggingEnabled"))
- end function
-
- @it("enableCrashLogging(true) onThen() no context provided should not log")
- function _()
- promises.configuration.enableCrashLogging(true)
-
- m.node.formatStackTraceCalled = 0
- m.stubCall(promises.internal.formatStackTrace, function(error, message)
- m.formatStackTraceCalled++
- return ""
- end function)
-
- return promises.chain(promises.resolve("resolved")).then(sub(value)
- throw "my error"
- end sub).catch(sub(error)
- m.testSuite.assertEqual(m.formatStackTraceCalled, 0)
- end sub).toPromise()
- end function
-
- @it("enableCrashLogging(true) onThen() context was provided")
- function _()
- promises.configuration.enableCrashLogging(true)
-
- m.node.formatStackTraceCalled = 0
- m.stubCall(promises.internal.formatStackTrace, function(error, message)
- m.testSuite.assertNotInvalid(error.message)
- m.testSuite.assertNotInvalid(error.backtrace)
- m.testSuite.assertEqual(message, "Divide by Zero.")
- m.formatStackTraceCalled++
- return ""
- end function)
-
- return promises.chain(promises.resolve("resolved"), {}).then(sub(value, context)
- test = 1/0
- end sub).catch(sub(error, context)
- m.testSuite.assertEqual(m.formatStackTraceCalled, 1)
- end sub).toPromise()
- end function
-
- @it("enableCrashLogging(true) onCatch() no context provided")
- function _()
- promises.configuration.enableCrashLogging(true)
-
- m.node.formatStackTraceCalled = 0
- m.stubCall(promises.internal.formatStackTrace, function(_, _)
- m.formatStackTraceCalled++
- return ""
- end function)
-
- return promises.chain(promises.reject("rejected")).catch(sub(error)
- test = 1/0
- end sub).catch(sub(error)
- m.testSuite.assertEqual(m.formatStackTraceCalled, 1)
- end sub).toPromise()
- end function
-
- @it("enableCrashLogging(true) onCatch() context was provided")
- function _()
- promises.configuration.enableCrashLogging(true)
-
- m.node.formatStackTraceCalled = 0
- m.stubCall(promises.internal.formatStackTrace, function(_, _)
- m.formatStackTraceCalled++
- return ""
- end function)
-
- return promises.chain(promises.reject("rejected"), {}).catch(sub(error, context)
- test = 1/0
- end sub).catch(sub(error, context)
- m.testSuite.assertEqual(m.formatStackTraceCalled, 1)
- end sub).toPromise()
- end function
-
- @it("enableCrashLogging(true) onFinally() no context provided")
- function _()
- promises.configuration.enableCrashLogging(true)
-
- m.node.formatStackTraceCalled = 0
- m.stubCall(promises.internal.formatStackTrace, function(_, _)
- m.formatStackTraceCalled++
- return ""
- end function)
-
- return promises.chain(promises.resolve("resolved")).finally(sub()
- test = 1/0
- end sub).catch(sub(error)
- m.testSuite.assertEqual(m.formatStackTraceCalled, 1)
- end sub).toPromise()
- end function
-
- @it("enableCrashLogging(true) onFinally() context was provided")
- function _()
- promises.configuration.enableCrashLogging(true)
-
- m.node.formatStackTraceCalled = 0
- m.stubCall(promises.internal.formatStackTrace, function(_, _)
- m.formatStackTraceCalled++
- return ""
- end function)
-
- return promises.chain(promises.resolve("resolved"), {}).finally(sub(context)
- test = 1/0
- end sub).catch(sub(error, context)
- m.testSuite.assertEqual(m.formatStackTraceCalled, 1)
- end sub).toPromise()
- end function
-
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @describe("does not resolve to soon or too late")
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- @async
- @it("timer promise")
- function _()
- timerDurationInMillis = 125
- promise = sleepPromise(timerDurationInMillis / 1000)
- promises.onThen(promise, sub(_ as dynamic, ctx as dynamic)
- elapsedTimeInMillis = ctx.timespan.totalMilliseconds()
- ? "elapsed time to resolve promise:" + elapsedTimeInMillis.tostr()
- tolerance = ctx.timerDurationInMillis * 0.2
- msg = "did not settle within 10% tolerance of timer duration"
- m.testSuite.assertTrue(ctx.timerDurationInMillis - tolerance <= elapsedTimeInMillis, msg)
- m.testSuite.assertTrue(ctx.timerDurationInMillis + tolerance >= elapsedTimeInMillis, msg)
- m.testSuite.done()
- end sub, {
- timespan: createObject("roTimespan")
- timerDurationInMillis: timerDurationInMillis
- })
- end function
-
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @describe("promises.try()")
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- @it("returns a the same promise if the callback returns a promise")
- function _()
- resolvedPromiseParam = promises.resolve(1)
- resolvedPromise = promises.try(function(arg)
- return arg
- end function, [resolvedPromiseParam])
-
- m.assertTrue(promises.isPromise(resolvedPromise))
- m.assertTrue(resolvedPromise.isSameNode(resolvedPromiseParam))
-
- rejectedPromiseParam = promises.reject("error")
- rejectedPromise = promises.try(function(arg)
- return arg
- end function, [rejectedPromiseParam])
-
- m.assertTrue(promises.isPromise(rejectedPromise))
- m.assertTrue(rejectedPromise.isSameNode(rejectedPromiseParam))
-
- return promises.onThen(promises.allSettled([resolvedPromise, rejectedPromise]), sub(results)
- m.testSuite.assertEqual(results, [
- { status: promises.PromiseState.resolved, value: 1 }
- { status: promises.PromiseState.rejected, reason: "error" }
- ])
- end sub)
- end function
-
- @it("returns a rejected promise if the callback throws an error")
- function _()
- promise = promises.try(function()
- throw "error"
- end function)
-
- m.assertTrue(promises.isPromise(promise))
-
- return promises.onCatch(promise, sub(error)
- m.testSuite.assertEqual(error.message, "error")
- m.testSuite.assertNotInvalid(error.backTrace)
- end sub)
- end function
-
- @it("calls the callback when supplied with no augments wrapped in a promise")
- function _()
- promise = promises.try(function()
- return true
- end function)
-
- m.assertTrue(promises.isPromise(promise))
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, true)
- end sub)
- end function
-
-
- @it("calls the callback when supplied empty augments")
- function _()
- promise = promises.try(function()
- return true
- end function, [])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, true)
- end sub)
- end function
-
- @it("calls the callback when supplied with 1 augment")
- function _()
- promise = promises.try(function(a)
- return [a]
- end function, [1])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1])
- end sub)
- end function
-
- @it("calls the callback when supplied with 2 augments")
- function _()
- promise = promises.try(function(a, b)
- return [a, b]
- end function, [1, 2])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2])
- end sub)
- end function
-
- @it("calls the callback when supplied with 3 augments")
- function _()
- promise = promises.try(function(a, b, c)
- return [a, b, c]
- end function, [1, 2, 3])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3])
- end sub)
- end function
-
- @it("calls the callback when supplied with 4 augments")
- function _()
- promise = promises.try(function(a, b, c, d)
- return [a, b, c, d]
- end function, [1, 2, 3, 4])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4])
- end sub)
- end function
-
- @it("calls the callback when supplied with 5 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e)
- return [a, b, c, d, e]
- end function, [1, 2, 3, 4, 5])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5])
- end sub)
- end function
-
- @it("calls the callback when supplied with 6 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f)
- return [a, b, c, d, e, f]
- end function, [1, 2, 3, 4, 5, 6])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6])
- end sub)
- end function
-
- @it("calls the callback when supplied with 7 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g)
- return [a, b, c, d, e, f, g]
- end function, [1, 2, 3, 4, 5, 6, 7])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7])
- end sub)
- end function
-
- @it("calls the callback when supplied with 8 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h)
- return [a, b, c, d, e, f, g, h]
- end function, [1, 2, 3, 4, 5, 6, 7, 8])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8])
- end sub)
- end function
-
- @it("calls the callback when supplied with 9 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i)
- return [a, b, c, d, e, f, g, h, i]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9])
- end sub)
- end function
-
- @it("calls the callback when supplied with 10 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j)
- return [a, b, c, d, e, f, g, h, i, j]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
- end sub)
- end function
-
- @it("calls the callback when supplied with 11 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k)
- return [a, b, c, d, e, f, g, h, i, j, k]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
- end sub)
- end function
-
- @it("calls the callback when supplied with 12 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l)
- return [a, b, c, d, e, f, g, h, i, j, k, l]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
- end sub)
- end function
-
- @it("calls the callback when supplied with 13 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])
- end sub)
- end function
-
- @it("calls the callback when supplied with 14 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
- end sub)
- end function
-
- @it("calls the callback when supplied with 15 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
- end sub)
- end function
-
- @it("calls the callback when supplied with 16 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])
- end sub)
- end function
-
- @it("calls the callback when supplied with 17 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])
- end sub)
- end function
-
- @it("calls the callback when supplied with 18 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18])
- end sub)
- end function
-
- @it("calls the callback when supplied with 19 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
- end sub)
- end function
-
- @it("calls the callback when supplied with 20 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20])
- end sub)
- end function
-
- @it("calls the callback when supplied with 21 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21])
- end sub)
- end function
-
- @it("calls the callback when supplied with 22 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22])
- end sub)
- end function
-
- @it("calls the callback when supplied with 23 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23])
- end sub)
- end function
-
- @it("calls the callback when supplied with 24 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24])
- end sub)
- end function
-
- @it("calls the callback when supplied with 25 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25])
- end sub)
- end function
-
- @it("calls the callback when supplied with 26 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26])
- end sub)
- end function
-
- @it("calls the callback when supplied with 27 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27])
- end sub)
- end function
-
- @it("calls the callback when supplied with 28 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28])
- end sub)
- end function
-
- @it("calls the callback when supplied with 29 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29])
- end sub)
- end function
-
- @it("calls the callback when supplied with 30 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30])
- end sub)
- end function
-
- @it("calls the callback when supplied with 31 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31])
- end sub)
- end function
-
- @it("calls the callback when supplied with 32 augments")
- function _()
- promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae, af)
- return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae, af]
- end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32])
-
- return promises.onThen(promise, sub(result)
- m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32])
- end sub)
- end function
-
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @describe("promises.resolve()/promises.reject()")
- '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- @async
- @it("resolved invalid")
- function _()
- promise = promises.resolve(invalid)
- promises.onThen(promise, sub(result as dynamic)
- m.testSuite.assertEqual(result, invalid)
- m.testSuite.done()
- end sub)
- end function
-
- @async
- @it("reject invalid")
- function _()
- promise = promises.reject(invalid)
- promises.onCatch(promise, sub(result as dynamic)
- m.testSuite.assertEqual(result, invalid)
- m.testSuite.done()
- end sub)
- end function
-
- @async
- @it("resolved integer")
- function _()
- promise = promises.resolve(1)
- promises.onThen(promise, sub(result as dynamic)
- m.testSuite.assertEqual(result, 1)
- m.testSuite.done()
- end sub)
- end function
-
- @async
- @it("reject integer")
- function _()
- promise = promises.reject(1)
- promises.onCatch(promise, sub(result as dynamic)
- m.testSuite.assertEqual(result, 1)
- m.testSuite.done()
- end sub)
- end function
-
- @async
- @it("resolved float")
- function _()
- promise = promises.resolve(1.1)
- promises.onThen(promise, sub(result as dynamic)
- m.testSuite.assertEqual(result, 1.1)
- m.testSuite.done()
- end sub)
- end function
-
- @async
- @it("reject float")
- function _()
- promise = promises.reject(1.1)
- promises.onCatch(promise, sub(result as dynamic)
- m.testSuite.assertEqual(result, 1.1)
- m.testSuite.done()
- end sub)
- end function
-
- @async
- @it("resolved boolean")
- function _()
- promise = promises.resolve(true)
- promises.onThen(promise, sub(result as dynamic)
- m.testSuite.assertEqual(result, true)
- m.testSuite.done()
- end sub)
- end function
-
- @async
- @it("reject boolean")
- function _()
- promise = promises.reject(true)
- promises.onCatch(promise, sub(result as dynamic)
- m.testSuite.assertEqual(result, true)
- m.testSuite.done()
- end sub)
- end function
-
- @async
- @it("resolved string")
- function _()
- promise = promises.resolve("my string")
- promises.onThen(promise, sub(result as dynamic)
- m.testSuite.assertEqual(result, "my string")
- m.testSuite.done()
- end sub)
- end function
-
- @async
- @it("reject string")
- function _()
- promise = promises.reject("my string")
- promises.onCatch(promise, sub(result as dynamic)
- m.testSuite.assertEqual(result, "my string")
- m.testSuite.done()
- end sub)
- end function
-
- @async
- @it("resolved array")
- function _()
- promise = promises.resolve([1, 2, 3])
- promises.onThen(promise, sub(result as dynamic)
- m.testSuite.assertEqual(result, [1, 2, 3])
- m.testSuite.done()
- end sub)
- end function
-
- @async
- @it("reject array")
- function _()
- promise = promises.reject([1, 2, 3])
- promises.onCatch(promise, sub(result as dynamic)
- m.testSuite.assertEqual(result, [1, 2, 3])
- m.testSuite.done()
- end sub)
- end function
-
- @async
- @it("resolved AA")
- function _()
- promise = promises.resolve({
- key: "value"
- })
- promises.onThen(promise, sub(result as dynamic)
- m.testSuite.assertEqual(result, {
- key: "value"
- })
- m.testSuite.done()
- end sub)
- end function
-
- @async
- @it("reject AA")
- function _()
- promise = promises.reject({
- key: "value"
- })
- promises.onCatch(promise, sub(result as dynamic)
- m.testSuite.assertEqual(result, {
- key: "value"
- })
- m.testSuite.done()
- end sub)
- end function
-
- @async
- @it("resolved AA with subtype")
- function _()
- promise = promises.resolve({
- subType: "Node"
- })
- promises.onThen(promise, sub(result as dynamic)
- m.testSuite.assertEqual(result, {
- subType: "Node"
- })
- m.testSuite.done()
- end sub)
- end function
-
- @async
- @it("reject AA with subtype")
- function _()
- promise = promises.reject({
- subType: "Node"
- })
- promises.onCatch(promise, sub(result as dynamic)
- m.testSuite.assertEqual(result, {
- subType: "Node"
- })
- m.testSuite.done()
- end sub)
- end function
-
- @async
- @it("resolved AA with children array")
- function _()
- promise = promises.resolve({
- children: [{ subType: "Node" }]
- })
- promises.onThen(promise, sub(result as dynamic)
- m.testSuite.assertEqual(result, {
- children: [{ subType: "Node" }]
- })
- m.testSuite.done()
- end sub)
- end function
-
- @async
- @it("reject AA with children array")
- function _()
- promise = promises.reject({
- children: [{ subType: "Node" }]
- })
- promises.onCatch(promise, sub(result as dynamic)
- m.testSuite.assertEqual(result, {
- children: [{ subType: "Node" }]
- })
- m.testSuite.done()
- end sub)
- end function
-
- @async
- @it("resolved SgNode")
- function _()
- testNode = createNode("Node")
- promise = promises.resolve(testNode)
- promises.onThen(promise, sub(result as dynamic, context as dynamic)
- m.testSuite.assertTrue(context.isSameNode(result))
- m.testSuite.done()
- end sub, testNode)
- end function
-
- @async
- @it("reject SgNode")
- function _()
- testNode = createNode("Node")
- promise = promises.reject(testNode)
- promises.onCatch(promise, sub(result as dynamic, context as dynamic)
- m.testSuite.assertTrue(context.isSameNode(result))
- m.testSuite.done()
- end sub, testNode)
- end function
-
- @async(60000)
- @it("unravels deep promise chain without crashing due to stackoverflow")
- function _()
- 'this function creates a promise that depends on another promise (until we hit a max)
- doWork = function(context)
- 'if we hit the max, resolve the promise and unravel the entire stack
- if context.currentCount > 10000
- return promises.resolve(true)
- end if
- context.currentCount = context.currentCount + 1
-
- 'return a promise that depends on another future promise
- return promises.onThen(promises.resolve(true), function(result, context)
- doWork = context.doWork
- return doWork(context)
- end function, context)
- end function
-
- promises.chain(promises.resolve(true), {
- currentCount: 0,
- doWork: doWork
- }).then(function(result, context)
- doWork = context.doWork
- return doWork(context)
- end function).then(function(result, context)
- m.testSuite.done()
- end function).catch(function(error, context)
- print "error", error, FormatJson(error.backtrace)
- end function).toPromise()
-
- end function
- end class
+ @SGNode("Test")
+ @suite
+ class PromisesTests extends rooibos.BaseTestSuite
+
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @describe("promises.create()")
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ @it("create promise")
+ sub _()
+ promise = promises.create()
+ m.assertTrue(promises.isPromise(promise))
+ end sub
+
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @describe("promises.isPromise()")
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ @it("promise validation")
+ sub _()
+ m.assertTrue(promises.isPromise(promises.create()))
+ promiseNode = createNode("node", { promiseState: 0 })
+ m.assertTrue(promises.isPromise(promiseNode))
+ notPromise = createNode()
+ m.assertFalse(promises.isPromise(notPromise))
+ m.assertFalse(promises.isPromise(invalid))
+ end sub
+
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @describe("promises.isComplete()")
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ @it("promise settlement check")
+ sub _()
+ m.assertFalse(promises.isComplete(promises.create()))
+ m.assertTrue(promises.isComplete(promises.resolve({})))
+ m.assertTrue(promises.isComplete(promises.reject({})))
+ m.assertFalse(promises.isComplete(createNode()))
+ m.assertFalse(promises.isComplete(invalid))
+ end sub
+
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @describe("promises.chain()")
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ @it("promise chain follows happy path")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ finallyCount: 0
+ result: ""
+ }
+
+ results = promises.chain(promises.resolve(1), context).then(sub(result, context)
+ context.thenCount++
+ context.result = result
+ end sub).catch(sub(error, context)
+ context.catchCount++
+ end sub).finally(sub(context)
+ context.finallyCount++
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 1
+ catchCount: 0
+ finallyCount: 1
+ result: 1
+ })
+ end sub, context)
+ end function
+
+ @it("handles default then identify passthrough calls")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ finallyCount: 0
+ result: []
+ }
+
+ results = promises.chain(promises.resolve(1), context).then(function(result, context)
+ context.thenCount++
+ context.result.push(result)
+ return 2
+ end function).then().then().then(function(result, context)
+ context.thenCount++
+ context.result.push(result)
+ end function).catch(sub(error, context)
+ context.catchCount++
+ end sub).finally(sub(context)
+ context.finallyCount++
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 2
+ catchCount: 0
+ finallyCount: 1
+ result: [1, 2]
+ })
+ end sub, context)
+ end function
+
+ @it("calls thens in order")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ finallyCount: 0
+ result: []
+ }
+
+ results = promises.chain(promises.resolve(1), context).then(function(result, context)
+ context.thenCount++
+ context.result.push(result)
+ return 2
+ end function).then(function(result, context)
+ context.thenCount++
+ context.result.push(result)
+ return 3
+ end function).then(function(result, context)
+ context.thenCount++
+ context.result.push(result)
+ return 4
+ end function).then(function(result, context)
+ context.thenCount++
+ context.result.push(result)
+ end function).catch(sub(error, context)
+ context.catchCount++
+ end sub).finally(sub(context)
+ context.finallyCount++
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 4
+ catchCount: 0
+ finallyCount: 1
+ result: [1, 2, 3, 4]
+ })
+ end sub, context)
+ end function
+
+ @it("calls catches in order")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ finallyCount: 0
+ result: []
+ }
+
+ results = promises.chain(promises.reject(1), context).then(function(result, context)
+ context.thenCount++
+ context.result.push(invalid)
+ end function).catch(function(result, context)
+ context.catchCount++
+ context.result.push(result)
+ return promises.reject(2)
+ end function).catch(function(result, context)
+ context.catchCount++
+ context.result.push(result)
+ return promises.reject(3)
+ end function).catch(function(result, context)
+ context.catchCount++
+ context.result.push(result)
+ return promises.reject(4)
+ end function).catch(function(result, context)
+ context.catchCount++
+ context.result.push(result)
+ end function).finally(sub(context)
+ context.finallyCount++
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 0
+ catchCount: 4
+ finallyCount: 1
+ result: [1, 2, 3, 4]
+ })
+ end sub, context)
+ end function
+
+ @it("handles default then thrower passthrough calls")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ finallyCount: 0
+ result: []
+ }
+
+ results = promises.chain(promises.reject(1), context).then(function(result, context)
+ context.thenCount++
+ context.result.push(invalid)
+ end function).catch(function(result, context)
+ context.catchCount++
+ context.result.push(result)
+ return promises.reject(2)
+ end function).catch().catch().catch(function(result, context)
+ context.catchCount++
+ context.result.push(result)
+ end function).finally(sub(context)
+ context.finallyCount++
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 0
+ catchCount: 2
+ finallyCount: 1
+ result: [1, 2]
+ })
+ end sub, context)
+ end function
+
+ @it("calls finally in order")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ finallyCount: 0
+ result: []
+ }
+
+ results = promises.chain(promises.resolve(1), context).then(function(result, context)
+ context.thenCount++
+ context.result.push(result)
+ return 2
+ end function).then(function(result, context)
+ context.thenCount++
+ context.result.push(result)
+ return 3
+ end function).then(function(result, context)
+ context.thenCount++
+ context.result.push(result)
+ return 4
+ end function).then(function(result, context)
+ context.thenCount++
+ context.result.push(result)
+ end function).catch(sub(error, context)
+ context.catchCount++
+ end sub).finally(function(context)
+ context.finallyCount++
+ end function).finally(function(context)
+ context.finallyCount++
+ end function).finally(function(context)
+ context.finallyCount++
+ end function).finally(function(context)
+ context.finallyCount++
+ end function).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 4
+ catchCount: 0
+ finallyCount: 4
+ result: [1, 2, 3, 4]
+ })
+ end sub, context)
+ end function
+
+ @it("handles default finally passthrough calls")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ finallyCount: 0
+ result: []
+ }
+
+ results = promises.chain(promises.resolve(1), context).then(function(result, context)
+ context.thenCount++
+ context.result.push(result)
+ return 2
+ end function).then(function(result, context)
+ context.thenCount++
+ context.result.push(result)
+ return 3
+ end function).then(function(result, context)
+ context.thenCount++
+ context.result.push(result)
+ return 4
+ end function).then(function(result, context)
+ context.thenCount++
+ context.result.push(result)
+ end function).catch(sub(error, context)
+ context.catchCount++
+ end sub).finally(function(context)
+ context.finallyCount++
+ end function).finally().finally().finally(function(context)
+ context.finallyCount++
+ end function).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 4
+ catchCount: 0
+ finallyCount: 2
+ result: [1, 2, 3, 4]
+ })
+ end sub, context)
+ end function
+
+ @it("skips thens when promise is rejected")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ finallyCount: 0
+ result: []
+ error: ""
+ }
+
+ results = promises.chain(promises.resolve(1), context).then(function(result, context)
+ context.thenCount++
+ context.result.push(result)
+ return promises.reject("rejected")
+ end function).then(function(result, context)
+ context.thenCount++
+ context.result.push(invalid)
+ end function).then(function(result, context)
+ context.thenCount++
+ context.result.push(invalid)
+ end function).then(function(result, context)
+ context.thenCount++
+ context.result.push(invalid)
+ end function).catch(sub(error, context)
+ context.catchCount++
+ context.error = error
+ end sub).finally(sub(context)
+ context.finallyCount++
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 1
+ catchCount: 1
+ finallyCount: 1
+ result: [1]
+ error: "rejected"
+ })
+ end sub, context)
+ end function
+
+ @it("ignores return value from finally when not crash or rejected promise")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ finallyCount: 0
+ result: ""
+ }
+
+ results = promises.chain(promises.resolve("I am happy"), context).finally(function(context)
+ context.finallyCount++
+ return "I am sad"
+ end function).then(sub(result as dynamic, context as dynamic)
+ context.thenCount++
+ context.result = result
+ end sub).catch(sub(result as dynamic, context as dynamic)
+ context.catchCount++
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 1
+ catchCount: 0
+ finallyCount: 1
+ result: "I am happy"
+ })
+ end sub, context)
+ end function
+
+ @it("finally does not prevent rejection from propagating down the chain")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ finallyCount: 0
+ errorMessage: ""
+ }
+
+ results = promises.chain(promises.reject("Crash"), context).finally(sub(context)
+ context.finallyCount++
+ end sub).then(sub(result as dynamic, context as dynamic)
+ context.thenCount++
+ end sub).catch(sub(result as dynamic, context as dynamic)
+ context.catchCount++
+ context.errorMessage = result
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 0
+ catchCount: 1
+ finallyCount: 1
+ errorMessage: "Crash"
+ })
+ end sub, context)
+ end function
+
+ @it("finally that returns resolved promises does not prevent rejection from propagating down the chain")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ finallyCount: 0
+ errorMessage: ""
+ }
+
+ results = promises.chain(promises.reject("Crash"), context).finally(function(context)
+ context.finallyCount++
+ return promises.resolve(true)
+ end function).then(sub(result as dynamic, context as dynamic)
+ context.thenCount++
+ end sub).catch(sub(result as dynamic, context as dynamic)
+ context.catchCount++
+ context.errorMessage = result
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 0
+ catchCount: 1
+ finallyCount: 1
+ errorMessage: "Crash"
+ })
+ end sub, context)
+ end function
+
+ @it("finally that returns value does not prevent rejection from propagating down the chain")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ finallyCount: 0
+ errorMessage: ""
+ }
+
+ results = promises.chain(promises.reject("Crash"), context).finally(function(context)
+ context.finallyCount++
+ return true
+ end function).then(sub(result as dynamic, context as dynamic)
+ context.thenCount++
+ end sub).catch(sub(result as dynamic, context as dynamic)
+ context.catchCount++
+ context.errorMessage = result
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 0
+ catchCount: 1
+ finallyCount: 1
+ errorMessage: "Crash"
+ })
+ end sub, context)
+ end function
+
+ @it("returned rejection in finally is propagated down the chain")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ finallyCount: 0
+ errorMessage: ""
+ }
+
+ results = promises.chain(promises.reject("Crash"), context).finally(function(context)
+ context.finallyCount++
+ return promises.reject("error in finally")
+ end function).then(sub(result as dynamic, context as dynamic)
+ context.thenCount++
+ end sub).catch(sub(result as dynamic, context as dynamic)
+ context.catchCount++
+ context.errorMessage = result
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 0
+ catchCount: 1
+ finallyCount: 1
+ errorMessage: "error in finally"
+ })
+ end sub, context)
+ end function
+
+ @it("crash in finally is propagated down the chain")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ finallyCount: 0
+ errorMessage: ""
+ }
+
+ results = promises.chain(promises.reject("Crash"), context).finally(function(context)
+ context.finallyCount++
+ throw "error in finally"
+ end function).then(sub(result as dynamic, context as dynamic)
+ context.thenCount++
+ end sub).catch(sub(result as dynamic, context as dynamic)
+ context.catchCount++
+ context.errorMessage = result.message
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 0
+ catchCount: 1
+ finallyCount: 1
+ errorMessage: "error in finally"
+ })
+ end sub, context)
+ end function
+
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @describe("promises.all()")
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ @it("handled non-array")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ errorMessage: ""
+ backtrace: invalid
+ }
+
+ results = promises.chain(promises.all(invalid), context).then(sub(result, context)
+ context.thenCount++
+ end sub).catch(function(error, context)
+ context.catchCount++
+ context.errorMessage = error.message
+ context.backtrace = error.backtrace
+ return true
+ end function).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ backtrace = context.backtrace
+ context.delete("backtrace")
+ m.testSuite.assertEqual(context, {
+ thenCount: 0
+ catchCount: 1
+ errorMessage: "Did not supply an array"
+ })
+ m.testSuite.assertNotInvalid(backtrace)
+ end sub, context)
+ end function
+
+ @it("handled empty array")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ result: invalid
+ }
+
+ results = promises.chain(promises.all([]), context).then(sub(result, context)
+ context.thenCount++
+ context.result = result
+ end sub).catch(sub(_, context)
+ context.catchCount++
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 1
+ catchCount: 0
+ result: []
+ })
+ end sub, context)
+ end function
+
+ @it("resolving all promises")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ result: invalid
+ }
+
+ results = promises.chain(promises.all([
+ promises.resolve(1)
+ promises.resolve(2)
+ promises.resolve(3)
+ ]), context).then(sub(result, context)
+ context.thenCount++
+ context.result = result
+ end sub).catch(sub(_, context)
+ context.catchCount++
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 1
+ catchCount: 0
+ result: [1, 2, 3]
+ })
+ end sub, context)
+ end function
+
+ @it("resolving works with non-promise entire all promises")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ result: invalid
+ }
+
+ results = promises.chain(promises.all([
+ promises.resolve(1)
+ 2
+ promises.resolve(3)
+ ]), context).then(sub(result, context)
+ context.thenCount++
+ context.result = result
+ end sub).catch(sub(_, context)
+ context.catchCount++
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 1
+ catchCount: 0
+ result: [1, 2, 3]
+ })
+ end sub, context)
+ end function
+
+ @it("resolving works with all non-promise entires all promises")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ result: invalid
+ }
+
+ results = promises.chain(promises.all([
+ 1
+ 2
+ 3
+ ]), context).then(sub(result, context)
+ context.thenCount++
+ context.result = result
+ end sub).catch(sub(_, context)
+ context.catchCount++
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 1
+ catchCount: 0
+ result: [1, 2, 3]
+ })
+ end sub, context)
+ end function
+
+ @it("rejecting all promises")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ result: ""
+ }
+
+ results = promises.chain(promises.all([
+ promises.resolve(1)
+ promises.reject(2)
+ promises.resolve(3)
+ ]), context).then(sub(_, context)
+ context.thenCount++
+ end sub).catch(sub(error, context)
+ context.catchCount++
+ context.result = error
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 0
+ catchCount: 1
+ result: 2
+ })
+ end sub, context)
+ end function
+
+
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @describe("promises.allSettled()")
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ @it("handled non-array")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ errorMessage: ""
+ backtrace: invalid
+ }
+
+ results = promises.chain(promises.allSettled(invalid), context).then(sub(_, context)
+ context.thenCount++
+ end sub).catch(function(error, context)
+ context.catchCount++
+ context.errorMessage = error.message
+ context.backtrace = error.backtrace
+ end function).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ backtrace = context.backtrace
+ context.delete("backtrace")
+ m.testSuite.assertEqual(context, {
+ thenCount: 0
+ catchCount: 1
+ errorMessage: "Did not supply an array"
+ })
+ m.testSuite.assertNotInvalid(backtrace)
+ end sub, context)
+ end function
+
+ @it("handled empty array")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ result: invalid
+ }
+
+ results = promises.chain(promises.allSettled([]), context).then(sub(result, context)
+ context.thenCount++
+ context.result = result
+ end sub).catch(sub(_, context)
+ context.catchCount++
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 1
+ catchCount: 0
+ result: []
+ })
+ end sub, context)
+ end function
+
+ @it("resolving all promises in allSettled")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ result: invalid
+ }
+
+ results = promises.chain(promises.allSettled([
+ promises.resolve(1)
+ promises.resolve(2)
+ promises.resolve(3)
+ ]), context).then(sub(result, context)
+ context.thenCount++
+ context.result = result
+ end sub).catch(sub(_, context)
+ context.catchCount++
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 1
+ catchCount: 0
+ result: [
+ { status: promises.PromiseState.resolved, value: 1 }
+ { status: promises.PromiseState.resolved, value: 2 }
+ { status: promises.PromiseState.resolved, value: 3 }
+ ]
+ })
+ end sub, context)
+ end function
+
+ @it("resolving works with non-promise entire in allSettled")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ result: invalid
+ }
+
+ results = promises.chain(promises.allSettled([
+ promises.resolve(1)
+ 2
+ promises.resolve(3)
+ ]), context).then(sub(result, context)
+ context.thenCount++
+ context.result = result
+ end sub).catch(sub(_, context)
+ context.catchCount++
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 1
+ catchCount: 0
+ result: [
+ { status: promises.PromiseState.resolved, value: 1 }
+ { status: promises.PromiseState.resolved, value: 2 }
+ { status: promises.PromiseState.resolved, value: 3 }
+ ]
+ })
+ end sub, context)
+ end function
+
+ @it("resolving works with all non-promise entire in allSettled")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ result: invalid
+ }
+
+ results = promises.chain(promises.allSettled([
+ 1
+ 2
+ 3
+ ]), context).then(sub(result, context)
+ context.thenCount++
+ context.result = result
+ end sub).catch(sub(_)
+ context.catchCount++
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 1
+ catchCount: 0
+ result: [
+ { status: promises.PromiseState.resolved, value: 1 }
+ { status: promises.PromiseState.resolved, value: 2 }
+ { status: promises.PromiseState.resolved, value: 3 }
+ ]
+ })
+ end sub, context)
+ end function
+
+ @it("rejecting a promise in allSettled")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ result: invalid
+ }
+
+ results = promises.chain(promises.allSettled([
+ promises.resolve(1)
+ promises.reject(2)
+ promises.resolve(3)
+ ]), context).then(sub(result, context)
+ context.thenCount++
+ context.result = result
+ end sub).catch(sub(_)
+ context.catchCount++
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 1
+ catchCount: 0
+ result: [
+ { status: promises.PromiseState.resolved, value: 1 }
+ { status: promises.PromiseState.rejected, reason: 2 }
+ { status: promises.PromiseState.resolved, value: 3 }
+ ]
+ })
+ end sub, context)
+ end function
+
+ @it("rejecting all promises in allSettled")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ result: invalid
+ }
+
+ results = promises.chain(promises.allSettled([
+ promises.reject(1)
+ promises.reject(2)
+ promises.reject(3)
+ ]), context).then(sub(result, context)
+ context.thenCount++
+ context.result = result
+ end sub).catch(sub(_)
+ context.catchCount++
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ m.testSuite.assertEqual(context, {
+ thenCount: 1
+ catchCount: 0
+ result: [
+ { status: promises.PromiseState.rejected, reason: 1 }
+ { status: promises.PromiseState.rejected, reason: 2 }
+ { status: promises.PromiseState.rejected, reason: 3 }
+ ]
+ })
+ end sub, context)
+ end function
+
+
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @describe("promises.any()")
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ @it("handled non-array")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ errors: invalid
+ errorMessage: ""
+ backtrace: invalid
+ }
+
+ results = promises.chain(promises.any(invalid), context).then(sub(_, context)
+ context.thenCount++
+ end sub).catch(sub(error, context)
+ context.catchCount++
+ context.errors = error.errors
+ context.errorMessage = error.message
+ context.backtrace = error.backtrace
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ backtrace = context.backtrace
+ context.delete("backtrace")
+ m.testSuite.assertEqual(context, {
+ thenCount: 0
+ catchCount: 1
+ errors: []
+ errorMessage: "All promises were rejected"
+ })
+ m.testSuite.assertNotInvalid(backtrace)
+ end sub, context)
+ end function
+
+ @it("handled empty array")
+ function _()
+ context = {
+ thenCount: 0
+ catchCount: 0
+ errors: invalid
+ errorMessage: ""
+ backtrace: invalid
+ }
+
+ results = promises.chain(promises.any([]), context).then(sub(_, context)
+ context.thenCount++
+ end sub).catch(sub(error, context)
+ context.catchCount++
+ context.errors = error.errors
+ context.errorMessage = error.message
+ context.backtrace = error.backtrace
+ end sub).toPromise()
+
+ return promises.onFinally(results, sub(context)
+ backtrace = context.backtrace
+ context.delete("backtrace")
+ m.testSuite.assertEqual(context, {
+ thenCount: 0
+ catchCount: 1
+ errors: []
+ errorMessage: "All promises were rejected"
+ })
+ m.testSuite.assertNotInvalid(backtrace)
+ end sub, context)
+ end function
+
+ @async
+ @it("handled a promise that resolves")
+ sub _()
+ promiseArray = [
+ promises.create()
+ promises.create()
+ promises.create()
+ ]
+
+ promises.chain(promises.any(promiseArray), promiseArray).then(sub(result, promiseArray)
+ m.testSuite.assertEqual(result, 2)
+ end sub).catch(sub(_, promiseArray)
+ m.testSuite.fail("should not get here")
+ end sub).finally(sub(promiseArray)
+ promises.resolve(invalid, promiseArray[0])
+ promises.resolve(invalid, promiseArray[2])
+
+ m.testSuite.done()
+ end sub)
+
+ promises.resolve(2, promiseArray[1])
+ end sub
+
+ @it("handles a pre-resolved promise")
+ function _()
+ promiseArray = [
+ promises.create()
+ promises.resolve(2)
+ promises.create()
+ ]
+
+ return promises.chain(promises.any(promiseArray), promiseArray).then(sub(result, promiseArray)
+ m.testSuite.assertEqual(result, 2)
+ end sub).catch(sub(_, promiseArray)
+ m.testSuite.fail("should not get here")
+ end sub).finally(sub(promiseArray)
+ promises.resolve(invalid, promiseArray[0])
+ promises.resolve(invalid, promiseArray[2])
+ end sub).toPromise()
+ end function
+
+ @it("handles a non-promise value amongst pending promises")
+ function _()
+ promiseArray = [
+ promises.create()
+ 2
+ promises.create()
+ ]
+
+ return promises.chain(promises.any(promiseArray), promiseArray).then(sub(result, promiseArray)
+ m.testSuite.assertEqual(result, 2)
+ end sub).catch(sub(_, promiseArray)
+ m.testSuite.fail("should not get here")
+ end sub).finally(sub(promiseArray)
+ promises.resolve(invalid, promiseArray[0])
+ promises.resolve(invalid, promiseArray[2])
+ end sub).toPromise()
+ end function
+
+ @it("handles a non-promise value amongst rejected promises")
+ function _()
+ promiseArray = [
+ promises.reject(1)
+ 2
+ promises.reject(2)
+ ]
+
+ return promises.chain(promises.any(promiseArray), promiseArray).then(sub(result, promiseArray)
+ m.testSuite.assertEqual(result, 2)
+ end sub).catch(sub(_, promiseArray)
+ m.testSuite.fail("should not get here")
+ end sub).toPromise()
+ end function
+
+ @it("handles a first pre-resolved promise")
+ function _()
+ promiseArray = [
+ promises.resolve(1)
+ promises.resolve(2)
+ promises.resolve(2)
+ ]
+
+ return promises.chain(promises.any(promiseArray), promiseArray).then(sub(result, promiseArray)
+ m.testSuite.assertEqual(result, 1)
+ end sub).catch(sub(_, promiseArray)
+ m.testSuite.fail("should not get here")
+ end sub).toPromise()
+ end function
+
+ @async
+ @it("handles first pre-resolved promise along with a non-promise value")
+ function _()
+ promiseArray = [
+ promises.resolve(1)
+ 2
+ promises.resolve(2)
+ ]
+
+ return promises.chain(promises.any(promiseArray), promiseArray).then(sub(result, promiseArray)
+ m.testSuite.assertEqual(result, 1)
+ end sub).catch(sub(_, promiseArray)
+ m.testSuite.fail("should not get here")
+ end sub).toPromise()
+ end function
+
+ @it("handles all promises being pre-rejected")
+ function _()
+ promiseArray = [
+ promises.reject("1")
+ promises.reject("2")
+ promises.reject("3")
+ ]
+
+ return promises.chain(promises.any(promiseArray), promiseArray).then(sub(result, promiseArray)
+ m.testSuite.fail("should not get here")
+ end sub).catch(sub(error, promiseArray)
+ m.testSuite.assertEqual(error.message, "All promises were rejected")
+ m.testSuite.assertEqual(error.errors, ["1", "2", "3"])
+ m.testSuite.assertNotInvalid(error.backtrace)
+ end sub).toPromise()
+ end function
+
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @describe("promises.race()")
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ @it("handled non-array")
+ function _()
+ return promises.chain(promises.race(invalid)).then(sub(result)
+ m.testSuite.fail("should not get here")
+ end sub).catch(sub(error)
+ m.testSuite.assertEqual(error.message, "All promises were rejected")
+ m.testSuite.assertEqual(error.errors, [])
+ m.testSuite.assertNotInvalid(error.backtrace)
+ end sub).toPromise()
+ end function
+
+ @it("handled empty array")
+ function _()
+ return promises.chain(promises.race([])).then(sub(result)
+ m.testSuite.fail("should not get here")
+ end sub).catch(sub(error)
+ m.testSuite.assertEqual(error.message, "All promises were rejected")
+ m.testSuite.assertEqual(error.errors, [])
+ m.testSuite.assertNotInvalid(error.backtrace)
+ end sub).toPromise()
+ end function
+
+ @async
+ @it("handled a promise that resolves")
+ sub _()
+ promiseArray = [
+ promises.create()
+ promises.create()
+ promises.create()
+ ]
+
+ promises.chain(promises.race(promiseArray), promiseArray).then(sub(result, promiseArray)
+ m.testSuite.assertEqual(result, 2)
+ end sub).catch(sub(_, promiseArray)
+ m.testSuite.fail("should not get here")
+ end sub).finally(sub(promiseArray)
+ promises.resolve(invalid, promiseArray[0])
+ promises.resolve(invalid, promiseArray[2])
+
+ m.testSuite.done()
+ end sub)
+
+ promises.resolve(2, promiseArray[1])
+ end sub
+
+ @it("handles a pre-resolved promise")
+ function _()
+ promiseArray = [
+ promises.create()
+ promises.resolve(2)
+ promises.create()
+ ]
+
+ return promises.chain(promises.race(promiseArray), promiseArray).then(sub(result, promiseArray)
+ m.testSuite.assertEqual(result, 2)
+ end sub).catch(sub(_, promiseArray)
+ m.testSuite.fail("should not get here")
+ end sub).finally(sub(promiseArray)
+ promises.resolve(invalid, promiseArray[0])
+ promises.resolve(invalid, promiseArray[2])
+ end sub).toPromise()
+ end function
+
+ @it("handles a non-promise value amongst pending promises")
+ function _()
+ promiseArray = [
+ promises.create()
+ 2
+ promises.create()
+ ]
+
+ promises.chain(promises.race(promiseArray), promiseArray).then(sub(result, promiseArray)
+ m.testSuite.assertEqual(result, 2)
+ end sub).catch(sub(_, promiseArray)
+ m.testSuite.fail("should not get here")
+ end sub).finally(sub(promiseArray)
+ promises.resolve(invalid, promiseArray[0])
+ promises.resolve(invalid, promiseArray[2])
+ end sub).toPromise()
+ end function
+
+ @it("handles a non-promise value amongst rejected promises")
+ function _()
+ promiseArray = [
+ promises.reject(1)
+ 2
+ promises.reject(3)
+ ]
+
+ return promises.chain(promises.race(promiseArray), promiseArray).then(sub(result, promiseArray)
+ m.testSuite.fail("should not get here")
+ end sub).catch(sub(error, promiseArray)
+ m.testSuite.assertEqual(error, 1)
+ end sub).toPromise()
+ end function
+
+ @it("handles a first pre-resolved promise")
+ function _()
+ promiseArray = [
+ promises.resolve(1)
+ promises.resolve(2)
+ promises.resolve(3)
+ ]
+
+ return promises.chain(promises.race(promiseArray), promiseArray).then(sub(result, promiseArray)
+ m.testSuite.assertEqual(result, 1)
+ end sub).catch(sub(_, promiseArray)
+ m.testSuite.fail("should not get here")
+ end sub).toPromise()
+ end function
+
+ @it("handles first pre-resolved promise along with a non-promise value")
+ function _()
+ promiseArray = [
+ promises.resolve(1)
+ 2
+ promises.resolve(3)
+ ]
+
+ return promises.chain(promises.race(promiseArray), promiseArray).then(sub(result, promiseArray)
+ m.testSuite.assertEqual(result, 1)
+ end sub).catch(sub(_, promiseArray)
+ m.testSuite.fail("should not get here")
+ end sub).toPromise()
+ end function
+
+ @it("handles all promises being pre-rejected")
+ function _()
+ promiseArray = [
+ promises.reject("1")
+ promises.reject("2")
+ promises.reject("3")
+ ]
+
+ return promises.chain(promises.race(promiseArray), promiseArray).then(sub(result, promiseArray)
+ m.testSuite.fail("should not get here")
+ end sub).catch(sub(error, promiseArray)
+ m.testSuite.assertEqual(error, "1")
+ end sub).toPromise()
+ end function
+
+ @it("handled a the first promise to resolve")
+ function _()
+ promiseArray = [
+ toPromiseWithDelay(0.3, 1)
+ toPromiseWithDelay(0.2, 2)
+ toPromiseWithDelay(0.1, 3)
+ ]
+
+ promises.chain(promises.race(promiseArray), promiseArray).then(sub(result, promiseArray)
+ m.testSuite.assertEqual(result, 3)
+ end sub).catch(sub(_, promiseArray)
+ m.testSuite.fail("should not get here")
+ end sub).toPromise()
+ end function
+
+ @it("handled a the first promise to reject")
+ function _()
+ promiseArray = [
+ toPromiseWithDelay(0.2, 1)
+ toPromiseWithDelay(0.1, 2, false)
+ toPromiseWithDelay(0.3, 3)
+ ]
+
+ promises.chain(promises.race(promiseArray), promiseArray).then(sub(result, promiseArray)
+ m.testSuite.fail("should not get here")
+ end sub).catch(sub(error, promiseArray)
+ m.testSuite.assertEqual(error, 2)
+ end sub).toPromise()
+ end function
+
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @describe("promises.onThen()")
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ @async
+ @it("catches resolved promises")
+ sub _()
+ promises.onThen(promises.resolve("resolved"), sub(value)
+ m.testSuite.assertEqual(value, "resolved")
+ m.testSuite.done()
+ end sub)
+ end sub
+
+ @async
+ @it("recovered on wrong num of callback args")
+ sub _()
+ context = {}
+ promises.onThen(promises.resolve("resolved"), sub(value)
+ m.testSuite.assertEqual(value, "resolved")
+ m.testSuite.done()
+ end sub, context)
+ end sub
+
+ @async
+ @it("handles empty callbacks")
+ sub _()
+ promises.onThen(promises.onThen(promises.resolve("resolved")), sub(value)
+ m.testSuite.assertEqual(value, "resolved")
+ m.testSuite.done()
+ end sub)
+ end sub
+
+ @async
+ @it("does not response to rejected promises")
+ sub _()
+ context = { thenCount: 0 }
+
+ promise = promises.onThen(promises.reject("rejected"), sub(value, context)
+ context.thenCount++
+ end sub, context)
+
+ promises.onFinally(promise, sub(context)
+ m.testSuite.assertEqual(context, { thenCount: 0 })
+ m.testSuite.done()
+ end sub, context)
+ end sub
+
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @describe("promises.onCatch()")
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ @async
+ @it("catches rejected promises")
+ sub _()
+ promises.onCatch(promises.reject("rejected"), sub(value)
+ m.testSuite.assertEqual(value, "rejected")
+ m.testSuite.done()
+ end sub)
+ end sub
+
+ @async
+ @it("recovered on wrong num of callback args")
+ sub _()
+ context = {}
+ promises.onCatch(promises.reject("rejected"), sub(value)
+ m.testSuite.assertEqual(value, "rejected")
+ m.testSuite.done()
+ end sub, context)
+ end sub
+
+ @async
+ @it("handles empty callbacks")
+ sub _()
+ promises.onCatch(promises.onCatch(promises.reject("rejected")), sub(value)
+ m.testSuite.assertEqual(value, "rejected")
+ m.testSuite.done()
+ end sub)
+ end sub
+
+ @async
+ @it("does not response to resolved promises")
+ sub _()
+ context = { catchCount: 0 }
+
+ promise = promises.onCatch(promises.resolve("resolved"), sub(value, context)
+ context.catchCount++
+ end sub, context)
+
+ promises.onFinally(promise, sub(context)
+ m.testSuite.assertEqual(context, { catchCount: 0 })
+ m.testSuite.done()
+ end sub, context)
+ end sub
+
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @describe("promises.onFinally()")
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ @async
+ @it("handles resolved promise")
+ sub _()
+ promise = promises.onFinally(promises.resolve("resolved"), sub()
+ end sub)
+
+ promises.onThen(promise, sub(value)
+ m.testSuite.assertEqual(value, "resolved")
+ m.testSuite.done()
+ end sub)
+ end sub
+
+ @async
+ @it("recovered on wrong num of callback args")
+ sub _()
+ context = {}
+ promises.onFinally(promises.resolve("resolved"), sub()
+ m.testSuite.done()
+ end sub, context)
+ end sub
+
+ @async
+ @it("handles resolved promise with empty callback")
+ sub _()
+ promise = promises.onFinally(promises.onFinally(promises.resolve("resolved")), sub()
+ end sub)
+
+ promises.onThen(promise, sub(value)
+ m.testSuite.assertEqual(value, "resolved")
+ m.testSuite.done()
+ end sub)
+ end sub
+
+ @async
+ @it("handles rejected promise")
+ sub _()
+ promise = promises.onFinally(promises.reject("rejected"), sub()
+ end sub)
+
+ promises.onCatch(promise, sub(value)
+ m.testSuite.assertEqual(value, "rejected")
+ m.testSuite.done()
+ end sub)
+ end sub
+
+ @async
+ @it("handles rejected promise with empty callback")
+ sub _()
+ promise = promises.onFinally(promises.onFinally(promises.reject("rejected")), sub()
+ end sub)
+
+ promises.onCatch(promise, sub(value)
+ m.testSuite.assertEqual(value, "rejected")
+ m.testSuite.done()
+ end sub)
+ end sub
+
+ @async
+ @it("handles returning as rejected promise from the finally")
+ sub _()
+ promise = promises.onFinally(promises.reject("rejected"), function()
+ return promises.reject("new rejected promise")
+ end function)
+
+ promises.onCatch(promise, sub(value)
+ m.testSuite.assertEqual(value, "new rejected promise")
+ m.testSuite.done()
+ end sub)
+ end sub
+
+ @async
+ @it("handles rejecting with a crash in the finally")
+ sub _()
+ promise = promises.onFinally(promises.reject("rejected"), sub()
+ throw "new rejected promise"
+ end sub)
+
+ promises.onCatch(promise, sub(value)
+ m.testSuite.assertEqual(value.message, "new rejected promise")
+ m.testSuite.assertNotInvalid(value.backtrace)
+ m.testSuite.done()
+ end sub)
+ end sub
+
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @describe("promises.enableCrashLogging()")
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ @beforeEach
+ sub beforeEachenableCrashLogging()
+ m.global.removeField("__promises__crashLoggingEnabled")
+ m.node.delete("formatStackTraceCalled")
+ end sub
+
+ @afterEach
+ sub afterEachenableCrashLogging()
+ m.global.removeField("__promises__crashLoggingEnabled")
+ m.node.delete("formatStackTraceCalled")
+ end sub
+
+ @it("properly adds and removes the setting from global")
+ function _()
+ m.assertFalse(m.global.hasField("__promises__crashLoggingEnabled"))
+ promises.configuration.enableCrashLogging(true)
+ m.assertNodeContainsFields(m.global, { "__promises__crashLoggingEnabled": true })
+ promises.configuration.enableCrashLogging(false)
+ m.assertFalse(m.global.hasField("__promises__crashLoggingEnabled"))
+ end function
+
+ @it("enableCrashLogging(true) onThen() no context provided should not log")
+ function _()
+ promises.configuration.enableCrashLogging(true)
+
+ m.node.formatStackTraceCalled = 0
+ m.stubCall(promises.internal.formatStackTrace, function(error, message)
+ m.formatStackTraceCalled++
+ return ""
+ end function)
+
+ return promises.chain(promises.resolve("resolved")).then(sub(value)
+ throw "my error"
+ end sub).catch(sub(error)
+ m.testSuite.assertEqual(m.formatStackTraceCalled, 0)
+ end sub).toPromise()
+ end function
+
+ @it("enableCrashLogging(true) onThen() context was provided")
+ function _()
+ promises.configuration.enableCrashLogging(true)
+
+ m.node.formatStackTraceCalled = 0
+ m.stubCall(promises.internal.formatStackTrace, function(error, message)
+ m.testSuite.assertNotInvalid(error.message)
+ m.testSuite.assertNotInvalid(error.backtrace)
+ m.testSuite.assertEqual(message, "Divide by Zero.")
+ m.formatStackTraceCalled++
+ return ""
+ end function)
+
+ return promises.chain(promises.resolve("resolved"), {}).then(sub(value, context)
+ test = 1 / 0
+ end sub).catch(sub(error, context)
+ m.testSuite.assertEqual(m.formatStackTraceCalled, 1)
+ end sub).toPromise()
+ end function
+
+ @it("enableCrashLogging(true) onCatch() no context provided")
+ function _()
+ promises.configuration.enableCrashLogging(true)
+
+ m.node.formatStackTraceCalled = 0
+ m.stubCall(promises.internal.formatStackTrace, function(_, _)
+ m.formatStackTraceCalled++
+ return ""
+ end function)
+
+ return promises.chain(promises.reject("rejected")).catch(sub(error)
+ test = 1 / 0
+ end sub).catch(sub(error)
+ m.testSuite.assertEqual(m.formatStackTraceCalled, 1)
+ end sub).toPromise()
+ end function
+
+ @it("enableCrashLogging(true) onCatch() context was provided")
+ function _()
+ promises.configuration.enableCrashLogging(true)
+
+ m.node.formatStackTraceCalled = 0
+ m.stubCall(promises.internal.formatStackTrace, function(_, _)
+ m.formatStackTraceCalled++
+ return ""
+ end function)
+
+ return promises.chain(promises.reject("rejected"), {}).catch(sub(error, context)
+ test = 1 / 0
+ end sub).catch(sub(error, context)
+ m.testSuite.assertEqual(m.formatStackTraceCalled, 1)
+ end sub).toPromise()
+ end function
+
+ @it("enableCrashLogging(true) onFinally() no context provided")
+ function _()
+ promises.configuration.enableCrashLogging(true)
+
+ m.node.formatStackTraceCalled = 0
+ m.stubCall(promises.internal.formatStackTrace, function(_, _)
+ m.formatStackTraceCalled++
+ return ""
+ end function)
+
+ return promises.chain(promises.resolve("resolved")).finally(sub()
+ test = 1 / 0
+ end sub).catch(sub(error)
+ m.testSuite.assertEqual(m.formatStackTraceCalled, 1)
+ end sub).toPromise()
+ end function
+
+ @it("enableCrashLogging(true) onFinally() context was provided")
+ function _()
+ promises.configuration.enableCrashLogging(true)
+
+ m.node.formatStackTraceCalled = 0
+ m.stubCall(promises.internal.formatStackTrace, function(_, _)
+ m.formatStackTraceCalled++
+ return ""
+ end function)
+
+ return promises.chain(promises.resolve("resolved"), {}).finally(sub(context)
+ test = 1 / 0
+ end sub).catch(sub(error, context)
+ m.testSuite.assertEqual(m.formatStackTraceCalled, 1)
+ end sub).toPromise()
+ end function
+
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @describe("does not resolve to soon or too late")
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ @async
+ @it("timer promise")
+ function _()
+ timerDurationInMillis = 125
+ promise = sleepPromise(timerDurationInMillis / 1000)
+ promises.onThen(promise, sub(_ as dynamic, ctx as dynamic)
+ elapsedTimeInMillis = ctx.timespan.totalMilliseconds()
+ ? "elapsed time to resolve promise:" + elapsedTimeInMillis.tostr()
+ tolerance = ctx.timerDurationInMillis * 0.2
+ msg = "did not settle within 10% tolerance of timer duration"
+ m.testSuite.assertTrue(ctx.timerDurationInMillis - tolerance <= elapsedTimeInMillis, msg)
+ m.testSuite.assertTrue(ctx.timerDurationInMillis + tolerance >= elapsedTimeInMillis, msg)
+ m.testSuite.done()
+ end sub, {
+ timespan: createObject("roTimespan")
+ timerDurationInMillis: timerDurationInMillis
+ })
+ end function
+
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @describe("promises.try()")
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ @it("returns a the same promise if the callback returns a promise")
+ function _()
+ resolvedPromiseParam = promises.resolve(1)
+ resolvedPromise = promises.try(function(arg)
+ return arg
+ end function, [resolvedPromiseParam])
+
+ m.assertTrue(promises.isPromise(resolvedPromise))
+ m.assertTrue(resolvedPromise.isSameNode(resolvedPromiseParam))
+
+ rejectedPromiseParam = promises.reject("error")
+ rejectedPromise = promises.try(function(arg)
+ return arg
+ end function, [rejectedPromiseParam])
+
+ m.assertTrue(promises.isPromise(rejectedPromise))
+ m.assertTrue(rejectedPromise.isSameNode(rejectedPromiseParam))
+
+ return promises.onThen(promises.allSettled([resolvedPromise, rejectedPromise]), sub(results)
+ m.testSuite.assertEqual(results, [
+ { status: promises.PromiseState.resolved, value: 1 }
+ { status: promises.PromiseState.rejected, reason: "error" }
+ ])
+ end sub)
+ end function
+
+ @it("returns a rejected promise if the callback throws an error")
+ function _()
+ promise = promises.try(function()
+ throw "error"
+ end function)
+
+ m.assertTrue(promises.isPromise(promise))
+
+ return promises.onCatch(promise, sub(error)
+ m.testSuite.assertEqual(error.message, "error")
+ m.testSuite.assertNotInvalid(error.backTrace)
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with no augments wrapped in a promise")
+ function _()
+ promise = promises.try(function()
+ return true
+ end function)
+
+ m.assertTrue(promises.isPromise(promise))
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, true)
+ end sub)
+ end function
+
+
+ @it("calls the callback when supplied empty augments")
+ function _()
+ promise = promises.try(function()
+ return true
+ end function, [])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, true)
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 1 augment")
+ function _()
+ promise = promises.try(function(a)
+ return [a]
+ end function, [1])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 2 augments")
+ function _()
+ promise = promises.try(function(a, b)
+ return [a, b]
+ end function, [1, 2])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 3 augments")
+ function _()
+ promise = promises.try(function(a, b, c)
+ return [a, b, c]
+ end function, [1, 2, 3])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 4 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d)
+ return [a, b, c, d]
+ end function, [1, 2, 3, 4])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 5 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e)
+ return [a, b, c, d, e]
+ end function, [1, 2, 3, 4, 5])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 6 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f)
+ return [a, b, c, d, e, f]
+ end function, [1, 2, 3, 4, 5, 6])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 7 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g)
+ return [a, b, c, d, e, f, g]
+ end function, [1, 2, 3, 4, 5, 6, 7])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 8 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h)
+ return [a, b, c, d, e, f, g, h]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 9 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i)
+ return [a, b, c, d, e, f, g, h, i]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 10 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j)
+ return [a, b, c, d, e, f, g, h, i, j]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 11 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k)
+ return [a, b, c, d, e, f, g, h, i, j, k]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 12 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l)
+ return [a, b, c, d, e, f, g, h, i, j, k, l]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 13 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 14 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 15 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 16 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 17 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 18 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 19 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 20 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 21 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 22 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 23 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 24 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 25 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 26 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 27 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 28 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 29 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 30 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 31 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31])
+ end sub)
+ end function
+
+ @it("calls the callback when supplied with 32 augments")
+ function _()
+ promise = promises.try(function(a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae, af)
+ return [a, b, c, d, e, f, g, h, i, j, k, l, mm, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae, af]
+ end function, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32])
+
+ return promises.onThen(promise, sub(result)
+ m.testSuite.assertEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32])
+ end sub)
+ end function
+
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @describe("promises.resolve()/promises.reject()")
+ '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ @async
+ @it("resolved invalid")
+ function _()
+ promise = promises.resolve(invalid)
+ promises.onThen(promise, sub(result as dynamic)
+ m.testSuite.assertEqual(result, invalid)
+ m.testSuite.done()
+ end sub)
+ end function
+
+ @async
+ @it("reject invalid")
+ function _()
+ promise = promises.reject(invalid)
+ promises.onCatch(promise, sub(result as dynamic)
+ m.testSuite.assertEqual(result, invalid)
+ m.testSuite.done()
+ end sub)
+ end function
+
+ @async
+ @it("resolved integer")
+ function _()
+ promise = promises.resolve(1)
+ promises.onThen(promise, sub(result as dynamic)
+ m.testSuite.assertEqual(result, 1)
+ m.testSuite.done()
+ end sub)
+ end function
+
+ @async
+ @it("reject integer")
+ function _()
+ promise = promises.reject(1)
+ promises.onCatch(promise, sub(result as dynamic)
+ m.testSuite.assertEqual(result, 1)
+ m.testSuite.done()
+ end sub)
+ end function
+
+ @async
+ @it("resolved float")
+ function _()
+ promise = promises.resolve(1.1)
+ promises.onThen(promise, sub(result as dynamic)
+ m.testSuite.assertEqual(result, 1.1)
+ m.testSuite.done()
+ end sub)
+ end function
+
+ @async
+ @it("reject float")
+ function _()
+ promise = promises.reject(1.1)
+ promises.onCatch(promise, sub(result as dynamic)
+ m.testSuite.assertEqual(result, 1.1)
+ m.testSuite.done()
+ end sub)
+ end function
+
+ @async
+ @it("resolved boolean")
+ function _()
+ promise = promises.resolve(true)
+ promises.onThen(promise, sub(result as dynamic)
+ m.testSuite.assertEqual(result, true)
+ m.testSuite.done()
+ end sub)
+ end function
+
+ @async
+ @it("reject boolean")
+ function _()
+ promise = promises.reject(true)
+ promises.onCatch(promise, sub(result as dynamic)
+ m.testSuite.assertEqual(result, true)
+ m.testSuite.done()
+ end sub)
+ end function
+
+ @async
+ @it("resolved string")
+ function _()
+ promise = promises.resolve("my string")
+ promises.onThen(promise, sub(result as dynamic)
+ m.testSuite.assertEqual(result, "my string")
+ m.testSuite.done()
+ end sub)
+ end function
+
+ @async
+ @it("reject string")
+ function _()
+ promise = promises.reject("my string")
+ promises.onCatch(promise, sub(result as dynamic)
+ m.testSuite.assertEqual(result, "my string")
+ m.testSuite.done()
+ end sub)
+ end function
+
+ @async
+ @it("resolved array")
+ function _()
+ promise = promises.resolve([1, 2, 3])
+ promises.onThen(promise, sub(result as dynamic)
+ m.testSuite.assertEqual(result, [1, 2, 3])
+ m.testSuite.done()
+ end sub)
+ end function
+
+ @async
+ @it("reject array")
+ function _()
+ promise = promises.reject([1, 2, 3])
+ promises.onCatch(promise, sub(result as dynamic)
+ m.testSuite.assertEqual(result, [1, 2, 3])
+ m.testSuite.done()
+ end sub)
+ end function
+
+ @async
+ @it("resolved AA")
+ function _()
+ promise = promises.resolve({
+ key: "value"
+ })
+ promises.onThen(promise, sub(result as dynamic)
+ m.testSuite.assertEqual(result, {
+ key: "value"
+ })
+ m.testSuite.done()
+ end sub)
+ end function
+
+ @async
+ @it("reject AA")
+ function _()
+ promise = promises.reject({
+ key: "value"
+ })
+ promises.onCatch(promise, sub(result as dynamic)
+ m.testSuite.assertEqual(result, {
+ key: "value"
+ })
+ m.testSuite.done()
+ end sub)
+ end function
+
+ @async
+ @it("resolved AA with subtype")
+ function _()
+ promise = promises.resolve({
+ subType: "Node"
+ })
+ promises.onThen(promise, sub(result as dynamic)
+ m.testSuite.assertEqual(result, {
+ subType: "Node"
+ })
+ m.testSuite.done()
+ end sub)
+ end function
+
+ @async
+ @it("reject AA with subtype")
+ function _()
+ promise = promises.reject({
+ subType: "Node"
+ })
+ promises.onCatch(promise, sub(result as dynamic)
+ m.testSuite.assertEqual(result, {
+ subType: "Node"
+ })
+ m.testSuite.done()
+ end sub)
+ end function
+
+ @async
+ @it("resolved AA with children array")
+ function _()
+ promise = promises.resolve({
+ children: [{ subType: "Node" }]
+ })
+ promises.onThen(promise, sub(result as dynamic)
+ m.testSuite.assertEqual(result, {
+ children: [{ subType: "Node" }]
+ })
+ m.testSuite.done()
+ end sub)
+ end function
+
+ @async
+ @it("reject AA with children array")
+ function _()
+ promise = promises.reject({
+ children: [{ subType: "Node" }]
+ })
+ promises.onCatch(promise, sub(result as dynamic)
+ m.testSuite.assertEqual(result, {
+ children: [{ subType: "Node" }]
+ })
+ m.testSuite.done()
+ end sub)
+ end function
+
+ @async
+ @it("resolved SgNode")
+ function _()
+ testNode = createNode("Node")
+ promise = promises.resolve(testNode)
+ promises.onThen(promise, sub(result as dynamic, context as dynamic)
+ m.testSuite.assertTrue(context.isSameNode(result))
+ m.testSuite.done()
+ end sub, testNode)
+ end function
+
+ @async
+ @it("reject SgNode")
+ function _()
+ testNode = createNode("Node")
+ promise = promises.reject(testNode)
+ promises.onCatch(promise, sub(result as dynamic, context as dynamic)
+ m.testSuite.assertTrue(context.isSameNode(result))
+ m.testSuite.done()
+ end sub, testNode)
+ end function
+
+ @async(60000)
+ @it("unravels deep promise chain without crashing due to stackoverflow")
+ function _()
+ 'this function creates a promise that depends on another promise (until we hit a max)
+ doWork = function(context)
+ 'if we hit the max, resolve the promise and unravel the entire stack
+ if context.currentCount > 10000
+ return promises.resolve(true)
+ end if
+ context.currentCount = context.currentCount + 1
+
+ 'return a promise that depends on another future promise
+ return promises.onThen(promises.resolve(true), function(result, context)
+ doWork = context.doWork
+ return doWork(context)
+ end function, context)
+ end function
+
+ promises.chain(promises.resolve(true), {
+ currentCount: 0,
+ doWork: doWork
+ }).then(function(result, context)
+ doWork = context.doWork
+ return doWork(context)
+ end function).then(function(result, context)
+ m.testSuite.done()
+ end function).catch(function(error, context)
+ print "error", error, FormatJson(error.backtrace)
+ end function).toPromise()
+
+ end function
+
+ @async
+ @it("Simple Promise In Task Test")
+ function _()
+ task = createObject("roSGNode", "TestTask")
+ promise = task@.doAction("test1")
+ promises.chain(promise).then(function(result)
+ m.testSuite.assertEqual(result, "task completed")
+ m.testSuite.done()
+ end function).catch(function(error)
+ print "error", error, FormatJson(error.backtrace)
+ end function)
+ end function
+
+
+ @async
+ @it("Promise In Task Test with Fake Network Call")
+ function _()
+ task = createObject("roSGNode", "TestTask")
+ promise = task@.doAction("test2")
+ promises.chain(promise).then(function(result)
+ m.testSuite.assertEqual(result.ipInfo, "hello")
+ m.testSuite.done()
+ end function).catch(function(error)
+ print "error", error, FormatJson(error.backtrace)
+ end function)
+ end function
+
+ @async
+ @it("Promise In Task Test with rejection")
+ function _()
+ task = createObject("roSGNode", "TestTask")
+ promise = task@.doAction("test3")
+ promises.chain(promise).then(function(result)
+ m.testSuite.fail("Promise was expected to be rejected but was resolved instead")
+ m.testSuite.done()
+ end function).catch(function(error)
+ print "Caught expected error:", error
+ m.testSuite.assertNotInvalid(error)
+ m.testSuite.done()
+ end function)
+ end function
+ end class
end namespace
function createNode(nodeType = "Node" as string, fields = {} as dynamic) as object
- node = createObject("roSGNode", nodeType)
- node.update(fields, true)
- return node
+ node = createObject("roSGNode", nodeType)
+ node.update(fields, true)
+ return node
end function
function sleepPromise(duration = 0.0001 as float) as dynamic
- promise = promises.create()
- promises.internal.delay(sub(promise as dynamic)
- promises.resolve(true, promise)
- end sub, promise, duration)
- return promise
+ promise = promises.create()
+ promises.internal.delay(sub(promise as dynamic)
+ promises.resolve(true, promise)
+ end sub, promise, duration)
+ return promise
end function
function toPromiseWithDelay(duration = 0.0001 as float, value = true as dynamic, resolve = true as boolean) as dynamic
- differed = promises.create()
- promises.internal.delay(sub(context as dynamic)
- if context.resolve then
- promises.resolve(context.value, context.differed)
- else
- promises.reject(context.value, context.differed)
- end if
- end sub, {differed: differed, value: value, resolve: resolve}, duration)
- return differed
+ differed = promises.create()
+ promises.internal.delay(sub(context as dynamic)
+ if context.resolve then
+ promises.resolve(context.value, context.differed)
+ else
+ promises.reject(context.value, context.differed)
+ end if
+ end sub, { differed: differed, value: value, resolve: resolve }, duration)
+ return differed
end function