aboutsummaryrefslogtreecommitdiff
path: root/node_modules/selenium-webdriver/test/lib
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/selenium-webdriver/test/lib')
-rw-r--r--node_modules/selenium-webdriver/test/lib/http_test.js14
-rw-r--r--node_modules/selenium-webdriver/test/lib/promise_aplus_test.js92
-rw-r--r--node_modules/selenium-webdriver/test/lib/promise_error_test.js1344
-rw-r--r--node_modules/selenium-webdriver/test/lib/promise_flow_test.js3596
-rw-r--r--node_modules/selenium-webdriver/test/lib/promise_generator_test.js452
-rw-r--r--node_modules/selenium-webdriver/test/lib/promise_test.js1705
-rw-r--r--node_modules/selenium-webdriver/test/lib/until_test.js2
-rw-r--r--node_modules/selenium-webdriver/test/lib/webdriver_test.js890
8 files changed, 4082 insertions, 4013 deletions
diff --git a/node_modules/selenium-webdriver/test/lib/http_test.js b/node_modules/selenium-webdriver/test/lib/http_test.js
index 343a04800..1c6c073ad 100644
--- a/node_modules/selenium-webdriver/test/lib/http_test.js
+++ b/node_modules/selenium-webdriver/test/lib/http_test.js
@@ -84,12 +84,14 @@ describe('http', function() {
describe('command routing', function() {
it('rejects unrecognized commands', function() {
- assert.throws(
- () => executor.execute(new Command('fake-name')),
- function (err) {
- return err instanceof error.UnknownCommandError
- && 'Unrecognized command: fake-name' === err.message;
- });
+ return executor.execute(new Command('fake-name'))
+ .then(assert.fail, err => {
+ if (err instanceof error.UnknownCommandError
+ && 'Unrecognized command: fake-name' === err.message) {
+ return;
+ }
+ throw err;
+ })
});
it('rejects promise if client fails to send request', function() {
diff --git a/node_modules/selenium-webdriver/test/lib/promise_aplus_test.js b/node_modules/selenium-webdriver/test/lib/promise_aplus_test.js
index a89391590..207f490a1 100644
--- a/node_modules/selenium-webdriver/test/lib/promise_aplus_test.js
+++ b/node_modules/selenium-webdriver/test/lib/promise_aplus_test.js
@@ -18,57 +18,61 @@
'use strict';
const promise = require('../../lib/promise');
+const {enablePromiseManager} = require('../../lib/test/promise');
describe('Promises/A+ Compliance Tests', function() {
- // The promise spec does not define behavior for unhandled rejections and
- // assumes they are effectively swallowed. This is not the case with our
- // implementation, so we have to disable error propagation to test that the
- // rest of our behavior is compliant.
- // We run the tests with a separate instance of the control flow to ensure
- // disablign error propagation does not impact other tests.
- var flow = new promise.ControlFlow();
- flow.setPropagateUnhandledRejections(false);
+ enablePromiseManager(() => {
+ // The promise spec does not define behavior for unhandled rejections and
+ // assumes they are effectively swallowed. This is not the case with our
+ // implementation, so we have to disable error propagation to test that the
+ // rest of our behavior is compliant.
+ // We run the tests with a separate instance of the control flow to ensure
+ // disablign error propagation does not impact other tests.
+ var flow = new promise.ControlFlow();
+ flow.setPropagateUnhandledRejections(false);
- // Skip the tests in 2.2.6.1/2. We are not compliant in these scenarios.
- var realDescribe = global.describe;
- global.describe = function(name, fn) {
- realDescribe(name, function() {
- var prefix = 'Promises/A+ Compliance Tests 2.2.6: '
- + '`then` may be called multiple times on the same promise.';
- var suffix = 'even when one handler is added inside another handler';
- if (this.fullTitle().startsWith(prefix)
- && this.fullTitle().endsWith(suffix)) {
- var realSpecify = global.specify;
- try {
- global.specify = function(name) {
- realSpecify(name);
- };
+ // Skip the tests in 2.2.6.1/2. We are not compliant in these scenarios.
+ var realDescribe = global.describe;
+ global.describe = function(name, fn) {
+ realDescribe(name, function() {
+ var prefix = 'Promises/A+ Compliance Tests '
+ + 'SELENIUM_PROMISE_MANAGER=true 2.2.6: '
+ + '`then` may be called multiple times on the same promise.';
+ var suffix = 'even when one handler is added inside another handler';
+ if (this.fullTitle().startsWith(prefix)
+ && this.fullTitle().endsWith(suffix)) {
+ var realSpecify = global.specify;
+ try {
+ global.specify = function(name) {
+ realSpecify(name);
+ };
+ fn();
+ } finally {
+ global.specify = realSpecify;
+ }
+ } else {
fn();
- } finally {
- global.specify = realSpecify;
}
- } else {
- fn();
+ });
+ };
+
+ require('promises-aplus-tests').mocha({
+ resolved: function(value) {
+ return new promise.Promise((fulfill) => fulfill(value), flow);
+ },
+ rejected: function(error) {
+ return new promise.Promise((_, reject) => reject(error), flow);
+ },
+ deferred: function() {
+ var d = new promise.Deferred(flow);
+ return {
+ resolve: d.fulfill,
+ reject: d.reject,
+ promise: d.promise
+ };
}
});
- };
- require('promises-aplus-tests').mocha({
- resolved: function(value) {
- return new promise.Promise((fulfill) => fulfill(value), flow);
- },
- rejected: function(error) {
- return new promise.Promise((_, reject) => reject(error), flow);
- },
- deferred: function() {
- var d = new promise.Deferred(flow);
- return {
- resolve: d.fulfill,
- reject: d.reject,
- promise: d.promise
- };
- }
+ global.describe = realDescribe;
});
-
- global.describe = realDescribe;
});
diff --git a/node_modules/selenium-webdriver/test/lib/promise_error_test.js b/node_modules/selenium-webdriver/test/lib/promise_error_test.js
index e6de3cb92..b89a2f875 100644
--- a/node_modules/selenium-webdriver/test/lib/promise_error_test.js
+++ b/node_modules/selenium-webdriver/test/lib/promise_error_test.js
@@ -27,6 +27,7 @@ const testutil = require('./testutil');
const assert = require('assert');
const promise = require('../../lib/promise');
+const {enablePromiseManager} = require('../../lib/test/promise');
const NativePromise = Promise;
const StubError = testutil.StubError;
@@ -34,244 +35,178 @@ const throwStubError = testutil.throwStubError;
const assertIsStubError = testutil.assertIsStubError;
describe('promise error handling', function() {
- var flow, uncaughtExceptions;
-
- beforeEach(function setUp() {
- flow = promise.controlFlow();
- uncaughtExceptions = [];
- flow.on('uncaughtException', onUncaughtException);
- });
-
- afterEach(function tearDown() {
- return waitForIdle(flow).then(function() {
- assert.deepEqual(
- [], uncaughtExceptions, 'There were uncaught exceptions');
- flow.reset();
- });
- });
-
- function onUncaughtException(e) {
- uncaughtExceptions.push(e);
- }
-
- function waitForAbort(opt_flow, opt_n) {
- var n = opt_n || 1;
- var theFlow = opt_flow || flow;
- theFlow.removeAllListeners(
- promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
- return new NativePromise(function(fulfill, reject) {
- theFlow.once('idle', function() {
- reject(Error('expected flow to report an unhandled error'));
- });
-
- var errors = [];
- theFlow.on('uncaughtException', onError);
- function onError(e) {
- errors.push(e);
- if (errors.length === n) {
- theFlow.removeListener('uncaughtException', onError);
- fulfill(n === 1 ? errors[0] : errors);
- }
+ enablePromiseManager(() => {
+ var flow, uncaughtExceptions;
+
+ beforeEach(function setUp() {
+ if (promise.USE_PROMISE_MANAGER) {
+ flow = promise.controlFlow();
+ uncaughtExceptions = [];
+ flow.on('uncaughtException', onUncaughtException);
}
});
- }
-
- function waitForIdle(opt_flow) {
- var theFlow = opt_flow || flow;
- return new NativePromise(function(fulfill, reject) {
- if (theFlow.isIdle()) {
- fulfill();
- return;
- }
- theFlow.once('idle', fulfill);
- theFlow.once('uncaughtException', reject);
- });
- }
-
- it('testRejectedPromiseTriggersErrorCallback', function() {
- return promise.rejected(new StubError).
- then(assert.fail, assertIsStubError);
- });
- describe('callback throws trigger subsequent error callback', function() {
- it('fulfilled promise', function() {
- return promise.fulfilled().
- then(throwStubError).
- then(assert.fail, assertIsStubError);
- });
-
- it('rejected promise', function() {
- var e = Error('not the droids you are looking for');
- return promise.rejected(e).
- then(assert.fail, throwStubError).
- then(assert.fail, assertIsStubError);
- });
- });
-
- describe('callback returns rejected promise triggers subsequent errback', function() {
- it('from fulfilled callback', function() {
- return promise.fulfilled().then(function() {
- return promise.rejected(new StubError);
- }).then(assert.fail, assertIsStubError);
- });
-
- it('from rejected callback', function() {
- var e = Error('not the droids you are looking for');
- return promise.rejected(e).
- then(assert.fail, function() {
- return promise.rejected(new StubError);
- }).
- then(assert.fail, assertIsStubError);
+ afterEach(function tearDown() {
+ if (promise.USE_PROMISE_MANAGER) {
+ return waitForIdle(flow).then(function() {
+ assert.deepEqual(
+ [], uncaughtExceptions, 'There were uncaught exceptions');
+ flow.reset();
+ });
+ }
});
- });
-
- it('testReportsUnhandledRejectionsThroughTheControlFlow', function() {
- promise.rejected(new StubError);
- return waitForAbort().then(assertIsStubError);
- });
- describe('multiple unhandled rejections outside a task', function() {
- it('are reported in order they occurred', function() {
- var e1 = Error('error 1');
- var e2 = Error('error 2');
+ function onUncaughtException(e) {
+ uncaughtExceptions.push(e);
+ }
- promise.rejected(e1);
- promise.rejected(e2);
+ function waitForAbort(opt_flow, opt_n) {
+ var n = opt_n || 1;
+ var theFlow = opt_flow || flow;
+ theFlow.removeAllListeners(
+ promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
+ return new NativePromise(function(fulfill, reject) {
+ theFlow.once('idle', function() {
+ reject(Error('expected flow to report an unhandled error'));
+ });
- return waitForAbort(flow).then(function(error) {
- assert.ok(
- error instanceof promise.MultipleUnhandledRejectionError);
- // TODO: switch to Array.from when we drop node 0.12.x
var errors = [];
- for (var e of error.errors) {
+ theFlow.on('uncaughtException', onError);
+ function onError(e) {
errors.push(e);
+ if (errors.length === n) {
+ theFlow.removeListener('uncaughtException', onError);
+ fulfill(n === 1 ? errors[0] : errors);
+ }
}
- assert.deepEqual([e1, e2], errors);
});
- });
- });
-
- describe('does not report unhandled rejection when', function() {
- it('handler added before next tick', function() {
- promise.rejected(new StubError).then(assert.fail, assertIsStubError);
- return waitForIdle();
- });
+ }
- it('added async but before next tick', function() {
- var called = false;
+ function waitForIdle(opt_flow) {
+ var theFlow = opt_flow || flow;
return new NativePromise(function(fulfill, reject) {
- var aPromise;
- NativePromise.resolve().then(function() {
- aPromise.then(assert.fail, function(e) {
- called = true;
- assertIsStubError(e);
- });
- waitForIdle().then(fulfill, reject);
- });
- aPromise = promise.rejected(new StubError);
- }).then(function() {
- assert.ok(called);
- })
+ if (theFlow.isIdle()) {
+ fulfill();
+ return;
+ }
+ theFlow.once('idle', fulfill);
+ theFlow.once('uncaughtException', reject);
+ });
+ }
+
+ it('testRejectedPromiseTriggersErrorCallback', function() {
+ return promise.rejected(new StubError).
+ then(assert.fail, assertIsStubError);
});
- });
- it('testTaskThrows', function() {
- return flow.execute(throwStubError).then(assert.fail, assertIsStubError);
- });
+ describe('callback throws trigger subsequent error callback', function() {
+ it('fulfilled promise', function() {
+ return promise.fulfilled().
+ then(throwStubError).
+ then(assert.fail, assertIsStubError);
+ });
- it('testTaskReturnsRejectedPromise', function() {
- return flow.execute(function() {
- return promise.rejected(new StubError)
- }).then(assert.fail, assertIsStubError);
- });
+ it('rejected promise', function() {
+ var e = Error('not the droids you are looking for');
+ return promise.rejected(e).
+ then(assert.fail, throwStubError).
+ then(assert.fail, assertIsStubError);
+ });
+ });
- it('testTaskHasUnhandledRejection', function() {
- return flow.execute(function() {
- promise.rejected(new StubError)
- }).then(assert.fail, assertIsStubError);
- });
+ describe('callback returns rejected promise triggers subsequent errback', function() {
+ it('from fulfilled callback', function() {
+ return promise.fulfilled().then(function() {
+ return promise.rejected(new StubError);
+ }).then(assert.fail, assertIsStubError);
+ });
- it('testTaskfails_returnedPromiseIsUnhandled', function() {
- flow.execute(throwStubError);
- return waitForAbort().then(assertIsStubError);
- });
+ it('from rejected callback', function() {
+ var e = Error('not the droids you are looking for');
+ return promise.rejected(e).
+ then(assert.fail, function() {
+ return promise.rejected(new StubError);
+ }).
+ then(assert.fail, assertIsStubError);
+ });
+ });
- it('testTaskHasUnhandledRejection_cancelsRemainingSubTasks', function() {
- var seen = [];
- flow.execute(function() {
+ it('testReportsUnhandledRejectionsThroughTheControlFlow', function() {
promise.rejected(new StubError);
-
- flow.execute(() => seen.push('a'))
- .then(() => seen.push('b'), (e) => seen.push(e));
- flow.execute(() => seen.push('c'))
- .then(() => seen.push('b'), (e) => seen.push(e));
+ return waitForAbort().then(assertIsStubError);
});
- return waitForAbort()
- .then(assertIsStubError)
- .then(() => assert.deepEqual([], seen));
- });
+ describe('multiple unhandled rejections outside a task', function() {
+ it('are reported in order they occurred', function() {
+ var e1 = Error('error 1');
+ var e2 = Error('error 2');
- describe('nested task failures', function() {
- it('returns up to paren', function() {
- return flow.execute(function() {
- return flow.execute(function() {
- return flow.execute(throwStubError);
- });
- }).then(assert.fail, assertIsStubError);
- });
+ promise.rejected(e1);
+ promise.rejected(e2);
- it('task throws; uncaught error bubbles up', function() {
- flow.execute(function() {
- flow.execute(function() {
- flow.execute(throwStubError);
+ return waitForAbort(flow).then(function(error) {
+ assert.ok(
+ error instanceof promise.MultipleUnhandledRejectionError);
+ // TODO: switch to Array.from when we drop node 0.12.x
+ var errors = [];
+ for (var e of error.errors) {
+ errors.push(e);
+ }
+ assert.deepEqual([e1, e2], errors);
});
});
- return waitForAbort().then(assertIsStubError);
});
- it('task throws; uncaught error bubbles up; is caught at root', function() {
- flow.execute(function() {
- flow.execute(function() {
- flow.execute(throwStubError);
- });
- }).then(assert.fail, assertIsStubError);
- return waitForIdle();
- });
+ describe('does not report unhandled rejection when', function() {
+ it('handler added before next tick', function() {
+ promise.rejected(new StubError).then(assert.fail, assertIsStubError);
+ return waitForIdle();
+ });
- it('unhandled rejection bubbles up', function() {
- flow.execute(function() {
- flow.execute(function() {
- flow.execute(function() {
- promise.rejected(new StubError);
+ it('added async but before next tick', function() {
+ var called = false;
+ return new NativePromise(function(fulfill, reject) {
+ var aPromise;
+ NativePromise.resolve().then(function() {
+ aPromise.then(assert.fail, function(e) {
+ called = true;
+ assertIsStubError(e);
+ });
+ waitForIdle().then(fulfill, reject);
});
- });
+ aPromise = promise.rejected(new StubError);
+ }).then(function() {
+ assert.ok(called);
+ })
});
- return waitForAbort().then(assertIsStubError);
});
- it('unhandled rejection bubbles up; caught at root', function() {
- flow.execute(function() {
- flow.execute(function() {
- promise.rejected(new StubError);
- });
+ it('testTaskThrows', function() {
+ return flow.execute(throwStubError).then(assert.fail, assertIsStubError);
+ });
+
+ it('testTaskReturnsRejectedPromise', function() {
+ return flow.execute(function() {
+ return promise.rejected(new StubError)
}).then(assert.fail, assertIsStubError);
- return waitForIdle();
});
- it('mixtureof hanging and free subtasks', function() {
- flow.execute(function() {
- return flow.execute(function() {
- flow.execute(throwStubError);
- });
- });
+ it('testTaskHasUnhandledRejection', function() {
+ return flow.execute(function() {
+ promise.rejected(new StubError)
+ }).then(assert.fail, assertIsStubError);
+ });
+
+ it('testTaskfails_returnedPromiseIsUnhandled', function() {
+ flow.execute(throwStubError);
return waitForAbort().then(assertIsStubError);
});
- it('cancels remaining tasks', function() {
+ it('testTaskHasUnhandledRejection_cancelsRemainingSubTasks', function() {
var seen = [];
flow.execute(function() {
- flow.execute(() => promise.rejected(new StubError));
+ promise.rejected(new StubError);
+
flow.execute(() => seen.push('a'))
.then(() => seen.push('b'), (e) => seen.push(e));
flow.execute(() => seen.push('c'))
@@ -282,598 +217,667 @@ describe('promise error handling', function() {
.then(assertIsStubError)
.then(() => assert.deepEqual([], seen));
});
- });
-
- it('testTaskReturnsPromiseLikeObjectThatInvokesErrback', function() {
- return flow.execute(function() {
- return {
- 'then': function(_, errback) {
- errback('abc123');
- }
- };
- }).then(assert.fail, function(value) {
- assert.equal('abc123', value);
- });
- });
-
- describe('ControlFlow#wait();', function() {
- describe('condition throws;', function() {
- it('failure is caught', function() {
- return flow.wait(throwStubError, 50).then(assert.fail, assertIsStubError);
- });
-
- it('failure is not caught', function() {
- flow.wait(throwStubError, 50);
- return waitForAbort().then(assertIsStubError);
- });
- });
- describe('condition returns promise', function() {
- it('failure is caught', function() {
- return flow.wait(function() {
- return promise.rejected(new StubError);
- }, 50).then(assert.fail, assertIsStubError);
+ describe('nested task failures', function() {
+ it('returns up to paren', function() {
+ return flow.execute(function() {
+ return flow.execute(function() {
+ return flow.execute(throwStubError);
+ });
+ }).then(assert.fail, assertIsStubError);
});
- it('failure is not caught', function() {
- flow.wait(function() {
- return promise.rejected(new StubError);
- }, 50);
+ it('task throws; uncaught error bubbles up', function() {
+ flow.execute(function() {
+ flow.execute(function() {
+ flow.execute(throwStubError);
+ });
+ });
return waitForAbort().then(assertIsStubError);
});
- });
- describe('condition has unhandled promise rejection', function() {
- it('failure is caught', function() {
- return flow.wait(function() {
- promise.rejected(new StubError);
- }, 50).then(assert.fail, assertIsStubError);
+ it('task throws; uncaught error bubbles up; is caught at root', function() {
+ flow.execute(function() {
+ flow.execute(function() {
+ flow.execute(throwStubError);
+ });
+ }).then(assert.fail, assertIsStubError);
+ return waitForIdle();
});
- it('failure is not caught', function() {
- flow.wait(function() {
- promise.rejected(new StubError);
- }, 50);
+ it('unhandled rejection bubbles up', function() {
+ flow.execute(function() {
+ flow.execute(function() {
+ flow.execute(function() {
+ promise.rejected(new StubError);
+ });
+ });
+ });
return waitForAbort().then(assertIsStubError);
});
- });
- describe('condition has subtask failure', function() {
- it('failure is caught', function() {
- return flow.wait(function() {
+ it('unhandled rejection bubbles up; caught at root', function() {
+ flow.execute(function() {
flow.execute(function() {
- flow.execute(throwStubError);
+ promise.rejected(new StubError);
});
- }, 50).then(assert.fail, assertIsStubError);
+ }).then(assert.fail, assertIsStubError);
+ return waitForIdle();
});
- it('failure is not caught', function() {
- flow.wait(function() {
- flow.execute(function() {
+ it('mixtureof hanging and free subtasks', function() {
+ flow.execute(function() {
+ return flow.execute(function() {
flow.execute(throwStubError);
});
- }, 50);
+ });
return waitForAbort().then(assertIsStubError);
});
- });
- });
- describe('errback throws a new error', function() {
- it('start with normal promise', function() {
- var error = Error('an error');
- return promise.rejected(error).
- catch(function(e) {
- assert.equal(e, error);
- throw new StubError;
- }).
- catch(assertIsStubError);
+ it('cancels remaining tasks', function() {
+ var seen = [];
+ flow.execute(function() {
+ flow.execute(() => promise.rejected(new StubError));
+ flow.execute(() => seen.push('a'))
+ .then(() => seen.push('b'), (e) => seen.push(e));
+ flow.execute(() => seen.push('c'))
+ .then(() => seen.push('b'), (e) => seen.push(e));
+ });
+
+ return waitForAbort()
+ .then(assertIsStubError)
+ .then(() => assert.deepEqual([], seen));
+ });
});
- it('start with task result', function() {
- var error = Error('an error');
+ it('testTaskReturnsPromiseLikeObjectThatInvokesErrback', function() {
return flow.execute(function() {
- throw error;
- }).
- catch(function(e) {
- assert.equal(e, error);
- throw new StubError;
- }).
- catch(assertIsStubError);
+ return {
+ 'then': function(_, errback) {
+ errback('abc123');
+ }
+ };
+ }).then(assert.fail, function(value) {
+ assert.equal('abc123', value);
+ });
});
- it('start with normal promise; uncaught error', function() {
- var error = Error('an error');
- promise.rejected(error).
- catch(function(e) {
- assert.equal(e, error);
- throw new StubError;
- });
- return waitForAbort().then(assertIsStubError);
- });
+ describe('ControlFlow#wait();', function() {
+ describe('condition throws;', function() {
+ it('failure is caught', function() {
+ return flow.wait(throwStubError, 50).then(assert.fail, assertIsStubError);
+ });
- it('start with task result; uncaught error', function() {
- var error = Error('an error');
- flow.execute(function() {
- throw error;
- }).
- catch(function(e) {
- assert.equal(e, error);
- throw new StubError;
+ it('failure is not caught', function() {
+ flow.wait(throwStubError, 50);
+ return waitForAbort().then(assertIsStubError);
+ });
});
- return waitForAbort().then(assertIsStubError);
- });
- });
- it('thrownPromiseCausesCallbackRejection', function() {
- let p = promise.fulfilled(1234);
- return promise.fulfilled().then(function() {
- throw p;
- }).then(assert.fail, function(value) {
- assert.strictEqual(p, value);
- });
- });
+ describe('condition returns promise', function() {
+ it('failure is caught', function() {
+ return flow.wait(function() {
+ return promise.rejected(new StubError);
+ }, 50).then(assert.fail, assertIsStubError);
+ });
- describe('task throws promise', function() {
- it('promise was fulfilled', function() {
- var toThrow = promise.fulfilled(1234);
- flow.execute(function() {
- throw toThrow;
- }).then(assert.fail, function(value) {
- assert.equal(toThrow, value);
- return toThrow;
- }).then(function(value) {
- assert.equal(1234, value);
+ it('failure is not caught', function() {
+ flow.wait(function() {
+ return promise.rejected(new StubError);
+ }, 50);
+ return waitForAbort().then(assertIsStubError);
+ });
});
- return waitForIdle();
- });
-
- it('promise was rejected', function() {
- var toThrow = promise.rejected(new StubError);
- toThrow.catch(function() {}); // For tearDown.
- flow.execute(function() {
- throw toThrow;
- }).then(assert.fail, function(e) {
- assert.equal(toThrow, e);
- return e;
- }).then(assert.fail, assertIsStubError);
- return waitForIdle();
- });
- });
- it('testFailsTaskIfThereIsAnUnhandledErrorWhileWaitingOnTaskResult', function() {
- var d = promise.defer();
- flow.execute(function() {
- promise.rejected(new StubError);
- return d.promise;
- }).then(assert.fail, assertIsStubError);
+ describe('condition has unhandled promise rejection', function() {
+ it('failure is caught', function() {
+ return flow.wait(function() {
+ promise.rejected(new StubError);
+ }, 50).then(assert.fail, assertIsStubError);
+ });
- return waitForIdle().then(function() {
- return d.promise;
- }).then(assert.fail, function(e) {
- assert.equal('CancellationError: StubError', e.toString());
- });
- });
+ it('failure is not caught', function() {
+ flow.wait(function() {
+ promise.rejected(new StubError);
+ }, 50);
+ return waitForAbort().then(assertIsStubError);
+ });
+ });
- it('testFailsParentTaskIfAsyncScheduledTaskFails', function() {
- var d = promise.defer();
- flow.execute(function() {
- flow.execute(throwStubError);
- return d.promise;
- }).then(assert.fail, assertIsStubError);
+ describe('condition has subtask failure', function() {
+ it('failure is caught', function() {
+ return flow.wait(function() {
+ flow.execute(function() {
+ flow.execute(throwStubError);
+ });
+ }, 50).then(assert.fail, assertIsStubError);
+ });
- return waitForIdle().then(function() {
- return d.promise;
- }).then(assert.fail, function(e) {
- assert.equal('CancellationError: StubError', e.toString());
+ it('failure is not caught', function() {
+ flow.wait(function() {
+ flow.execute(function() {
+ flow.execute(throwStubError);
+ });
+ }, 50);
+ return waitForAbort().then(assertIsStubError);
+ });
+ });
});
- });
- describe('long stack traces', function() {
- afterEach(() => promise.LONG_STACK_TRACES = false);
+ describe('errback throws a new error', function() {
+ it('start with normal promise', function() {
+ var error = Error('an error');
+ return promise.rejected(error).
+ catch(function(e) {
+ assert.equal(e, error);
+ throw new StubError;
+ }).
+ catch(assertIsStubError);
+ });
- it('always includes task stacks in failures', function() {
- promise.LONG_STACK_TRACES = false;
- flow.execute(function() {
- flow.execute(function() {
- flow.execute(throwStubError, 'throw error');
- }, 'two');
- }, 'three').
- then(assert.fail, function(e) {
- assertIsStubError(e);
- if (typeof e.stack !== 'string') {
- return;
- }
- var messages = e.stack.split(/\n/).filter(function(line, index) {
- return /^From: /.test(line);
- });
- assert.deepEqual([
- 'From: Task: throw error',
- 'From: Task: two',
- 'From: Task: three'
- ], messages);
+ it('start with task result', function() {
+ var error = Error('an error');
+ return flow.execute(function() {
+ throw error;
+ }).
+ catch(function(e) {
+ assert.equal(e, error);
+ throw new StubError;
+ }).
+ catch(assertIsStubError);
+ });
+
+ it('start with normal promise; uncaught error', function() {
+ var error = Error('an error');
+ promise.rejected(error).
+ catch(function(e) {
+ assert.equal(e, error);
+ throw new StubError;
+ });
+ return waitForAbort().then(assertIsStubError);
});
- return waitForIdle();
- });
- it('does not include completed tasks', function () {
- flow.execute(function() {}, 'succeeds');
- flow.execute(throwStubError, 'kaboom').then(assert.fail, function(e) {
- assertIsStubError(e);
- if (typeof e.stack !== 'string') {
- return;
- }
- var messages = e.stack.split(/\n/).filter(function(line, index) {
- return /^From: /.test(line);
+ it('start with task result; uncaught error', function() {
+ var error = Error('an error');
+ flow.execute(function() {
+ throw error;
+ }).
+ catch(function(e) {
+ assert.equal(e, error);
+ throw new StubError;
});
- assert.deepEqual(['From: Task: kaboom'], messages);
+ return waitForAbort().then(assertIsStubError);
});
- return waitForIdle();
});
- it('does not include promise chain when disabled', function() {
- promise.LONG_STACK_TRACES = false;
- flow.execute(function() {
- flow.execute(function() {
- return promise.fulfilled().
- then(function() {}).
- then(function() {}).
- then(throwStubError);
- }, 'eventually assert.fails');
- }, 'start').
- then(assert.fail, function(e) {
- assertIsStubError(e);
- if (typeof e.stack !== 'string') {
- return;
- }
- var messages = e.stack.split(/\n/).filter(function(line, index) {
- return /^From: /.test(line);
- });
- assert.deepEqual([
- 'From: Task: eventually assert.fails',
- 'From: Task: start'
- ], messages);
+ it('thrownPromiseCausesCallbackRejection', function() {
+ let p = promise.fulfilled(1234);
+ return promise.fulfilled().then(function() {
+ throw p;
+ }).then(assert.fail, function(value) {
+ assert.strictEqual(p, value);
});
- return waitForIdle();
});
- it('includes promise chain when enabled', function() {
- promise.LONG_STACK_TRACES = true;
- flow.execute(function() {
+ describe('task throws promise', function() {
+ it('promise was fulfilled', function() {
+ var toThrow = promise.fulfilled(1234);
flow.execute(function() {
- return promise.fulfilled().
- then(function() {}).
- then(function() {}).
- then(throwStubError);
- }, 'eventually assert.fails');
- }, 'start').
- then(assert.fail, function(e) {
- assertIsStubError(e);
- if (typeof e.stack !== 'string') {
- return;
- }
- var messages = e.stack.split(/\n/).filter(function(line, index) {
- return /^From: /.test(line);
+ throw toThrow;
+ }).then(assert.fail, function(value) {
+ assert.equal(toThrow, value);
+ return toThrow;
+ }).then(function(value) {
+ assert.equal(1234, value);
});
- assert.deepEqual([
- 'From: Promise: then',
- 'From: Task: eventually assert.fails',
- 'From: Task: start'
- ], messages);
+ return waitForIdle();
});
- return waitForIdle();
- });
- });
- describe('frame cancels remaining tasks', function() {
- it('on unhandled task failure', function() {
- var run = false;
- return flow.execute(function() {
- flow.execute(throwStubError);
- flow.execute(function() { run = true; });
- }).then(assert.fail, function(e) {
- assertIsStubError(e);
- assert.ok(!run);
+ it('promise was rejected', function() {
+ var toThrow = promise.rejected(new StubError);
+ toThrow.catch(function() {}); // For tearDown.
+ flow.execute(function() {
+ throw toThrow;
+ }).then(assert.fail, function(e) {
+ assert.equal(toThrow, e);
+ return e;
+ }).then(assert.fail, assertIsStubError);
+ return waitForIdle();
});
});
- it('on unhandled promise rejection', function() {
- var run = false;
- return flow.execute(function() {
+ it('testFailsTaskIfThereIsAnUnhandledErrorWhileWaitingOnTaskResult', function() {
+ var d = promise.defer();
+ flow.execute(function() {
promise.rejected(new StubError);
- flow.execute(function() { run = true; });
+ return d.promise;
+ }).then(assert.fail, assertIsStubError);
+
+ return waitForIdle().then(function() {
+ return d.promise;
}).then(assert.fail, function(e) {
- assertIsStubError(e);
- assert.ok(!run);
+ assert.equal('CancellationError: StubError', e.toString());
});
});
- it('if task throws', function() {
- var run = false;
- return flow.execute(function() {
- flow.execute(function() { run = true; });
- throw new StubError;
+ it('testFailsParentTaskIfAsyncScheduledTaskFails', function() {
+ var d = promise.defer();
+ flow.execute(function() {
+ flow.execute(throwStubError);
+ return d.promise;
+ }).then(assert.fail, assertIsStubError);
+
+ return waitForIdle().then(function() {
+ return d.promise;
}).then(assert.fail, function(e) {
- assertIsStubError(e);
- assert.ok(!run);
+ assert.equal('CancellationError: StubError', e.toString());
});
});
- describe('task callbacks scheduled in another frame', function() {
- flow = promise.controlFlow();
- function noop() {}
-
- let subTask;
+ describe('long stack traces', function() {
+ afterEach(() => promise.LONG_STACK_TRACES = false);
- before(function() {
+ it('always includes task stacks in failures', function() {
+ promise.LONG_STACK_TRACES = false;
flow.execute(function() {
- // This task will be discarded and never run because of the error below.
- subTask = flow.execute(() => 'abc');
- throw new StubError('stub');
- }).catch(noop);
- });
-
- function assertCancellation(e) {
- assert.ok(e instanceof promise.CancellationError);
- assert.equal(
- 'Task was discarded due to a previous failure: stub', e.message);
- }
-
- it('are rejected with cancellation error', function() {
- let result;
- return Promise.resolve().then(function() {
- return flow.execute(function() {
- result = subTask.then(assert.fail);
+ flow.execute(function() {
+ flow.execute(throwStubError, 'throw error');
+ }, 'two');
+ }, 'three').
+ then(assert.fail, function(e) {
+ assertIsStubError(e);
+ if (typeof e.stack !== 'string') {
+ return;
+ }
+ var messages = e.stack.split(/\n/).filter(function(line, index) {
+ return /^From: /.test(line);
});
- })
- .then(() => result)
- .then(assert.fail, assertCancellation);
+ assert.deepEqual([
+ 'From: Task: throw error',
+ 'From: Task: two',
+ 'From: Task: three'
+ ], messages);
+ });
+ return waitForIdle();
+ });
+
+ it('does not include completed tasks', function () {
+ flow.execute(function() {}, 'succeeds');
+ flow.execute(throwStubError, 'kaboom').then(assert.fail, function(e) {
+ assertIsStubError(e);
+ if (typeof e.stack !== 'string') {
+ return;
+ }
+ var messages = e.stack.split(/\n/).filter(function(line, index) {
+ return /^From: /.test(line);
+ });
+ assert.deepEqual(['From: Task: kaboom'], messages);
+ });
+ return waitForIdle();
});
- it('cancellation errors propagate through callbacks (1)', function() {
- let result;
- return Promise.resolve().then(function() {
- return flow.execute(function() {
- result = subTask
- .then(assert.fail, assertCancellation)
- .then(() => 'abc123');
+ it('does not include promise chain when disabled', function() {
+ promise.LONG_STACK_TRACES = false;
+ flow.execute(function() {
+ flow.execute(function() {
+ return promise.fulfilled().
+ then(function() {}).
+ then(function() {}).
+ then(throwStubError);
+ }, 'eventually assert.fails');
+ }, 'start').
+ then(assert.fail, function(e) {
+ assertIsStubError(e);
+ if (typeof e.stack !== 'string') {
+ return;
+ }
+ var messages = e.stack.split(/\n/).filter(function(line, index) {
+ return /^From: /.test(line);
});
- })
- .then(() => result)
- .then(value => assert.equal('abc123', value));
+ assert.deepEqual([
+ 'From: Task: eventually assert.fails',
+ 'From: Task: start'
+ ], messages);
+ });
+ return waitForIdle();
});
- it('cancellation errors propagate through callbacks (2)', function() {
- let result;
- return Promise.resolve().then(function() {
- return flow.execute(function() {
- result = subTask.then(assert.fail)
- .then(noop, assertCancellation)
- .then(() => 'fin');
+ it('includes promise chain when enabled', function() {
+ promise.LONG_STACK_TRACES = true;
+ flow.execute(function() {
+ flow.execute(function() {
+ return promise.fulfilled().
+ then(function() {}).
+ then(function() {}).
+ then(throwStubError);
+ }, 'eventually assert.fails');
+ }, 'start').
+ then(assert.fail, function(e) {
+ assertIsStubError(e);
+ if (typeof e.stack !== 'string') {
+ return;
+ }
+ var messages = e.stack.split(/\n/).filter(function(line, index) {
+ return /^From: /.test(line);
});
- })
- // Verify result actually computed successfully all the way through.
- .then(() => result)
- .then(value => assert.equal('fin', value));
+ assert.deepEqual([
+ 'From: Promise: then',
+ 'From: Task: eventually assert.fails',
+ 'From: Task: start'
+ ], messages);
+ });
+ return waitForIdle();
});
});
- });
- it('testRegisteredTaskCallbacksAreDroppedWhenTaskIsCancelled_return', function() {
- var seen = [];
- return flow.execute(function() {
- flow.execute(throwStubError);
+ describe('frame cancels remaining tasks', function() {
+ it('on unhandled task failure', function() {
+ var run = false;
+ return flow.execute(function() {
+ flow.execute(throwStubError);
+ flow.execute(function() { run = true; });
+ }).then(assert.fail, function(e) {
+ assertIsStubError(e);
+ assert.ok(!run);
+ });
+ });
- flow.execute(function() {
- seen.push(1);
- }).then(function() {
- seen.push(2);
- }, function() {
- seen.push(3);
- });
- }).then(assert.fail, function(e) {
- assertIsStubError(e);
- assert.deepEqual([], seen);
- });
- });
+ it('on unhandled promise rejection', function() {
+ var run = false;
+ return flow.execute(function() {
+ promise.rejected(new StubError);
+ flow.execute(function() { run = true; });
+ }).then(assert.fail, function(e) {
+ assertIsStubError(e);
+ assert.ok(!run);
+ });
+ });
- it('testRegisteredTaskCallbacksAreDroppedWhenTaskIsCancelled_withReturn', function() {
- var seen = [];
- return flow.execute(function() {
- flow.execute(throwStubError);
+ it('if task throws', function() {
+ var run = false;
+ return flow.execute(function() {
+ flow.execute(function() { run = true; });
+ throw new StubError;
+ }).then(assert.fail, function(e) {
+ assertIsStubError(e);
+ assert.ok(!run);
+ });
+ });
- return flow.execute(function() {
- seen.push(1);
- }).then(function() {
- seen.push(2);
- }, function() {
- seen.push(3);
- });
- }).then(assert.fail, function(e) {
- assertIsStubError(e);
- assert.deepEqual([], seen);
- });
- });
+ describe('task callbacks scheduled in another frame', function() {
+ flow = promise.controlFlow();
+ function noop() {}
- it('testTasksWithinACallbackAreDroppedIfContainingTaskIsAborted', function() {
- var seen = [];
- return flow.execute(function() {
- flow.execute(throwStubError);
+ let subTask;
- // None of the callbacks on this promise should execute because the
- // task assert.failure above is never handled, causing the containing task to
- // abort.
- promise.fulfilled().then(function() {
- seen.push(1);
- return flow.execute(function() {
- seen.push(2);
+ before(function() {
+ flow.execute(function() {
+ // This task will be discarded and never run because of the error below.
+ subTask = flow.execute(() => 'abc');
+ throw new StubError('stub');
+ }).catch(noop);
});
- }).finally(function() {
- seen.push(3);
- });
- }).then(assert.fail, function(e) {
- assertIsStubError(e);
- assert.deepEqual([], seen);
- });
- });
+ function assertCancellation(e) {
+ assert.ok(e instanceof promise.CancellationError);
+ assert.equal(
+ 'Task was discarded due to a previous failure: stub', e.message);
+ }
- it('testTaskIsCancelledAfterWaitTimeout', function() {
- var seen = [];
- return flow.execute(function() {
- flow.wait(function() {
- return promise.delayed(50);
- }, 5);
+ it('are rejected with cancellation error', function() {
+ let result;
+ return Promise.resolve().then(function() {
+ return flow.execute(function() {
+ result = subTask.then(assert.fail);
+ });
+ })
+ .then(() => result)
+ .then(assert.fail, assertCancellation);
+ });
- return flow.execute(function() {
- seen.push(1);
- }).then(function() {
- seen.push(2);
- }, function() {
- seen.push(3);
- });
- }).then(assert.fail, function() {
- assert.deepEqual([], seen);
+ it('cancellation errors propagate through callbacks (1)', function() {
+ let result;
+ return Promise.resolve().then(function() {
+ return flow.execute(function() {
+ result = subTask
+ .then(assert.fail, assertCancellation)
+ .then(() => 'abc123');
+ });
+ })
+ .then(() => result)
+ .then(value => assert.equal('abc123', value));
+ });
+
+ it('cancellation errors propagate through callbacks (2)', function() {
+ let result;
+ return Promise.resolve().then(function() {
+ return flow.execute(function() {
+ result = subTask.then(assert.fail)
+ .then(noop, assertCancellation)
+ .then(() => 'fin');
+ });
+ })
+ // Verify result actually computed successfully all the way through.
+ .then(() => result)
+ .then(value => assert.equal('fin', value));
+ });
+ });
});
- });
- describe('task callbacks get cancellation error if registered after task was cancelled', function() {
- it('(a)', function() {
- var task;
- flow.execute(function() {
+ it('testRegisteredTaskCallbacksAreDroppedWhenTaskIsCancelled_return', function() {
+ var seen = [];
+ return flow.execute(function() {
flow.execute(throwStubError);
- task = flow.execute(function() {});
- }).then(assert.fail, assertIsStubError);
- return waitForIdle().then(function() {
- return task.then(assert.fail, function(e) {
- assert.ok(e instanceof promise.CancellationError);
+
+ flow.execute(function() {
+ seen.push(1);
+ }).then(function() {
+ seen.push(2);
+ }, function() {
+ seen.push(3);
});
+ }).then(assert.fail, function(e) {
+ assertIsStubError(e);
+ assert.deepEqual([], seen);
});
});
- it('(b)', function() {
+ it('testRegisteredTaskCallbacksAreDroppedWhenTaskIsCancelled_withReturn', function() {
var seen = [];
-
- var task;
- flow.execute(function() {
+ return flow.execute(function() {
flow.execute(throwStubError);
- task = flow.execute(function() {});
- task.then(() => seen.push(1))
- .then(() => seen.push(2));
- task.then(() => seen.push(3))
- .then(() => seen.push(4));
+ return flow.execute(function() {
+ seen.push(1);
+ }).then(function() {
+ seen.push(2);
+ }, function() {
+ seen.push(3);
+ });
+ }).then(assert.fail, function(e) {
+ assertIsStubError(e);
+ assert.deepEqual([], seen);
+ });
+ });
- }).then(assert.fail, assertIsStubError);
+ it('testTasksWithinACallbackAreDroppedIfContainingTaskIsAborted', function() {
+ var seen = [];
+ return flow.execute(function() {
+ flow.execute(throwStubError);
- return waitForIdle().then(function() {
- return task.then(assert.fail, function(e) {
- seen.push(5);
- assert.ok(e instanceof promise.CancellationError);
+ // None of the callbacks on this promise should execute because the
+ // task assert.failure above is never handled, causing the containing task to
+ // abort.
+ promise.fulfilled().then(function() {
+ seen.push(1);
+ return flow.execute(function() {
+ seen.push(2);
+ });
+ }).finally(function() {
+ seen.push(3);
});
- }).then(() => assert.deepEqual([5], seen));
+
+ }).then(assert.fail, function(e) {
+ assertIsStubError(e);
+ assert.deepEqual([], seen);
+ });
});
- });
- it('unhandledRejectionInParallelTaskQueue', function() {
- var seen = [];
- function schedule(name) {
- return flow.execute(() => seen.push(name), name);
- }
+ it('testTaskIsCancelledAfterWaitTimeout', function() {
+ var seen = [];
+ return flow.execute(function() {
+ flow.wait(function() {
+ return promise.delayed(50);
+ }, 5);
- flow.async(function() {
- schedule('a.1');
- flow.execute(throwStubError, 'a.2 (throws)');
+ return flow.execute(function() {
+ seen.push(1);
+ }).then(function() {
+ seen.push(2);
+ }, function() {
+ seen.push(3);
+ });
+ }).then(assert.fail, function() {
+ assert.deepEqual([], seen);
+ });
});
- var b3;
- flow.async(function() {
- schedule('b.1');
- schedule('b.2');
- b3 = schedule('b.3');
- });
+ describe('task callbacks get cancellation error if registered after task was cancelled', function() {
+ it('(a)', function() {
+ var task;
+ flow.execute(function() {
+ flow.execute(throwStubError);
+ task = flow.execute(function() {});
+ }).then(assert.fail, assertIsStubError);
+ return waitForIdle().then(function() {
+ return task.then(assert.fail, function(e) {
+ assert.ok(e instanceof promise.CancellationError);
+ });
+ });
+ });
- var c3;
- flow.async(function() {
- schedule('c.1');
- schedule('c.2');
- c3 = schedule('c.3');
- });
+ it('(b)', function() {
+ var seen = [];
+
+ var task;
+ flow.execute(function() {
+ flow.execute(throwStubError);
+ task = flow.execute(function() {});
+
+ task.then(() => seen.push(1))
+ .then(() => seen.push(2));
+ task.then(() => seen.push(3))
+ .then(() => seen.push(4));
+
+ }).then(assert.fail, assertIsStubError);
- function assertWasCancelled(p) {
- return p.then(assert.fail, function(e) {
- assert.ok(e instanceof promise.CancellationError);
+ return waitForIdle().then(function() {
+ return task.then(assert.fail, function(e) {
+ seen.push(5);
+ assert.ok(e instanceof promise.CancellationError);
+ });
+ }).then(() => assert.deepEqual([5], seen));
});
- }
+ });
- return waitForAbort()
- .then(function() {
- assert.deepEqual(['a.1', 'b.1', 'c.1', 'b.2', 'c.2'], seen);
- assert.ok(!b3.isPending());
- assert.ok(!c3.isPending());
- })
- .then(() => assertWasCancelled(b3))
- .then(() => assertWasCancelled(c3));
- });
+ it('unhandledRejectionInParallelTaskQueue', function() {
+ var seen = [];
+ function schedule(name) {
+ return flow.execute(() => seen.push(name), name);
+ }
- it('errorsInAsyncFunctionsAreReportedAsUnhandledRejection', function() {
- flow.removeAllListeners(); // For tearDown.
+ flow.async(function() {
+ schedule('a.1');
+ flow.execute(throwStubError, 'a.2 (throws)');
+ });
- var task;
- return new Promise(function(fulfill) {
- flow.once('uncaughtException', fulfill);
+ var b3;
flow.async(function() {
- task = flow.execute(function() {});
- throw Error('boom');
+ schedule('b.1');
+ schedule('b.2');
+ b3 = schedule('b.3');
});
- }).then(function(error) {
- assert.ok(error instanceof promise.CancellationError);
- assert.ok(!task.isPending());
- return task.catch(function(error) {
- assert.ok(error instanceof promise.CancellationError);
+
+ var c3;
+ flow.async(function() {
+ schedule('c.1');
+ schedule('c.2');
+ c3 = schedule('c.3');
});
+
+ function assertWasCancelled(p) {
+ return p.then(assert.fail, function(e) {
+ assert.ok(e instanceof promise.CancellationError);
+ });
+ }
+
+ return waitForAbort()
+ .then(function() {
+ assert.deepEqual(['a.1', 'b.1', 'c.1', 'b.2', 'c.2'], seen);
+ })
+ .then(() => assertWasCancelled(b3))
+ .then(() => assertWasCancelled(c3));
});
- });
- describe('does not wait for values thrown from callbacks to be resolved', function() {
- it('(a)', function() {
- var p1 = promise.fulfilled();
- var reason = promise.fulfilled('should not see me');
- return p1.then(function() {
- throw reason;
- }).then(assert.fail, function(e) {
- assert.equal(reason, e);
+ it('errorsInAsyncFunctionsAreReportedAsUnhandledRejection', function() {
+ flow.removeAllListeners(); // For tearDown.
+
+ var task;
+ return new Promise(function(fulfill) {
+ flow.once('uncaughtException', fulfill);
+ flow.async(function() {
+ task = flow.execute(function() {});
+ throw Error('boom');
+ });
+ }).then(function(error) {
+ assert.ok(error instanceof promise.CancellationError);
+ return task.catch(function(error) {
+ assert.ok(error instanceof promise.CancellationError);
+ });
});
});
- it('(b)', function() {
- var p1 = promise.fulfilled();
- var reason = promise.rejected('should not see me');
- reason.catch(function() {}); // For tearDown.
- return p1.then(function() {
- throw reason;
- }).then(assert.fail, function(e) {
- assert.equal(reason, e);
+ describe('does not wait for values thrown from callbacks to be resolved', function() {
+ it('(a)', function() {
+ var p1 = promise.fulfilled();
+ var reason = promise.fulfilled('should not see me');
+ return p1.then(function() {
+ throw reason;
+ }).then(assert.fail, function(e) {
+ assert.equal(reason, e);
+ });
});
- });
- it('(c)', function() {
- var p1 = promise.fulfilled();
- var reason = promise.defer();
- setTimeout(() => reason.fulfill('should not see me'), 100);
- return p1.then(function() {
- throw reason.promise;
- }).then(assert.fail, function(e) {
- assert.equal(reason.promise, e);
+ it('(b)', function() {
+ var p1 = promise.fulfilled();
+ var reason = promise.rejected('should not see me');
+ reason.catch(function() {}); // For tearDown.
+ return p1.then(function() {
+ throw reason;
+ }).then(assert.fail, function(e) {
+ assert.equal(reason, e);
+ });
});
- });
- it('(d)', function() {
- var p1 = promise.fulfilled();
- var reason = {then: function() {}}; // A thenable like object.
- return p1.then(function() {
- throw reason;
- }).then(assert.fail, function(e) {
- assert.equal(reason, e);
+ it('(c)', function() {
+ var p1 = promise.fulfilled();
+ var reason = promise.defer();
+ setTimeout(() => reason.fulfill('should not see me'), 100);
+ return p1.then(function() {
+ throw reason.promise;
+ }).then(assert.fail, function(e) {
+ assert.equal(reason.promise, e);
+ });
+ });
+
+ it('(d)', function() {
+ var p1 = promise.fulfilled();
+ var reason = {then: function() {}}; // A thenable like object.
+ return p1.then(function() {
+ throw reason;
+ }).then(assert.fail, function(e) {
+ assert.equal(reason, e);
+ });
});
});
});
diff --git a/node_modules/selenium-webdriver/test/lib/promise_flow_test.js b/node_modules/selenium-webdriver/test/lib/promise_flow_test.js
index b42ac5209..407fd547e 100644
--- a/node_modules/selenium-webdriver/test/lib/promise_flow_test.js
+++ b/node_modules/selenium-webdriver/test/lib/promise_flow_test.js
@@ -22,7 +22,9 @@ const fail = assert.fail;
const sinon = require('sinon');
const testutil = require('./testutil');
+const {TimeoutError} = require('../../lib/error');
const promise = require('../../lib/promise');
+const {enablePromiseManager} = require('../../lib/test/promise');
const NativePromise = Promise;
@@ -33,2252 +35,2254 @@ const callbackPair = testutil.callbackPair;
const throwStubError = testutil.throwStubError;
describe('promise control flow', function() {
- let flow, flowHistory, messages, uncaughtExceptions;
-
- beforeEach(function setUp() {
- promise.LONG_STACK_TRACES = false;
- flow = new promise.ControlFlow();
- promise.setDefaultFlow(flow);
- messages = [];
- flowHistory = [];
-
- uncaughtExceptions = [];
- flow.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
- onUncaughtException);
- });
-
- afterEach(function tearDown() {
- flow.removeAllListeners(
- promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
- assert.deepEqual([], uncaughtExceptions,
- 'There were uncaught exceptions');
- flow.reset();
- promise.LONG_STACK_TRACES = false;
- });
+ enablePromiseManager(() => {
+ let flow, flowHistory, messages, uncaughtExceptions;
- function onUncaughtException(e) {
- uncaughtExceptions.push(e);
- }
-
- function waitForAbort(opt_flow) {
- var theFlow = opt_flow || flow;
- theFlow.removeAllListeners(
- promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
- return new NativePromise(function(fulfill, reject) {
- theFlow.once(promise.ControlFlow.EventType.IDLE, function() {
- reject(Error('expected flow to report an unhandled error'));
- });
- theFlow.once(
- promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
- fulfill);
- });
- }
-
- function waitForIdle(opt_flow) {
- var theFlow = opt_flow || flow;
- return new NativePromise(function(fulfill, reject) {
- theFlow.once(promise.ControlFlow.EventType.IDLE, fulfill);
- theFlow.once(
- promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, reject);
- });
- }
+ beforeEach(function setUp() {
+ promise.LONG_STACK_TRACES = false;
+ flow = new promise.ControlFlow();
+ promise.setDefaultFlow(flow);
+ messages = [];
+ flowHistory = [];
- function timeout(ms) {
- return new NativePromise(function(fulfill) {
- setTimeout(fulfill, ms);
+ uncaughtExceptions = [];
+ flow.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
+ onUncaughtException);
});
- }
-
- function schedule(msg, opt_return) {
- return scheduleAction(msg, function() {
- return opt_return;
- });
- }
-
- /**
- * @param {string} value The value to push.
- * @param {promise.Promise=} opt_taskPromise Promise to return from
- * the task.
- * @return {!promise.Promise} The result.
- */
- function schedulePush(value, opt_taskPromise) {
- return scheduleAction(value, function() {
- messages.push(value);
- return opt_taskPromise;
- });
- }
-
- /**
- * @param {string} msg Debug message.
- * @param {!Function} actionFn The function.
- * @return {!promise.Promise} The function result.
- */
- function scheduleAction(msg, actionFn) {
- return promise.controlFlow().execute(function() {
- flowHistory.push(msg);
- return actionFn();
- }, msg);
- }
-
- /**
- * @param {!Function} condition The condition function.
- * @param {number=} opt_timeout The timeout.
- * @param {string=} opt_message Optional message.
- * @return {!promise.Promise} The wait result.
- */
- function scheduleWait(condition, opt_timeout, opt_message) {
- var msg = opt_message || '';
- // It's not possible to hook into when the wait itself is scheduled, so
- // we record each iteration of the wait loop.
- var count = 0;
- return promise.controlFlow().wait(function() {
- flowHistory.push((count++) + ': ' + msg);
- return condition();
- }, opt_timeout, msg);
- }
-
- function asyncRun(fn, opt_self) {
- NativePromise.resolve().then(() => fn.call(opt_self));
- }
-
- function assertFlowHistory(var_args) {
- var expected = Array.prototype.slice.call(arguments, 0);
- assert.deepEqual(expected, flowHistory);
- }
-
- function assertMessages(var_args) {
- var expected = Array.prototype.slice.call(arguments, 0);
- assert.deepEqual(expected, messages);
- }
-
- function assertingMessages(var_args) {
- var args = Array.prototype.slice.call(arguments, 0);
- return () => assertMessages.apply(null, args);
- }
-
- function assertFlowIs(flow) {
- assert.equal(flow, promise.controlFlow());
- }
-
- describe('testScheduling', function() {
- it('aSimpleFunction', function() {
- schedule('go');
- return waitForIdle().then(function() {
- assertFlowHistory('go');
- });
- });
-
- it('aSimpleFunctionWithANonPromiseReturnValue', function() {
- schedule('go', 123).then(function(value) {
- assert.equal(123, value);
- });
- return waitForIdle().then(function() {
- assertFlowHistory('go');
- });
+ afterEach(function tearDown() {
+ flow.removeAllListeners(
+ promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
+ assert.deepEqual([], uncaughtExceptions,
+ 'There were uncaught exceptions');
+ flow.reset();
+ promise.LONG_STACK_TRACES = false;
});
- it('aSimpleSequence', function() {
- schedule('a');
- schedule('b');
- schedule('c');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c');
- });
- });
+ function onUncaughtException(e) {
+ uncaughtExceptions.push(e);
+ }
- it('invokesCallbacksWhenTaskIsDone', function() {
- var d = new promise.Deferred();
- var called = false;
- var done = schedule('a', d.promise).then(function(value) {
- called = true;
- assert.equal(123, value);
- });
- return timeout(5).then(function() {
- assert.ok(!called);
- d.fulfill(123);
- return done;
- }).
- then(function() {
- assertFlowHistory('a');
+ function defer() {
+ let d = {};
+ let promise = new Promise((resolve, reject) => {
+ Object.assign(d, {resolve, reject});
});
- });
-
- it('blocksUntilPromiseReturnedByTaskIsResolved', function() {
- var done = promise.defer();
- schedulePush('a', done.promise);
- schedulePush('b');
- setTimeout(function() {
- done.fulfill();
- messages.push('c');
- }, 25);
- return waitForIdle().then(assertingMessages('a', 'c', 'b'));
- });
+ d.promise = promise;
+ return d;
+ }
- it('waitsForReturnedPromisesToResolve', function() {
- var d1 = new promise.Deferred();
- var d2 = new promise.Deferred();
-
- var callback = sinon.spy();
- schedule('a', d1.promise).then(callback);
-
- return timeout(5).then(function() {
- assert(!callback.called);
- d1.fulfill(d2.promise);
- return timeout(5);
- }).then(function() {
- assert(!callback.called);
- d2.fulfill('fluffy bunny');
- return waitForIdle();
- }).then(function() {
- assert(callback.called);
- assert.equal('fluffy bunny', callback.getCall(0).args[0]);
- assertFlowHistory('a');
+ function waitForAbort(opt_flow) {
+ var theFlow = opt_flow || flow;
+ theFlow.removeAllListeners(
+ promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
+ return new NativePromise(function(fulfill, reject) {
+ theFlow.once(promise.ControlFlow.EventType.IDLE, function() {
+ reject(Error('expected flow to report an unhandled error'));
+ });
+ theFlow.once(
+ promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
+ fulfill);
});
- });
+ }
- it('executesTasksInAFutureTurnAfterTheyAreScheduled', function() {
+ function waitForIdle(opt_flow) {
+ var theFlow = opt_flow || flow;
+ return new NativePromise(function(fulfill, reject) {
+ theFlow.once(promise.ControlFlow.EventType.IDLE, fulfill);
+ theFlow.once(
+ promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, reject);
+ });
+ }
+
+ function timeout(ms) {
+ return new NativePromise(function(fulfill) {
+ setTimeout(fulfill, ms);
+ });
+ }
+
+
+ function schedule(msg, opt_return) {
+ return scheduleAction(msg, function() {
+ return opt_return;
+ });
+ }
+
+ /**
+ * @param {string} value The value to push.
+ * @param {promise.Promise=} opt_taskPromise Promise to return from
+ * the task.
+ * @return {!promise.Promise} The result.
+ */
+ function schedulePush(value, opt_taskPromise) {
+ return scheduleAction(value, function() {
+ messages.push(value);
+ return opt_taskPromise;
+ });
+ }
+
+ /**
+ * @param {string} msg Debug message.
+ * @param {!Function} actionFn The function.
+ * @return {!promise.Promise} The function result.
+ */
+ function scheduleAction(msg, actionFn) {
+ return promise.controlFlow().execute(function() {
+ flowHistory.push(msg);
+ return actionFn();
+ }, msg);
+ }
+
+ /**
+ * @param {!Function} condition The condition function.
+ * @param {number=} opt_timeout The timeout.
+ * @param {string=} opt_message Optional message.
+ * @return {!promise.Promise} The wait result.
+ */
+ function scheduleWait(condition, opt_timeout, opt_message) {
+ var msg = opt_message || '';
+ // It's not possible to hook into when the wait itself is scheduled, so
+ // we record each iteration of the wait loop.
var count = 0;
- function incr() { count++; }
-
- scheduleAction('', incr);
- assert.equal(0, count);
- return waitForIdle().then(function() {
- assert.equal(1, count);
+ return promise.controlFlow().wait(function() {
+ flowHistory.push((count++) + ': ' + msg);
+ return condition();
+ }, opt_timeout, msg);
+ }
+
+ function asyncRun(fn, opt_self) {
+ NativePromise.resolve().then(() => fn.call(opt_self));
+ }
+
+ function assertFlowHistory(var_args) {
+ var expected = Array.prototype.slice.call(arguments, 0);
+ assert.deepEqual(expected, flowHistory);
+ }
+
+ function assertMessages(var_args) {
+ var expected = Array.prototype.slice.call(arguments, 0);
+ assert.deepEqual(expected, messages);
+ }
+
+ function assertingMessages(var_args) {
+ var args = Array.prototype.slice.call(arguments, 0);
+ return () => assertMessages.apply(null, args);
+ }
+
+ function assertFlowIs(flow) {
+ assert.equal(flow, promise.controlFlow());
+ }
+
+ describe('testScheduling', function() {
+ it('aSimpleFunction', function() {
+ schedule('go');
+ return waitForIdle().then(function() {
+ assertFlowHistory('go');
+ });
});
- });
- it('executesOneTaskPerTurnOfTheEventLoop', function() {
- var order = [];
- function go() {
- order.push(order.length / 2);
- asyncRun(function() {
- order.push('-');
+ it('aSimpleFunctionWithANonPromiseReturnValue', function() {
+ schedule('go', 123).then(function(value) {
+ assert.equal(123, value);
});
- }
-
- scheduleAction('', go);
- scheduleAction('', go);
- return waitForIdle().then(function() {
- assert.deepEqual([0, '-', 1, '-'], order);
- })
- });
+ return waitForIdle().then(function() {
+ assertFlowHistory('go');
+ });
+ });
- it('firstScheduledTaskIsWithinACallback', function() {
- promise.fulfilled().then(function() {
+ it('aSimpleSequence', function() {
schedule('a');
schedule('b');
schedule('c');
- }).then(function() {
- assertFlowHistory('a', 'b', 'c');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c');
+ });
});
- return waitForIdle();
- });
- it('newTasksAddedWhileWaitingOnTaskReturnedPromise1', function() {
- scheduleAction('a', function() {
- var d = promise.defer();
- setTimeout(function() {
- schedule('c');
- d.fulfill();
- }, 10);
- return d.promise;
- });
- schedule('b');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c');
+ it('invokesCallbacksWhenTaskIsDone', function() {
+ var d = new promise.Deferred();
+ var called = false;
+ var done = schedule('a', d.promise).then(function(value) {
+ called = true;
+ assert.equal(123, value);
+ });
+ return timeout(5).then(function() {
+ assert.ok(!called);
+ d.fulfill(123);
+ return done;
+ }).
+ then(function() {
+ assertFlowHistory('a');
+ });
});
- });
- it('newTasksAddedWhileWaitingOnTaskReturnedPromise2', function() {
- scheduleAction('a', function() {
- var d = promise.defer();
+ it('blocksUntilPromiseReturnedByTaskIsResolved', function() {
+ var done = promise.defer();
+ schedulePush('a', done.promise);
+ schedulePush('b');
setTimeout(function() {
- schedule('c');
- asyncRun(d.fulfill);
- }, 10);
- return d.promise;
- });
- schedule('b');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'c', 'b');
+ done.fulfill();
+ messages.push('c');
+ }, 25);
+ return waitForIdle().then(assertingMessages('a', 'c', 'b'));
});
- });
- });
- describe('testFraming', function() {
- it('callbacksRunInANewFrame', function() {
- schedule('a').then(function() {
- schedule('c');
+ it('waitsForReturnedPromisesToResolve', function() {
+ var d1 = new promise.Deferred();
+ var d2 = new promise.Deferred();
+
+ var callback = sinon.spy();
+ schedule('a', d1.promise).then(callback);
+
+ return timeout(5).then(function() {
+ assert(!callback.called);
+ d1.fulfill(d2.promise);
+ return timeout(5);
+ }).then(function() {
+ assert(!callback.called);
+ d2.fulfill('fluffy bunny');
+ return waitForIdle();
+ }).then(function() {
+ assert(callback.called);
+ assert.equal('fluffy bunny', callback.getCall(0).args[0]);
+ assertFlowHistory('a');
+ });
});
- schedule('b');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'c', 'b');
+
+ it('executesTasksInAFutureTurnAfterTheyAreScheduled', function() {
+ var count = 0;
+ function incr() { count++; }
+
+ scheduleAction('', incr);
+ assert.equal(0, count);
+ return waitForIdle().then(function() {
+ assert.equal(1, count);
+ });
});
- });
- it('lotsOfNesting', function() {
- schedule('a').then(function() {
- schedule('c').then(function() {
- schedule('e').then(function() {
- schedule('g');
+ it('executesOneTaskPerTurnOfTheEventLoop', function() {
+ var order = [];
+ function go() {
+ order.push(order.length / 2);
+ asyncRun(function() {
+ order.push('-');
});
- schedule('f');
- });
- schedule('d');
+ }
+
+ scheduleAction('', go);
+ scheduleAction('', go);
+ return waitForIdle().then(function() {
+ assert.deepEqual([0, '-', 1, '-'], order);
+ })
});
- schedule('b');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'c', 'e', 'g', 'f', 'd', 'b');
+ it('firstScheduledTaskIsWithinACallback', function() {
+ promise.fulfilled().then(function() {
+ schedule('a');
+ schedule('b');
+ schedule('c');
+ }).then(function() {
+ assertFlowHistory('a', 'b', 'c');
+ });
+ return waitForIdle();
});
- });
- it('callbackReturnsPromiseThatDependsOnATask_1', function() {
- schedule('a').then(function() {
+ it('newTasksAddedWhileWaitingOnTaskReturnedPromise1', function() {
+ scheduleAction('a', function() {
+ var d = promise.defer();
+ setTimeout(function() {
+ schedule('c');
+ d.fulfill();
+ }, 10);
+ return d.promise;
+ });
schedule('b');
- return promise.delayed(5).then(function() {
- return schedule('c');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c');
});
});
- schedule('d');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c', 'd');
+ it('newTasksAddedWhileWaitingOnTaskReturnedPromise2', function() {
+ scheduleAction('a', function() {
+ var d = promise.defer();
+ setTimeout(function() {
+ schedule('c');
+ asyncRun(d.fulfill);
+ }, 10);
+ return d.promise;
+ });
+ schedule('b');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'c', 'b');
+ });
});
});
- it('callbackReturnsPromiseThatDependsOnATask_2', function() {
- schedule('a').then(function() {
+ describe('testFraming', function() {
+ it('callbacksRunInANewFrame', function() {
+ schedule('a').then(function() {
+ schedule('c');
+ });
schedule('b');
- return promise.delayed(5).
- then(function() { return promise.delayed(5) }).
- then(function() { return promise.delayed(5) }).
- then(function() { return promise.delayed(5) }).
- then(function() { return schedule('c'); });
- });
- schedule('d');
-
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c', 'd');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'c', 'b');
+ });
});
- });
- it('eachCallbackWaitsForAllScheduledTasksToComplete', function() {
- schedule('a').
- then(function() {
- schedule('b');
- schedule('c');
- }).
- then(function() {
- schedule('d');
+ it('lotsOfNesting', function() {
+ schedule('a').then(function() {
+ schedule('c').then(function() {
+ schedule('e').then(function() {
+ schedule('g');
+ });
+ schedule('f');
});
- schedule('e');
+ schedule('d');
+ });
+ schedule('b');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c', 'd', 'e');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'c', 'e', 'g', 'f', 'd', 'b');
+ });
});
- });
- it('eachCallbackWaitsForReturnTasksToComplete', function() {
- schedule('a').
- then(function() {
- schedule('b');
+ it('callbackReturnsPromiseThatDependsOnATask_1', function() {
+ schedule('a').then(function() {
+ schedule('b');
+ return promise.delayed(5).then(function() {
return schedule('c');
- }).
- then(function() {
- schedule('d');
});
- schedule('e');
+ });
+ schedule('d');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c', 'd', 'e');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c', 'd');
+ });
});
- });
- it('callbacksOnAResolvedPromiseInsertIntoTheCurrentFlow', function() {
- promise.fulfilled().then(function() {
- schedule('b');
- });
- schedule('a');
+ it('callbackReturnsPromiseThatDependsOnATask_2', function() {
+ schedule('a').then(function() {
+ schedule('b');
+ return promise.delayed(5).
+ then(function() { return promise.delayed(5) }).
+ then(function() { return promise.delayed(5) }).
+ then(function() { return promise.delayed(5) }).
+ then(function() { return schedule('c'); });
+ });
+ schedule('d');
- return waitForIdle().then(function() {
- assertFlowHistory('b', 'a');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c', 'd');
+ });
});
- });
- it('callbacksInterruptTheFlowWhenPromiseIsResolved', function() {
- schedule('a').then(function() {
- schedule('c');
- });
- schedule('b');
+ it('eachCallbackWaitsForAllScheduledTasksToComplete', function() {
+ schedule('a').
+ then(function() {
+ schedule('b');
+ schedule('c');
+ }).
+ then(function() {
+ schedule('d');
+ });
+ schedule('e');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'c', 'b');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c', 'd', 'e');
+ });
});
- });
- it('allCallbacksInAFrameAreScheduledWhenPromiseIsResolved', function() {
- var a = schedule('a');
- a.then(function() { schedule('b'); });
- schedule('c');
- a.then(function() { schedule('d'); });
- schedule('e');
+ it('eachCallbackWaitsForReturnTasksToComplete', function() {
+ schedule('a').
+ then(function() {
+ schedule('b');
+ return schedule('c');
+ }).
+ then(function() {
+ schedule('d');
+ });
+ schedule('e');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c', 'd', 'e');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c', 'd', 'e');
+ });
});
- });
- it('tasksScheduledInInActiveFrameDoNotGetPrecedence', function() {
- var d = promise.fulfilled();
- schedule('a');
- schedule('b');
- d.then(function() { schedule('c'); });
+ it('callbacksOnAResolvedPromiseInsertIntoTheCurrentFlow', function() {
+ promise.fulfilled().then(function() {
+ schedule('b');
+ });
+ schedule('a');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c');
+ return waitForIdle().then(function() {
+ assertFlowHistory('b', 'a');
+ });
});
- });
- it('tasksScheduledInAFrameGetPrecedence_1', function() {
- var a = schedule('a');
- schedule('b').then(function() {
- a.then(function() {
+ it('callbacksInterruptTheFlowWhenPromiseIsResolved', function() {
+ schedule('a').then(function() {
schedule('c');
- schedule('d');
- });
- var e = schedule('e');
- a.then(function() {
- schedule('f');
- e.then(function() {
- schedule('g');
- });
- schedule('h');
});
- schedule('i');
- });
- schedule('j');
+ schedule('b');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'c', 'b');
+ });
});
- });
- });
- describe('testErrorHandling', function() {
- it('thrownErrorsArePassedToTaskErrback', function() {
- scheduleAction('function that throws', throwStubError).
- then(fail, assertIsStubError);
- return waitForIdle();
- });
+ it('allCallbacksInAFrameAreScheduledWhenPromiseIsResolved', function() {
+ var a = schedule('a');
+ a.then(function() { schedule('b'); });
+ schedule('c');
+ a.then(function() { schedule('d'); });
+ schedule('e');
- it('thrownErrorsPropagateThroughPromiseChain', function() {
- scheduleAction('function that throws', throwStubError).
- then(fail).
- then(fail, assertIsStubError);
- return waitForIdle();
- });
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c', 'd', 'e');
+ });
+ });
- it('catchesErrorsFromFailedTasksInAFrame', function() {
- schedule('a').then(function() {
+ it('tasksScheduledInInActiveFrameDoNotGetPrecedence', function() {
+ var d = promise.fulfilled();
+ schedule('a');
schedule('b');
- scheduleAction('function that throws', throwStubError);
- }).
- then(fail, assertIsStubError);
- return waitForIdle();
- });
+ d.then(function() { schedule('c'); });
- it('abortsIfOnlyTaskReturnsAnUnhandledRejection', function() {
- scheduleAction('function that returns rejected promise', function() {
- return promise.rejected(new StubError);
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c');
+ });
});
- return waitForAbort().then(assertIsStubError);
- });
- it('abortsIfThereIsAnUnhandledRejection', function() {
- promise.rejected(new StubError);
- schedule('this should not run');
- return waitForAbort().
- then(assertIsStubError).
- then(function() {
- assertFlowHistory(/* none */);
- });
- });
-
- it('abortsSequenceIfATaskFails', function() {
- schedule('a');
- schedule('b');
- scheduleAction('c', throwStubError);
- schedule('d'); // Should never execute.
-
- return waitForAbort().
- then(assertIsStubError).
- then(function() {
- assertFlowHistory('a', 'b', 'c');
+ it('tasksScheduledInAFrameGetPrecedence_1', function() {
+ var a = schedule('a');
+ schedule('b').then(function() {
+ a.then(function() {
+ schedule('c');
+ schedule('d');
});
- });
-
- it('abortsFromUnhandledFramedTaskFailures_1', function() {
- schedule('outer task').then(function() {
- scheduleAction('inner task', throwStubError);
- });
- schedule('this should not run');
- return waitForAbort().
- then(assertIsStubError).
- then(function() {
- assertFlowHistory('outer task', 'inner task');
+ var e = schedule('e');
+ a.then(function() {
+ schedule('f');
+ e.then(function() {
+ schedule('g');
+ });
+ schedule('h');
});
- });
+ schedule('i');
+ });
+ schedule('j');
- it('abortsFromUnhandledFramedTaskFailures_2', function() {
- schedule('a').then(function() {
- schedule('b').then(function() {
- scheduleAction('c', throwStubError);
- // This should not execute.
- schedule('d');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j');
});
});
-
- return waitForAbort().
- then(assertIsStubError).
- then(function() {
- assertFlowHistory('a', 'b', 'c');
- });
});
- it('abortsWhenErrorBubblesUpFromFullyResolvingAnObject', function() {
- var callback = sinon.spy();
+ describe('testErrorHandling', function() {
+ it('thrownErrorsArePassedToTaskErrback', function() {
+ scheduleAction('function that throws', throwStubError).
+ then(fail, assertIsStubError);
+ return waitForIdle();
+ });
- scheduleAction('', function() {
- var obj = {'foo': promise.rejected(new StubError)};
- return promise.fullyResolved(obj).then(callback);
+ it('thrownErrorsPropagateThroughPromiseChain', function() {
+ scheduleAction('function that throws', throwStubError).
+ then(fail).
+ then(fail, assertIsStubError);
+ return waitForIdle();
});
- return waitForAbort().
- then(assertIsStubError).
- then(() => assert(!callback.called));
- });
+ it('catchesErrorsFromFailedTasksInAFrame', function() {
+ schedule('a').then(function() {
+ schedule('b');
+ scheduleAction('function that throws', throwStubError);
+ }).
+ then(fail, assertIsStubError);
+ return waitForIdle();
+ });
- it('abortsWhenErrorBubblesUpFromFullyResolvingAnObject_withCallback', function() {
- var callback1 = sinon.spy();
- var callback2 = sinon.spy();
+ it('abortsIfOnlyTaskReturnsAnUnhandledRejection', function() {
+ scheduleAction('function that returns rejected promise', function() {
+ return promise.rejected(new StubError);
+ });
+ return waitForAbort().then(assertIsStubError);
+ });
- scheduleAction('', function() {
- var obj = {'foo': promise.rejected(new StubError)};
- return promise.fullyResolved(obj).then(callback1);
- }).then(callback2);
+ it('abortsIfThereIsAnUnhandledRejection', function() {
+ promise.rejected(new StubError);
+ schedule('this should not run');
+ return waitForAbort().
+ then(assertIsStubError).
+ then(function() {
+ assertFlowHistory(/* none */);
+ });
+ });
- return waitForAbort().
- then(assertIsStubError).
- then(() => assert(!callback1.called)).
- then(() => assert(!callback2.called));
- });
+ it('abortsSequenceIfATaskFails', function() {
+ schedule('a');
+ schedule('b');
+ scheduleAction('c', throwStubError);
+ schedule('d'); // Should never execute.
- it('canCatchErrorsFromNestedTasks', function() {
- var errback = sinon.spy();
- schedule('a').
- then(function() {
- return scheduleAction('b', throwStubError);
- }).
- catch(errback);
- return waitForIdle().then(function() {
- assert(errback.called);
- assertIsStubError(errback.getCall(0).args[0]);
+ return waitForAbort().
+ then(assertIsStubError).
+ then(function() {
+ assertFlowHistory('a', 'b', 'c');
+ });
});
- });
- it('nestedCommandFailuresCanBeCaughtAndSuppressed', function() {
- var errback = sinon.spy();
- schedule('a').then(function() {
- return schedule('b').then(function() {
- return schedule('c').then(function() {
- throw new StubError;
- });
+ it('abortsFromUnhandledFramedTaskFailures_1', function() {
+ schedule('outer task').then(function() {
+ scheduleAction('inner task', throwStubError);
});
- }).catch(errback);
- schedule('d');
- return waitForIdle().
- then(function() {
- assert(errback.called);
- assertIsStubError(errback.getCall(0).args[0]);
- assertFlowHistory('a', 'b', 'c', 'd');
- });
- });
-
- it('aTaskWithAnUnhandledPromiseRejection', function() {
- schedule('a');
- scheduleAction('sub-tasks', function() {
- promise.rejected(new StubError);
+ schedule('this should not run');
+ return waitForAbort().
+ then(assertIsStubError).
+ then(function() {
+ assertFlowHistory('outer task', 'inner task');
+ });
});
- schedule('should never run');
- return waitForAbort().
- then(assertIsStubError).
- then(function() {
- assertFlowHistory('a', 'sub-tasks');
+ it('abortsFromUnhandledFramedTaskFailures_2', function() {
+ schedule('a').then(function() {
+ schedule('b').then(function() {
+ scheduleAction('c', throwStubError);
+ // This should not execute.
+ schedule('d');
});
- });
+ });
- it('aTaskThatReutrnsARejectedPromise', function() {
- schedule('a');
- scheduleAction('sub-tasks', function() {
- return promise.rejected(new StubError);
+ return waitForAbort().
+ then(assertIsStubError).
+ then(function() {
+ assertFlowHistory('a', 'b', 'c');
+ });
});
- schedule('should never run');
-
- return waitForAbort().
- then(assertIsStubError).
- then(function() {
- assertFlowHistory('a', 'sub-tasks');
- });
- });
- it('discardsSubtasksIfTaskThrows', function() {
- var pair = callbackPair(null, assertIsStubError);
- scheduleAction('a', function() {
- schedule('b');
- schedule('c');
- throwStubError();
- }).then(pair.callback, pair.errback);
- schedule('d');
+ it('abortsWhenErrorBubblesUpFromFullyResolvingAnObject', function() {
+ var callback = sinon.spy();
- return waitForIdle().
- then(pair.assertErrback).
- then(function() {
- assertFlowHistory('a', 'd');
- });
- });
+ scheduleAction('', function() {
+ var obj = {'foo': promise.rejected(new StubError)};
+ return promise.fullyResolved(obj).then(callback);
+ });
- it('discardsRemainingSubtasksIfASubtaskFails', function() {
- var pair = callbackPair(null, assertIsStubError);
- scheduleAction('a', function() {
- schedule('b');
- scheduleAction('c', throwStubError);
- schedule('d');
- }).then(pair.callback, pair.errback);
- schedule('e');
+ return waitForAbort().
+ then(assertIsStubError).
+ then(() => assert(!callback.called));
+ });
- return waitForIdle().
- then(pair.assertErrback).
- then(function() {
- assertFlowHistory('a', 'b', 'c', 'e');
- });
- });
- });
+ it('abortsWhenErrorBubblesUpFromFullyResolvingAnObject_withCallback', function() {
+ var callback1 = sinon.spy();
+ var callback2 = sinon.spy();
- describe('testTryModelingFinally', function() {
- it('happyPath', function() {
- /* Model:
- try {
- doFoo();
- doBar();
- } finally {
- doBaz();
- }
- */
- schedulePush('foo').
- then(() => schedulePush('bar')).
- finally(() => schedulePush('baz'));
- return waitForIdle().then(assertingMessages('foo', 'bar', 'baz'));
- });
+ scheduleAction('', function() {
+ var obj = {'foo': promise.rejected(new StubError)};
+ return promise.fullyResolved(obj).then(callback1);
+ }).then(callback2);
- it('firstTryFails', function() {
- /* Model:
- try {
- doFoo();
- doBar();
- } finally {
- doBaz();
- }
- */
-
- scheduleAction('doFoo and throw', function() {
- messages.push('foo');
- throw new StubError;
- }).
- then(function() { schedulePush('bar'); }).
- finally(function() { schedulePush('baz'); });
+ return waitForAbort().
+ then(assertIsStubError).
+ then(() => assert(!callback1.called)).
+ then(() => assert(!callback2.called));
+ });
- return waitForAbort().
- then(assertIsStubError).
- then(assertingMessages('foo', 'baz'));
- });
+ it('canCatchErrorsFromNestedTasks', function() {
+ var errback = sinon.spy();
+ schedule('a').
+ then(function() {
+ return scheduleAction('b', throwStubError);
+ }).
+ catch(errback);
+ return waitForIdle().then(function() {
+ assert(errback.called);
+ assertIsStubError(errback.getCall(0).args[0]);
+ });
+ });
- it('secondTryFails', function() {
- /* Model:
- try {
- doFoo();
- doBar();
- } finally {
- doBaz();
- }
- */
-
- schedulePush('foo').
- then(function() {
- return scheduleAction('doBar and throw', function() {
- messages.push('bar');
+ it('nestedCommandFailuresCanBeCaughtAndSuppressed', function() {
+ var errback = sinon.spy();
+ schedule('a').then(function() {
+ return schedule('b').then(function() {
+ return schedule('c').then(function() {
throw new StubError;
});
- }).
- finally(function() {
- return schedulePush('baz');
});
- return waitForAbort().
- then(assertIsStubError).
- then(assertingMessages('foo', 'bar', 'baz'));
- });
- });
-
- describe('testTaskCallbacksInterruptFlow', function() {
- it('(base case)', function() {
- schedule('a').then(function() {
- schedule('b');
- });
- schedule('c');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c');
+ }).catch(errback);
+ schedule('d');
+ return waitForIdle().
+ then(function() {
+ assert(errback.called);
+ assertIsStubError(errback.getCall(0).args[0]);
+ assertFlowHistory('a', 'b', 'c', 'd');
+ });
});
- });
- it('taskDependsOnImmediatelyFulfilledPromise', function() {
- scheduleAction('a', function() {
- return promise.fulfilled();
- }).then(function() {
- schedule('b');
- });
- schedule('c');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c');
- });
- });
+ it('aTaskWithAnUnhandledPromiseRejection', function() {
+ schedule('a');
+ scheduleAction('sub-tasks', function() {
+ promise.rejected(new StubError);
+ });
+ schedule('should never run');
- it('taskDependsOnPreviouslyFulfilledPromise', function() {
- var aPromise = promise.fulfilled(123);
- scheduleAction('a', function() {
- return aPromise;
- }).then(function(value) {
- assert.equal(123, value);
- schedule('b');
- });
- schedule('c');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c');
+ return waitForAbort().
+ then(assertIsStubError).
+ then(function() {
+ assertFlowHistory('a', 'sub-tasks');
+ });
});
- });
- it('taskDependsOnAsyncPromise', function() {
- scheduleAction('a', function() {
- return promise.delayed(25);
- }).then(function() {
- schedule('b');
- });
- schedule('c');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c');
- });
- });
+ it('aTaskThatReutrnsARejectedPromise', function() {
+ schedule('a');
+ scheduleAction('sub-tasks', function() {
+ return promise.rejected(new StubError);
+ });
+ schedule('should never run');
- it('promiseChainedToTaskInterruptFlow', function() {
- schedule('a').then(function() {
- return promise.fulfilled();
- }).then(function() {
- return promise.fulfilled();
- }).then(function() {
- schedule('b');
- });
- schedule('c');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c');
+ return waitForAbort().
+ then(assertIsStubError).
+ then(function() {
+ assertFlowHistory('a', 'sub-tasks');
+ });
});
- });
- it('nestedTaskCallbacksInterruptFlowWhenResolved', function() {
- schedule('a').then(function() {
- schedule('b').then(function() {
+ it('discardsSubtasksIfTaskThrows', function() {
+ var pair = callbackPair(null, assertIsStubError);
+ scheduleAction('a', function() {
+ schedule('b');
schedule('c');
- });
- });
- schedule('d');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c', 'd');
+ throwStubError();
+ }).then(pair.callback, pair.errback);
+ schedule('d');
+
+ return waitForIdle().
+ then(pair.assertErrback).
+ then(function() {
+ assertFlowHistory('a', 'd');
+ });
});
- });
- });
- describe('testDelayedNesting', function() {
+ it('discardsRemainingSubtasksIfASubtaskFails', function() {
+ var pair = callbackPair(null, assertIsStubError);
+ scheduleAction('a', function() {
+ schedule('b');
+ scheduleAction('c', throwStubError);
+ schedule('d');
+ }).then(pair.callback, pair.errback);
+ schedule('e');
- it('1', function() {
- var a = schedule('a');
- schedule('b').then(function() {
- a.then(function() { schedule('c'); });
- schedule('d');
+ return waitForIdle().
+ then(pair.assertErrback).
+ then(function() {
+ assertFlowHistory('a', 'b', 'c', 'e');
+ });
});
- schedule('e');
+ });
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c', 'd', 'e');
+ describe('testTryModelingFinally', function() {
+ it('happyPath', function() {
+ /* Model:
+ try {
+ doFoo();
+ doBar();
+ } finally {
+ doBaz();
+ }
+ */
+ schedulePush('foo').
+ then(() => schedulePush('bar')).
+ finally(() => schedulePush('baz'));
+ return waitForIdle().then(assertingMessages('foo', 'bar', 'baz'));
+ });
+
+ it('firstTryFails', function() {
+ /* Model:
+ try {
+ doFoo();
+ doBar();
+ } finally {
+ doBaz();
+ }
+ */
+
+ scheduleAction('doFoo and throw', function() {
+ messages.push('foo');
+ throw new StubError;
+ }).
+ then(function() { schedulePush('bar'); }).
+ finally(function() { schedulePush('baz'); });
+
+ return waitForAbort().
+ then(assertIsStubError).
+ then(assertingMessages('foo', 'baz'));
+ });
+
+ it('secondTryFails', function() {
+ /* Model:
+ try {
+ doFoo();
+ doBar();
+ } finally {
+ doBaz();
+ }
+ */
+
+ schedulePush('foo').
+ then(function() {
+ return scheduleAction('doBar and throw', function() {
+ messages.push('bar');
+ throw new StubError;
+ });
+ }).
+ finally(function() {
+ return schedulePush('baz');
+ });
+ return waitForAbort().
+ then(assertIsStubError).
+ then(assertingMessages('foo', 'bar', 'baz'));
});
});
- it('2', function() {
- var a = schedule('a');
- schedule('b').then(function() {
- a.then(function() { schedule('c'); });
- schedule('d');
- a.then(function() { schedule('e'); });
+ describe('testTaskCallbacksInterruptFlow', function() {
+ it('(base case)', function() {
+ schedule('a').then(function() {
+ schedule('b');
+ });
+ schedule('c');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c');
+ });
});
- schedule('f');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f');
+ it('taskDependsOnImmediatelyFulfilledPromise', function() {
+ scheduleAction('a', function() {
+ return promise.fulfilled();
+ }).then(function() {
+ schedule('b');
+ });
+ schedule('c');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c');
+ });
});
- });
- it('3', function() {
- var a = schedule('a');
- schedule('b').then(function() {
- a.then(function() { schedule('c'); });
- a.then(function() { schedule('d'); });
+ it('taskDependsOnPreviouslyFulfilledPromise', function() {
+ var aPromise = promise.fulfilled(123);
+ scheduleAction('a', function() {
+ return aPromise;
+ }).then(function(value) {
+ assert.equal(123, value);
+ schedule('b');
+ });
+ schedule('c');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c');
+ });
});
- schedule('e');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c', 'd', 'e');
+ it('taskDependsOnAsyncPromise', function() {
+ scheduleAction('a', function() {
+ return promise.delayed(25);
+ }).then(function() {
+ schedule('b');
+ });
+ schedule('c');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c');
+ });
});
- });
- it('4', function() {
- var a = schedule('a');
- schedule('b').then(function() {
- a.then(function() { schedule('c'); }).then(function() {
- schedule('d');
+ it('promiseChainedToTaskInterruptFlow', function() {
+ schedule('a').then(function() {
+ return promise.fulfilled();
+ }).then(function() {
+ return promise.fulfilled();
+ }).then(function() {
+ schedule('b');
+ });
+ schedule('c');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c');
});
- a.then(function() { schedule('e'); });
});
- schedule('f');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f');
+ it('nestedTaskCallbacksInterruptFlowWhenResolved', function() {
+ schedule('a').then(function() {
+ schedule('b').then(function() {
+ schedule('c');
+ });
+ });
+ schedule('d');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c', 'd');
+ });
});
});
- it('5', function() {
- var a = schedule('a');
- schedule('b').then(function() {
- var c;
- a.then(function() { c = schedule('c'); }).then(function() {
+ describe('testDelayedNesting', function() {
+
+ it('1', function() {
+ var a = schedule('a');
+ schedule('b').then(function() {
+ a.then(function() { schedule('c'); });
schedule('d');
- a.then(function() { schedule('e'); });
- c.then(function() { schedule('f'); });
- schedule('g');
});
- a.then(function() { schedule('h'); });
- });
- schedule('i');
-
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i');
- });
- });
- });
+ schedule('e');
- describe('testWaiting', function() {
- it('onAConditionThatIsAlwaysTrue', function() {
- scheduleWait(function() { return true;}, 0, 'waiting on true');
- return waitForIdle().then(function() {
- assertFlowHistory('0: waiting on true');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c', 'd', 'e');
+ });
});
- });
- it('aSimpleCountingCondition', function() {
- var count = 0;
- scheduleWait(function() {
- return ++count == 3;
- }, 100, 'counting to 3');
+ it('2', function() {
+ var a = schedule('a');
+ schedule('b').then(function() {
+ a.then(function() { schedule('c'); });
+ schedule('d');
+ a.then(function() { schedule('e'); });
+ });
+ schedule('f');
- return waitForIdle().then(function() {
- assert.equal(3, count);
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f');
+ });
});
- });
-
- it('aConditionThatReturnsAPromise', function() {
- var d = new promise.Deferred();
- var count = 0;
- scheduleWait(function() {
- count += 1;
- return d.promise;
- }, 0, 'waiting for promise');
+ it('3', function() {
+ var a = schedule('a');
+ schedule('b').then(function() {
+ a.then(function() { schedule('c'); });
+ a.then(function() { schedule('d'); });
+ });
+ schedule('e');
- return timeout(50).then(function() {
- assert.equal(1, count);
- d.fulfill(123);
- return waitForIdle();
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c', 'd', 'e');
+ });
});
- });
- it('aConditionThatReturnsAPromise_2', function() {
- var count = 0;
- scheduleWait(function() {
- return promise.fulfilled(++count == 3);
- }, 100, 'waiting for promise');
+ it('4', function() {
+ var a = schedule('a');
+ schedule('b').then(function() {
+ a.then(function() { schedule('c'); }).then(function() {
+ schedule('d');
+ });
+ a.then(function() { schedule('e'); });
+ });
+ schedule('f');
- return waitForIdle().then(function() {
- assert.equal(3, count);
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f');
+ });
});
- });
- it('aConditionThatReturnsATaskResult', function() {
- var count = 0;
- scheduleWait(function() {
- return scheduleAction('increment count', function() {
- return ++count == 3;
+ it('5', function() {
+ var a = schedule('a');
+ schedule('b').then(function() {
+ var c;
+ a.then(function() { c = schedule('c'); }).then(function() {
+ schedule('d');
+ a.then(function() { schedule('e'); });
+ c.then(function() { schedule('f'); });
+ schedule('g');
+ });
+ a.then(function() { schedule('h'); });
});
- }, 100, 'counting to 3');
- schedule('post wait');
+ schedule('i');
- return waitForIdle().then(function() {
- assert.equal(3, count);
- assertFlowHistory(
- '0: counting to 3', 'increment count',
- '1: counting to 3', 'increment count',
- '2: counting to 3', 'increment count',
- 'post wait');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i');
+ });
});
});
- it('conditionContainsASubtask', function() {
- var count = 0;
- scheduleWait(function() {
- schedule('sub task');
- return ++count == 3;
- }, 100, 'counting to 3');
- schedule('post wait');
-
- return waitForIdle().then(function() {
- assert.equal(3, count);
- assertFlowHistory(
- '0: counting to 3', 'sub task',
- '1: counting to 3', 'sub task',
- '2: counting to 3', 'sub task',
- 'post wait');
+ describe('testWaiting', function() {
+ it('onAConditionThatIsAlwaysTrue', function() {
+ scheduleWait(function() { return true;}, 0, 'waiting on true');
+ return waitForIdle().then(function() {
+ assertFlowHistory('0: waiting on true');
+ });
});
- });
- it('cancelsWaitIfScheduledTaskFails', function() {
- var pair = callbackPair(null, assertIsStubError);
- scheduleWait(function() {
- scheduleAction('boom', throwStubError);
- schedule('this should not run');
- return true;
- }, 100, 'waiting to go boom').then(pair.callback, pair.errback);
- schedule('post wait');
+ it('aSimpleCountingCondition', function() {
+ var count = 0;
+ scheduleWait(function() {
+ return ++count == 3;
+ }, 100, 'counting to 3');
- return waitForIdle().
- then(pair.assertErrback).
- then(function() {
- assertFlowHistory(
- '0: waiting to go boom', 'boom',
- 'post wait');
- });
- });
+ return waitForIdle().then(function() {
+ assert.equal(3, count);
+ });
+ });
- it('failsIfConditionThrows', function() {
- var callbacks = callbackPair(null, assertIsStubError);
- scheduleWait(throwStubError, 0, 'goes boom').
- then(callbacks.callback, callbacks.errback);
- schedule('post wait');
+ it('aConditionThatReturnsAPromise', function() {
+ var d = new promise.Deferred();
+ var count = 0;
- return waitForIdle().
- then(callbacks.assertErrback).
- then(function() {
- assertFlowHistory('0: goes boom', 'post wait');
- });
- });
+ scheduleWait(function() {
+ count += 1;
+ return d.promise;
+ }, 0, 'waiting for promise');
- it('failsIfConditionReturnsARejectedPromise', function() {
- var callbacks = callbackPair(null, assertIsStubError);
- scheduleWait(function() {
- return promise.rejected(new StubError);
- }, 0, 'goes boom').then(callbacks.callback, callbacks.errback);
- schedule('post wait');
+ return timeout(50).then(function() {
+ assert.equal(1, count);
+ d.fulfill(123);
+ return waitForIdle();
+ });
+ });
- return waitForIdle().
- then(callbacks.assertErrback).
- then(function() {
- assertFlowHistory('0: goes boom', 'post wait');
- });
- });
+ it('aConditionThatReturnsAPromise_2', function() {
+ var count = 0;
+ scheduleWait(function() {
+ return promise.fulfilled(++count == 3);
+ }, 100, 'waiting for promise');
- it('failsIfConditionHasUnhandledRejection', function() {
- var callbacks = callbackPair(null, assertIsStubError);
- scheduleWait(function() {
- promise.controlFlow().execute(throwStubError);
- }, 0, 'goes boom').then(callbacks.callback, callbacks.errback);
- schedule('post wait');
+ return waitForIdle().then(function() {
+ assert.equal(3, count);
+ });
+ });
- return waitForIdle().
- then(callbacks.assertErrback).
- then(function() {
- assertFlowHistory('0: goes boom', 'post wait');
+ it('aConditionThatReturnsATaskResult', function() {
+ var count = 0;
+ scheduleWait(function() {
+ return scheduleAction('increment count', function() {
+ return ++count == 3;
});
- });
+ }, 100, 'counting to 3');
+ schedule('post wait');
+
+ return waitForIdle().then(function() {
+ assert.equal(3, count);
+ assertFlowHistory(
+ '0: counting to 3', 'increment count',
+ '1: counting to 3', 'increment count',
+ '2: counting to 3', 'increment count',
+ 'post wait');
+ });
+ });
- it('failsIfConditionHasAFailedSubtask', function() {
- var callbacks = callbackPair(null, assertIsStubError);
- var count = 0;
- scheduleWait(function() {
- scheduleAction('maybe throw', function() {
- if (++count == 2) {
- throw new StubError;
- }
+ it('conditionContainsASubtask', function() {
+ var count = 0;
+ scheduleWait(function() {
+ schedule('sub task');
+ return ++count == 3;
+ }, 100, 'counting to 3');
+ schedule('post wait');
+
+ return waitForIdle().then(function() {
+ assert.equal(3, count);
+ assertFlowHistory(
+ '0: counting to 3', 'sub task',
+ '1: counting to 3', 'sub task',
+ '2: counting to 3', 'sub task',
+ 'post wait');
});
- }, 100, 'waiting').then(callbacks.callback, callbacks.errback);
- schedule('post wait');
+ });
- return waitForIdle().then(function() {
- assert.equal(2, count);
- assertFlowHistory(
- '0: waiting', 'maybe throw',
- '1: waiting', 'maybe throw',
- 'post wait');
+ it('cancelsWaitIfScheduledTaskFails', function() {
+ var pair = callbackPair(null, assertIsStubError);
+ scheduleWait(function() {
+ scheduleAction('boom', throwStubError);
+ schedule('this should not run');
+ return true;
+ }, 100, 'waiting to go boom').then(pair.callback, pair.errback);
+ schedule('post wait');
+
+ return waitForIdle().
+ then(pair.assertErrback).
+ then(function() {
+ assertFlowHistory(
+ '0: waiting to go boom', 'boom',
+ 'post wait');
+ });
});
- });
- it('pollingLoopWaitsForAllScheduledTasksInCondition', function() {
- var count = 0;
- scheduleWait(function() {
- scheduleAction('increment count', function() { ++count; });
- return count >= 3;
- }, 100, 'counting to 3');
- schedule('post wait');
+ it('failsIfConditionThrows', function() {
+ var callbacks = callbackPair(null, assertIsStubError);
+ scheduleWait(throwStubError, 0, 'goes boom').
+ then(callbacks.callback, callbacks.errback);
+ schedule('post wait');
- return waitForIdle().then(function() {
- assert.equal(4, count);
- assertFlowHistory(
- '0: counting to 3', 'increment count',
- '1: counting to 3', 'increment count',
- '2: counting to 3', 'increment count',
- '3: counting to 3', 'increment count',
- 'post wait');
+ return waitForIdle().
+ then(callbacks.assertErrback).
+ then(function() {
+ assertFlowHistory('0: goes boom', 'post wait');
+ });
});
- });
- it('waitsForeverOnAZeroTimeout', function() {
- var done = false;
- setTimeout(function() {
- done = true;
- }, 150);
- var waitResult = scheduleWait(function() {
- return done;
- }, 0);
+ it('failsIfConditionReturnsARejectedPromise', function() {
+ var callbacks = callbackPair(null, assertIsStubError);
+ scheduleWait(function() {
+ return promise.rejected(new StubError);
+ }, 0, 'goes boom').then(callbacks.callback, callbacks.errback);
+ schedule('post wait');
- return timeout(75).then(function() {
- assert.ok(!done);
- return timeout(100);
- }).then(function() {
- assert.ok(done);
- return waitResult;
+ return waitForIdle().
+ then(callbacks.assertErrback).
+ then(function() {
+ assertFlowHistory('0: goes boom', 'post wait');
+ });
});
- });
- it('waitsForeverIfTimeoutOmitted', function() {
- var done = false;
- setTimeout(function() {
- done = true;
- }, 150);
- var waitResult = scheduleWait(function() {
- return done;
+ it('failsIfConditionHasUnhandledRejection', function() {
+ var callbacks = callbackPair(null, assertIsStubError);
+ scheduleWait(function() {
+ promise.controlFlow().execute(throwStubError);
+ }, 0, 'goes boom').then(callbacks.callback, callbacks.errback);
+ schedule('post wait');
+
+ return waitForIdle().
+ then(callbacks.assertErrback).
+ then(function() {
+ assertFlowHistory('0: goes boom', 'post wait');
+ });
});
- return timeout(75).then(function() {
- assert.ok(!done);
- return timeout(100);
- }).then(function() {
- assert.ok(done);
- return waitResult;
+ it('failsIfConditionHasAFailedSubtask', function() {
+ var callbacks = callbackPair(null, assertIsStubError);
+ var count = 0;
+ scheduleWait(function() {
+ scheduleAction('maybe throw', function() {
+ if (++count == 2) {
+ throw new StubError;
+ }
+ });
+ }, 100, 'waiting').then(callbacks.callback, callbacks.errback);
+ schedule('post wait');
+
+ return waitForIdle().then(function() {
+ assert.equal(2, count);
+ assertFlowHistory(
+ '0: waiting', 'maybe throw',
+ '1: waiting', 'maybe throw',
+ 'post wait');
+ });
});
- });
- it('timesOut_nonZeroTimeout', function() {
- var count = 0;
- scheduleWait(function() {
- count += 1;
- var ms = count === 2 ? 65 : 5;
- return promise.delayed(ms).then(function() {
- return false;
- });
- }, 60, 'counting to 3');
- return waitForAbort().then(function(e) {
- switch (count) {
- case 1:
- assertFlowHistory('0: counting to 3');
- break;
- case 2:
- assertFlowHistory('0: counting to 3', '1: counting to 3');
- break;
- default:
- fail('unexpected polling count: ' + count);
- }
- assert.ok(
- /^counting to 3\nWait timed out after \d+ms$/.test(e.message));
+ it('pollingLoopWaitsForAllScheduledTasksInCondition', function() {
+ var count = 0;
+ scheduleWait(function() {
+ scheduleAction('increment count', function() { ++count; });
+ return count >= 3;
+ }, 100, 'counting to 3');
+ schedule('post wait');
+
+ return waitForIdle().then(function() {
+ assert.equal(4, count);
+ assertFlowHistory(
+ '0: counting to 3', 'increment count',
+ '1: counting to 3', 'increment count',
+ '2: counting to 3', 'increment count',
+ '3: counting to 3', 'increment count',
+ 'post wait');
+ });
});
- });
- it('shouldFailIfConditionReturnsARejectedPromise', function() {
- scheduleWait(function() {
- return promise.rejected(new StubError);
- }, 100, 'returns rejected promise on first pass');
- return waitForAbort().then(assertIsStubError);
- });
+ it('waitsForeverOnAZeroTimeout', function() {
+ var done = false;
+ setTimeout(function() {
+ done = true;
+ }, 150);
+ var waitResult = scheduleWait(function() {
+ return done;
+ }, 0);
+
+ return timeout(75).then(function() {
+ assert.ok(!done);
+ return timeout(100);
+ }).then(function() {
+ assert.ok(done);
+ return waitResult;
+ });
+ });
- it('scheduleWithIntermittentWaits', function() {
- schedule('a');
- scheduleWait(function() { return true; }, 0, 'wait 1');
- schedule('b');
- scheduleWait(function() { return true; }, 0, 'wait 2');
- schedule('c');
- scheduleWait(function() { return true; }, 0, 'wait 3');
+ it('waitsForeverIfTimeoutOmitted', function() {
+ var done = false;
+ setTimeout(function() {
+ done = true;
+ }, 150);
+ var waitResult = scheduleWait(function() {
+ return done;
+ });
- return waitForIdle().then(function() {
- assertFlowHistory('a', '0: wait 1', 'b', '0: wait 2', 'c', '0: wait 3');
+ return timeout(75).then(function() {
+ assert.ok(!done);
+ return timeout(100);
+ }).then(function() {
+ assert.ok(done);
+ return waitResult;
+ });
});
- });
- it('scheduleWithIntermittentAndNestedWaits', function() {
- schedule('a');
- scheduleWait(function() { return true; }, 0, 'wait 1').
- then(function() {
- schedule('d');
- scheduleWait(function() { return true; }, 0, 'wait 2');
- schedule('e');
+ it('timesOut_nonZeroTimeout', function() {
+ var count = 0;
+ scheduleWait(function() {
+ count += 1;
+ var ms = count === 2 ? 65 : 5;
+ return promise.delayed(ms).then(function() {
+ return false;
});
- schedule('b');
- scheduleWait(function() { return true; }, 0, 'wait 3');
- schedule('c');
- scheduleWait(function() { return true; }, 0, 'wait 4');
-
- return waitForIdle().then(function() {
- assertFlowHistory(
- 'a', '0: wait 1', 'd', '0: wait 2', 'e', 'b', '0: wait 3', 'c',
- '0: wait 4');
+ }, 60, 'counting to 3');
+ return waitForAbort().then(function(e) {
+ switch (count) {
+ case 1:
+ assertFlowHistory('0: counting to 3');
+ break;
+ case 2:
+ assertFlowHistory('0: counting to 3', '1: counting to 3');
+ break;
+ default:
+ fail('unexpected polling count: ' + count);
+ }
+ assert.ok(e instanceof TimeoutError, 'Unexpected error: ' + e);
+ assert.ok(
+ /^counting to 3\nWait timed out after \d+ms$/.test(e.message));
+ });
});
- });
- it('requiresConditionToBeAPromiseOrFunction', function() {
- assert.throws(function() {
- flow.wait(1234, 0);
+ it('shouldFailIfConditionReturnsARejectedPromise', function() {
+ scheduleWait(function() {
+ return promise.rejected(new StubError);
+ }, 100, 'returns rejected promise on first pass');
+ return waitForAbort().then(assertIsStubError);
});
- flow.wait(function() { return true;}, 0);
- flow.wait(promise.fulfilled(), 0);
- return waitForIdle();
- });
- it('promiseThatDoesNotResolveBeforeTimeout', function() {
- var d = promise.defer();
- flow.wait(d.promise, 5).then(fail, function(e) {
- assert.ok(
- /Timed out waiting for promise to resolve after \d+ms/
- .test(e.message),
- 'unexpected error message: ' + e.message);
+ it('scheduleWithIntermittentWaits', function() {
+ schedule('a');
+ scheduleWait(function() { return true; }, 0, 'wait 1');
+ schedule('b');
+ scheduleWait(function() { return true; }, 0, 'wait 2');
+ schedule('c');
+ scheduleWait(function() { return true; }, 0, 'wait 3');
+
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', '0: wait 1', 'b', '0: wait 2', 'c', '0: wait 3');
+ });
});
- return waitForIdle().then(function() {
- assert.ok('Promise should not be cancelled', d.promise.isPending());
+
+ it('scheduleWithIntermittentAndNestedWaits', function() {
+ schedule('a');
+ scheduleWait(function() { return true; }, 0, 'wait 1').
+ then(function() {
+ schedule('d');
+ scheduleWait(function() { return true; }, 0, 'wait 2');
+ schedule('e');
+ });
+ schedule('b');
+ scheduleWait(function() { return true; }, 0, 'wait 3');
+ schedule('c');
+ scheduleWait(function() { return true; }, 0, 'wait 4');
+
+ return waitForIdle().then(function() {
+ assertFlowHistory(
+ 'a', '0: wait 1', 'd', '0: wait 2', 'e', 'b', '0: wait 3', 'c',
+ '0: wait 4');
+ });
});
- });
- it('unboundedWaitOnPromiseResolution', function() {
- var messages = [];
- var d = promise.defer();
- var waitResult = flow.wait(d.promise).then(function(value) {
- messages.push('b');
- assert.equal(1234, value);
+ it('requiresConditionToBeAPromiseOrFunction', function() {
+ assert.throws(function() {
+ flow.wait(1234, 0);
+ });
+ flow.wait(function() { return true;}, 0);
+ flow.wait(promise.fulfilled(), 0);
+ return waitForIdle();
});
- setTimeout(function() {
- messages.push('a');
- }, 5);
-
- timeout(10).then(function() {
- assert.deepEqual(['a'], messages);
- assert.ok(waitResult.isPending());
- d.fulfill(1234);
- return waitResult;
- }).then(function() {
- assert.deepEqual(['a', 'b'], messages);
+
+ it('promiseThatDoesNotResolveBeforeTimeout', function() {
+ var d = promise.defer();
+ flow.wait(d.promise, 5).then(fail, function(e) {
+ assert.ok(e instanceof TimeoutError, 'Unexpected error: ' + e);
+ assert.ok(
+ /Timed out waiting for promise to resolve after \d+ms/
+ .test(e.message),
+ 'unexpected error message: ' + e.message);
+ });
+ return waitForIdle();
});
- return waitForIdle();
- });
- });
+ it('unboundedWaitOnPromiseResolution', function() {
+ var messages = [];
+ var d = promise.defer();
+ var waitResult = flow.wait(d.promise).then(function(value) {
+ messages.push('b');
+ assert.equal(1234, value);
+ });
+ setTimeout(function() {
+ messages.push('a');
+ }, 5);
- describe('testSubtasks', function() {
- it('(base case)', function() {
- schedule('a');
- scheduleAction('sub-tasks', function() {
- schedule('c');
- schedule('d');
- });
- schedule('b');
+ timeout(10).then(function() {
+ assert.deepEqual(['a'], messages);
+ d.fulfill(1234);
+ return waitResult;
+ }).then(function() {
+ assert.deepEqual(['a', 'b'], messages);
+ });
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'sub-tasks', 'c', 'd', 'b');
+ return waitForIdle();
});
});
- it('nesting', function() {
- schedule('a');
- scheduleAction('sub-tasks', function() {
- schedule('b');
- scheduleAction('sub-sub-tasks', function() {
+ describe('testSubtasks', function() {
+ it('(base case)', function() {
+ schedule('a');
+ scheduleAction('sub-tasks', function() {
schedule('c');
schedule('d');
});
- schedule('e');
- });
- schedule('f');
+ schedule('b');
- return waitForIdle().then(function() {
- assertFlowHistory(
- 'a', 'sub-tasks', 'b', 'sub-sub-tasks', 'c', 'd', 'e', 'f');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'sub-tasks', 'c', 'd', 'b');
+ });
});
- });
- it('taskReturnsSubTaskResult_1', function() {
- schedule('a');
- scheduleAction('sub-tasks', function() {
- return schedule('c');
- });
- schedule('b');
+ it('nesting', function() {
+ schedule('a');
+ scheduleAction('sub-tasks', function() {
+ schedule('b');
+ scheduleAction('sub-sub-tasks', function() {
+ schedule('c');
+ schedule('d');
+ });
+ schedule('e');
+ });
+ schedule('f');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'sub-tasks', 'c', 'b');
+ return waitForIdle().then(function() {
+ assertFlowHistory(
+ 'a', 'sub-tasks', 'b', 'sub-sub-tasks', 'c', 'd', 'e', 'f');
+ });
});
- });
- it('taskReturnsSubTaskResult_2', function() {
- let pair = callbackPair((value) => assert.equal(123, value));
- schedule('a');
- schedule('sub-tasks', promise.fulfilled(123)).then(pair.callback);
- schedule('b');
+ it('taskReturnsSubTaskResult_1', function() {
+ schedule('a');
+ scheduleAction('sub-tasks', function() {
+ return schedule('c');
+ });
+ schedule('b');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'sub-tasks','b');
- pair.assertCallback();
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'sub-tasks', 'c', 'b');
+ });
});
- });
- it('taskReturnsPromiseThatDependsOnSubtask_1', function() {
- scheduleAction('a', function() {
- return promise.delayed(10).then(function() {
- schedule('b');
+ it('taskReturnsSubTaskResult_2', function() {
+ let pair = callbackPair((value) => assert.equal(123, value));
+ schedule('a');
+ schedule('sub-tasks', promise.fulfilled(123)).then(pair.callback);
+ schedule('b');
+
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'sub-tasks','b');
+ pair.assertCallback();
});
});
- schedule('c');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c');
- });
- });
- it('taskReturnsPromiseThatDependsOnSubtask_2', function() {
- scheduleAction('a', function() {
- return promise.fulfilled().then(function() {
- schedule('b');
+ it('taskReturnsPromiseThatDependsOnSubtask_1', function() {
+ scheduleAction('a', function() {
+ return promise.delayed(10).then(function() {
+ schedule('b');
+ });
+ });
+ schedule('c');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c');
});
});
- schedule('c');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c');
- });
- });
- it('taskReturnsPromiseThatDependsOnSubtask_3', function() {
- scheduleAction('a', function() {
- return promise.delayed(10).then(function() {
- return schedule('b');
+ it('taskReturnsPromiseThatDependsOnSubtask_2', function() {
+ scheduleAction('a', function() {
+ return promise.fulfilled().then(function() {
+ schedule('b');
+ });
+ });
+ schedule('c');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c');
});
});
- schedule('c');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c');
- });
- });
- it('taskReturnsPromiseThatDependsOnSubtask_4', function() {
- scheduleAction('a', function() {
- return promise.delayed(5).then(function() {
- return promise.delayed(5).then(function() {
+ it('taskReturnsPromiseThatDependsOnSubtask_3', function() {
+ scheduleAction('a', function() {
+ return promise.delayed(10).then(function() {
return schedule('b');
});
});
+ schedule('c');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c');
+ });
});
- schedule('c');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c');
+
+ it('taskReturnsPromiseThatDependsOnSubtask_4', function() {
+ scheduleAction('a', function() {
+ return promise.delayed(5).then(function() {
+ return promise.delayed(5).then(function() {
+ return schedule('b');
+ });
+ });
+ });
+ schedule('c');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c');
+ });
});
- });
- it('taskReturnsPromiseThatDependsOnSubtask_5', function() {
- scheduleAction('a', function() {
- return promise.delayed(5).then(function() {
+ it('taskReturnsPromiseThatDependsOnSubtask_5', function() {
+ scheduleAction('a', function() {
return promise.delayed(5).then(function() {
return promise.delayed(5).then(function() {
return promise.delayed(5).then(function() {
- return schedule('b');
+ return promise.delayed(5).then(function() {
+ return schedule('b');
+ });
});
});
});
});
+ schedule('c');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c');
+ });
});
- schedule('c');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c');
- });
- });
- it('taskReturnsPromiseThatDependsOnSubtask_6', function() {
- scheduleAction('a', function() {
- return promise.delayed(5).
- then(function() { return promise.delayed(5) }).
- then(function() { return promise.delayed(5) }).
- then(function() { return promise.delayed(5) }).
- then(function() { return schedule('b'); });
- });
- schedule('c');
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'b', 'c');
+ it('taskReturnsPromiseThatDependsOnSubtask_6', function() {
+ scheduleAction('a', function() {
+ return promise.delayed(5).
+ then(function() { return promise.delayed(5) }).
+ then(function() { return promise.delayed(5) }).
+ then(function() { return promise.delayed(5) }).
+ then(function() { return schedule('b'); });
+ });
+ schedule('c');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'b', 'c');
+ });
});
- });
- it('subTaskFails_1', function() {
- schedule('a');
- scheduleAction('sub-tasks', function() {
- scheduleAction('sub-task that fails', throwStubError);
+ it('subTaskFails_1', function() {
+ schedule('a');
+ scheduleAction('sub-tasks', function() {
+ scheduleAction('sub-task that fails', throwStubError);
+ });
+ schedule('should never execute');
+
+ return waitForAbort().
+ then(assertIsStubError).
+ then(function() {
+ assertFlowHistory('a', 'sub-tasks', 'sub-task that fails');
+ });
});
- schedule('should never execute');
- return waitForAbort().
- then(assertIsStubError).
- then(function() {
- assertFlowHistory('a', 'sub-tasks', 'sub-task that fails');
- });
- });
+ it('subTaskFails_2', function() {
+ schedule('a');
+ scheduleAction('sub-tasks', function() {
+ return promise.rejected(new StubError);
+ });
+ schedule('should never execute');
- it('subTaskFails_2', function() {
- schedule('a');
- scheduleAction('sub-tasks', function() {
- return promise.rejected(new StubError);
+ return waitForAbort().
+ then(assertIsStubError).
+ then(function() {
+ assertFlowHistory('a', 'sub-tasks');
+ });
});
- schedule('should never execute');
- return waitForAbort().
- then(assertIsStubError).
- then(function() {
- assertFlowHistory('a', 'sub-tasks');
- });
- });
-
- it('subTaskFails_3', function() {
- var callbacks = callbackPair(null, assertIsStubError);
+ it('subTaskFails_3', function() {
+ var callbacks = callbackPair(null, assertIsStubError);
- schedule('a');
- scheduleAction('sub-tasks', function() {
- return promise.rejected(new StubError);
- }).then(callbacks.callback, callbacks.errback);
- schedule('b');
+ schedule('a');
+ scheduleAction('sub-tasks', function() {
+ return promise.rejected(new StubError);
+ }).then(callbacks.callback, callbacks.errback);
+ schedule('b');
- return waitForIdle().
- then(function() {
- assertFlowHistory('a', 'sub-tasks', 'b');
- callbacks.assertErrback();
- });
+ return waitForIdle().
+ then(function() {
+ assertFlowHistory('a', 'sub-tasks', 'b');
+ callbacks.assertErrback();
+ });
+ });
});
- });
- describe('testEventLoopWaitsOnPendingPromiseRejections', function() {
- it('oneRejection', function() {
- var d = new promise.Deferred;
- scheduleAction('one', function() {
- return d.promise;
+ describe('testEventLoopWaitsOnPendingPromiseRejections', function() {
+ it('oneRejection', function() {
+ var d = new promise.Deferred;
+ scheduleAction('one', function() {
+ return d.promise;
+ });
+ scheduleAction('two', function() {});
+
+ return timeout(50).then(function() {
+ assertFlowHistory('one');
+ d.reject(new StubError);
+ return waitForAbort();
+ }).
+ then(assertIsStubError).
+ then(function() {
+ assertFlowHistory('one');
+ });
});
- scheduleAction('two', function() {});
- return timeout(50).then(function() {
- assertFlowHistory('one');
- d.reject(new StubError);
- return waitForAbort();
- }).
- then(assertIsStubError).
- then(function() {
- assertFlowHistory('one');
+ it('multipleRejections', function() {
+ var once = Error('once');
+ var twice = Error('twice');
+
+ scheduleAction('one', function() {
+ promise.rejected(once);
+ promise.rejected(twice);
+ });
+ var twoResult = scheduleAction('two', function() {});
+
+ flow.removeAllListeners(
+ promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
+ return new NativePromise(function(fulfill, reject) {
+ setTimeout(function() {
+ reject(Error('Should have reported the two errors by now'));
+ }, 50);
+ flow.on(
+ promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
+ fulfill);
+ }).then(function(e) {
+ assert.ok(e instanceof promise.MultipleUnhandledRejectionError,
+ 'Not a MultipleUnhandledRejectionError');
+ let errors = Array.from(e.errors);
+ assert.deepEqual([once, twice], errors);
+ assertFlowHistory('one');
+ });
});
});
- it('multipleRejections', function() {
- var once = Error('once');
- var twice = Error('twice');
+ describe('testCancelsPromiseReturnedByCallbackIfFrameFails', function() {
+ it('promiseCallback', function() {
+ var chainPair = callbackPair(null, assertIsStubError);
+ var deferredPair = callbackPair(null, function(e) {
+ assert.equal('CancellationError: StubError', e.toString(),
+ 'callback result should be cancelled');
+ });
- scheduleAction('one', function() {
- promise.rejected(once);
- promise.rejected(twice);
+ var d = new promise.Deferred();
+ d.promise.then(deferredPair.callback, deferredPair.errback);
+
+ promise.fulfilled().
+ then(function() {
+ scheduleAction('boom', throwStubError);
+ schedule('this should not run');
+ return d.promise;
+ }).
+ then(chainPair.callback, chainPair.errback);
+
+ return waitForIdle().then(function() {
+ assertFlowHistory('boom');
+ chainPair.assertErrback('chain errback not invoked');
+ deferredPair.assertErrback('deferred errback not invoked');
+ });
});
- var twoResult = scheduleAction('two', function() {});
- flow.removeAllListeners(
- promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
- return new NativePromise(function(fulfill, reject) {
- setTimeout(function() {
- reject(Error('Should have reported the two errors by now'));
- }, 50);
- flow.on(
- promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
- fulfill);
- }).then(function(e) {
- assert.ok(e instanceof promise.MultipleUnhandledRejectionError,
- 'Not a MultipleUnhandledRejectionError');
- let errors = Array.from(e.errors);
- assert.deepEqual([once, twice], errors);
- assertFlowHistory('one');
- assert.ok(!twoResult.isPending(), 'Did not cancel the second task');
- });
- });
- });
+ it('taskCallback', function() {
+ var chainPair = callbackPair(null, assertIsStubError);
+ var deferredPair = callbackPair(null, function(e) {
+ assert.equal('CancellationError: StubError', e.toString(),
+ 'callback result should be cancelled');
+ });
- describe('testCancelsPromiseReturnedByCallbackIfFrameFails', function() {
- it('promiseCallback', function() {
- var chainPair = callbackPair(null, assertIsStubError);
- var deferredPair = callbackPair(null, function(e) {
- assert.equal('CancellationError: StubError', e.toString(),
- 'callback result should be cancelled');
+ var d = new promise.Deferred();
+ d.promise.then(deferredPair.callback, deferredPair.errback);
+
+ schedule('a').
+ then(function() {
+ scheduleAction('boom', throwStubError);
+ schedule('this should not run');
+ return d.promise;
+ }).
+ then(chainPair.callback, chainPair.errback);
+
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'boom');
+ chainPair.assertErrback('chain errback not invoked');
+ deferredPair.assertErrback('deferred errback not invoked');
+ });
});
+ });
- var d = new promise.Deferred();
- d.promise.then(deferredPair.callback, deferredPair.errback);
-
- promise.fulfilled().
+ it('testMaintainsOrderInCallbacksWhenATaskReturnsAPromise', function() {
+ schedule('__start__', promise.fulfilled()).
then(function() {
- scheduleAction('boom', throwStubError);
- schedule('this should not run');
- return d.promise;
+ messages.push('a');
+ schedulePush('b');
+ messages.push('c');
}).
- then(chainPair.callback, chainPair.errback);
+ then(function() {
+ messages.push('d');
+ });
+ schedulePush('e');
return waitForIdle().then(function() {
- assertFlowHistory('boom');
- chainPair.assertErrback('chain errback not invoked');
- deferredPair.assertErrback('deferred errback not invoked');
+ assertFlowHistory('__start__', 'b', 'e');
+ assertMessages('a', 'c', 'b', 'd', 'e');
});
});
- it('taskCallback', function() {
- var chainPair = callbackPair(null, assertIsStubError);
- var deferredPair = callbackPair(null, function(e) {
- assert.equal('CancellationError: StubError', e.toString(),
- 'callback result should be cancelled');
- });
+ it('testOwningFlowIsActivatedForExecutingTasks', function() {
+ var defaultFlow = promise.controlFlow();
+ var order = [];
- var d = new promise.Deferred();
- d.promise.then(deferredPair.callback, deferredPair.errback);
+ promise.createFlow(function(flow) {
+ assertFlowIs(flow);
+ order.push(0);
- schedule('a').
- then(function() {
- scheduleAction('boom', throwStubError);
- schedule('this should not run');
- return d.promise;
- }).
- then(chainPair.callback, chainPair.errback);
+ defaultFlow.execute(function() {
+ assertFlowIs(defaultFlow);
+ order.push(1);
+ });
+ });
return waitForIdle().then(function() {
- assertFlowHistory('a', 'boom');
- chainPair.assertErrback('chain errback not invoked');
- deferredPair.assertErrback('deferred errback not invoked');
+ assertFlowIs(defaultFlow);
+ assert.deepEqual([0, 1], order);
});
});
- });
- it('testMaintainsOrderInCallbacksWhenATaskReturnsAPromise', function() {
- schedule('__start__', promise.fulfilled()).
- then(function() {
- messages.push('a');
- schedulePush('b');
- messages.push('c');
- }).
- then(function() {
- messages.push('d');
+ it('testCreateFlowReturnsPromisePairedWithCreatedFlow', function() {
+ return new NativePromise(function(fulfill, reject) {
+ var newFlow;
+ promise.createFlow(function(flow) {
+ newFlow = flow;
+ assertFlowIs(newFlow);
+ }).then(function() {
+ assertFlowIs(newFlow);
+ waitForIdle(newFlow).then(fulfill, reject);
});
- schedulePush('e');
-
- return waitForIdle().then(function() {
- assertFlowHistory('__start__', 'b', 'e');
- assertMessages('a', 'c', 'b', 'd', 'e');
+ });
});
- });
- it('testOwningFlowIsActivatedForExecutingTasks', function() {
- var defaultFlow = promise.controlFlow();
- var order = [];
-
- promise.createFlow(function(flow) {
- assertFlowIs(flow);
- order.push(0);
-
- defaultFlow.execute(function() {
+ it('testDeferredFactoriesCreateForActiveFlow_defaultFlow', function() {
+ var e = Error();
+ var defaultFlow = promise.controlFlow();
+ promise.fulfilled().then(function() {
assertFlowIs(defaultFlow);
- order.push(1);
});
- });
-
- return waitForIdle().then(function() {
- assertFlowIs(defaultFlow);
- assert.deepEqual([0, 1], order);
- });
- });
-
- it('testCreateFlowReturnsPromisePairedWithCreatedFlow', function() {
- return new NativePromise(function(fulfill, reject) {
- var newFlow;
- promise.createFlow(function(flow) {
- newFlow = flow;
- assertFlowIs(newFlow);
- }).then(function() {
- assertFlowIs(newFlow);
- waitForIdle(newFlow).then(fulfill, reject);
+ promise.rejected(e).then(null, function(err) {
+ assert.equal(e, err);
+ assertFlowIs(defaultFlow);
+ });
+ promise.defer().promise.then(function() {
+ assertFlowIs(defaultFlow);
});
- });
- });
- it('testDeferredFactoriesCreateForActiveFlow_defaultFlow', function() {
- var e = Error();
- var defaultFlow = promise.controlFlow();
- promise.fulfilled().then(function() {
- assertFlowIs(defaultFlow);
- });
- promise.rejected(e).then(null, function(err) {
- assert.equal(e, err);
- assertFlowIs(defaultFlow);
- });
- promise.defer().promise.then(function() {
- assertFlowIs(defaultFlow);
+ return waitForIdle();
});
- return waitForIdle();
- });
+ it('testDeferredFactoriesCreateForActiveFlow_newFlow', function() {
+ var e = Error();
+ var newFlow = new promise.ControlFlow;
+ newFlow.execute(function() {
+ promise.fulfilled().then(function() {
+ assertFlowIs(newFlow);
+ });
- it('testDeferredFactoriesCreateForActiveFlow_newFlow', function() {
- var e = Error();
- var newFlow = new promise.ControlFlow;
- newFlow.execute(function() {
- promise.fulfilled().then(function() {
- assertFlowIs(newFlow);
- });
+ promise.rejected(e).then(null, function(err) {
+ assert.equal(e, err);
+ assertFlowIs(newFlow);
+ });
- promise.rejected(e).then(null, function(err) {
- assert.equal(e, err);
+ let d = promise.defer();
+ d.promise.then(function() {
+ assertFlowIs(newFlow);
+ });
+ d.fulfill();
+ }).then(function() {
assertFlowIs(newFlow);
});
- let d = promise.defer();
- d.promise.then(function() {
- assertFlowIs(newFlow);
- });
- d.fulfill();
- }).then(function() {
- assertFlowIs(newFlow);
+ return waitForIdle(newFlow);
});
- return waitForIdle(newFlow);
- });
-
- it('testFlowsSynchronizeWithThemselvesNotEachOther', function() {
- var defaultFlow = promise.controlFlow();
- schedulePush('a', 'a');
- promise.controlFlow().timeout(250);
- schedulePush('b', 'b');
+ it('testFlowsSynchronizeWithThemselvesNotEachOther', function() {
+ var defaultFlow = promise.controlFlow();
+ schedulePush('a', 'a');
+ promise.controlFlow().timeout(500);
+ schedulePush('b', 'b');
- promise.createFlow(function() {
- schedulePush('c', 'c');
- schedulePush('d', 'd');
- });
+ promise.createFlow(function(flow2) {
+ assertFlowIs(flow2);
+ schedulePush('c', 'c');
+ schedulePush('d', 'd');
+ });
- return waitForIdle().then(function() {
- assertMessages('a', 'c', 'd', 'b');
+ return waitForIdle().then(function() {
+ assertMessages('a', 'c', 'd', 'b');
+ });
});
- });
- it('testUnhandledErrorsAreReportedToTheOwningFlow', function() {
- var error1 = Error('e1');
- var error2 = Error('e2');
+ it('testUnhandledErrorsAreReportedToTheOwningFlow', function() {
+ var error1 = Error('e1');
+ var error2 = Error('e2');
- var defaultFlow = promise.controlFlow();
- defaultFlow.removeAllListeners('uncaughtException');
+ var defaultFlow = promise.controlFlow();
+ defaultFlow.removeAllListeners('uncaughtException');
- var flow1Error = NativePromise.defer();
- flow1Error.promise.then(function(value) {
- assert.equal(error2, value);
- });
+ var flow1Error = defer();
+ flow1Error.promise.then(function(value) {
+ assert.equal(error2, value);
+ });
- var flow2Error = NativePromise.defer();
- flow2Error.promise.then(function(value) {
- assert.equal(error1, value);
- });
+ var flow2Error = defer();
+ flow2Error.promise.then(function(value) {
+ assert.equal(error1, value);
+ });
- promise.createFlow(function(flow) {
- flow.once('uncaughtException', flow2Error.resolve);
- promise.rejected(error1);
+ promise.createFlow(function(flow) {
+ flow.once('uncaughtException', flow2Error.resolve);
+ promise.rejected(error1);
- defaultFlow.once('uncaughtException', flow1Error.resolve);
- defaultFlow.execute(function() {
- promise.rejected(error2);
+ defaultFlow.once('uncaughtException', flow1Error.resolve);
+ defaultFlow.execute(function() {
+ promise.rejected(error2);
+ });
});
- });
- return NativePromise.all([flow1Error.promise, flow2Error.promise]);
- });
+ return NativePromise.all([flow1Error.promise, flow2Error.promise]);
+ });
- it('testCanSynchronizeFlowsByReturningPromiseFromOneToAnother', function() {
- var flow1 = new promise.ControlFlow;
- var flow1Done = NativePromise.defer();
- flow1.once('idle', flow1Done.resolve);
- flow1.once('uncaughtException', flow1Done.reject);
+ it('testCanSynchronizeFlowsByReturningPromiseFromOneToAnother', function() {
+ var flow1 = new promise.ControlFlow;
+ var flow1Done = defer();
+ flow1.once('idle', flow1Done.resolve);
+ flow1.once('uncaughtException', flow1Done.reject);
- var flow2 = new promise.ControlFlow;
- var flow2Done = NativePromise.defer();
- flow2.once('idle', flow2Done.resolve);
- flow2.once('uncaughtException', flow2Done.reject);
+ var flow2 = new promise.ControlFlow;
+ var flow2Done = defer();
+ flow2.once('idle', flow2Done.resolve);
+ flow2.once('uncaughtException', flow2Done.reject);
- flow1.execute(function() {
- schedulePush('a', 'a');
- return promise.delayed(25);
- }, 'start flow 1');
+ flow1.execute(function() {
+ schedulePush('a', 'a');
+ return promise.delayed(25);
+ }, 'start flow 1');
- flow2.execute(function() {
- schedulePush('b', 'b');
- schedulePush('c', 'c');
flow2.execute(function() {
- return flow1.execute(function() {
- schedulePush('d', 'd');
- }, 'flow 1 task');
- }, 'inject flow1 result into flow2');
- schedulePush('e', 'e');
- }, 'start flow 2');
-
- return NativePromise.all([flow1Done.promise, flow2Done.promise]).
- then(function() {
- assertMessages('a', 'b', 'c', 'd', 'e');
- });
- });
+ schedulePush('b', 'b');
+ schedulePush('c', 'c');
+ flow2.execute(function() {
+ return flow1.execute(function() {
+ schedulePush('d', 'd');
+ }, 'flow 1 task');
+ }, 'inject flow1 result into flow2');
+ schedulePush('e', 'e');
+ }, 'start flow 2');
+
+ return NativePromise.all([flow1Done.promise, flow2Done.promise]).
+ then(function() {
+ assertMessages('a', 'b', 'c', 'd', 'e');
+ });
+ });
- it('testFramesWaitToCompleteForPendingRejections', function() {
- return new NativePromise(function(fulfill, reject) {
+ it('testFramesWaitToCompleteForPendingRejections', function() {
+ return new NativePromise(function(fulfill, reject) {
- promise.controlFlow().execute(function() {
- promise.rejected(new StubError);
- }).then(fulfill, reject);
+ promise.controlFlow().execute(function() {
+ promise.rejected(new StubError);
+ }).then(fulfill, reject);
- }).
- then(() => fail('expected to fail'), assertIsStubError);
- });
+ }).
+ then(() => fail('expected to fail'), assertIsStubError);
+ });
- it('testSynchronizeErrorsPropagateToOuterFlow', function() {
- var outerFlow = new promise.ControlFlow;
- var innerFlow = new promise.ControlFlow;
+ it('testSynchronizeErrorsPropagateToOuterFlow', function() {
+ var outerFlow = new promise.ControlFlow;
+ var innerFlow = new promise.ControlFlow;
- var block = NativePromise.defer();
- innerFlow.execute(function() {
- return block.promise;
- }, 'block inner flow');
+ var block = defer();
+ innerFlow.execute(function() {
+ return block.promise;
+ }, 'block inner flow');
- outerFlow.execute(function() {
- block.resolve();
- return innerFlow.execute(function() {
- promise.rejected(new StubError);
- }, 'trigger unhandled rejection error');
- }, 'run test');
+ outerFlow.execute(function() {
+ block.resolve();
+ return innerFlow.execute(function() {
+ promise.rejected(new StubError);
+ }, 'trigger unhandled rejection error');
+ }, 'run test');
- return NativePromise.all([
- waitForIdle(innerFlow),
- waitForAbort(outerFlow).then(assertIsStubError)
- ]);
- });
+ return NativePromise.all([
+ waitForIdle(innerFlow),
+ waitForAbort(outerFlow).then(assertIsStubError)
+ ]);
+ });
- it('testFailsIfErrbackThrows', function() {
- promise.rejected('').then(null, throwStubError);
- return waitForAbort().then(assertIsStubError);
- });
+ it('testFailsIfErrbackThrows', function() {
+ promise.rejected('').then(null, throwStubError);
+ return waitForAbort().then(assertIsStubError);
+ });
- it('testFailsIfCallbackReturnsRejectedPromise', function() {
- promise.fulfilled().then(function() {
- return promise.rejected(new StubError);
+ it('testFailsIfCallbackReturnsRejectedPromise', function() {
+ promise.fulfilled().then(function() {
+ return promise.rejected(new StubError);
+ });
+ return waitForAbort().then(assertIsStubError);
});
- return waitForAbort().then(assertIsStubError);
- });
- it('testAbortsFrameIfTaskFails', function() {
- promise.fulfilled().then(function() {
- promise.controlFlow().execute(throwStubError);
+ it('testAbortsFrameIfTaskFails', function() {
+ promise.fulfilled().then(function() {
+ promise.controlFlow().execute(throwStubError);
+ });
+ return waitForAbort().then(assertIsStubError);
});
- return waitForAbort().then(assertIsStubError);
- });
- it('testAbortsFramePromisedChainedFromTaskIsNotHandled', function() {
- promise.fulfilled().then(function() {
- promise.controlFlow().execute(function() {}).
- then(throwStubError);
+ it('testAbortsFramePromisedChainedFromTaskIsNotHandled', function() {
+ promise.fulfilled().then(function() {
+ promise.controlFlow().execute(function() {}).
+ then(throwStubError);
+ });
+ return waitForAbort().then(assertIsStubError);
});
- return waitForAbort().then(assertIsStubError);
- });
- it('testTrapsChainedUnhandledRejectionsWithinAFrame', function() {
- var pair = callbackPair(null, assertIsStubError);
- promise.fulfilled().then(function() {
- promise.controlFlow().execute(function() {}).
- then(throwStubError);
- }).then(pair.callback, pair.errback);
+ it('testTrapsChainedUnhandledRejectionsWithinAFrame', function() {
+ var pair = callbackPair(null, assertIsStubError);
+ promise.fulfilled().then(function() {
+ promise.controlFlow().execute(function() {}).
+ then(throwStubError);
+ }).then(pair.callback, pair.errback);
- return waitForIdle().then(pair.assertErrback);
- });
+ return waitForIdle().then(pair.assertErrback);
+ });
- it('testCancelsRemainingTasksIfFrameThrowsDuringScheduling', function() {
- var task1, task2;
- var pair = callbackPair(null, assertIsStubError);
- var flow = promise.controlFlow();
- flow.execute(function() {
- task1 = flow.execute(function() {});
- task2 = flow.execute(function() {});
- throw new StubError;
- }).then(pair.callback, pair.errback);
-
- return waitForIdle().
- then(pair.assertErrback).
- then(function() {
- assert.ok(!task1.isPending());
- pair = callbackPair();
- return task1.then(pair.callback, pair.errback);
- }).
- then(function() {
- pair.assertErrback();
- assert.ok(!task2.isPending());
- pair = callbackPair();
- return task2.then(pair.callback, pair.errback);
- }).
- then(function() {
- pair.assertErrback();
- });
- });
+ it('testCancelsRemainingTasksIfFrameThrowsDuringScheduling', function() {
+ var task1, task2;
+ var pair = callbackPair(null, assertIsStubError);
+ var flow = promise.controlFlow();
+ flow.execute(function() {
+ task1 = flow.execute(function() {});
+ task2 = flow.execute(function() {});
+ throw new StubError;
+ }).then(pair.callback, pair.errback);
- it('testCancelsRemainingTasksInFrameIfATaskFails', function() {
- var task;
- var pair = callbackPair(null, assertIsStubError);
- var flow = promise.controlFlow();
- flow.execute(function() {
- flow.execute(throwStubError);
- task = flow.execute(function() {});
- }).then(pair.callback, pair.errback);
-
- return waitForIdle().then(pair.assertErrback).then(function() {
- assert.ok(!task.isPending());
- pair = callbackPair();
- task.then(pair.callback, pair.errback);
- }).then(function() {
- pair.assertErrback();
+ return waitForIdle().
+ then(pair.assertErrback).
+ then(function() {
+ pair = callbackPair();
+ return task1.then(pair.callback, pair.errback);
+ }).
+ then(function() {
+ pair.assertErrback();
+ pair = callbackPair();
+ return task2.then(pair.callback, pair.errback);
+ }).
+ then(function() {
+ pair.assertErrback();
+ });
});
- });
- it('testDoesNotModifyRejectionErrorIfPromiseNotInsideAFlow', function() {
- var error = Error('original message');
- var originalStack = error.stack;
- var originalStr = error.toString();
+ it('testCancelsRemainingTasksInFrameIfATaskFails', function() {
+ var task;
+ var pair = callbackPair(null, assertIsStubError);
+ var flow = promise.controlFlow();
+ flow.execute(function() {
+ flow.execute(throwStubError);
+ task = flow.execute(function() {});
+ }).then(pair.callback, pair.errback);
- var pair = callbackPair(null, function(e) {
- assert.equal(error, e);
- assert.equal('original message', e.message);
- assert.equal(originalStack, e.stack);
- assert.equal(originalStr, e.toString());
+ return waitForIdle().then(pair.assertErrback).then(function() {
+ pair = callbackPair();
+ task.then(pair.callback, pair.errback);
+ }).then(function() {
+ pair.assertErrback();
+ });
});
- promise.rejected(error).then(pair.callback, pair.errback);
- return waitForIdle().then(pair.assertErrback);
- });
+ it('testDoesNotModifyRejectionErrorIfPromiseNotInsideAFlow', function() {
+ var error = Error('original message');
+ var originalStack = error.stack;
+ var originalStr = error.toString();
- /** See https://github.com/SeleniumHQ/selenium/issues/444 */
- it('testMaintainsOrderWithPromiseChainsCreatedWithinAForeach_1', function() {
- var messages = [];
- flow.execute(function() {
- return promise.fulfilled(['a', 'b', 'c', 'd']);
- }, 'start').then(function(steps) {
- steps.forEach(function(step) {
- promise.fulfilled(step)
- .then(function() {
- messages.push(step + '.1');
- }).then(function() {
- messages.push(step + '.2');
- });
- })
- });
- return waitForIdle().then(function() {
- assert.deepEqual(
- ['a.1', 'a.2', 'b.1', 'b.2', 'c.1', 'c.2', 'd.1', 'd.2'],
- messages);
+ var pair = callbackPair(null, function(e) {
+ assert.equal(error, e);
+ assert.equal('original message', e.message);
+ assert.equal(originalStack, e.stack);
+ assert.equal(originalStr, e.toString());
+ });
+
+ promise.rejected(error).then(pair.callback, pair.errback);
+ return waitForIdle().then(pair.assertErrback);
});
- });
- /** See https://github.com/SeleniumHQ/selenium/issues/444 */
- it('testMaintainsOrderWithPromiseChainsCreatedWithinAForeach_2', function() {
- var messages = [];
- flow.execute(function() {
- return promise.fulfilled(['a', 'b', 'c', 'd']);
- }, 'start').then(function(steps) {
- steps.forEach(function(step) {
- promise.fulfilled(step)
- .then(function() {
- messages.push(step + '.1');
- }).then(function() {
- flow.execute(function() {}, step + '.2').then(function() {
+ /** See https://github.com/SeleniumHQ/selenium/issues/444 */
+ it('testMaintainsOrderWithPromiseChainsCreatedWithinAForeach_1', function() {
+ var messages = [];
+ flow.execute(function() {
+ return promise.fulfilled(['a', 'b', 'c', 'd']);
+ }, 'start').then(function(steps) {
+ steps.forEach(function(step) {
+ promise.fulfilled(step)
+ .then(function() {
+ messages.push(step + '.1');
+ }).then(function() {
messages.push(step + '.2');
});
- });
- })
- });
- return waitForIdle().then(function() {
- assert.deepEqual(
- ['a.1', 'a.2', 'b.1', 'b.2', 'c.1', 'c.2', 'd.1', 'd.2'],
- messages);
+ })
+ });
+ return waitForIdle().then(function() {
+ assert.deepEqual(
+ ['a.1', 'a.2', 'b.1', 'b.2', 'c.1', 'c.2', 'd.1', 'd.2'],
+ messages);
+ });
});
- });
- /** See https://github.com/SeleniumHQ/selenium/issues/444 */
- it('testMaintainsOrderWithPromiseChainsCreatedWithinAForeach_3', function() {
- var messages = [];
- flow.execute(function() {
- return promise.fulfilled(['a', 'b', 'c', 'd']);
- }, 'start').then(function(steps) {
- steps.forEach(function(step) {
- promise.fulfilled(step)
- .then(function(){})
- .then(function() {
- messages.push(step + '.1');
- return flow.execute(function() {}, step + '.1');
- }).then(function() {
- flow.execute(function() {}, step + '.2').then(function(text) {
- messages.push(step + '.2');
+ /** See https://github.com/SeleniumHQ/selenium/issues/444 */
+ it('testMaintainsOrderWithPromiseChainsCreatedWithinAForeach_2', function() {
+ var messages = [];
+ flow.execute(function() {
+ return promise.fulfilled(['a', 'b', 'c', 'd']);
+ }, 'start').then(function(steps) {
+ steps.forEach(function(step) {
+ promise.fulfilled(step)
+ .then(function() {
+ messages.push(step + '.1');
+ }).then(function() {
+ flow.execute(function() {}, step + '.2').then(function() {
+ messages.push(step + '.2');
+ });
});
- });
- })
+ })
+ });
+ return waitForIdle().then(function() {
+ assert.deepEqual(
+ ['a.1', 'a.2', 'b.1', 'b.2', 'c.1', 'c.2', 'd.1', 'd.2'],
+ messages);
+ });
});
- return waitForIdle().then(function() {
- assert.deepEqual(
- ['a.1', 'a.2', 'b.1', 'b.2', 'c.1', 'c.2', 'd.1', 'd.2'],
- messages);
+
+ /** See https://github.com/SeleniumHQ/selenium/issues/444 */
+ it('testMaintainsOrderWithPromiseChainsCreatedWithinAForeach_3', function() {
+ var messages = [];
+ flow.execute(function() {
+ return promise.fulfilled(['a', 'b', 'c', 'd']);
+ }, 'start').then(function(steps) {
+ steps.forEach(function(step) {
+ promise.fulfilled(step)
+ .then(function(){})
+ .then(function() {
+ messages.push(step + '.1');
+ return flow.execute(function() {}, step + '.1');
+ }).then(function() {
+ flow.execute(function() {}, step + '.2').then(function(text) {
+ messages.push(step + '.2');
+ });
+ });
+ })
+ });
+ return waitForIdle().then(function() {
+ assert.deepEqual(
+ ['a.1', 'a.2', 'b.1', 'b.2', 'c.1', 'c.2', 'd.1', 'd.2'],
+ messages);
+ });
});
- });
- /** See https://github.com/SeleniumHQ/selenium/issues/363 */
- it('testTasksScheduledInASeparateTurnOfTheEventLoopGetASeparateTaskQueue_2', function() {
- scheduleAction('a', () => promise.delayed(10));
- schedule('b');
- setTimeout(() => schedule('c'), 0);
+ /** See https://github.com/SeleniumHQ/selenium/issues/363 */
+ it('testTasksScheduledInASeparateTurnOfTheEventLoopGetASeparateTaskQueue_2', function() {
+ scheduleAction('a', () => promise.delayed(10));
+ schedule('b');
+ setTimeout(() => schedule('c'), 0);
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'c', 'b');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'c', 'b');
+ });
});
- });
- /** See https://github.com/SeleniumHQ/selenium/issues/363 */
- it('testTasksScheduledInASeparateTurnOfTheEventLoopGetASeparateTaskQueue_2', function() {
- scheduleAction('a', () => promise.delayed(10));
- schedule('b');
- schedule('c');
- setTimeout(function() {
- schedule('d');
- scheduleAction('e', () => promise.delayed(10));
- schedule('f');
- }, 0);
-
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'd', 'e', 'b', 'c', 'f');
- });
- });
+ /** See https://github.com/SeleniumHQ/selenium/issues/363 */
+ it('testTasksScheduledInASeparateTurnOfTheEventLoopGetASeparateTaskQueue_2', function() {
+ scheduleAction('a', () => promise.delayed(10));
+ schedule('b');
+ schedule('c');
+ setTimeout(function() {
+ schedule('d');
+ scheduleAction('e', () => promise.delayed(10));
+ schedule('f');
+ }, 0);
- /** See https://github.com/SeleniumHQ/selenium/issues/363 */
- it('testCanSynchronizeTasksFromAdjacentTaskQueues', function() {
- var task1 = scheduleAction('a', () => promise.delayed(10));
- schedule('b');
- setTimeout(function() {
- scheduleAction('c', () => task1);
- schedule('d');
- }, 0);
-
- return waitForIdle().then(function() {
- assertFlowHistory('a', 'c', 'd', 'b');
+ return waitForIdle().then(function() {
+ assertFlowHistory('a', 'd', 'e', 'b', 'c', 'f');
+ });
});
- });
- describe('testCancellingAScheduledTask', function() {
- it('1', function() {
- var called = false;
- var task1 = scheduleAction('a', () => called = true);
- task1.cancel('no soup for you');
+ /** See https://github.com/SeleniumHQ/selenium/issues/363 */
+ it('testCanSynchronizeTasksFromAdjacentTaskQueues', function() {
+ var task1 = scheduleAction('a', () => promise.delayed(10));
+ schedule('b');
+ setTimeout(function() {
+ scheduleAction('c', () => task1);
+ schedule('d');
+ }, 0);
return waitForIdle().then(function() {
- assert.ok(!called);
- assertFlowHistory();
- return task1.catch(function(e) {
- assert.ok(e instanceof promise.CancellationError);
- assert.equal('no soup for you', e.message);
- });
+ assertFlowHistory('a', 'c', 'd', 'b');
});
});
- it('2', function() {
- schedule('a');
- var called = false;
- var task2 = scheduleAction('b', () => called = true);
- schedule('c');
+ describe('testCancellingAScheduledTask', function() {
+ it('1', function() {
+ var called = false;
+ var task1 = scheduleAction('a', () => called = true);
+ task1.cancel('no soup for you');
- task2.cancel('no soup for you');
-
- return waitForIdle().then(function() {
- assert.ok(!called);
- assertFlowHistory('a', 'c');
- return task2.catch(function(e) {
- assert.ok(e instanceof promise.CancellationError);
- assert.equal('no soup for you', e.message);
+ return waitForIdle().then(function() {
+ assert.ok(!called);
+ assertFlowHistory();
+ return task1.catch(function(e) {
+ assert.ok(e instanceof promise.CancellationError);
+ assert.equal('no soup for you', e.message);
+ });
});
});
- });
- it('3', function() {
- var called = false;
- var task = scheduleAction('a', () => called = true);
- task.cancel(new StubError);
+ it('2', function() {
+ schedule('a');
+ var called = false;
+ var task2 = scheduleAction('b', () => called = true);
+ schedule('c');
- return waitForIdle().then(function() {
- assert.ok(!called);
- assertFlowHistory();
- return task.catch(function(e) {
- assert.ok(e instanceof promise.CancellationError);
+ task2.cancel('no soup for you');
+
+ return waitForIdle().then(function() {
+ assert.ok(!called);
+ assertFlowHistory('a', 'c');
+ return task2.catch(function(e) {
+ assert.ok(e instanceof promise.CancellationError);
+ assert.equal('no soup for you', e.message);
+ });
});
});
- });
- it('4', function() {
- var seen = [];
- var task = scheduleAction('a', () => seen.push(1))
- .then(() => seen.push(2))
- .then(() => seen.push(3))
- .then(() => seen.push(4))
- .then(() => seen.push(5));
- task.cancel(new StubError);
+ it('3', function() {
+ var called = false;
+ var task = scheduleAction('a', () => called = true);
+ task.cancel(new StubError);
- return waitForIdle().then(function() {
- assert.deepEqual([], seen);
- assertFlowHistory();
- return task.catch(function(e) {
- assert.ok(e instanceof promise.CancellationError);
+ return waitForIdle().then(function() {
+ assert.ok(!called);
+ assertFlowHistory();
+ return task.catch(function(e) {
+ assert.ok(e instanceof promise.CancellationError);
+ });
});
});
- });
- it('fromWithinAnExecutingTask', function() {
- var called = false;
- var task;
- scheduleAction('a', function() {
- task.cancel('no soup for you');
+ it('4', function() {
+ var seen = [];
+ var task = scheduleAction('a', () => seen.push(1))
+ .then(() => seen.push(2))
+ .then(() => seen.push(3))
+ .then(() => seen.push(4))
+ .then(() => seen.push(5));
+ task.cancel(new StubError);
+
+ return waitForIdle().then(function() {
+ assert.deepEqual([], seen);
+ assertFlowHistory();
+ return task.catch(function(e) {
+ assert.ok(e instanceof promise.CancellationError);
+ });
+ });
});
- task = scheduleAction('b', () => called = true);
- schedule('c');
- return waitForIdle().then(function() {
- assert.ok(!called);
- assertFlowHistory('a', 'c');
- return task.catch(function(e) {
- assert.ok(e instanceof promise.CancellationError);
- assert.equal('no soup for you', e.message);
+ it('fromWithinAnExecutingTask', function() {
+ var called = false;
+ var task;
+ scheduleAction('a', function() {
+ task.cancel('no soup for you');
+ });
+ task = scheduleAction('b', () => called = true);
+ schedule('c');
+
+ return waitForIdle().then(function() {
+ assert.ok(!called);
+ assertFlowHistory('a', 'c');
+ return task.catch(function(e) {
+ assert.ok(e instanceof promise.CancellationError);
+ assert.equal('no soup for you', e.message);
+ });
});
});
});
- });
- it('testCancellingAPendingTask', function() {
- var order = [];
- var unresolved = promise.defer();
+ it('testCancellingAPendingTask', function() {
+ var order = [];
+ var unresolved = promise.defer();
- var innerTask;
- var outerTask = scheduleAction('a', function() {
- order.push(1);
+ var innerTask;
+ var outerTask = scheduleAction('a', function() {
+ order.push(1);
- // Schedule a task that will never finish.
- innerTask = scheduleAction('a.1', function() {
- return unresolved.promise;
- });
+ // Schedule a task that will never finish.
+ innerTask = scheduleAction('a.1', function() {
+ return unresolved.promise;
+ });
- // Since the outerTask is cancelled below, innerTask should be cancelled
- // with a DiscardedTaskError, which means its callbacks are silently
- // dropped - so this should never execute.
- innerTask.catch(function(e) {
- order.push(2);
+ // Since the outerTask is cancelled below, innerTask should be cancelled
+ // with a DiscardedTaskError, which means its callbacks are silently
+ // dropped - so this should never execute.
+ innerTask.catch(function(e) {
+ order.push(2);
+ });
});
- });
- schedule('b');
+ schedule('b');
- outerTask.catch(function(e) {
- order.push(3);
- assert.ok(e instanceof promise.CancellationError);
- assert.equal('no soup for you', e.message);
- });
+ outerTask.catch(function(e) {
+ order.push(3);
+ assert.ok(e instanceof promise.CancellationError);
+ assert.equal('no soup for you', e.message);
+ });
- unresolved.promise.catch(function(e) {
- order.push(4);
- assert.ok(e instanceof promise.CancellationError);
- });
+ unresolved.promise.catch(function(e) {
+ order.push(4);
+ assert.ok(e instanceof promise.CancellationError);
+ });
- return timeout(10).then(function() {
- assert.deepEqual([1], order);
- assert.ok(unresolved.promise.isPending());
+ return timeout(10).then(function() {
+ assert.deepEqual([1], order);
- outerTask.cancel('no soup for you');
- return waitForIdle();
- }).then(function() {
- assertFlowHistory('a', 'a.1', 'b');
- assert.deepEqual([1, 3, 4], order);
+ outerTask.cancel('no soup for you');
+ return waitForIdle();
+ }).then(function() {
+ assertFlowHistory('a', 'a.1', 'b');
+ assert.deepEqual([1, 3, 4], order);
+ });
});
- });
- it('testCancellingAPendingPromiseCallback', function() {
- var called = false;
+ it('testCancellingAPendingPromiseCallback', function() {
+ var called = false;
- var root = promise.fulfilled();
- root.then(function() {
- cb2.cancel('no soup for you');
- });
+ var root = promise.fulfilled();
+ root.then(function() {
+ cb2.cancel('no soup for you');
+ });
- var cb2 = root.then(fail, fail); // These callbacks should never be called.
- cb2.then(fail, function(e) {
- called = true;
- assert.ok(e instanceof promise.CancellationError);
- assert.equal('no soup for you', e.message);
- });
+ var cb2 = root.then(fail, fail); // These callbacks should never be called.
+ cb2.then(fail, function(e) {
+ called = true;
+ assert.ok(e instanceof promise.CancellationError);
+ assert.equal('no soup for you', e.message);
+ });
- return waitForIdle().then(function() {
- assert.ok(called);
+ return waitForIdle().then(function() {
+ assert.ok(called);
+ });
});
- });
- describe('testResetFlow', function() {
- it('1', function() {
- var called = 0;
- var task = flow.execute(() => called++);
- task.finally(() => called++);
+ describe('testResetFlow', function() {
+ it('1', function() {
+ var called = 0;
+ var task = flow.execute(() => called++);
+ task.finally(() => called++);
- return new Promise(function(fulfill) {
- flow.once('reset', fulfill);
- flow.reset();
+ return new Promise(function(fulfill) {
+ flow.once('reset', fulfill);
+ flow.reset();
- }).then(function() {
- assert.equal(0, called);
- assert.ok(!task.isPending());
- return task;
+ }).then(function() {
+ assert.equal(0, called);
+ return task;
- }).then(fail, function(e) {
- assert.ok(e instanceof promise.CancellationError);
- assert.equal('ControlFlow was reset', e.message);
+ }).then(fail, function(e) {
+ assert.ok(e instanceof promise.CancellationError);
+ assert.equal('ControlFlow was reset', e.message);
+ });
});
- });
- it('2', function() {
- var called = 0;
- var task1 = flow.execute(() => called++);
- task1.finally(() => called++);
+ it('2', function() {
+ var called = 0;
+ var task1 = flow.execute(() => called++);
+ task1.finally(() => called++);
- var task2 = flow.execute(() => called++);
- task2.finally(() => called++);
+ var task2 = flow.execute(() => called++);
+ task2.finally(() => called++);
- var task3 = flow.execute(() => called++);
- task3.finally(() => called++);
+ var task3 = flow.execute(() => called++);
+ task3.finally(() => called++);
- return new Promise(function(fulfill) {
- flow.once('reset', fulfill);
- flow.reset();
+ return new Promise(function(fulfill) {
+ flow.once('reset', fulfill);
+ flow.reset();
- }).then(function() {
- assert.equal(0, called);
- assert.ok(!task1.isPending());
- assert.ok(!task2.isPending());
- assert.ok(!task3.isPending());
+ }).then(function() {
+ assert.equal(0, called);
+ });
});
});
- });
- describe('testPromiseFulfilledInsideTask', function() {
- it('1', function() {
- var order = [];
+ describe('testPromiseFulfilledInsideTask', function() {
+ it('1', function() {
+ var order = [];
- flow.execute(function() {
- var d = promise.defer();
+ flow.execute(function() {
+ var d = promise.defer();
- d.promise.then(() => order.push('a'));
- d.promise.then(() => order.push('b'));
- d.promise.then(() => order.push('c'));
- d.fulfill();
+ d.promise.then(() => order.push('a'));
+ d.promise.then(() => order.push('b'));
+ d.promise.then(() => order.push('c'));
+ d.fulfill();
- flow.execute(() => order.push('d'));
+ flow.execute(() => order.push('d'));
- }).then(() => order.push('fin'));
+ }).then(() => order.push('fin'));
- return waitForIdle().then(function() {
- assert.deepEqual(['a', 'b', 'c', 'd', 'fin'], order);
+ return waitForIdle().then(function() {
+ assert.deepEqual(['a', 'b', 'c', 'd', 'fin'], order);
+ });
});
- });
- it('2', function() {
- var order = [];
+ it('2', function() {
+ var order = [];
- flow.execute(function() {
- flow.execute(() => order.push('a'));
- flow.execute(() => order.push('b'));
+ flow.execute(function() {
+ flow.execute(() => order.push('a'));
+ flow.execute(() => order.push('b'));
+
+ var d = promise.defer();
+ d.promise.then(() => order.push('c'));
+ d.promise.then(() => order.push('d'));
+ d.fulfill();
+ flow.execute(() => order.push('e'));
+
+ }).then(() => order.push('fin'));
+
+ return waitForIdle().then(function() {
+ assert.deepEqual(['a', 'b', 'c', 'd', 'e', 'fin'], order);
+ });
+ });
+
+ it('3', function() {
+ var order = [];
var d = promise.defer();
d.promise.then(() => order.push('c'));
d.promise.then(() => order.push('d'));
- d.fulfill();
- flow.execute(() => order.push('e'));
+ flow.execute(function() {
+ flow.execute(() => order.push('a'));
+ flow.execute(() => order.push('b'));
- }).then(() => order.push('fin'));
+ d.promise.then(() => order.push('e'));
+ d.fulfill();
- return waitForIdle().then(function() {
- assert.deepEqual(['a', 'b', 'c', 'd', 'e', 'fin'], order);
+ flow.execute(() => order.push('f'));
+
+ }).then(() => order.push('fin'));
+
+ return waitForIdle().then(function() {
+ assert.deepEqual(['c', 'd', 'a', 'b', 'e', 'f', 'fin'], order);
+ });
});
- });
- it('3', function() {
- var order = [];
- var d = promise.defer();
- d.promise.then(() => order.push('c'));
- d.promise.then(() => order.push('d'));
+ it('4', function() {
+ var order = [];
+ var d = promise.defer();
+ d.promise.then(() => order.push('a'));
+ d.promise.then(() => order.push('b'));
- flow.execute(function() {
- flow.execute(() => order.push('a'));
- flow.execute(() => order.push('b'));
+ flow.execute(function() {
+ flow.execute(function() {
+ order.push('c');
+ flow.execute(() => order.push('d'));
+ d.promise.then(() => order.push('e'));
+ });
+ flow.execute(() => order.push('f'));
- d.promise.then(() => order.push('e'));
- d.fulfill();
+ d.promise.then(() => order.push('g'));
+ d.fulfill();
- flow.execute(() => order.push('f'));
+ flow.execute(() => order.push('h'));
- }).then(() => order.push('fin'));
+ }).then(() => order.push('fin'));
- return waitForIdle().then(function() {
- assert.deepEqual(['c', 'd', 'a', 'b', 'e', 'f', 'fin'], order);
+ return waitForIdle().then(function() {
+ assert.deepEqual(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'fin'], order);
+ });
});
});
- it('4', function() {
- var order = [];
- var d = promise.defer();
- d.promise.then(() => order.push('a'));
- d.promise.then(() => order.push('b'));
+ describe('testSettledPromiseCallbacksInsideATask', function() {
+ it('1', function() {
+ var order = [];
+ var p = promise.fulfilled();
- flow.execute(function() {
flow.execute(function() {
- order.push('c');
- flow.execute(() => order.push('d'));
- d.promise.then(() => order.push('e'));
+ flow.execute(() => order.push('a'));
+ p.then(() => order.push('b'));
+ flow.execute(() => order.push('c'));
+ p.then(() => order.push('d'));
+ }).then(() => order.push('fin'));
+
+ return waitForIdle().then(function() {
+ assert.deepEqual(['a', 'b', 'c', 'd', 'fin'], order);
});
- flow.execute(() => order.push('f'));
-
- d.promise.then(() => order.push('g'));
- d.fulfill();
+ });
- flow.execute(() => order.push('h'));
+ it('2', function() {
+ var order = [];
- }).then(() => order.push('fin'));
+ flow.execute(function() {
+ flow.execute(() => order.push('a'))
+ .then( () => order.push('c'));
+ flow.execute(() => order.push('b'));
+ }).then(() => order.push('fin'));
- return waitForIdle().then(function() {
- assert.deepEqual(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'fin'], order);
+ return waitForIdle().then(function() {
+ assert.deepEqual(['a', 'c', 'b', 'fin'], order);
+ });
});
});
- });
- describe('testSettledPromiseCallbacksInsideATask', function() {
- it('1', function() {
+ it('testTasksDoNotWaitForNewlyCreatedPromises', function() {
var order = [];
- var p = promise.fulfilled();
flow.execute(function() {
- flow.execute(() => order.push('a'));
- p.then(() => order.push('b'));
- flow.execute(() => order.push('c'));
- p.then(() => order.push('d'));
- }).then(() => order.push('fin'));
-
- return waitForIdle().then(function() {
- assert.deepEqual(['a', 'b', 'c', 'd', 'fin'], order);
- });
- });
+ var d = promise.defer();
- it('2', function() {
- var order = [];
+ // This is a normal promise, not a task, so the task for this callback is
+ // considered volatile. Volatile tasks should be skipped when they reach
+ // the front of the task queue.
+ d.promise.then(() => order.push('a'));
- flow.execute(function() {
- flow.execute(() => order.push('a'))
- .then( () => order.push('c'));
flow.execute(() => order.push('b'));
+ flow.execute(function() {
+ flow.execute(() => order.push('c'));
+ d.promise.then(() => order.push('d'));
+ d.fulfill();
+ });
+ flow.execute(() => order.push('e'));
+
}).then(() => order.push('fin'));
return waitForIdle().then(function() {
- assert.deepEqual(['a', 'c', 'b', 'fin'], order);
+ assert.deepEqual(['b', 'a', 'c', 'd', 'e', 'fin'], order);
});
});
- });
-
- it('testTasksDoNotWaitForNewlyCreatedPromises', function() {
- var order = [];
- flow.execute(function() {
- var d = promise.defer();
-
- // This is a normal promise, not a task, so the task for this callback is
- // considered volatile. Volatile tasks should be skipped when they reach
- // the front of the task queue.
- d.promise.then(() => order.push('a'));
-
- flow.execute(() => order.push('b'));
- flow.execute(function() {
- flow.execute(() => order.push('c'));
- d.promise.then(() => order.push('d'));
- d.fulfill();
+ it('testCallbackDependenciesDoNotDeadlock', function() {
+ var order = [];
+ var root = promise.defer();
+ var dep = promise.fulfilled().then(function() {
+ order.push('a');
+ return root.promise.then(function() {
+ order.push('b');
+ });
});
- flow.execute(() => order.push('e'));
-
- }).then(() => order.push('fin'));
+ // This callback depends on |dep|, which depends on another callback
+ // attached to |root| via a chain.
+ root.promise.then(function() {
+ order.push('c');
+ return dep.then(() => order.push('d'));
+ }).then(() => order.push('fin'));
- return waitForIdle().then(function() {
- assert.deepEqual(['b', 'a', 'c', 'd', 'e', 'fin'], order);
- });
- });
+ setTimeout(() => root.fulfill(), 20);
- it('testCallbackDependenciesDoNotDeadlock', function() {
- var order = [];
- var root = promise.defer();
- var dep = promise.fulfilled().then(function() {
- order.push('a');
- return root.promise.then(function() {
- order.push('b');
+ return waitForIdle().then(function() {
+ assert.deepEqual(['a', 'b', 'c', 'd', 'fin'], order);
});
});
- // This callback depends on |dep|, which depends on another callback
- // attached to |root| via a chain.
- root.promise.then(function() {
- order.push('c');
- return dep.then(() => order.push('d'));
- }).then(() => order.push('fin'));
-
- setTimeout(() => root.fulfill(), 20);
-
- return waitForIdle().then(function() {
- assert.deepEqual(['a', 'b', 'c', 'd', 'fin'], order);
- });
});
});
diff --git a/node_modules/selenium-webdriver/test/lib/promise_generator_test.js b/node_modules/selenium-webdriver/test/lib/promise_generator_test.js
index 5fdff9f80..b3388da78 100644
--- a/node_modules/selenium-webdriver/test/lib/promise_generator_test.js
+++ b/node_modules/selenium-webdriver/test/lib/promise_generator_test.js
@@ -19,237 +19,165 @@
const assert = require('assert');
const promise = require('../../lib/promise');
+const {enablePromiseManager, promiseManagerSuite} = require('../../lib/test/promise');
describe('promise.consume()', function() {
- it('requires inputs to be generator functions', function() {
- assert.throws(function() {
- promise.consume(function() {});
+ promiseManagerSuite(() => {
+ it('requires inputs to be generator functions', function() {
+ assert.throws(function() {
+ promise.consume(function() {});
+ });
});
- });
- it('handles a basic generator with no yielded promises', function() {
- var values = [];
- return promise.consume(function* () {
- var i = 0;
- while (i < 4) {
- i = yield i + 1;
- values.push(i);
- }
- }).then(function() {
- assert.deepEqual([1, 2, 3, 4], values);
+ it('handles a basic generator with no yielded promises', function() {
+ var values = [];
+ return promise.consume(function* () {
+ var i = 0;
+ while (i < 4) {
+ i = yield i + 1;
+ values.push(i);
+ }
+ }).then(function() {
+ assert.deepEqual([1, 2, 3, 4], values);
+ });
});
- });
- it('handles a promise yielding generator', function() {
- var values = [];
- return promise.consume(function* () {
- var i = 0;
- while (i < 4) {
- // Test that things are actually async here.
- setTimeout(function() {
- values.push(i * 2);
- }, 10);
-
- yield promise.delayed(10).then(function() {
- values.push(i++);
- });
- }
- }).then(function() {
- assert.deepEqual([0, 0, 2, 1, 4, 2, 6, 3], values);
+ it('handles a promise yielding generator', function() {
+ var values = [];
+ return promise.consume(function* () {
+ var i = 0;
+ while (i < 4) {
+ // Test that things are actually async here.
+ setTimeout(function() {
+ values.push(i * 2);
+ }, 10);
+
+ yield promise.delayed(10).then(function() {
+ values.push(i++);
+ });
+ }
+ }).then(function() {
+ assert.deepEqual([0, 0, 2, 1, 4, 2, 6, 3], values);
+ });
});
- });
- it('assignemnts to yielded promises get fulfilled value', function() {
- return promise.consume(function* () {
- var p = promise.fulfilled(2);
- var x = yield p;
- assert.equal(2, x);
+ it('assignments to yielded promises get fulfilled value', function() {
+ return promise.consume(function* () {
+ let x = yield Promise.resolve(2);
+ assert.equal(2, x);
+ });
});
- });
- it('is possible to cancel promise generators', function() {
- var values = [];
- var p = promise.consume(function* () {
- var i = 0;
- while (i < 3) {
- yield promise.delayed(100).then(function() {
- values.push(i++);
- });
- }
- });
- return promise.delayed(75).then(function() {
- p.cancel();
- return p.catch(function() {
- return promise.delayed(300);
+ it('uses final return value as fulfillment value', function() {
+ return promise.consume(function* () {
+ yield 1;
+ yield 2;
+ return 3;
+ }).then(function(value) {
+ assert.equal(3, value);
});
- }).then(function() {
- assert.deepEqual([0], values);
});
- });
- it('uses final return value as fulfillment value', function() {
- return promise.consume(function* () {
- yield 1;
- yield 2;
- return 3;
- }).then(function(value) {
- assert.equal(3, value);
+ it('throws rejected promise errors within the generator', function() {
+ var values = [];
+ return promise.consume(function* () {
+ values.push('a');
+ var e = Error('stub error');
+ try {
+ yield Promise.reject(e);
+ values.push('b');
+ } catch (ex) {
+ assert.equal(e, ex);
+ values.push('c');
+ }
+ values.push('d');
+ }).then(function() {
+ assert.deepEqual(['a', 'c', 'd'], values);
+ });
});
- });
- it('throws rejected promise errors within the generator', function() {
- var values = [];
- return promise.consume(function* () {
- values.push('a');
+ it('aborts the generator if there is an unhandled rejection', function() {
+ var values = [];
var e = Error('stub error');
- try {
+ return promise.consume(function* () {
+ values.push(1);
yield promise.rejected(e);
- values.push('b');
- } catch (ex) {
- assert.equal(e, ex);
- values.push('c');
- }
- values.push('d');
- }).then(function() {
- assert.deepEqual(['a', 'c', 'd'], values);
- });
- });
-
- it('aborts the generator if there is an unhandled rejection', function() {
- var values = [];
- var e = Error('stub error');
- return promise.consume(function* () {
- values.push(1);
- yield promise.rejected(e);
- values.push(2);
- }).catch(function() {
- assert.deepEqual([1], values);
- });
- });
-
- it('yield waits for promises', function() {
- var values = [];
- var d = promise.defer();
-
- setTimeout(function() {
- assert.deepEqual([1], values);
- d.fulfill(2);
- }, 100);
-
- return promise.consume(function* () {
- values.push(1);
- values.push((yield d.promise), 3);
- }).then(function() {
- assert.deepEqual([1, 2, 3], values);
- });
- });
-
- it('accepts custom scopes', function() {
- return promise.consume(function* () {
- return this.name;
- }, {name: 'Bob'}).then(function(value) {
- assert.equal('Bob', value);
+ values.push(2);
+ }).catch(function() {
+ assert.deepEqual([1], values);
+ });
});
- });
- it('accepts initial generator arguments', function() {
- return promise.consume(function* (a, b) {
- assert.equal('red', a);
- assert.equal('apples', b);
- }, null, 'red', 'apples');
- });
-
- it('executes generator within the control flow', function() {
- var promises = [
- promise.defer(),
- promise.defer()
- ];
- var values = [];
-
- setTimeout(function() {
- assert.deepEqual([], values);
- promises[0].fulfill(1);
- }, 100);
-
- setTimeout(function() {
- assert.deepEqual([1], values);
- promises[1].fulfill(2);
- }, 200);
-
- return promise.controlFlow().execute(function* () {
- values.push(yield promises[0].promise);
- values.push(yield promises[1].promise);
- values.push('fin');
- }).then(function() {
- assert.deepEqual([1, 2, 'fin'], values);
- });
- });
-
- it('handles tasks scheduled in generator', function() {
- var flow = promise.controlFlow();
- return flow.execute(function* () {
- var x = yield flow.execute(function() {
- return promise.delayed(10).then(function() {
- return 1;
- });
+ it('yield waits for promises', function() {
+ let values = [];
+ let blocker = promise.delayed(100).then(() => {
+ assert.deepEqual([1], values);
+ return 2;
});
- var y = yield flow.execute(function() {
- return 2;
+ return promise.consume(function* () {
+ values.push(1);
+ values.push(yield blocker, 3);
+ }).then(function() {
+ assert.deepEqual([1, 2, 3], values);
});
+ });
- return x + y;
- }).then(function(value) {
- assert.equal(3, value);
+ it('accepts custom scopes', function() {
+ return promise.consume(function* () {
+ return this.name;
+ }, {name: 'Bob'}).then(function(value) {
+ assert.equal('Bob', value);
+ });
});
- });
- it('blocks the control flow while processing generator', function() {
- var values = [];
- return promise.controlFlow().wait(function* () {
- yield values.push(1);
- values.push(yield promise.delayed(10).then(function() {
- return 2;
- }));
- yield values.push(3);
- return values.length === 6;
- }, 250).then(function() {
- assert.deepEqual([1, 2, 3, 1, 2, 3], values);
+ it('accepts initial generator arguments', function() {
+ return promise.consume(function* (a, b) {
+ assert.equal('red', a);
+ assert.equal('apples', b);
+ }, null, 'red', 'apples');
});
});
- it('ControlFlow.wait() will timeout on long generator', function() {
- var values = [];
- return promise.controlFlow().wait(function* () {
- var i = 0;
- while (i < 3) {
- yield promise.delayed(100).then(function() {
- values.push(i++);
+ enablePromiseManager(() => {
+ it('is possible to cancel promise generators', function() {
+ var values = [];
+ var p = promise.consume(function* () {
+ var i = 0;
+ while (i < 3) {
+ yield promise.delayed(100).then(function() {
+ values.push(i++);
+ });
+ }
+ });
+ return promise.delayed(75).then(function() {
+ p.cancel();
+ return p.catch(function() {
+ return promise.delayed(300);
});
- }
- }, 75).catch(function() {
- assert.deepEqual(
- [0, 1, 2], values, 'Should complete one loop of wait condition');
+ }).then(function() {
+ assert.deepEqual([0], values);
+ });
});
- });
- describe('generators in promise callbacks', function() {
- it('works with no initial value', function() {
+ it('executes generator within the control flow', function() {
var promises = [
- promise.defer(),
- promise.defer()
+ promise.defer(),
+ promise.defer()
];
var values = [];
setTimeout(function() {
+ assert.deepEqual([], values);
promises[0].fulfill(1);
- }, 50);
+ }, 100);
setTimeout(function() {
+ assert.deepEqual([1], values);
promises[1].fulfill(2);
- }, 100);
+ }, 200);
- return promise.fulfilled().then(function*() {
+ return promise.controlFlow().execute(function* () {
values.push(yield promises[0].promise);
values.push(yield promises[1].promise);
values.push('fin');
@@ -258,49 +186,123 @@ describe('promise.consume()', function() {
});
});
- it('starts the generator with promised value', function() {
- var promises = [
- promise.defer(),
- promise.defer()
- ];
- var values = [];
+ it('handles tasks scheduled in generator', function() {
+ var flow = promise.controlFlow();
+ return flow.execute(function* () {
+ var x = yield flow.execute(function() {
+ return promise.delayed(10).then(function() {
+ return 1;
+ });
+ });
- setTimeout(function() {
- promises[0].fulfill(1);
- }, 50);
+ var y = yield flow.execute(function() {
+ return 2;
+ });
- setTimeout(function() {
- promises[1].fulfill(2);
- }, 100);
+ return x + y;
+ }).then(function(value) {
+ assert.equal(3, value);
+ });
+ });
- return promise.fulfilled(3).then(function*(value) {
- var p1 = yield promises[0].promise;
- var p2 = yield promises[1].promise;
- values.push(value + p1);
- values.push(value + p2);
- values.push('fin');
- }).then(function() {
- assert.deepEqual([4, 5, 'fin'], values);
+ it('blocks the control flow while processing generator', function() {
+ var values = [];
+ return promise.controlFlow().wait(function* () {
+ yield values.push(1);
+ values.push(yield promise.delayed(10).then(function() {
+ return 2;
+ }));
+ yield values.push(3);
+ return values.length === 6;
+ }, 250).then(function() {
+ assert.deepEqual([1, 2, 3, 1, 2, 3], values);
});
});
- it('throws yielded rejections within the generator callback', function() {
- var d = promise.defer();
- var e = Error('stub');
+ it('ControlFlow.wait() will timeout on long generator', function() {
+ var values = [];
+ return promise.controlFlow().wait(function* () {
+ var i = 0;
+ while (i < 3) {
+ yield promise.delayed(100).then(function() {
+ values.push(i++);
+ });
+ }
+ }, 75).catch(function() {
+ assert.deepEqual(
+ [0, 1, 2], values, 'Should complete one loop of wait condition');
+ });
+ });
- setTimeout(function() {
- d.reject(e);
- }, 50);
+ describe('generators in promise callbacks', function() {
+ it('works with no initial value', function() {
+ var promises = [
+ promise.defer(),
+ promise.defer()
+ ];
+ var values = [];
- return promise.fulfilled().then(function*() {
- var threw = false;
- try {
- yield d.promise;
- } catch (ex) {
- threw = true;
- assert.equal(e, ex);
- }
- assert.ok(threw);
+ setTimeout(function() {
+ promises[0].fulfill(1);
+ }, 50);
+
+ setTimeout(function() {
+ promises[1].fulfill(2);
+ }, 100);
+
+ return promise.fulfilled().then(function*() {
+ values.push(yield promises[0].promise);
+ values.push(yield promises[1].promise);
+ values.push('fin');
+ }).then(function() {
+ assert.deepEqual([1, 2, 'fin'], values);
+ });
+ });
+
+ it('starts the generator with promised value', function() {
+ var promises = [
+ promise.defer(),
+ promise.defer()
+ ];
+ var values = [];
+
+ setTimeout(function() {
+ promises[0].fulfill(1);
+ }, 50);
+
+ setTimeout(function() {
+ promises[1].fulfill(2);
+ }, 100);
+
+ return promise.fulfilled(3).then(function*(value) {
+ var p1 = yield promises[0].promise;
+ var p2 = yield promises[1].promise;
+ values.push(value + p1);
+ values.push(value + p2);
+ values.push('fin');
+ }).then(function() {
+ assert.deepEqual([4, 5, 'fin'], values);
+ });
+ });
+
+ it('throws yielded rejections within the generator callback', function() {
+ var d = promise.defer();
+ var e = Error('stub');
+
+ setTimeout(function() {
+ d.reject(e);
+ }, 50);
+
+ return promise.fulfilled().then(function*() {
+ var threw = false;
+ try {
+ yield d.promise;
+ } catch (ex) {
+ threw = true;
+ assert.equal(e, ex);
+ }
+ assert.ok(threw);
+ });
});
});
});
diff --git a/node_modules/selenium-webdriver/test/lib/promise_test.js b/node_modules/selenium-webdriver/test/lib/promise_test.js
index 51554ecd9..96d2ccc22 100644
--- a/node_modules/selenium-webdriver/test/lib/promise_test.js
+++ b/node_modules/selenium-webdriver/test/lib/promise_test.js
@@ -21,6 +21,7 @@ const assert = require('assert');
const testutil = require('./testutil');
const promise = require('../../lib/promise');
+const {enablePromiseManager, promiseManagerSuite} = require('../../lib/test/promise');
// Aliases for readability.
const NativePromise = Promise;
@@ -36,1032 +37,1054 @@ describe('promise', function() {
var app, uncaughtExceptions;
beforeEach(function setUp() {
- promise.LONG_STACK_TRACES = false;
- uncaughtExceptions = [];
+ if (promise.USE_PROMISE_MANAGER) {
+ promise.LONG_STACK_TRACES = false;
+ uncaughtExceptions = [];
- app = promise.controlFlow();
- app.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
- (e) => uncaughtExceptions.push(e));
+ app = promise.controlFlow();
+ app.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION,
+ (e) => uncaughtExceptions.push(e));
+ }
});
afterEach(function tearDown() {
- app.reset();
- promise.setDefaultFlow(new promise.ControlFlow);
- assert.deepEqual([], uncaughtExceptions,
- 'Did not expect any uncaught exceptions');
- promise.LONG_STACK_TRACES = false;
+ if (promise.USE_PROMISE_MANAGER) {
+ app.reset();
+ promise.setDefaultFlow(new promise.ControlFlow);
+ assert.deepEqual([], uncaughtExceptions,
+ 'Did not expect any uncaught exceptions');
+ promise.LONG_STACK_TRACES = false;
+ }
});
const assertIsPromise = (p) => assert.ok(promise.isPromise(p));
const assertNotPromise = (v) => assert.ok(!promise.isPromise(v));
+ function defer() {
+ let d = {};
+ let promise = new Promise((resolve, reject) => {
+ Object.assign(d, {resolve, reject});
+ });
+ d.promise = promise;
+ return d;
+ }
+
function createRejectedPromise(reason) {
- var p = promise.rejected(reason);
- p.catch(function() {});
+ var p = Promise.reject(reason);
+ p.catch(function() {}); // Silence unhandled rejection handlers.
return p;
}
- it('testCanDetectPromiseLikeObjects', function() {
- assertIsPromise(new promise.Promise(function(fulfill) {
- fulfill();
- }));
- assertIsPromise(new promise.Deferred().promise);
- assertIsPromise({then:function() {}});
-
- assertNotPromise(new promise.Deferred());
- assertNotPromise(undefined);
- assertNotPromise(null);
- assertNotPromise('');
- assertNotPromise(true);
- assertNotPromise(false);
- assertNotPromise(1);
- assertNotPromise({});
- assertNotPromise({then:1});
- assertNotPromise({then:true});
- assertNotPromise({then:''});
- });
-
- describe('then', function() {
- it('returnsOwnPromiseIfNoCallbacksWereGiven', function() {
- var deferred = new promise.Deferred();
- assert.equal(deferred.promise, deferred.promise.then());
- assert.equal(deferred.promise, deferred.promise.catch());
- assert.equal(deferred.promise, promise.when(deferred.promise));
- });
-
- it('stillConsideredUnHandledIfNoCallbacksWereGivenOnCallsToThen', function() {
- promise.rejected(new StubError).then();
- var handler = callbackHelper(assertIsStubError);
-
- // so tearDown() doesn't throw
- app.removeAllListeners();
- app.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, handler);
- return NativePromise.resolve()
- // Macro yield so the uncaught exception has a chance to trigger.
- .then(() => new NativePromise(resolve => setTimeout(resolve, 0)))
- .then(() => handler.assertCalled());
- });
- });
+ enablePromiseManager(() => {
+ it('testCanDetectPromiseLikeObjects', function() {
+ assertIsPromise(new promise.Promise(function(fulfill) {
+ fulfill();
+ }));
+ assertIsPromise(new promise.Deferred().promise);
+ assertIsPromise(Promise.resolve(123));
+ assertIsPromise({then:function() {}});
+
+ assertNotPromise(new promise.Deferred());
+ assertNotPromise(undefined);
+ assertNotPromise(null);
+ assertNotPromise('');
+ assertNotPromise(true);
+ assertNotPromise(false);
+ assertNotPromise(1);
+ assertNotPromise({});
+ assertNotPromise({then:1});
+ assertNotPromise({then:true});
+ assertNotPromise({then:''});
+ });
+
+ describe('then', function() {
+ it('returnsOwnPromiseIfNoCallbacksWereGiven', function() {
+ var deferred = new promise.Deferred();
+ assert.equal(deferred.promise, deferred.promise.then());
+ assert.equal(deferred.promise, deferred.promise.catch());
+ assert.equal(deferred.promise, promise.when(deferred.promise));
+ });
- describe('finally', function() {
- it('nonFailingCallbackDoesNotSuppressOriginalError', function() {
- var done = callbackHelper(assertIsStubError);
- return promise.rejected(new StubError).
- finally(function() {}).
- catch(done).
- finally(done.assertCalled);
+ it('stillConsideredUnHandledIfNoCallbacksWereGivenOnCallsToThen', function() {
+ promise.rejected(new StubError).then();
+ var handler = callbackHelper(assertIsStubError);
+
+ // so tearDown() doesn't throw
+ app.removeAllListeners();
+ app.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, handler);
+ return NativePromise.resolve()
+ // Macro yield so the uncaught exception has a chance to trigger.
+ .then(() => new NativePromise(resolve => setTimeout(resolve, 0)))
+ .then(() => handler.assertCalled());
+ });
});
- it('failingCallbackSuppressesOriginalError', function() {
- var done = callbackHelper(assertIsStubError);
- return promise.rejected(new Error('original')).
- finally(throwStubError).
- catch(done).
- finally(done.assertCalled);
- });
+ describe('finally', function() {
+ it('nonFailingCallbackDoesNotSuppressOriginalError', function() {
+ var done = callbackHelper(assertIsStubError);
+ return promise.rejected(new StubError).
+ finally(function() {}).
+ catch(done).
+ finally(done.assertCalled);
+ });
- it('callbackThrowsAfterFulfilledPromise', function() {
- var done = callbackHelper(assertIsStubError);
- return promise.fulfilled().
- finally(throwStubError).
- catch(done).
- finally(done.assertCalled);
- });
+ it('failingCallbackSuppressesOriginalError', function() {
+ var done = callbackHelper(assertIsStubError);
+ return promise.rejected(new Error('original')).
+ finally(throwStubError).
+ catch(done).
+ finally(done.assertCalled);
+ });
- it('callbackReturnsRejectedPromise', function() {
- var done = callbackHelper(assertIsStubError);
- return promise.fulfilled().
- finally(function() {
- return promise.rejected(new StubError);
- }).
- catch(done).
- finally(done.assertCalled);
- });
- });
+ it('callbackThrowsAfterFulfilledPromise', function() {
+ var done = callbackHelper(assertIsStubError);
+ return promise.fulfilled().
+ finally(throwStubError).
+ catch(done).
+ finally(done.assertCalled);
+ });
- describe('cancel', function() {
- it('passesTheCancellationReasonToReject', function() {
- var d = new promise.Deferred();
- var res = d.promise.then(assert.fail, function(e) {
- assert.ok(e instanceof promise.CancellationError);
- assert.equal('because i said so', e.message);
+ it('callbackReturnsRejectedPromise', function() {
+ var done = callbackHelper(assertIsStubError);
+ return promise.fulfilled().
+ finally(function() {
+ return promise.rejected(new StubError);
+ }).
+ catch(done).
+ finally(done.assertCalled);
});
- d.promise.cancel('because i said so');
- return res;
});
- describe('can cancel original promise from its child;', function() {
- it('child created by then()', function() {
+ describe('cancel', function() {
+ it('passesTheCancellationReasonToReject', function() {
var d = new promise.Deferred();
- var p = d.promise.then(assert.fail, function(e) {
+ var res = d.promise.then(assert.fail, function(e) {
assert.ok(e instanceof promise.CancellationError);
assert.equal('because i said so', e.message);
- return 123;
});
-
- p.cancel('because i said so');
- return p.then(v => assert.equal(123, v));
+ d.promise.cancel('because i said so');
+ return res;
});
- it('child linked by resolving with parent', function() {
- let parent = promise.defer();
- let child = new promise.Promise(resolve => resolve(parent.promise));
- child.cancel('all done');
-
- return parent.promise.then(
- () => assert.fail('expected a cancellation'),
- e => {
- assert.ok(e instanceof promise.CancellationError);
- assert.equal('all done', e.message);
- });
- });
-
- it('grand child through thenable chain', function() {
- let p = new promise.Promise(function() {/* never resolve*/});
-
- let noop = function() {};
- let gc = p.then(noop).then(noop).then(noop);
- gc.cancel('stop!');
-
- return p.then(
- () => assert.fail('expected to be cancelled'),
- (e) => {
- assert.ok(e instanceof promise.CancellationError);
- assert.equal('stop!', e.message);
- });
- });
-
- it('grand child through thenable chain started at resolve', function() {
- function noop() {}
-
- let parent = promise.defer();
- let child = new promise.Promise(resolve => resolve(parent.promise));
- let grandChild = child.then(noop).then(noop).then(noop);
- grandChild.cancel('all done');
-
- return parent.promise.then(
- () => assert.fail('expected a cancellation'),
- e => {
- assert.ok(e instanceof promise.CancellationError);
- assert.equal('all done', e.message);
- });
- });
-
- it('"parent" is a Thenable', function() {
- function noop() {}
+ describe('can cancel original promise from its child;', function() {
+ it('child created by then()', function() {
+ var d = new promise.Deferred();
+ var p = d.promise.then(assert.fail, function(e) {
+ assert.ok(e instanceof promise.CancellationError);
+ assert.equal('because i said so', e.message);
+ return 123;
+ });
- class FakeThenable {
- constructor(p) {
- this.promise = p;
- }
+ p.cancel('because i said so');
+ return p.then(v => assert.equal(123, v));
+ });
- cancel(reason) {
- this.promise.cancel(reason);
- }
+ it('child linked by resolving with parent', function() {
+ let parent = promise.defer();
+ let child = new promise.Promise(resolve => resolve(parent.promise));
+ child.cancel('all done');
- then(cb, eb) {
- let result = this.promise.then(cb, eb);
- return new FakeThenable(result);
- }
- }
- promise.Thenable.addImplementation(FakeThenable);
+ return parent.promise.then(
+ () => assert.fail('expected a cancellation'),
+ e => {
+ assert.ok(e instanceof promise.CancellationError);
+ assert.equal('all done', e.message);
+ });
+ });
- let root = new promise.Promise(noop);
- let thenable = new FakeThenable(root);
- assert.ok(promise.Thenable.isImplementation(thenable));
+ it('grand child through thenable chain', function() {
+ let p = new promise.Promise(function() {/* never resolve*/});
- let child = new promise.Promise(resolve => resolve(thenable));
- assert.ok(child instanceof promise.Promise);
- child.cancel('stop!');
+ let noop = function() {};
+ let gc = p.then(noop).then(noop).then(noop);
+ gc.cancel('stop!');
- function assertStopped(p) {
return p.then(
- () => assert.fail('not stopped!'),
+ () => assert.fail('expected to be cancelled'),
(e) => {
assert.ok(e instanceof promise.CancellationError);
assert.equal('stop!', e.message);
});
- }
+ });
- return assertStopped(child).then(() => assertStopped(root));
- });
- });
+ it('grand child through thenable chain started at resolve', function() {
+ function noop() {}
- it('canCancelATimeout', function() {
- var p = promise.delayed(25)
- .then(assert.fail, (e) => e instanceof promise.CancellationError);
- setTimeout(() => p.cancel(), 20);
- p.cancel();
- return p;
- });
+ let parent = promise.defer();
+ let child = new promise.Promise(resolve => resolve(parent.promise));
+ let grandChild = child.then(noop).then(noop).then(noop);
+ grandChild.cancel('all done');
- it('can cancel timeout from grandchild', function() {
- });
-
- it('cancelIsANoopOnceAPromiseHasBeenFulfilled', function() {
- var p = promise.fulfilled(123);
- p.cancel();
- return p.then((v) => assert.equal(123, v));
- });
+ return parent.promise.then(
+ () => assert.fail('expected a cancellation'),
+ e => {
+ assert.ok(e instanceof promise.CancellationError);
+ assert.equal('all done', e.message);
+ });
+ });
- it('cancelIsANoopOnceAPromiseHasBeenRejected', function() {
- var p = promise.rejected(new StubError);
- p.cancel();
+ it('"parent" is a CancellableThenable', function() {
+ function noop() {}
- var pair = callbackPair(null, assertIsStubError);
- return p.then(assert.fail, assertIsStubError);
- });
+ class FakeThenable {
+ constructor(p) {
+ this.promise = p;
+ }
- it('noopCancelTriggeredOnCallbackOfResolvedPromise', function() {
- var d = promise.defer();
- var p = d.promise.then();
+ cancel(reason) {
+ this.promise.cancel(reason);
+ }
- d.fulfill();
- p.cancel(); // This should not throw.
- return p; // This should not trigger a failure.
- });
- });
+ then(cb, eb) {
+ let result = this.promise.then(cb, eb);
+ return new FakeThenable(result);
+ }
+ }
+ promise.CancellableThenable.addImplementation(FakeThenable);
+
+ let root = new promise.Promise(noop);
+ let thenable = new FakeThenable(root);
+ assert.ok(promise.Thenable.isImplementation(thenable));
+ assert.ok(promise.CancellableThenable.isImplementation(thenable));
+
+ let child = new promise.Promise(resolve => resolve(thenable));
+ assert.ok(child instanceof promise.Promise);
+ child.cancel('stop!');
+
+ function assertStopped(p) {
+ return p.then(
+ () => assert.fail('not stopped!'),
+ (e) => {
+ assert.ok(e instanceof promise.CancellationError);
+ assert.equal('stop!', e.message);
+ });
+ }
- describe('when', function() {
- it('ReturnsAResolvedPromiseIfGivenANonPromiseValue', function() {
- var ret = promise.when('abc');
- assertIsPromise(ret);
- return ret.then((value) => assert.equal('abc', value));
- });
+ return assertStopped(child).then(() => assertStopped(root));
+ });
+ });
- it('PassesRawErrorsToCallbacks', function() {
- var error = new Error('boo!');
- return promise.when(error, function(value) {
- assert.equal(error, value);
+ it('canCancelATimeout', function() {
+ var p = promise.delayed(25)
+ .then(assert.fail, (e) => e instanceof promise.CancellationError);
+ setTimeout(() => p.cancel(), 20);
+ p.cancel();
+ return p;
});
- });
- it('WaitsForValueToBeResolvedBeforeInvokingCallback', function() {
- var d = new promise.Deferred(), callback;
- let result = promise.when(d.promise, callback = callbackHelper(function(value) {
- assert.equal('hi', value);
- }));
- callback.assertNotCalled();
- d.fulfill('hi');
- return result.then(callback.assertCalled);
- });
- });
+ it('can cancel timeout from grandchild', function() {
+ });
- it('firesUncaughtExceptionEventIfRejectionNeverHandled', function() {
- promise.rejected(new StubError);
- var handler = callbackHelper(assertIsStubError);
+ it('cancelIsANoopOnceAPromiseHasBeenFulfilled', function() {
+ var p = promise.fulfilled(123);
+ p.cancel();
+ return p.then((v) => assert.equal(123, v));
+ });
- // so tearDown() doesn't throw
- app.removeAllListeners();
- app.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, handler);
+ it('cancelIsANoopOnceAPromiseHasBeenRejected', function() {
+ var p = promise.rejected(new StubError);
+ p.cancel();
- return NativePromise.resolve()
- // Macro yield so the uncaught exception has a chance to trigger.
- .then(() => new NativePromise(resolve => setTimeout(resolve, 0)))
- .then(handler.assertCalled);
- });
+ var pair = callbackPair(null, assertIsStubError);
+ return p.then(assert.fail, assertIsStubError);
+ });
- it('cannotResolveADeferredWithItself', function() {
- var deferred = new promise.Deferred();
- assert.throws(() => deferred.fulfill(deferred));
- assert.throws(() => deferred.reject(deferred));
- });
+ it('noopCancelTriggeredOnCallbackOfResolvedPromise', function() {
+ var d = promise.defer();
+ var p = d.promise.then();
- describe('fullyResolved', function() {
- it('primitives', function() {
- function runTest(value) {
- var callback, errback;
- return promise.fullyResolved(value)
- .then((resolved) => assert.equal(value, resolved));
- }
- return runTest(true)
- .then(() => runTest(function() {}))
- .then(() => runTest(null))
- .then(() => runTest(123))
- .then(() => runTest('foo bar'))
- .then(() => runTest(undefined));
+ d.fulfill();
+ p.cancel(); // This should not throw.
+ return p; // This should not trigger a failure.
+ });
});
+ });
- it('arrayOfPrimitives', function() {
- var fn = function() {};
- var array = [true, fn, null, 123, '', undefined, 1];
- return promise.fullyResolved(array).then(function(resolved) {
- assert.equal(array, resolved);
- assert.deepEqual([true, fn, null, 123, '', undefined, 1],
- resolved);
+ promiseManagerSuite(() => {
+ describe('when', function() {
+ it('ReturnsAResolvedPromiseIfGivenANonPromiseValue', function() {
+ var ret = promise.when('abc');
+ assertIsPromise(ret);
+ return ret.then((value) => assert.equal('abc', value));
});
- });
- it('nestedArrayOfPrimitives', function() {
- var fn = function() {};
- var array = [true, [fn, null, 123], '', undefined];
- return promise.fullyResolved(array)
- .then(function(resolved) {
- assert.equal(array, resolved);
- assert.deepEqual([true, [fn, null, 123], '', undefined], resolved);
- assert.deepEqual([fn, null, 123], resolved[1]);
- });
- });
+ it('PassesRawErrorsToCallbacks', function() {
+ var error = new Error('boo!');
+ return promise.when(error, function(value) {
+ assert.equal(error, value);
+ });
+ });
- it('arrayWithPromisedPrimitive', function() {
- return promise.fullyResolved([promise.fulfilled(123)])
- .then(function(resolved) {
- assert.deepEqual([123], resolved);
- });
+ it('WaitsForValueToBeResolvedBeforeInvokingCallback', function() {
+ let d = defer();
+ let callback;
+ let result = promise.when(d.promise, callback = callbackHelper(function(value) {
+ assert.equal('hi', value);
+ }));
+ callback.assertNotCalled();
+ d.resolve('hi');
+ return result.then(callback.assertCalled);
+ });
});
- it('promiseResolvesToPrimitive', function() {
- return promise.fullyResolved(promise.fulfilled(123))
- .then((resolved) => assert.equal(123, resolved));
- });
+ describe('fullyResolved', function() {
+ it('primitives', function() {
+ function runTest(value) {
+ var callback, errback;
+ return promise.fullyResolved(value)
+ .then((resolved) => assert.equal(value, resolved));
+ }
+ return runTest(true)
+ .then(() => runTest(function() {}))
+ .then(() => runTest(null))
+ .then(() => runTest(123))
+ .then(() => runTest('foo bar'))
+ .then(() => runTest(undefined));
+ });
- it('promiseResolvesToArray', function() {
- var fn = function() {};
- var array = [true, [fn, null, 123], '', undefined];
- var aPromise = promise.fulfilled(array);
+ it('arrayOfPrimitives', function() {
+ var fn = function() {};
+ var array = [true, fn, null, 123, '', undefined, 1];
+ return promise.fullyResolved(array).then(function(resolved) {
+ assert.equal(array, resolved);
+ assert.deepEqual([true, fn, null, 123, '', undefined, 1],
+ resolved);
+ });
+ });
- var result = promise.fullyResolved(aPromise);
- return result.then(function(resolved) {
- assert.equal(array, resolved);
- assert.deepEqual([true, [fn, null, 123], '', undefined],
- resolved);
- assert.deepEqual([fn, null, 123], resolved[1]);
+ it('nestedArrayOfPrimitives', function() {
+ var fn = function() {};
+ var array = [true, [fn, null, 123], '', undefined];
+ return promise.fullyResolved(array)
+ .then(function(resolved) {
+ assert.equal(array, resolved);
+ assert.deepEqual([true, [fn, null, 123], '', undefined], resolved);
+ assert.deepEqual([fn, null, 123], resolved[1]);
+ });
});
- });
- it('promiseResolvesToArrayWithPromises', function() {
- var nestedPromise = promise.fulfilled(123);
- var aPromise = promise.fulfilled([true, nestedPromise]);
- return promise.fullyResolved(aPromise)
- .then(function(resolved) {
- assert.deepEqual([true, 123], resolved);
- });
- });
+ it('arrayWithPromisedPrimitive', function() {
+ return promise.fullyResolved([Promise.resolve(123)])
+ .then(function(resolved) {
+ assert.deepEqual([123], resolved);
+ });
+ });
- it('rejectsIfArrayPromiseRejects', function() {
- var nestedPromise = createRejectedPromise(new StubError);
- var aPromise = promise.fulfilled([true, nestedPromise]);
+ it('promiseResolvesToPrimitive', function() {
+ return promise.fullyResolved(Promise.resolve(123))
+ .then((resolved) => assert.equal(123, resolved));
+ });
- var pair = callbackPair(null, assertIsStubError);
- return promise.fullyResolved(aPromise)
- .then(assert.fail, assertIsStubError);
- });
+ it('promiseResolvesToArray', function() {
+ var fn = function() {};
+ var array = [true, [fn, null, 123], '', undefined];
+ var aPromise = Promise.resolve(array);
+
+ var result = promise.fullyResolved(aPromise);
+ return result.then(function(resolved) {
+ assert.equal(array, resolved);
+ assert.deepEqual([true, [fn, null, 123], '', undefined],
+ resolved);
+ assert.deepEqual([fn, null, 123], resolved[1]);
+ });
+ });
- it('rejectsOnFirstArrayRejection', function() {
- var e1 = new Error('foo');
- var e2 = new Error('bar');
- var aPromise = promise.fulfilled([
- createRejectedPromise(e1),
- createRejectedPromise(e2)
- ]);
-
- return promise.fullyResolved(aPromise)
- .then(assert.fail, function(error) {
- assert.strictEqual(e1, error);
- });
- });
+ it('promiseResolvesToArrayWithPromises', function() {
+ var nestedPromise = Promise.resolve(123);
+ var aPromise = Promise.resolve([true, nestedPromise]);
+ return promise.fullyResolved(aPromise)
+ .then(function(resolved) {
+ assert.deepEqual([true, 123], resolved);
+ });
+ });
- it('rejectsIfNestedArrayPromiseRejects', function() {
- var aPromise = promise.fulfilled([
- promise.fulfilled([
- createRejectedPromise(new StubError)
- ])
- ]);
+ it('rejectsIfArrayPromiseRejects', function() {
+ var nestedPromise = createRejectedPromise(new StubError);
+ var aPromise = Promise.resolve([true, nestedPromise]);
- return promise.fullyResolved(aPromise)
- .then(assert.fail, assertIsStubError);
- });
+ var pair = callbackPair(null, assertIsStubError);
+ return promise.fullyResolved(aPromise)
+ .then(assert.fail, assertIsStubError);
+ });
- it('simpleHash', function() {
- var hash = {'a': 123};
- return promise.fullyResolved(hash)
- .then(function(resolved) {
- assert.strictEqual(hash, resolved);
- assert.deepEqual(hash, {'a': 123});
- });
- });
+ it('rejectsOnFirstArrayRejection', function() {
+ var e1 = new Error('foo');
+ var e2 = new Error('bar');
+ var aPromise = Promise.resolve([
+ createRejectedPromise(e1),
+ createRejectedPromise(e2)
+ ]);
+
+ return promise.fullyResolved(aPromise)
+ .then(assert.fail, function(error) {
+ assert.strictEqual(e1, error);
+ });
+ });
- it('nestedHash', function() {
- var nestedHash = {'foo':'bar'};
- var hash = {'a': 123, 'b': nestedHash};
+ it('rejectsIfNestedArrayPromiseRejects', function() {
+ var aPromise = Promise.resolve([
+ Promise.resolve([
+ createRejectedPromise(new StubError)
+ ])
+ ]);
- return promise.fullyResolved(hash)
- .then(function(resolved) {
- assert.strictEqual(hash, resolved);
- assert.deepEqual({'a': 123, 'b': {'foo': 'bar'}}, resolved);
- assert.strictEqual(nestedHash, resolved['b']);
- });
- });
+ return promise.fullyResolved(aPromise)
+ .then(assert.fail, assertIsStubError);
+ });
- it('promiseResolvesToSimpleHash', function() {
- var hash = {'a': 123};
- var aPromise = promise.fulfilled(hash);
+ it('simpleHash', function() {
+ var hash = {'a': 123};
+ return promise.fullyResolved(hash)
+ .then(function(resolved) {
+ assert.strictEqual(hash, resolved);
+ assert.deepEqual(hash, {'a': 123});
+ });
+ });
- return promise.fullyResolved(aPromise)
- .then((resolved) => assert.strictEqual(hash, resolved));
- });
+ it('nestedHash', function() {
+ var nestedHash = {'foo':'bar'};
+ var hash = {'a': 123, 'b': nestedHash};
- it('promiseResolvesToNestedHash', function() {
- var nestedHash = {'foo':'bar'};
- var hash = {'a': 123, 'b': nestedHash};
- var aPromise = promise.fulfilled(hash);
+ return promise.fullyResolved(hash)
+ .then(function(resolved) {
+ assert.strictEqual(hash, resolved);
+ assert.deepEqual({'a': 123, 'b': {'foo': 'bar'}}, resolved);
+ assert.strictEqual(nestedHash, resolved['b']);
+ });
+ });
- return promise.fullyResolved(aPromise)
- .then(function(resolved) {
- assert.strictEqual(hash, resolved);
- assert.strictEqual(nestedHash, resolved['b']);
- assert.deepEqual(hash, {'a': 123, 'b': {'foo': 'bar'}});
- });
- });
+ it('promiseResolvesToSimpleHash', function() {
+ var hash = {'a': 123};
+ var aPromise = Promise.resolve(hash);
- it('promiseResolvesToHashWithPromises', function() {
- var aPromise = promise.fulfilled({
- 'a': promise.fulfilled(123)
+ return promise.fullyResolved(aPromise)
+ .then((resolved) => assert.strictEqual(hash, resolved));
});
- return promise.fullyResolved(aPromise)
- .then(function(resolved) {
- assert.deepEqual({'a': 123}, resolved);
- });
- });
+ it('promiseResolvesToNestedHash', function() {
+ var nestedHash = {'foo':'bar'};
+ var hash = {'a': 123, 'b': nestedHash};
+ var aPromise = Promise.resolve(hash);
- it('rejectsIfHashPromiseRejects', function() {
- var aPromise = promise.fulfilled({
- 'a': createRejectedPromise(new StubError)
+ return promise.fullyResolved(aPromise)
+ .then(function(resolved) {
+ assert.strictEqual(hash, resolved);
+ assert.strictEqual(nestedHash, resolved['b']);
+ assert.deepEqual(hash, {'a': 123, 'b': {'foo': 'bar'}});
+ });
});
- return promise.fullyResolved(aPromise)
- .then(assert.fail, assertIsStubError);
- });
+ it('promiseResolvesToHashWithPromises', function() {
+ var aPromise = Promise.resolve({
+ 'a': Promise.resolve(123)
+ });
- it('rejectsIfNestedHashPromiseRejects', function() {
- var aPromise = promise.fulfilled({
- 'a': {'b': createRejectedPromise(new StubError)}
+ return promise.fullyResolved(aPromise)
+ .then(function(resolved) {
+ assert.deepEqual({'a': 123}, resolved);
+ });
});
- return promise.fullyResolved(aPromise)
- .then(assert.fail, assertIsStubError);
- });
-
- it('instantiatedObject', function() {
- function Foo() {
- this.bar = 'baz';
- }
- var foo = new Foo;
+ it('rejectsIfHashPromiseRejects', function() {
+ var aPromise = Promise.resolve({
+ 'a': createRejectedPromise(new StubError)
+ });
- return promise.fullyResolved(foo).then(function(resolvedFoo) {
- assert.equal(foo, resolvedFoo);
- assert.ok(resolvedFoo instanceof Foo);
- assert.deepEqual(new Foo, resolvedFoo);
+ return promise.fullyResolved(aPromise)
+ .then(assert.fail, assertIsStubError);
});
- });
- it('withEmptyArray', function() {
- return promise.fullyResolved([]).then(function(resolved) {
- assert.deepEqual([], resolved);
- });
- });
+ it('rejectsIfNestedHashPromiseRejects', function() {
+ var aPromise = Promise.resolve({
+ 'a': {'b': createRejectedPromise(new StubError)}
+ });
- it('withEmptyHash', function() {
- return promise.fullyResolved({}).then(function(resolved) {
- assert.deepEqual({}, resolved);
+ return promise.fullyResolved(aPromise)
+ .then(assert.fail, assertIsStubError);
});
- });
- it('arrayWithPromisedHash', function() {
- var obj = {'foo': 'bar'};
- var array = [promise.fulfilled(obj)];
+ it('instantiatedObject', function() {
+ function Foo() {
+ this.bar = 'baz';
+ }
+ var foo = new Foo;
- return promise.fullyResolved(array).then(function(resolved) {
- assert.deepEqual(resolved, [obj]);
+ return promise.fullyResolved(foo).then(function(resolvedFoo) {
+ assert.equal(foo, resolvedFoo);
+ assert.ok(resolvedFoo instanceof Foo);
+ assert.deepEqual(new Foo, resolvedFoo);
+ });
});
- });
- });
- describe('checkedNodeCall', function() {
- it('functionThrows', function() {
- return promise.checkedNodeCall(throwStubError)
- .then(assert.fail, assertIsStubError);
- });
+ it('withEmptyArray', function() {
+ return promise.fullyResolved([]).then(function(resolved) {
+ assert.deepEqual([], resolved);
+ });
+ });
- it('functionReturnsAnError', function() {
- return promise.checkedNodeCall(function(callback) {
- callback(new StubError);
- }).then(assert.fail, assertIsStubError);
- });
+ it('withEmptyHash', function() {
+ return promise.fullyResolved({}).then(function(resolved) {
+ assert.deepEqual({}, resolved);
+ });
+ });
- it('functionReturnsSuccess', function() {
- var success = 'success!';
- return promise.checkedNodeCall(function(callback) {
- callback(null, success);
- }).then((value) => assert.equal(success, value));
- });
+ it('arrayWithPromisedHash', function() {
+ var obj = {'foo': 'bar'};
+ var array = [Promise.resolve(obj)];
- it('functionReturnsAndThrows', function() {
- var error = new Error('boom');
- var error2 = new Error('boom again');
- return promise.checkedNodeCall(function(callback) {
- callback(error);
- throw error2;
- }).then(assert.fail, (e) => assert.equal(error, e));
- });
-
- it('functionThrowsAndReturns', function() {
- var error = new Error('boom');
- var error2 = new Error('boom again');
- return promise.checkedNodeCall(function(callback) {
- setTimeout(() => callback(error), 10);
- throw error2;
- }).then(assert.fail, (e) => assert.equal(error2, e));
+ return promise.fullyResolved(array).then(function(resolved) {
+ assert.deepEqual(resolved, [obj]);
+ });
+ });
});
- });
- describe('all', function() {
- it('(base case)', function() {
- let defer = [promise.defer(), promise.defer()];
- var a = [
- 0, 1,
- defer[0].promise,
- defer[1].promise,
- 4, 5, 6
- ];
- delete a[5];
+ describe('checkedNodeCall', function() {
+ it('functionThrows', function() {
+ return promise.checkedNodeCall(throwStubError)
+ .then(assert.fail, assertIsStubError);
+ });
- var pair = callbackPair(function(value) {
- assert.deepEqual([0, 1, 2, 3, 4, undefined, 6], value);
+ it('functionReturnsAnError', function() {
+ return promise.checkedNodeCall(function(callback) {
+ callback(new StubError);
+ }).then(assert.fail, assertIsStubError);
});
- var result = promise.all(a).then(pair.callback, pair.errback);
- pair.assertNeither();
+ it('functionReturnsSuccess', function() {
+ var success = 'success!';
+ return promise.checkedNodeCall(function(callback) {
+ callback(null, success);
+ }).then((value) => assert.equal(success, value));
+ });
- defer[0].fulfill(2);
- pair.assertNeither();
+ it('functionReturnsAndThrows', function() {
+ var error = new Error('boom');
+ var error2 = new Error('boom again');
+ return promise.checkedNodeCall(function(callback) {
+ callback(error);
+ throw error2;
+ }).then(assert.fail, (e) => assert.equal(error, e));
+ });
- defer[1].fulfill(3);
- return result.then(() => pair.assertCallback());
+ it('functionThrowsAndReturns', function() {
+ var error = new Error('boom');
+ var error2 = new Error('boom again');
+ return promise.checkedNodeCall(function(callback) {
+ setTimeout(() => callback(error), 10);
+ throw error2;
+ }).then(assert.fail, (e) => assert.equal(error2, e));
+ });
});
- it('empty array', function() {
- return promise.all([]).then((a) => assert.deepEqual([], a));
- });
+ describe('all', function() {
+ it('(base case)', function() {
+ let deferredObjs = [defer(), defer()];
+ var a = [
+ 0, 1,
+ deferredObjs[0].promise,
+ deferredObjs[1].promise,
+ 4, 5, 6
+ ];
+ delete a[5];
- it('usesFirstRejection', function() {
- let defer = [promise.defer(), promise.defer()];
- let a = [defer[0].promise, defer[1].promise];
+ var pair = callbackPair(function(value) {
+ assert.deepEqual([0, 1, 2, 3, 4, undefined, 6], value);
+ });
- var result = promise.all(a).then(assert.fail, assertIsStubError);
- defer[1].reject(new StubError);
- setTimeout(() => defer[0].reject(Error('ignored')), 0);
- return result;
- });
- });
+ var result = promise.all(a).then(pair.callback, pair.errback);
+ pair.assertNeither();
+
+ deferredObjs[0].resolve(2);
+ pair.assertNeither();
- describe('map', function() {
- it('(base case)', function() {
- var a = [1, 2, 3];
- return promise.map(a, function(value, index, a2) {
- assert.equal(a, a2);
- assert.equal('number', typeof index, 'not a number');
- return value + 1;
- }).then(function(value) {
- assert.deepEqual([2, 3, 4], value);
+ deferredObjs[1].resolve(3);
+ return result.then(() => pair.assertCallback());
});
- });
- it('omitsDeleted', function() {
- var a = [0, 1, 2, 3, 4, 5, 6];
- delete a[1];
- delete a[3];
- delete a[4];
- delete a[6];
+ it('empty array', function() {
+ return promise.all([]).then((a) => assert.deepEqual([], a));
+ });
- var expected = [0, 1, 4, 9, 16, 25, 36];
- delete expected[1];
- delete expected[3];
- delete expected[4];
- delete expected[6];
+ it('usesFirstRejection', function() {
+ let deferredObjs = [defer(), defer()];
+ let a = [deferredObjs[0].promise, deferredObjs[1].promise];
- return promise.map(a, function(value) {
- return value * value;
- }).then(function(value) {
- assert.deepEqual(expected, value);
+ var result = promise.all(a).then(assert.fail, assertIsStubError);
+ deferredObjs[1].reject(new StubError);
+ setTimeout(() => deferredObjs[0].reject(Error('ignored')), 0);
+ return result;
});
});
- it('emptyArray', function() {
- return promise.map([], function(value) {
- return value + 1;
- }).then(function(value) {
- assert.deepEqual([], value);
+ describe('map', function() {
+ it('(base case)', function() {
+ var a = [1, 2, 3];
+ return promise.map(a, function(value, index, a2) {
+ assert.equal(a, a2);
+ assert.equal('number', typeof index, 'not a number');
+ return value + 1;
+ }).then(function(value) {
+ assert.deepEqual([2, 3, 4], value);
+ });
});
- });
- it('inputIsPromise', function() {
- var input = promise.defer();
- var result = promise.map(input.promise, function(value) {
- return value + 1;
+ it('omitsDeleted', function() {
+ var a = [0, 1, 2, 3, 4, 5, 6];
+ delete a[1];
+ delete a[3];
+ delete a[4];
+ delete a[6];
+
+ var expected = [0, 1, 4, 9, 16, 25, 36];
+ delete expected[1];
+ delete expected[3];
+ delete expected[4];
+ delete expected[6];
+
+ return promise.map(a, function(value) {
+ return value * value;
+ }).then(function(value) {
+ assert.deepEqual(expected, value);
+ });
});
- var pair = callbackPair(function(value) {
- assert.deepEqual([2, 3, 4], value);
+ it('emptyArray', function() {
+ return promise.map([], function(value) {
+ return value + 1;
+ }).then(function(value) {
+ assert.deepEqual([], value);
+ });
});
- result = result.then(pair.callback, pair.errback);
- setTimeout(function() {
- pair.assertNeither();
- input.fulfill([1, 2, 3]);
- }, 10);
+ it('inputIsPromise', function() {
+ var input = defer();
+ var result = promise.map(input.promise, function(value) {
+ return value + 1;
+ });
- return result;
- });
+ var pair = callbackPair(function(value) {
+ assert.deepEqual([2, 3, 4], value);
+ });
+ result = result.then(pair.callback, pair.errback);
- it('waitsForFunctionResultToResolve', function() {
- var innerResults = [
- promise.defer(),
- promise.defer()
- ];
+ setTimeout(function() {
+ pair.assertNeither();
+ input.resolve([1, 2, 3]);
+ }, 10);
- var result = promise.map([1, 2], function(value, index) {
- return innerResults[index].promise;
+ return result;
});
- var pair = callbackPair(function(value) {
- assert.deepEqual(['a', 'b'], value);
- });
- result = result.then(pair.callback, pair.errback);
+ it('waitsForFunctionResultToResolve', function() {
+ var innerResults = [
+ defer(),
+ defer()
+ ];
- return NativePromise.resolve()
- .then(function() {
- pair.assertNeither();
- innerResults[0].fulfill('a');
- })
- .then(function() {
- pair.assertNeither();
- innerResults[1].fulfill('b');
- return result;
- })
- .then(pair.assertCallback);
- });
-
- it('rejectsPromiseIfFunctionThrows', function() {
- return promise.map([1], throwStubError)
- .then(assert.fail, assertIsStubError);
- });
+ var result = promise.map([1, 2], function(value, index) {
+ return innerResults[index].promise;
+ });
- it('rejectsPromiseIfFunctionReturnsRejectedPromise', function() {
- return promise.map([1], function() {
- return promise.rejected(new StubError);
- }).then(assert.fail, assertIsStubError);
- });
+ var pair = callbackPair(function(value) {
+ assert.deepEqual(['a', 'b'], value);
+ });
+ result = result.then(pair.callback, pair.errback);
+
+ return NativePromise.resolve()
+ .then(function() {
+ pair.assertNeither();
+ innerResults[0].resolve('a');
+ })
+ .then(function() {
+ pair.assertNeither();
+ innerResults[1].resolve('b');
+ return result;
+ })
+ .then(pair.assertCallback);
+ });
- it('stopsCallingFunctionIfPreviousIterationFailed', function() {
- var count = 0;
- return promise.map([1, 2, 3, 4], function() {
- count++;
- if (count == 3) {
- throw new StubError;
- }
- }).then(assert.fail, function(e) {
- assertIsStubError(e);
- assert.equal(3, count);
+ it('rejectsPromiseIfFunctionThrows', function() {
+ return promise.map([1], throwStubError)
+ .then(assert.fail, assertIsStubError);
});
- });
- it('rejectsWithFirstRejectedPromise', function() {
- var innerResult = [
- promise.fulfilled(),
- createRejectedPromise(new StubError),
- createRejectedPromise(Error('should be ignored'))
- ];
- var count = 0;
- return promise.map([1, 2, 3, 4], function(value, index) {
- count += 1;
- return innerResult[index];
- }).then(assert.fail, function(e) {
- assertIsStubError(e);
- assert.equal(2, count);
+ it('rejectsPromiseIfFunctionReturnsRejectedPromise', function() {
+ return promise.map([1], function() {
+ return createRejectedPromise(new StubError);
+ }).then(assert.fail, assertIsStubError);
});
- });
- it('preservesOrderWhenMapReturnsPromise', function() {
- var deferreds = [
- promise.defer(),
- promise.defer(),
- promise.defer(),
- promise.defer()
- ];
- var result = promise.map(deferreds, function(value) {
- return value.promise;
+ it('stopsCallingFunctionIfPreviousIterationFailed', function() {
+ var count = 0;
+ return promise.map([1, 2, 3, 4], function() {
+ count++;
+ if (count == 3) {
+ throw new StubError;
+ }
+ }).then(assert.fail, function(e) {
+ assertIsStubError(e);
+ assert.equal(3, count);
+ });
});
- var pair = callbackPair(function(value) {
- assert.deepEqual([0, 1, 2, 3], value);
+ it('rejectsWithFirstRejectedPromise', function() {
+ var innerResult = [
+ Promise.resolve(),
+ createRejectedPromise(new StubError),
+ createRejectedPromise(Error('should be ignored'))
+ ];
+ var count = 0;
+ return promise.map([1, 2, 3, 4], function(value, index) {
+ count += 1;
+ return innerResult[index];
+ }).then(assert.fail, function(e) {
+ assertIsStubError(e);
+ assert.equal(2, count);
+ });
});
- result = result.then(pair.callback, pair.errback);
- return NativePromise.resolve()
- .then(function() {
- pair.assertNeither();
- for (let i = deferreds.length; i > 0; i -= 1) {
- deferreds[i - 1].fulfill(i - 1);
- }
- return result;
- }).then(pair.assertCallback);
- });
- });
+ it('preservesOrderWhenMapReturnsPromise', function() {
+ var deferreds = [
+ defer(),
+ defer(),
+ defer(),
+ defer()
+ ];
+ var result = promise.map(deferreds, function(value) {
+ return value.promise;
+ });
- describe('filter', function() {
- it('basicFiltering', function() {
- var a = [0, 1, 2, 3];
- return promise.filter(a, function(val, index, a2) {
- assert.equal(a, a2);
- assert.equal('number', typeof index, 'not a number');
- return val > 1;
- }).then(function(val) {
- assert.deepEqual([2, 3], val);
+ var pair = callbackPair(function(value) {
+ assert.deepEqual([0, 1, 2, 3], value);
+ });
+ result = result.then(pair.callback, pair.errback);
+
+ return Promise.resolve()
+ .then(function() {
+ pair.assertNeither();
+ for (let i = deferreds.length; i > 0; i -= 1) {
+ deferreds[i - 1].resolve(i - 1);
+ }
+ return result;
+ }).then(pair.assertCallback);
});
});
- it('omitsDeleted', function() {
- var a = [0, 1, 2, 3, 4, 5, 6];
- delete a[3];
- delete a[4];
-
- return promise.filter(a, function(value) {
- return value > 1 && value < 6;
- }).then(function(val) {
- assert.deepEqual([2, 5], val);
+ describe('filter', function() {
+ it('basicFiltering', function() {
+ var a = [0, 1, 2, 3];
+ return promise.filter(a, function(val, index, a2) {
+ assert.equal(a, a2);
+ assert.equal('number', typeof index, 'not a number');
+ return val > 1;
+ }).then(function(val) {
+ assert.deepEqual([2, 3], val);
+ });
});
- });
- it('preservesInputs', function() {
- var a = [0, 1, 2, 3];
+ it('omitsDeleted', function() {
+ var a = [0, 1, 2, 3, 4, 5, 6];
+ delete a[3];
+ delete a[4];
- return promise.filter(a, function(value, i, a2) {
- assert.equal(a, a2);
- // Even if a function modifies the input array, the original value
- // should be inserted into the new array.
- a2[i] = a2[i] - 1;
- return a2[i] >= 1;
- }).then(function(val) {
- assert.deepEqual([2, 3], val);
+ return promise.filter(a, function(value) {
+ return value > 1 && value < 6;
+ }).then(function(val) {
+ assert.deepEqual([2, 5], val);
+ });
});
- });
- it('inputIsPromise', function() {
- var input = promise.defer();
- var result = promise.filter(input.promise, function(value) {
- return value > 1 && value < 3;
+ it('preservesInputs', function() {
+ var a = [0, 1, 2, 3];
+
+ return promise.filter(a, function(value, i, a2) {
+ assert.equal(a, a2);
+ // Even if a function modifies the input array, the original value
+ // should be inserted into the new array.
+ a2[i] = a2[i] - 1;
+ return a2[i] >= 1;
+ }).then(function(val) {
+ assert.deepEqual([2, 3], val);
+ });
});
- var pair = callbackPair(function(value) {
- assert.deepEqual([2], value);
+ it('inputIsPromise', function() {
+ var input = defer();
+ var result = promise.filter(input.promise, function(value) {
+ return value > 1 && value < 3;
+ });
+
+ var pair = callbackPair(function(value) {
+ assert.deepEqual([2], value);
+ });
+ result = result.then(pair.callback, pair.errback);
+ return NativePromise.resolve()
+ .then(function() {
+ pair.assertNeither();
+ input.resolve([1, 2, 3]);
+ return result;
+ })
+ .then(pair.assertCallback);
});
- result = result.then(pair.callback, pair.errback);
- return NativePromise.resolve()
- .then(function() {
- pair.assertNeither();
- input.fulfill([1, 2, 3]);
- return result;
- })
- .then(pair.assertCallback);
- });
- it('waitsForFunctionResultToResolve', function() {
- var innerResults = [
- promise.defer(),
- promise.defer()
- ];
+ it('waitsForFunctionResultToResolve', function() {
+ var innerResults = [
+ defer(),
+ defer()
+ ];
- var result = promise.filter([1, 2], function(value, index) {
- return innerResults[index].promise;
- });
+ var result = promise.filter([1, 2], function(value, index) {
+ return innerResults[index].promise;
+ });
- var pair = callbackPair(function(value) {
- assert.deepEqual([2], value);
+ var pair = callbackPair(function(value) {
+ assert.deepEqual([2], value);
+ });
+ result = result.then(pair.callback, pair.errback);
+ return NativePromise.resolve()
+ .then(function() {
+ pair.assertNeither();
+ innerResults[0].resolve(false);
+ })
+ .then(function() {
+ pair.assertNeither();
+ innerResults[1].resolve(true);
+ return result;
+ })
+ .then(pair.assertCallback);
});
- result = result.then(pair.callback, pair.errback);
- return NativePromise.resolve()
- .then(function() {
- pair.assertNeither();
- innerResults[0].fulfill(false);
- })
- .then(function() {
- pair.assertNeither();
- innerResults[1].fulfill(true);
- return result;
- })
- .then(pair.assertCallback);
- });
- it('rejectsPromiseIfFunctionReturnsRejectedPromise', function() {
- return promise.filter([1], function() {
- return promise.rejected(new StubError);
- }).then(assert.fail, assertIsStubError);
- });
+ it('rejectsPromiseIfFunctionReturnsRejectedPromise', function() {
+ return promise.filter([1], function() {
+ return createRejectedPromise(new StubError);
+ }).then(assert.fail, assertIsStubError);
+ });
- it('stopsCallingFunctionIfPreviousIterationFailed', function() {
- var count = 0;
- return promise.filter([1, 2, 3, 4], function() {
- count++;
- if (count == 3) {
- throw new StubError;
- }
- }).then(assert.fail, function(e) {
- assertIsStubError(e);
- assert.equal(3, count);
+ it('stopsCallingFunctionIfPreviousIterationFailed', function() {
+ var count = 0;
+ return promise.filter([1, 2, 3, 4], function() {
+ count++;
+ if (count == 3) {
+ throw new StubError;
+ }
+ }).then(assert.fail, function(e) {
+ assertIsStubError(e);
+ assert.equal(3, count);
+ });
});
- });
- it('rejectsWithFirstRejectedPromise', function() {
- var innerResult = [
- promise.fulfilled(),
- createRejectedPromise(new StubError),
- createRejectedPromise(Error('should be ignored'))
- ];
-
- return promise.filter([1, 2, 3, 4], function(value, index) {
- assert.ok(index < innerResult.length);
- return innerResult[index];
- }).then(assert.fail, assertIsStubError);
- });
+ it('rejectsWithFirstRejectedPromise', function() {
+ var innerResult = [
+ Promise.resolve(),
+ createRejectedPromise(new StubError),
+ createRejectedPromise(Error('should be ignored'))
+ ];
- it('preservesOrderWhenFilterReturnsPromise', function() {
- var deferreds = [
- promise.defer(),
- promise.defer(),
- promise.defer(),
- promise.defer()
- ];
- var result = promise.filter([0, 1, 2, 3], function(value, index) {
- return deferreds[index].promise;
+ return promise.filter([1, 2, 3, 4], function(value, index) {
+ assert.ok(index < innerResult.length);
+ return innerResult[index];
+ }).then(assert.fail, assertIsStubError);
});
- var pair = callbackPair(function(value) {
- assert.deepEqual([1, 2], value);
- });
- result = result.then(pair.callback, pair.errback);
+ it('preservesOrderWhenFilterReturnsPromise', function() {
+ var deferreds = [
+ defer(),
+ defer(),
+ defer(),
+ defer()
+ ];
+ var result = promise.filter([0, 1, 2, 3], function(value, index) {
+ return deferreds[index].promise;
+ });
- return NativePromise.resolve()
- .then(function() {
- pair.assertNeither();
- for (let i = deferreds.length - 1; i >= 0; i -= 1) {
- deferreds[i].fulfill(i > 0 && i < 3);
- }
- return result;
- }).then(pair.assertCallback);
+ var pair = callbackPair(function(value) {
+ assert.deepEqual([1, 2], value);
+ });
+ result = result.then(pair.callback, pair.errback);
+
+ return NativePromise.resolve()
+ .then(function() {
+ pair.assertNeither();
+ for (let i = deferreds.length - 1; i >= 0; i -= 1) {
+ deferreds[i].resolve(i > 0 && i < 3);
+ }
+ return result;
+ }).then(pair.assertCallback);
+ });
});
});
- it('testAddThenableImplementation', function() {
- function tmp() {}
- assert.ok(!promise.Thenable.isImplementation(new tmp()));
- promise.Thenable.addImplementation(tmp);
- assert.ok(promise.Thenable.isImplementation(new tmp()));
-
- class tmpClass {}
- assert.ok(!promise.Thenable.isImplementation(new tmpClass()));
- promise.Thenable.addImplementation(tmpClass);
- assert.ok(promise.Thenable.isImplementation(new tmpClass()));
- });
-
- describe('testLongStackTraces', function() {
- beforeEach(() => promise.LONG_STACK_TRACES = false);
- afterEach(() => promise.LONG_STACK_TRACES = false);
+ enablePromiseManager(() => {
+ it('firesUncaughtExceptionEventIfRejectionNeverHandled', function() {
+ promise.rejected(new StubError);
+ var handler = callbackHelper(assertIsStubError);
- it('doesNotAppendStackIfFeatureDisabled', function() {
- promise.LONG_STACK_TRACES = false;
+ // so tearDown() doesn't throw
+ app.removeAllListeners();
+ app.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, handler);
- var error = Error('hello');
- var originalStack = error.stack;
- return promise.rejected(error).
- then(fail).
- then(fail).
- then(fail).
- then(fail, function(e) {
- assert.equal(error, e);
- assert.equal(originalStack, e.stack);
- });
+ return NativePromise.resolve()
+ // Macro yield so the uncaught exception has a chance to trigger.
+ .then(() => new NativePromise(resolve => setTimeout(resolve, 0)))
+ .then(handler.assertCalled);
});
- function getStackMessages(error) {
- return error.stack.split(/\n/).filter(function(line) {
- return /^From: /.test(line);
+ it('cannotResolveADeferredWithItself', function() {
+ var deferred = new promise.Deferred();
+ assert.throws(() => deferred.fulfill(deferred));
+ assert.throws(() => deferred.reject(deferred));
+ });
+
+ describe('testLongStackTraces', function() {
+ beforeEach(() => promise.LONG_STACK_TRACES = false);
+ afterEach(() => promise.LONG_STACK_TRACES = false);
+
+ it('doesNotAppendStackIfFeatureDisabled', function() {
+ promise.LONG_STACK_TRACES = false;
+
+ var error = Error('hello');
+ var originalStack = error.stack;
+ return promise.rejected(error).
+ then(fail).
+ then(fail).
+ then(fail).
+ then(fail, function(e) {
+ assert.equal(error, e);
+ assert.equal(originalStack, e.stack);
+ });
});
- }
- it('appendsInitialPromiseCreation_resolverThrows', function() {
- promise.LONG_STACK_TRACES = true;
+ function getStackMessages(error) {
+ return error.stack.split(/\n/).filter(function(line) {
+ return /^From: /.test(line);
+ });
+ }
- var error = Error('hello');
- var originalStack = '(placeholder; will be overwritten later)';
+ it('appendsInitialPromiseCreation_resolverThrows', function() {
+ promise.LONG_STACK_TRACES = true;
- return new promise.Promise(function() {
- try {
- throw error;
- } catch (e) {
- originalStack = e.stack;
- throw e;
- }
- }).then(fail, function(e) {
- assert.strictEqual(error, e);
- if (typeof originalStack !== 'string') {
- return;
- }
- assert.notEqual(originalStack, e.stack);
- assert.equal(e.stack.indexOf(originalStack), 0,
- 'should start with original stack');
- assert.deepEqual(['From: ManagedPromise: new'], getStackMessages(e));
+ var error = Error('hello');
+ var originalStack = '(placeholder; will be overwritten later)';
+
+ return new promise.Promise(function() {
+ try {
+ throw error;
+ } catch (e) {
+ originalStack = e.stack;
+ throw e;
+ }
+ }).then(fail, function(e) {
+ assert.strictEqual(error, e);
+ if (typeof originalStack !== 'string') {
+ return;
+ }
+ assert.notEqual(originalStack, e.stack);
+ assert.equal(e.stack.indexOf(originalStack), 0,
+ 'should start with original stack');
+ assert.deepEqual(['From: ManagedPromise: new'], getStackMessages(e));
+ });
});
- });
- it('appendsInitialPromiseCreation_rejectCalled', function() {
- promise.LONG_STACK_TRACES = true;
+ it('appendsInitialPromiseCreation_rejectCalled', function() {
+ promise.LONG_STACK_TRACES = true;
- var error = Error('hello');
- var originalStack = error.stack;
+ var error = Error('hello');
+ var originalStack = error.stack;
- return new promise.Promise(function(_, reject) {
- reject(error);
- }).then(fail, function(e) {
- assert.equal(error, e);
- if (typeof originalStack !== 'string') {
- return;
- }
- assert.notEqual(originalStack, e.stack);
- assert.equal(e.stack.indexOf(originalStack), 0,
- 'should start with original stack');
- assert.deepEqual(['From: ManagedPromise: new'], getStackMessages(e));
+ return new promise.Promise(function(_, reject) {
+ reject(error);
+ }).then(fail, function(e) {
+ assert.equal(error, e);
+ if (typeof originalStack !== 'string') {
+ return;
+ }
+ assert.notEqual(originalStack, e.stack);
+ assert.equal(e.stack.indexOf(originalStack), 0,
+ 'should start with original stack');
+ assert.deepEqual(['From: ManagedPromise: new'], getStackMessages(e));
+ });
});
- });
- it('appendsEachStepToRejectionError', function() {
- promise.LONG_STACK_TRACES = true;
+ it('appendsEachStepToRejectionError', function() {
+ promise.LONG_STACK_TRACES = true;
- var error = Error('hello');
- var originalStack = '(placeholder; will be overwritten later)';
+ var error = Error('hello');
+ var originalStack = '(placeholder; will be overwritten later)';
- return new promise.Promise(function() {
- try {
- throw error;
- } catch (e) {
- originalStack = e.stack;
- throw e;
- }
- }).
- then(fail).
- catch(function(e) { throw e; }).
- then(fail).
- catch(function(e) { throw e; }).
- then(fail, function(e) {
- assert.equal(error, e);
- if (typeof originalStack !== 'string') {
- return;
- }
- assert.notEqual(originalStack, e.stack);
- assert.equal(e.stack.indexOf(originalStack), 0,
- 'should start with original stack');
- assert.deepEqual([
- 'From: ManagedPromise: new',
- 'From: Promise: then',
- 'From: Promise: catch',
- 'From: Promise: then',
- 'From: Promise: catch',
- ], getStackMessages(e));
+ return new promise.Promise(function() {
+ try {
+ throw error;
+ } catch (e) {
+ originalStack = e.stack;
+ throw e;
+ }
+ }).
+ then(fail).
+ catch(function(e) { throw e; }).
+ then(fail).
+ catch(function(e) { throw e; }).
+ then(fail, function(e) {
+ assert.equal(error, e);
+ if (typeof originalStack !== 'string') {
+ return;
+ }
+ assert.notEqual(originalStack, e.stack);
+ assert.equal(e.stack.indexOf(originalStack), 0,
+ 'should start with original stack');
+ assert.deepEqual([
+ 'From: ManagedPromise: new',
+ 'From: Promise: then',
+ 'From: Promise: catch',
+ 'From: Promise: then',
+ 'From: Promise: catch',
+ ], getStackMessages(e));
+ });
});
- });
- it('errorOccursInCallbackChain', function() {
- promise.LONG_STACK_TRACES = true;
-
- var error = Error('hello');
- var originalStack = '(placeholder; will be overwritten later)';
-
- return promise.fulfilled().
- then(function() {}).
- then(function() {}).
- then(function() {
- try {
- throw error;
- } catch (e) {
- originalStack = e.stack;
- throw e;
- }
- }).
- catch(function(e) { throw e; }).
- then(fail, function(e) {
- assert.equal(error, e);
- if (typeof originalStack !== 'string') {
- return;
- }
- assert.notEqual(originalStack, e.stack);
- assert.equal(e.stack.indexOf(originalStack), 0,
- 'should start with original stack');
- assert.deepEqual([
- 'From: Promise: then',
- 'From: Promise: catch',
- ], getStackMessages(e));
- });
+ it('errorOccursInCallbackChain', function() {
+ promise.LONG_STACK_TRACES = true;
+
+ var error = Error('hello');
+ var originalStack = '(placeholder; will be overwritten later)';
+
+ return promise.fulfilled().
+ then(function() {}).
+ then(function() {}).
+ then(function() {
+ try {
+ throw error;
+ } catch (e) {
+ originalStack = e.stack;
+ throw e;
+ }
+ }).
+ catch(function(e) { throw e; }).
+ then(fail, function(e) {
+ assert.equal(error, e);
+ if (typeof originalStack !== 'string') {
+ return;
+ }
+ assert.notEqual(originalStack, e.stack);
+ assert.equal(e.stack.indexOf(originalStack), 0,
+ 'should start with original stack');
+ assert.deepEqual([
+ 'From: Promise: then',
+ 'From: Promise: catch',
+ ], getStackMessages(e));
+ });
+ });
});
});
+
+ it('testAddThenableImplementation', function() {
+ function tmp() {}
+ assert.ok(!promise.Thenable.isImplementation(new tmp()));
+ promise.Thenable.addImplementation(tmp);
+ assert.ok(promise.Thenable.isImplementation(new tmp()));
+
+ class tmpClass {}
+ assert.ok(!promise.Thenable.isImplementation(new tmpClass()));
+ promise.Thenable.addImplementation(tmpClass);
+ assert.ok(promise.Thenable.isImplementation(new tmpClass()));
+ });
});
diff --git a/node_modules/selenium-webdriver/test/lib/until_test.js b/node_modules/selenium-webdriver/test/lib/until_test.js
index d3e81ec18..31b2b32ad 100644
--- a/node_modules/selenium-webdriver/test/lib/until_test.js
+++ b/node_modules/selenium-webdriver/test/lib/until_test.js
@@ -84,7 +84,7 @@ describe('until', function() {
it('byWebElementPromise', function() {
executor.on(CommandName.SWITCH_TO_FRAME, () => true);
var el = new webdriver.WebElementPromise(driver,
- promise.fulfilled(new webdriver.WebElement(driver, {ELEMENT: 1234})));
+ Promise.resolve(new webdriver.WebElement(driver, {ELEMENT: 1234})));
return driver.wait(until.ableToSwitchToFrame(el), 100);
});
diff --git a/node_modules/selenium-webdriver/test/lib/webdriver_test.js b/node_modules/selenium-webdriver/test/lib/webdriver_test.js
index d2d87ca3e..0a124530e 100644
--- a/node_modules/selenium-webdriver/test/lib/webdriver_test.js
+++ b/node_modules/selenium-webdriver/test/lib/webdriver_test.js
@@ -29,6 +29,8 @@ const Key = require('../../lib/input').Key;
const logging = require('../../lib/logging');
const Session = require('../../lib/session').Session;
const promise = require('../../lib/promise');
+const {enablePromiseManager, promiseManagerSuite} = require('../../lib/test/promise');
+const until = require('../../lib/until');
const Alert = require('../../lib/webdriver').Alert;
const AlertPromise = require('../../lib/webdriver').AlertPromise;
const UnhandledAlertError = require('../../lib/webdriver').UnhandledAlertError;
@@ -73,6 +75,9 @@ describe('WebDriver', function() {
});
afterEach(function tearDown() {
+ if (!promise.USE_PROMISE_MANAGER) {
+ return;
+ }
return waitForIdle(flow).then(function() {
assert.deepEqual([], uncaughtExceptions);
flow.reset();
@@ -83,7 +88,19 @@ describe('WebDriver', function() {
uncaughtExceptions.push(e);
}
+ function defer() {
+ let d = {};
+ let promise = new Promise((resolve, reject) => {
+ Object.assign(d, {resolve, reject});
+ });
+ d.promise = promise;
+ return d;
+ }
+
function waitForIdle(opt_flow) {
+ if (!promise.USE_PROMISE_MANAGER) {
+ return Promise.resolve();
+ }
var theFlow = opt_flow || flow;
return new Promise(function(fulfill, reject) {
if (theFlow.isIdle()) {
@@ -300,19 +317,21 @@ describe('WebDriver', function() {
return waitForIdle(driver.controlFlow());
});
- it('canAttachInCustomFlow', function() {
- let executor = new FakeExecutor().
- expect(CName.DESCRIBE_SESSION).
- withParameters({'sessionId': SESSION_ID}).
- andReturnSuccess({}).
- end();
+ enablePromiseManager(() => {
+ it('canAttachInCustomFlow', function() {
+ let executor = new FakeExecutor().
+ expect(CName.DESCRIBE_SESSION).
+ withParameters({'sessionId': SESSION_ID}).
+ andReturnSuccess({}).
+ end();
- var otherFlow = new promise.ControlFlow();
- var driver = WebDriver.attachToSession(executor, SESSION_ID, otherFlow);
- assert.equal(otherFlow, driver.controlFlow());
- assert.notEqual(otherFlow, promise.controlFlow());
+ var otherFlow = new promise.ControlFlow();
+ var driver = WebDriver.attachToSession(executor, SESSION_ID, otherFlow);
+ assert.equal(otherFlow, driver.controlFlow());
+ assert.notEqual(otherFlow, promise.controlFlow());
- return waitForIdle(otherFlow);
+ return waitForIdle(otherFlow);
+ });
});
});
@@ -345,7 +364,7 @@ describe('WebDriver', function() {
return driver.getSession().then(v => assert.strictEqual(v, aSession));
});
- it('handles desired and requried capabilities', function() {
+ it('handles desired and required capabilities', function() {
let aSession = new Session(SESSION_ID, {'browserName': 'firefox'});
let executor = new FakeExecutor().
expect(CName.NEW_SESSION).
@@ -374,6 +393,23 @@ describe('WebDriver', function() {
return driver.getSession().then(fail, assertIsStubError);
});
+ it('invokes quit callback if it fails to create a session', function() {
+ let called = false;
+ let executor = new FakeExecutor()
+ .expect(CName.NEW_SESSION)
+ .withParameters({'desiredCapabilities': {'browserName': 'firefox'}})
+ .andReturnError(new StubError())
+ .end();
+
+ var driver =
+ WebDriver.createSession(executor, {'browserName': 'firefox'},
+ null, null, () => called = true);
+ return driver.getSession().then(fail, err => {
+ assert.ok(called);
+ assertIsStubError(err);
+ });
+ });
+
it('usesActiveFlowByDefault', function() {
let executor = new FakeExecutor().
expect(CName.NEW_SESSION).
@@ -387,26 +423,60 @@ describe('WebDriver', function() {
return waitForIdle(driver.controlFlow());
});
- it('canCreateInCustomFlow', function() {
- let executor = new FakeExecutor().
- expect(CName.NEW_SESSION).
- withParameters({'desiredCapabilities': {}}).
- andReturnSuccess({}).
- end();
+ enablePromiseManager(() => {
+ it('canCreateInCustomFlow', function() {
+ let executor = new FakeExecutor().
+ expect(CName.NEW_SESSION).
+ withParameters({'desiredCapabilities': {}}).
+ andReturnSuccess({}).
+ end();
- var otherFlow = new promise.ControlFlow();
- var driver = WebDriver.createSession(executor, {}, otherFlow);
- assert.equal(otherFlow, driver.controlFlow());
- assert.notEqual(otherFlow, promise.controlFlow());
+ var otherFlow = new promise.ControlFlow();
+ var driver = WebDriver.createSession(executor, {}, otherFlow);
+ assert.equal(otherFlow, driver.controlFlow());
+ assert.notEqual(otherFlow, promise.controlFlow());
+
+ return waitForIdle(otherFlow);
+ });
- return waitForIdle(otherFlow);
+ describe('creation failures bubble up in control flow', function() {
+ function runTest(...args) {
+ let executor = new FakeExecutor()
+ .expect(CName.NEW_SESSION)
+ .withParameters({'desiredCapabilities': {'browserName': 'firefox'}})
+ .andReturnError(new StubError())
+ .end();
+
+ WebDriver.createSession(
+ executor, {'browserName': 'firefox'}, ...args);
+ return waitForAbort().then(assertIsStubError);
+ }
+
+ it('no onQuit callback', () => runTest());
+ it('has onQuit callback', () => runTest(null, null, function() {}));
+
+ it('onQuit callback failure suppress creation failure', function() {
+ let e = new Error('hi!');
+ let executor = new FakeExecutor()
+ .expect(CName.NEW_SESSION)
+ .withParameters({'desiredCapabilities': {'browserName': 'firefox'}})
+ .andReturnError(new StubError())
+ .end();
+
+ WebDriver.createSession(
+ executor, {'browserName': 'firefox'}, null, null,
+ () => {throw e});
+ return waitForAbort().then(err => assert.strictEqual(err, e));
+ });
+ });
});
});
it('testDoesNotExecuteCommandIfSessionDoesNotResolve', function() {
var session = Promise.reject(new StubError);
- new FakeExecutor().createDriver(session).getTitle();
- return waitForAbort().then(assertIsStubError);
+ return new FakeExecutor().createDriver(session)
+ .getTitle()
+ .then(_ => assert.fail('should have failed'), assertIsStubError);
});
it('testCommandReturnValuesArePassedToFirstCallback', function() {
@@ -415,9 +485,8 @@ describe('WebDriver', function() {
end();
var driver = executor.createDriver();
- return driver.getTitle().then(function(title) {
- assert.equal('Google Search', title);
- });
+ return driver.getTitle()
+ .then(title => assert.equal('Google Search', title));
});
it('testStopsCommandExecutionWhenAnErrorOccurs', function() {
@@ -431,11 +500,11 @@ describe('WebDriver', function() {
andReturnError(e).
end();
- var driver = executor.createDriver();
- driver.switchTo().window('foo');
- driver.getTitle(); // mock should blow if this gets executed
-
- return waitForAbort().then(v => assert.strictEqual(v, e));
+ let driver = executor.createDriver();
+ return driver.switchTo().window('foo')
+ .then(
+ _ => driver.getTitle(), // mock should blow if this gets executed
+ v => assert.strictEqual(v, e));
});
it('testCanSuppressCommandFailures', function() {
@@ -469,8 +538,9 @@ describe('WebDriver', function() {
andReturnError(e).
end();
- executor.createDriver().switchTo().window('foo');
- return waitForAbort().then(v => assert.strictEqual(v, e));
+ return executor.createDriver()
+ .switchTo().window('foo')
+ .then(_ => assert.fail(), v => assert.strictEqual(v, e));
});
it('testErrbacksThatReturnErrorsStillSwitchToCallbackChain', function() {
@@ -486,7 +556,7 @@ describe('WebDriver', function() {
var driver = executor.createDriver();
return driver.switchTo().window('foo').
catch(function() { return new StubError; });
- then(assertIsStubError);
+ then(assertIsStubError, () => assert.fail());
});
it('testErrbacksThrownCanOverrideOriginalError', function() {
@@ -499,27 +569,9 @@ describe('WebDriver', function() {
end();
var driver = executor.createDriver();
- driver.switchTo().window('foo').catch(throwStubError);
-
- return waitForAbort().then(assertIsStubError);
- });
-
- it('testCannotScheduleCommandsIfTheSessionIdHasBeenDeleted', function() {
- var driver = new FakeExecutor().createDriver();
- delete driver.session_;
- assert.throws(() => driver.get('http://www.google.com'));
- });
-
- it('testDeletesSessionIdAfterQuitting', function() {
- var driver;
- let executor = new FakeExecutor().
- expect(CName.QUIT).
- end();
-
- driver = executor.createDriver();
- return driver.quit().then(function() {
- assert.equal(void 0, driver.session_);
- });
+ return driver.switchTo().window('foo')
+ .catch(throwStubError)
+ .then(assert.fail, assertIsStubError);
});
it('testReportsErrorWhenExecutingCommandsAfterExecutingAQuit', function() {
@@ -527,14 +579,15 @@ describe('WebDriver', function() {
expect(CName.QUIT).
end();
- var driver = executor.createDriver();
- driver.quit();
- driver.get('http://www.google.com');
- return waitForAbort().
- then(expectedError(
- error.NoSuchSessionError,
- 'This driver instance does not have a valid session ID ' +
- '(did you call WebDriver.quit()?) and may no longer be used.'));
+ let verifyError = expectedError(
+ error.NoSuchSessionError,
+ 'This driver instance does not have a valid session ID ' +
+ '(did you call WebDriver.quit()?) and may no longer be used.');
+
+ let driver = executor.createDriver();
+ return driver.quit()
+ .then(_ => driver.get('http://www.google.com'))
+ .then(assert.fail, verifyError);
});
it('testCallbackCommandsExecuteBeforeNextCommand', function() {
@@ -556,114 +609,29 @@ describe('WebDriver', function() {
return waitForIdle();
});
- it('testEachCallbackFrameRunsToCompletionBeforeTheNext', function() {
- let executor = new FakeExecutor().
- expect(CName.GET_TITLE).
- expect(CName.GET_CURRENT_URL).
- expect(CName.GET_CURRENT_WINDOW_HANDLE).
- expect(CName.CLOSE).
- expect(CName.QUIT).
- end();
-
- var driver = executor.createDriver();
- driver.getTitle().
- // Everything in this callback...
- then(function() {
- driver.getCurrentUrl();
- driver.getWindowHandle();
- }).
- // ...should execute before everything in this callback.
- then(function() {
- driver.close();
- });
- // This should execute after everything above
- driver.quit();
-
- return waitForIdle();
- });
-
- describe('nestedCommandFailures', function() {
- it('bubbleUpToGlobalHandlerIfUnsuppressed', function() {
- let e = new error.NoSuchWindowError('window not found');
- let executor = new FakeExecutor().
- expect(CName.GET_TITLE).
- expect(CName.SWITCH_TO_WINDOW, {
- 'name': 'foo',
- 'handle': 'foo'
- }).
- andReturnError(e).
- end();
-
- var driver = executor.createDriver();
- driver.getTitle().then(function() {
- driver.switchTo().window('foo');
- });
-
- return waitForAbort().then(v => assert.strictEqual(v, e));
- });
-
- it('canBeSuppressWhenTheyOccur', function() {
+ enablePromiseManager(() => {
+ it('testEachCallbackFrameRunsToCompletionBeforeTheNext', function() {
let executor = new FakeExecutor().
expect(CName.GET_TITLE).
- expect(CName.SWITCH_TO_WINDOW, {
- 'name': 'foo',
- 'handle': 'foo'
- }).
- andReturnError(new error.NoSuchWindowError('window not found')).
+ expect(CName.GET_CURRENT_URL).
+ expect(CName.GET_CURRENT_WINDOW_HANDLE).
expect(CName.CLOSE).
- end();
-
- var driver = executor.createDriver();
- driver.getTitle().then(function() {
- driver.switchTo().window('foo').catch(function() {});
- });
- driver.close();
-
- return waitForIdle();
- });
-
- it('bubbleUpThroughTheFrameStack', function() {
- let e = new error.NoSuchWindowError('window not found');
- let executor = new FakeExecutor().
- expect(CName.GET_TITLE).
- expect(CName.SWITCH_TO_WINDOW, {
- 'name': 'foo',
- 'handle': 'foo'
- }).
- andReturnError(e).
+ expect(CName.QUIT).
end();
var driver = executor.createDriver();
driver.getTitle().
+ // Everything in this callback...
then(function() {
- return driver.switchTo().window('foo');
- }).
- catch(v => assert.strictEqual(v, e));
-
- return waitForIdle();
- });
-
- it('canBeCaughtAndSuppressed', function() {
- let executor = new FakeExecutor().
- expect(CName.GET_TITLE).
- expect(CName.GET_CURRENT_URL).
- expect(CName.SWITCH_TO_WINDOW, {
- 'name': 'foo',
- 'handle': 'foo'
+ driver.getCurrentUrl();
+ driver.getWindowHandle();
}).
- andReturnError(new StubError()).
- expect(CName.CLOSE).
- end();
-
- var driver = executor.createDriver();
- driver.getTitle().then(function() {
- driver.getCurrentUrl().
- then(function() {
- return driver.switchTo().window('foo');
- }).
- catch(function() {});
- driver.close();
- });
+ // ...should execute before everything in this callback.
+ then(function() {
+ driver.close();
+ });
+ // This should execute after everything above
+ driver.quit();
return waitForIdle();
});
@@ -678,18 +646,16 @@ describe('WebDriver', function() {
end();
var driver = executor.createDriver();
- driver.getTitle().
+ return driver.getTitle().
then(function() {
return driver.getCurrentUrl();
}).
then(function(value) {
assert.equal('http://www.google.com', value);
});
- return waitForIdle();
});
it('fromAnErrbackSuppressesTheError', function() {
- var count = 0;
let executor = new FakeExecutor().
expect(CName.SWITCH_TO_WINDOW, {
'name': 'foo',
@@ -701,19 +667,12 @@ describe('WebDriver', function() {
end();
var driver = executor.createDriver();
- driver.switchTo().window('foo').
+ return driver.switchTo().window('foo').
catch(function(e) {
assertIsStubError(e);
- count += 1;
return driver.getCurrentUrl();
}).
- then(function(url) {
- count += 1;
- assert.equal('http://www.google.com', url);
- });
- return waitForIdle().then(function() {
- assert.equal(2, count);
- });
+ then(url => assert.equal('http://www.google.com', url));
});
});
@@ -725,23 +684,25 @@ describe('WebDriver', function() {
});
});
- it('executionOrderWithCustomFunctions', function() {
- var msg = [];
- let executor = new FakeExecutor().
- expect(CName.GET_TITLE).andReturnSuccess('cheese ').
- expect(CName.GET_CURRENT_URL).andReturnSuccess('tasty').
- end();
+ enablePromiseManager(() => {
+ it('executionOrderWithCustomFunctions', function() {
+ var msg = [];
+ let executor = new FakeExecutor().
+ expect(CName.GET_TITLE).andReturnSuccess('cheese ').
+ expect(CName.GET_CURRENT_URL).andReturnSuccess('tasty').
+ end();
- var driver = executor.createDriver();
+ var driver = executor.createDriver();
- var pushMsg = msg.push.bind(msg);
- driver.getTitle().then(pushMsg);
- driver.call(() => 'is ').then(pushMsg);
- driver.getCurrentUrl().then(pushMsg);
- driver.call(() => '!').then(pushMsg);
+ var pushMsg = msg.push.bind(msg);
+ driver.getTitle().then(pushMsg);
+ driver.call(() => 'is ').then(pushMsg);
+ driver.getCurrentUrl().then(pushMsg);
+ driver.call(() => '!').then(pushMsg);
- return waitForIdle().then(function() {
- assert.equal('cheese is tasty!', msg.join(''));
+ return waitForIdle().then(function() {
+ assert.equal('cheese is tasty!', msg.join(''));
+ });
});
});
@@ -756,7 +717,7 @@ describe('WebDriver', function() {
});
it('passingPromisedArgumentsToACustomFunction', function() {
- var promisedArg = promise.fulfilled(2);
+ var promisedArg = Promise.resolve(2);
var add = function(a, b) {
return a + b;
};
@@ -834,30 +795,32 @@ describe('WebDriver', function() {
}).then(fail, assertIsStubError);
});
- it('doesNotCompleteUntilReturnedPromiseIsResolved', function() {
- var order = [];
- var driver = new FakeExecutor().createDriver();
+ enablePromiseManager(() => {
+ it('doesNotCompleteUntilReturnedPromiseIsResolved', function() {
+ var order = [];
+ var driver = new FakeExecutor().createDriver();
- var d = promise.defer();
- d.promise.then(function() {
- order.push('b');
- });
+ var d = promise.defer();
+ d.promise.then(function() {
+ order.push('b');
+ });
- driver.call(function() {
- order.push('a');
- return d.promise;
- });
- driver.call(function() {
- order.push('c');
- });
+ driver.call(function() {
+ order.push('a');
+ return d.promise;
+ });
+ driver.call(function() {
+ order.push('c');
+ });
- // timeout to ensure the first function starts its execution before we
- // trigger d's callbacks.
- return new Promise(f => setTimeout(f, 0)).then(function() {
- assert.deepEqual(['a'], order);
- d.fulfill();
- return waitForIdle().then(function() {
- assert.deepEqual(['a', 'b', 'c'], order);
+ // timeout to ensure the first function starts its execution before we
+ // trigger d's callbacks.
+ return new Promise(f => setTimeout(f, 0)).then(function() {
+ assert.deepEqual(['a'], order);
+ d.fulfill();
+ return waitForIdle().then(function() {
+ assert.deepEqual(['a', 'b', 'c'], order);
+ });
});
});
});
@@ -878,36 +841,58 @@ describe('WebDriver', function() {
});
describe('nestedCommands', function() {
- it('commandExecutionOrder', function() {
- var msg = [];
- var driver = new FakeExecutor().createDriver();
- driver.call(msg.push, msg, 'a');
- driver.call(function() {
- driver.call(msg.push, msg, 'c');
+ enablePromiseManager(() => {
+ it('commandExecutionOrder', function() {
+ var msg = [];
+ var driver = new FakeExecutor().createDriver();
+ driver.call(msg.push, msg, 'a');
driver.call(function() {
- driver.call(msg.push, msg, 'e');
- driver.call(msg.push, msg, 'f');
+ driver.call(msg.push, msg, 'c');
+ driver.call(function() {
+ driver.call(msg.push, msg, 'e');
+ driver.call(msg.push, msg, 'f');
+ });
+ driver.call(msg.push, msg, 'd');
+ });
+ driver.call(msg.push, msg, 'b');
+ return waitForIdle().then(function() {
+ assert.equal('acefdb', msg.join(''));
});
- driver.call(msg.push, msg, 'd');
- });
- driver.call(msg.push, msg, 'b');
- return waitForIdle().then(function() {
- assert.equal('acefdb', msg.join(''));
});
- });
- it('basicUsage', function() {
- var msg = [];
- var driver = new FakeExecutor().createDriver();
- var pushMsg = msg.push.bind(msg);
- driver.call(() => 'cheese ').then(pushMsg);
- driver.call(function() {
- driver.call(() => 'is ').then(pushMsg);
- driver.call(() => 'tasty').then(pushMsg);
+ it('basicUsage', function() {
+ var msg = [];
+ var driver = new FakeExecutor().createDriver();
+ var pushMsg = msg.push.bind(msg);
+ driver.call(() => 'cheese ').then(pushMsg);
+ driver.call(function() {
+ driver.call(() => 'is ').then(pushMsg);
+ driver.call(() => 'tasty').then(pushMsg);
+ });
+ driver.call(() => '!').then(pushMsg);
+ return waitForIdle().then(function() {
+ assert.equal('cheese is tasty!', msg.join(''));
+ });
});
- driver.call(() => '!').then(pushMsg);
- return waitForIdle().then(function() {
- assert.equal('cheese is tasty!', msg.join(''));
+
+ it('normalCommandAfterNestedCommandThatReturnsAnAction', function() {
+ var msg = [];
+ let executor = new FakeExecutor().
+ expect(CName.CLOSE).
+ end();
+ var driver = executor.createDriver();
+ driver.call(function() {
+ return driver.call(function() {
+ msg.push('a');
+ return driver.call(() => 'foobar');
+ });
+ });
+ driver.close().then(function() {
+ msg.push('b');
+ });
+ return waitForIdle().then(function() {
+ assert.equal('ab', msg.join(''));
+ });
});
});
@@ -922,26 +907,6 @@ describe('WebDriver', function() {
});
});
- it('normalCommandAfterNestedCommandThatReturnsAnAction', function() {
- var msg = [];
- let executor = new FakeExecutor().
- expect(CName.CLOSE).
- end();
- var driver = executor.createDriver();
- driver.call(function() {
- return driver.call(function() {
- msg.push('a');
- return driver.call(() => 'foobar');
- });
- });
- driver.close().then(function() {
- msg.push('b');
- });
- return waitForIdle().then(function() {
- assert.equal('ab', msg.join(''));
- });
- });
-
it('errorsBubbleUp_caught', function() {
var driver = new FakeExecutor().createDriver();
var result = driver.call(function() {
@@ -954,12 +919,12 @@ describe('WebDriver', function() {
it('errorsBubbleUp_uncaught', function() {
var driver = new FakeExecutor().createDriver();
- driver.call(function() {
+ return driver.call(function() {
return driver.call(function() {
return driver.call(throwStubError);
});
- });
- return waitForAbort().then(assertIsStubError);
+ })
+ .then(_ => assert.fail('should have failed'), assertIsStubError);
});
it('canScheduleCommands', function() {
@@ -980,29 +945,27 @@ describe('WebDriver', function() {
});
describe('WebElementPromise', function() {
+ let driver = new FakeExecutor().createDriver();
+
it('resolvesWhenUnderlyingElementDoes', function() {
- var el = new WebElement({}, {'ELEMENT': 'foo'});
- return new WebElementPromise({}, promise.fulfilled(el)).then(function(e) {
- assert.strictEqual(e, el);
- });
+ let el = new WebElement(driver, {'ELEMENT': 'foo'});
+ return new WebElementPromise(driver, Promise.resolve(el))
+ .then(e => assert.strictEqual(e, el));
});
it('resolvesBeforeCallbacksOnWireValueTrigger', function() {
- var el = new promise.Deferred();
+ var el = defer();
- var element = new WebElementPromise({}, el.promise);
+ var element = new WebElementPromise(driver, el.promise);
var messages = [];
- element.then(function() {
- messages.push('element resolved');
- });
- element.getId().then(function() {
- messages.push('wire value resolved');
- });
+ let steps = [
+ element.then(_ => messages.push('element resolved')),
+ element.getId().then(_ => messages.push('wire value resolved'))
+ ];
- assert.deepEqual([], messages);
- el.fulfill(new WebElement({}, {'ELEMENT': 'foo'}));
- return waitForIdle().then(function() {
+ el.resolve(new WebElement(driver, {'ELEMENT': 'foo'}));
+ return Promise.all(steps).then(function() {
assert.deepEqual([
'element resolved',
'wire value resolved'
@@ -1011,7 +974,8 @@ describe('WebDriver', function() {
});
it('isRejectedIfUnderlyingIdIsRejected', function() {
- var element = new WebElementPromise({}, promise.rejected(new StubError));
+ let element =
+ new WebElementPromise(driver, Promise.reject(new StubError));
return element.then(fail, assertIsStubError);
});
});
@@ -1207,7 +1171,7 @@ describe('WebDriver', function() {
it('failsIfArgumentIsARejectedPromise', function() {
let executor = new FakeExecutor();
- var arg = promise.rejected(new StubError);
+ var arg = Promise.reject(new StubError);
arg.catch(function() {}); // Suppress default handler.
var driver = executor.createDriver();
@@ -1218,7 +1182,7 @@ describe('WebDriver', function() {
describe('executeAsyncScript', function() {
it('failsIfArgumentIsARejectedPromise', function() {
- var arg = promise.rejected(new StubError);
+ var arg = Promise.reject(new StubError);
arg.catch(function() {}); // Suppress default handler.
var driver = new FakeExecutor().createDriver();
@@ -1236,9 +1200,8 @@ describe('WebDriver', function() {
end();
var driver = executor.createDriver();
- var element = driver.findElement(By.id('foo'));
- element.click(); // This should never execute.
- return waitForAbort().then(assertIsStubError);
+ return driver.findElement(By.id('foo'))
+ .then(assert.fail, assertIsStubError);
});
it('elementNotFoundInACallback', function() {
@@ -1249,11 +1212,9 @@ describe('WebDriver', function() {
end();
var driver = executor.createDriver();
- promise.fulfilled().then(function() {
- var element = driver.findElement(By.id('foo'));
- return element.click(); // Should not execute.
- });
- return waitForAbort().then(assertIsStubError);
+ return Promise.resolve()
+ .then(_ => driver.findElement(By.id('foo')))
+ .then(assert.fail, assertIsStubError);
});
it('elementFound', function() {
@@ -1261,7 +1222,7 @@ describe('WebDriver', function() {
expect(CName.FIND_ELEMENT,
{using: 'css selector', value: '*[id="foo"]'}).
andReturnSuccess(WebElement.buildId('bar')).
- expect(CName.CLICK_ELEMENT, {'id': 'bar'}).
+ expect(CName.CLICK_ELEMENT, {'id': WebElement.buildId('bar')}).
andReturnSuccess().
end();
@@ -1276,7 +1237,7 @@ describe('WebDriver', function() {
expect(CName.FIND_ELEMENT,
{using: 'css selector', value: '*[id="foo"]'}).
andReturnSuccess(WebElement.buildId('bar')).
- expect(CName.CLICK_ELEMENT, {'id': 'bar'}).
+ expect(CName.CLICK_ELEMENT, {'id': WebElement.buildId('bar')}).
andReturnSuccess().
end();
@@ -1294,7 +1255,7 @@ describe('WebDriver', function() {
'args': []
}).
andReturnSuccess(WebElement.buildId('bar')).
- expect(CName.CLICK_ELEMENT, {'id': 'bar'}).
+ expect(CName.CLICK_ELEMENT, {'id': WebElement.buildId('bar')}).
end();
var driver = executor.createDriver();
@@ -1310,12 +1271,12 @@ describe('WebDriver', function() {
end();
var driver = executor.createDriver();
- var element = driver.findElement(By.js('return 123'));
- element.click(); // Should not execute.
- return waitForAbort().then(function(e) {
- assertIsInstance(TypeError, e);
- assert.equal('Custom locator did not return a WebElement', e.message);
- });
+ return driver.findElement(By.js('return 123'))
+ .then(assert.fail, function(e) {
+ assertIsInstance(TypeError, e);
+ assert.equal(
+ 'Custom locator did not return a WebElement', e.message);
+ });
});
it('byJs_canPassArguments', function() {
@@ -1325,7 +1286,7 @@ describe('WebDriver', function() {
'script': script,
'args': ['div']
}).
- andReturnSuccess({'ELEMENT':'one'}).
+ andReturnSuccess(WebElement.buildId('one')).
end();
var driver = executor.createDriver();
driver.findElement(By.js(script, 'div'));
@@ -1338,7 +1299,7 @@ describe('WebDriver', function() {
andReturnSuccess([
WebElement.buildId('foo'),
WebElement.buildId('bar')]).
- expect(CName.CLICK_ELEMENT, {'id': 'foo'}).
+ expect(CName.CLICK_ELEMENT, {'id': WebElement.buildId('foo')}).
andReturnSuccess().
end();
@@ -1347,19 +1308,17 @@ describe('WebDriver', function() {
assert.equal(driver, d);
return d.findElements(By.tagName('a'));
});
- element.click();
- return waitForIdle();
+ return element.click();
});
it('customLocatorThrowsIfresultIsNotAWebElement', function() {
var driver = new FakeExecutor().createDriver();
- driver.findElement(function() {
- return 1;
- });
- return waitForAbort().then(function(e) {
- assertIsInstance(TypeError, e);
- assert.equal('Custom locator did not return a WebElement', e.message);
- });
+ return driver.findElement(_ => 1)
+ .then(assert.fail, function(e) {
+ assertIsInstance(TypeError, e);
+ assert.equal(
+ 'Custom locator did not return a WebElement', e.message);
+ });
});
});
@@ -1486,7 +1445,8 @@ describe('WebDriver', function() {
it('convertsVarArgsIntoStrings_simpleArgs', function() {
let executor = new FakeExecutor().
expect(CName.SEND_KEYS_TO_ELEMENT,
- {'id': 'one', 'value':'12abc3'.split('')}).
+ {'id': WebElement.buildId('one'),
+ 'value':'12abc3'.split('')}).
andReturnSuccess().
end();
@@ -1502,16 +1462,17 @@ describe('WebDriver', function() {
{'using':'css selector', 'value':'*[id="foo"]'}).
andReturnSuccess(WebElement.buildId('one')).
expect(CName.SEND_KEYS_TO_ELEMENT,
- {'id':'one', 'value':'abc123def'.split('')}).
+ {'id':WebElement.buildId('one'),
+ 'value':'abc123def'.split('')}).
andReturnSuccess().
end();
var driver = executor.createDriver();
var element = driver.findElement(By.id('foo'));
- element.sendKeys(
- promise.fulfilled('abc'), 123,
- promise.fulfilled('def'));
- return waitForIdle();
+ return element.sendKeys(
+ Promise.resolve('abc'),
+ 123,
+ Promise.resolve('def'));
});
it('sendKeysWithAFileDetector', function() {
@@ -1520,7 +1481,8 @@ describe('WebDriver', function() {
{'using':'css selector', 'value':'*[id="foo"]'}).
andReturnSuccess(WebElement.buildId('one')).
expect(CName.SEND_KEYS_TO_ELEMENT,
- {'id': 'one', 'value':'modified/path'.split('')}).
+ {'id': WebElement.buildId('one'),
+ 'value':'modified/path'.split('')}).
andReturnSuccess().
end();
@@ -1528,13 +1490,11 @@ describe('WebDriver', function() {
let handleFile = function(d, path) {
assert.strictEqual(driver, d);
assert.equal(path, 'original/path');
- return promise.fulfilled('modified/path');
+ return Promise.resolve('modified/path');
};
driver.setFileDetector({handleFile});
- var element = driver.findElement(By.id('foo'));
- element.sendKeys('original/', 'path');
- return waitForIdle();
+ return driver.findElement(By.id('foo')).sendKeys('original/', 'path');
});
});
@@ -1554,7 +1514,7 @@ describe('WebDriver', function() {
return waitForIdle();
});
- it('should propogate exceptions', function() {
+ it('should propagate exceptions', function() {
let e = new error.NoSuchWindowError('window not found');
let executor = new FakeExecutor().
expect(CName.SWITCH_TO_WINDOW).
@@ -1565,21 +1525,21 @@ describe('WebDriver', function() {
andReturnError(e).
end();
- executor.createDriver().switchTo().window('foo');
- return waitForAbort().then(v => assert.strictEqual(v, e));
+ return executor.createDriver()
+ .switchTo().window('foo')
+ .then(assert.fail, v => assert.strictEqual(v, e));
});
});
});
describe('elementEquality', function() {
it('isReflexive', function() {
- var a = new WebElement({}, 'foo');
+ var a = new WebElement(new FakeExecutor().createDriver(), 'foo');
return WebElement.equals(a, a).then(assert.ok);
});
it('failsIfAnInputElementCouldNotBeFound', function() {
- var id = promise.rejected(new StubError);
- id.catch(function() {}); // Suppress default handler.
+ let id = Promise.reject(new StubError);
var driver = new FakeExecutor().createDriver();
var a = new WebElement(driver, 'foo');
@@ -1590,71 +1550,134 @@ describe('WebDriver', function() {
});
describe('waiting', function() {
- it('waitSucceeds', function() {
- let executor = new FakeExecutor().
- expect(CName.FIND_ELEMENTS,
- {using: 'css selector', value: '*[id="foo"]'}).
- andReturnSuccess([]).
- times(2).
- expect(CName.FIND_ELEMENTS,
- {using: 'css selector', value: '*[id="foo"]'}).
- andReturnSuccess([WebElement.buildId('bar')]).
- end();
+ describe('supports custom wait functions', function() {
+ it('waitSucceeds', function() {
+ let executor = new FakeExecutor().
+ expect(CName.FIND_ELEMENTS,
+ {using: 'css selector', value: '*[id="foo"]'}).
+ andReturnSuccess([]).
+ times(2).
+ expect(CName.FIND_ELEMENTS,
+ {using: 'css selector', value: '*[id="foo"]'}).
+ andReturnSuccess([WebElement.buildId('bar')]).
+ end();
- var driver = executor.createDriver();
- driver.wait(function() {
- return driver.findElements(By.id('foo')).then(els => els.length > 0);
- }, 200);
- return waitForIdle();
+ var driver = executor.createDriver();
+ driver.wait(function() {
+ return driver.findElements(By.id('foo')).then(els => els.length > 0);
+ }, 200);
+ return waitForIdle();
+ });
+
+ it('waitTimesout_timeoutCaught', function() {
+ let executor = new FakeExecutor().
+ expect(CName.FIND_ELEMENTS,
+ {using: 'css selector', value: '*[id="foo"]'}).
+ andReturnSuccess([]).
+ anyTimes().
+ end();
+
+ var driver = executor.createDriver();
+ return driver.wait(function() {
+ return driver.findElements(By.id('foo')).then(els => els.length > 0);
+ }, 25).then(fail, function(e) {
+ assert.equal('Wait timed out after ',
+ e.message.substring(0, 'Wait timed out after '.length));
+ });
+ });
+
+ enablePromiseManager(() => {
+ it('waitTimesout_timeoutNotCaught', function() {
+ let executor = new FakeExecutor().
+ expect(CName.FIND_ELEMENTS,
+ {using: 'css selector', value: '*[id="foo"]'}).
+ andReturnSuccess([]).
+ anyTimes().
+ end();
+
+ var driver = executor.createDriver();
+ driver.wait(function() {
+ return driver.findElements(By.id('foo')).then(els => els.length > 0);
+ }, 25);
+ return waitForAbort().then(function(e) {
+ assert.equal('Wait timed out after ',
+ e.message.substring(0, 'Wait timed out after '.length));
+ });
+ });
+ });
});
- it('waitTimesout_timeoutCaught', function() {
- let executor = new FakeExecutor().
- expect(CName.FIND_ELEMENTS,
- {using: 'css selector', value: '*[id="foo"]'}).
- andReturnSuccess([]).
- anyTimes().
- end();
+ describe('supports condition objects', function() {
+ it('wait succeeds', function() {
+ let executor = new FakeExecutor()
+ .expect(CName.FIND_ELEMENTS,
+ {using: 'css selector', value: '*[id="foo"]'})
+ .andReturnSuccess([])
+ .times(2)
+ .expect(CName.FIND_ELEMENTS,
+ {using: 'css selector', value: '*[id="foo"]'})
+ .andReturnSuccess([WebElement.buildId('bar')])
+ .end();
- var driver = executor.createDriver();
- return driver.wait(function() {
- return driver.findElements(By.id('foo')).then(els => els.length > 0);
- }, 25).then(fail, function(e) {
- assert.equal('Wait timed out after ',
- e.message.substring(0, 'Wait timed out after '.length));
+ let driver = executor.createDriver();
+ return driver.wait(until.elementLocated(By.id('foo')), 200);
+ });
+
+ it('wait times out', function() {
+ let executor = new FakeExecutor()
+ .expect(CName.FIND_ELEMENTS,
+ {using: 'css selector', value: '*[id="foo"]'})
+ .andReturnSuccess([])
+ .anyTimes()
+ .end();
+
+ let driver = executor.createDriver();
+ return driver.wait(until.elementLocated(By.id('foo')), 5)
+ .then(fail, err => assert.ok(err instanceof error.TimeoutError));
});
});
- it('waitTimesout_timeoutNotCaught', function() {
- let executor = new FakeExecutor().
- expect(CName.FIND_ELEMENTS,
- {using: 'css selector', value: '*[id="foo"]'}).
- andReturnSuccess([]).
- anyTimes().
- end();
+ describe('supports promise objects', function() {
+ it('wait succeeds', function() {
+ let promise = new Promise(resolve => {
+ setTimeout(() => resolve(1), 10);
+ });
- var driver = executor.createDriver();
- driver.wait(function() {
- return driver.findElements(By.id('foo')).then(els => els.length > 0);
- }, 25);
- return waitForAbort().then(function(e) {
- assert.equal('Wait timed out after ',
- e.message.substring(0, 'Wait timed out after '.length));
+ let driver = new FakeExecutor().createDriver();
+ return driver.wait(promise, 200).then(v => assert.equal(v, 1));
+ });
+
+ it('wait times out', function() {
+ let promise = new Promise(resolve => {/* never resolves */});
+
+ let driver = new FakeExecutor().createDriver();
+ return driver.wait(promise, 5)
+ .then(fail, err => assert.ok(err instanceof error.TimeoutError));
+ });
+
+ it('wait fails if promise is rejected', function() {
+ let err = Error('boom');
+ let driver = new FakeExecutor().createDriver();
+ return driver.wait(Promise.reject(err), 5)
+ .then(fail, e => assert.strictEqual(e, err));
});
});
+
+ it('fails if not supported condition type provided', function() {
+ let driver = new FakeExecutor().createDriver();
+ assert.throws(() => driver.wait({}, 5), TypeError);
+ });
});
describe('alert handling', function() {
it('alertResolvesWhenPromisedTextResolves', function() {
- var deferredText = new promise.Deferred();
+ let driver = new FakeExecutor().createDriver();
+ let deferredText = defer();
- var alert = new AlertPromise({}, deferredText.promise);
- assert.ok(alert.isPending());
+ let alert = new AlertPromise(driver, deferredText.promise);
- deferredText.fulfill(new Alert({}, 'foo'));
- return alert.getText().then(function(text) {
- assert.equal('foo', text);
- });
+ deferredText.resolve(new Alert(driver, 'foo'));
+ return alert.getText().then(text => assert.equal(text, 'foo'));
});
it('cannotSwitchToAlertThatIsNotPresent', function() {
@@ -1664,32 +1687,33 @@ describe('WebDriver', function() {
.andReturnError(e)
.end();
- var driver = executor.createDriver();
- var alert = driver.switchTo().alert();
- alert.dismiss(); // Should never execute.
- return waitForAbort().then(v => assert.strictEqual(v, e));
+ return executor.createDriver()
+ .switchTo().alert()
+ .then(assert.fail, v => assert.strictEqual(v, e));
});
- it('alertsBelongToSameFlowAsParentDriver', function() {
- let executor = new FakeExecutor()
- .expect(CName.GET_ALERT_TEXT).andReturnSuccess('hello')
- .end();
+ enablePromiseManager(() => {
+ it('alertsBelongToSameFlowAsParentDriver', function() {
+ let executor = new FakeExecutor()
+ .expect(CName.GET_ALERT_TEXT).andReturnSuccess('hello')
+ .end();
- var driver = executor.createDriver();
- var otherFlow = new promise.ControlFlow();
- otherFlow.execute(function() {
- driver.switchTo().alert().then(function() {
- assert.strictEqual(
- driver.controlFlow(), promise.controlFlow(),
- 'Alert should belong to the same flow as its parent driver');
+ var driver = executor.createDriver();
+ var otherFlow = new promise.ControlFlow();
+ otherFlow.execute(function() {
+ driver.switchTo().alert().then(function() {
+ assert.strictEqual(
+ driver.controlFlow(), promise.controlFlow(),
+ 'Alert should belong to the same flow as its parent driver');
+ });
});
- });
- assert.notEqual(otherFlow, driver.controlFlow);
- return Promise.all([
- waitForIdle(otherFlow),
- waitForIdle(driver.controlFlow())
- ]);
+ assert.notEqual(otherFlow, driver.controlFlow);
+ return Promise.all([
+ waitForIdle(otherFlow),
+ waitForIdle(driver.controlFlow())
+ ]);
+ });
});
it('commandsFailIfAlertNotPresent', function() {
@@ -1715,26 +1739,28 @@ describe('WebDriver', function() {
});
});
- it('testWebElementsBelongToSameFlowAsParentDriver', function() {
- let executor = new FakeExecutor()
- .expect(CName.FIND_ELEMENT,
- {using: 'css selector', value: '*[id="foo"]'})
- .andReturnSuccess(WebElement.buildId('abc123'))
- .end();
+ enablePromiseManager(() => {
+ it('testWebElementsBelongToSameFlowAsParentDriver', function() {
+ let executor = new FakeExecutor()
+ .expect(CName.FIND_ELEMENT,
+ {using: 'css selector', value: '*[id="foo"]'})
+ .andReturnSuccess(WebElement.buildId('abc123'))
+ .end();
- var driver = executor.createDriver();
- var otherFlow = new promise.ControlFlow();
- otherFlow.execute(function() {
- driver.findElement({id: 'foo'}).then(function() {
- assert.equal(driver.controlFlow(), promise.controlFlow());
+ var driver = executor.createDriver();
+ var otherFlow = new promise.ControlFlow();
+ otherFlow.execute(function() {
+ driver.findElement({id: 'foo'}).then(function() {
+ assert.equal(driver.controlFlow(), promise.controlFlow());
+ });
});
- });
- assert.notEqual(otherFlow, driver.controlFlow);
- return Promise.all([
- waitForIdle(otherFlow),
- waitForIdle(driver.controlFlow())
- ]);
+ assert.notEqual(otherFlow, driver.controlFlow);
+ return Promise.all([
+ waitForIdle(otherFlow),
+ waitForIdle(driver.controlFlow())
+ ]);
+ });
});
it('testFetchingLogs', function() {
@@ -1763,7 +1789,7 @@ describe('WebDriver', function() {
});
it('testCommandsFailIfInitialSessionCreationFailed', function() {
- var session = promise.rejected(new StubError);
+ var session = Promise.reject(new StubError);
var driver = new FakeExecutor().createDriver(session);
var navigateResult = driver.get('some-url').then(fail, assertIsStubError);
@@ -1811,10 +1837,10 @@ describe('WebDriver', function() {
describe('actions()', function() {
it('failsIfInitialDriverCreationFailed', function() {
- let session = promise.rejected(new StubError);
- session.catch(function() {});
- return new FakeExecutor().
- createDriver(session).
+ let session = Promise.reject(new StubError('no session for you'));
+ let driver = new FakeExecutor().createDriver(session);
+ driver.getSession().catch(function() {});
+ return driver.
actions().
mouseDown().
mouseUp().
@@ -1900,10 +1926,10 @@ describe('WebDriver', function() {
describe('touchActions()', function() {
it('failsIfInitialDriverCreationFailed', function() {
- let session = promise.rejected(new StubError);
- session.catch(function() {});
- return new FakeExecutor().
- createDriver(session).
+ let session = Promise.reject(new StubError);
+ let driver = new FakeExecutor().createDriver(session);
+ driver.getSession().catch(function() {});
+ return driver.
touchActions().
scroll({x: 3, y: 4}).
perform().
@@ -1937,8 +1963,8 @@ describe('WebDriver', function() {
it('canUseGeneratorsWithWebDriverCall', function() {
return driver.call(function* () {
- var x = yield promise.fulfilled(1);
- var y = yield promise.fulfilled(2);
+ var x = yield Promise.resolve(1);
+ var y = yield Promise.resolve(2);
return x + y;
}).then(function(value) {
assert.deepEqual(3, value);
@@ -1947,7 +1973,7 @@ describe('WebDriver', function() {
it('canDefineScopeOnGeneratorCall', function() {
return driver.call(function* () {
- var x = yield promise.fulfilled(1);
+ var x = yield Promise.resolve(1);
return this.name + x;
}, {name: 'Bob'}).then(function(value) {
assert.deepEqual('Bob1', value);
@@ -1956,8 +1982,8 @@ describe('WebDriver', function() {
it('canSpecifyArgsOnGeneratorCall', function() {
return driver.call(function* (a, b) {
- var x = yield promise.fulfilled(1);
- var y = yield promise.fulfilled(2);
+ var x = yield Promise.resolve(1);
+ var y = yield Promise.resolve(2);
return [x + y, a, b];
}, null, 'abc', 123).then(function(value) {
assert.deepEqual([3, 'abc', 123], value);
@@ -1992,6 +2018,8 @@ describe('WebDriver', function() {
});
describe('wire format', function() {
+ const FAKE_DRIVER = new FakeExecutor().createDriver();
+
describe('can serialize', function() {
function runSerializeTest(input, want) {
let executor = new FakeExecutor().
@@ -2035,14 +2063,15 @@ describe('WebDriver', function() {
it('WebElement', function() {
return runSerializeTest(
- new WebElement({}, 'fefifofum'),
+ new WebElement(FAKE_DRIVER, 'fefifofum'),
WebElement.buildId('fefifofum'));
});
it('WebElementPromise', function() {
return runSerializeTest(
new WebElementPromise(
- {}, promise.fulfilled(new WebElement({}, 'fefifofum'))),
+ FAKE_DRIVER,
+ Promise.resolve(new WebElement(FAKE_DRIVER, 'fefifofum'))),
WebElement.buildId('fefifofum'));
});
@@ -2053,14 +2082,15 @@ describe('WebDriver', function() {
it('with WebElement', function() {
return runSerializeTest(
- [new WebElement({}, 'fefifofum')],
+ [new WebElement(FAKE_DRIVER, 'fefifofum')],
[WebElement.buildId('fefifofum')]);
});
it('with WebElementPromise', function() {
return runSerializeTest(
[new WebElementPromise(
- {}, promise.fulfilled(new WebElement({}, 'fefifofum')))],
+ FAKE_DRIVER,
+ Promise.resolve(new WebElement(FAKE_DRIVER, 'fefifofum')))],
[WebElement.buildId('fefifofum')]);
});
@@ -2070,7 +2100,7 @@ describe('WebDriver', function() {
[123, {'foo': 'bar'}]
];
- var element = new WebElement({}, 'fefifofum');
+ var element = new WebElement(FAKE_DRIVER, 'fefifofum');
var input = ['abc', 123, true, element, [123, {'foo': 'bar'}]];
return runSerializeTest(input, expected);
});
@@ -2114,7 +2144,7 @@ describe('WebDriver', function() {
'sessionId': 'foo'
};
- var element = new WebElement({}, 'fefifofum');
+ var element = new WebElement(FAKE_DRIVER, 'fefifofum');
var parameters = {
'script': 'return 1',
'args':['abc', 123, true, element, [123, {'foo': 'bar'}]],