diff options
Diffstat (limited to 'remoting/webapp/unittests')
| -rw-r--r-- | remoting/webapp/unittests/spy_promise.js | 294 | ||||
| -rw-r--r-- | remoting/webapp/unittests/spy_promise_unittest.js | 253 |
2 files changed, 0 insertions, 547 deletions
diff --git a/remoting/webapp/unittests/spy_promise.js b/remoting/webapp/unittests/spy_promise.js deleted file mode 100644 index fb0894a..0000000 --- a/remoting/webapp/unittests/spy_promise.js +++ /dev/null @@ -1,294 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -'use strict'; - -/** @suppress {duplicate} */ -var base = base || {}; - -(function() { -/** - * A wrapper around a Promise object that keeps track of all - * outstanding promises. This function is written to serve as a - * drop-in replacement for the native Promise constructor. To create - * a SpyPromise from an existing native Promise, use - * SpyPromise.resolve. - * - * Note that this is a pseudo-constructor that actually returns a - * regular promise with appropriate handlers attached. This detail - * should be transparent when SpyPromise.activate has been called. - * - * The normal way to use this class is within a call to - * SpyPromise.run, for example: - * - * base.SpyPromise.run(function() { - * myCodeThatUsesPromises(); - * }); - * base.SpyPromise.settleAll().then(function() { - * console.log('All promises have been settled!'); - * }); - * - * @constructor - * @extends {Promise} - * @param {function(function(?):?, function(*):?):?} func A function - * of the same type used as an argument to the native Promise - * constructor, in other words, a function which is called - * immediately, and whose arguments are a resolve function and a - * reject function. - */ -base.SpyPromise = function(func) { - var unsettled = new RealPromise(func); - var unsettledId = remember(unsettled); - return unsettled.then(function(/** * */value) { - forget(unsettledId); - return value; - }, function(error) { - forget(unsettledId); - throw error; - }); -}; - -/** - * The real promise constructor. Needed because it is normally hidden - * by SpyPromise.activate or SpyPromise.run. - * @const - */ -var RealPromise = Promise; - -/** - * The real window.setTimeout method. Needed because some test - * frameworks like to replace this method with a fake implementation. - * @const - */ -var realSetTimeout = window.setTimeout.bind(window); - -/** - * The number of unsettled promises. - * @type {number} - */ -base.SpyPromise.unsettledCount; // initialized by reset() - -/** - * A collection of all unsettled promises. - * @type {!Object<number,!Promise>} - */ -var unsettled; // initialized by reset() - -/** - * A counter used to assign ID numbers to new SpyPromise objects. - * @type {number} - */ -var nextPromiseId; // initialized by reset() - -/** - * A promise returned by SpyPromise.settleAll. - * @type {Promise<null>} - */ -var settleAllPromise; // initialized by reset() - -/** - * Records an unsettled promise. - * - * @param {!Promise} unsettledPromise - * @return {number} The ID number to be passed to forget_. - */ -function remember(unsettledPromise) { - var id = nextPromiseId++; - if (unsettled[id] != null) { - throw Error('Duplicate ID: ' + id); - } - base.SpyPromise.unsettledCount++; - unsettled[id] = unsettledPromise; - return id; -}; - -/** - * Forgets a promise. Called after the promise has been settled. - * - * @param {number} id - * @private - */ -function forget(id) { - console.assert(unsettled[id] != null, 'No such Promise: ' + id + '.'); - base.SpyPromise.unsettledCount--; - delete unsettled[id]; -}; - -/** - * Forgets about all unsettled promises. - */ -base.SpyPromise.reset = function() { - base.SpyPromise.unsettledCount = 0; - unsettled = {}; - nextPromiseId = 0; - settleAllPromise = null; -}; - -// Initialize static variables. -base.SpyPromise.reset(); - -/** - * Tries to wait until all promises has been settled. - * - * @param {number=} opt_maxTimeMs The maximum number of milliseconds - * (approximately) to wait (default: 1000). - * @return {!Promise<null>} A real promise that is resolved when all - * SpyPromises have been settled, or rejected after opt_maxTimeMs - * milliseconds have elapsed. - */ -base.SpyPromise.settleAll = function(opt_maxTimeMs) { - if (settleAllPromise) { - return settleAllPromise; - } - - var maxDelay = opt_maxTimeMs == null ? 1000 : opt_maxTimeMs; - - /** - * @param {number} count - * @param {number} totalDelay - * @return {!Promise<null>} - */ - function loop(count, totalDelay) { - return new RealPromise(function(resolve, reject) { - if (base.SpyPromise.unsettledCount == 0) { - settleAllPromise = null; - resolve(null); - } else if (totalDelay > maxDelay) { - settleAllPromise = null; - base.SpyPromise.reset(); - reject(new Error('base.SpyPromise.settleAll timed out')); - } else { - // This implements quadratic backoff according to Euler's - // triangular number formula. - var delay = count; - - // Must jump through crazy hoops to get a real timer in a unit test. - realSetTimeout(function() { - resolve(loop( - count + 1, - delay + totalDelay)); - }, delay); - } - }); - }; - - // An extra promise needed here to prevent the loop function from - // finishing before settleAllPromise is set. If that happens, - // settleAllPromise will never be reset to null. - settleAllPromise = RealPromise.resolve().then(function() { - return loop(0, 0); - }); - return settleAllPromise; -}; - -/** - * Only for testing this class. Do not use. - * @returns {boolean} True if settleAll is executing. - */ -base.SpyPromise.isSettleAllRunning = function() { - return settleAllPromise != null; -}; - -/** - * Wrapper for Promise.resolve. - * - * @param {*} value - * @return {!base.SpyPromise} - */ -base.SpyPromise.resolve = function(value) { - return new base.SpyPromise(function(resolve, reject) { - resolve(value); - }); -}; - -/** - * Wrapper for Promise.reject. - * - * @param {*} value - * @return {!base.SpyPromise} - */ -base.SpyPromise.reject = function(value) { - return new base.SpyPromise(function(resolve, reject) { - reject(value); - }); -}; - -/** - * Wrapper for Promise.all. - * - * @param {!Array<Promise>} promises - * @return {!base.SpyPromise} - */ -base.SpyPromise.all = function(promises) { - return base.SpyPromise.resolve(RealPromise.all(promises)); -}; - -/** - * Wrapper for Promise.race. - * - * @param {!Array<Promise>} promises - * @return {!base.SpyPromise} - */ -base.SpyPromise.race = function(promises) { - return base.SpyPromise.resolve(RealPromise.race(promises)); -}; - -/** - * Sets Promise = base.SpyPromise. Must not be called more than once - * without an intervening call to restore(). - */ -base.SpyPromise.activate = function() { - if (settleAllPromise) { - throw Error('called base.SpyPromise.activate while settleAll is running'); - } - if (Promise === base.SpyPromise) { - throw Error('base.SpyPromise is already active'); - } - Promise = /** @type {function(new:Promise)} */(base.SpyPromise); -}; - -/** - * Restores the original value of Promise. - */ -base.SpyPromise.restore = function() { - if (settleAllPromise) { - throw Error('called base.SpyPromise.restore while settleAll is running'); - } - if (Promise === base.SpyPromise) { - Promise = RealPromise; - } else if (Promise === RealPromise) { - throw new Error('base.SpyPromise is not active.'); - } else { - throw new Error('Something fishy is going on.'); - } -}; - -/** - * Calls func with Promise equal to base.SpyPromise. - * - * @param {function():void} func A function which is expected to - * create one or more promises. - * @param {number=} opt_timeoutMs An optional timeout specifying how - * long to wait for promise chains started in func to be settled. - * (default: 1000 ms) - * @return {!Promise<null>} A promise that is resolved after every - * promise chain started in func is fully settled, or rejected - * after a opt_timeoutMs. In any case, the original value of the - * Promise constructor is restored before this promise is settled. - */ -base.SpyPromise.run = function(func, opt_timeoutMs) { - base.SpyPromise.activate(); - try { - func(); - } finally { - return base.SpyPromise.settleAll(opt_timeoutMs).then(function() { - base.SpyPromise.restore(); - return null; - }, function(error) { - base.SpyPromise.restore(); - throw error; - }); - } -}; -})(); diff --git a/remoting/webapp/unittests/spy_promise_unittest.js b/remoting/webapp/unittests/spy_promise_unittest.js deleted file mode 100644 index 8071248a..0000000 --- a/remoting/webapp/unittests/spy_promise_unittest.js +++ /dev/null @@ -1,253 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -(function() { - -'use strict'; - -var originalGlobalPromise = Promise; - -QUnit.module('spy_promise', { - beforeEach: function(/** QUnit.Assert*/ assert) { - assertInitialState(assert); - base.SpyPromise.reset(); // Defend against broken tests. - }, - afterEach: function(/** QUnit.Assert*/ assert) { - assertInitialState(assert); - } -}); - -function assertInitialState(/** QUnit.Assert */ assert) { - assert.equal(Promise, originalGlobalPromise); - assert.ok( - !base.SpyPromise.isSettleAllRunning(), - 'settleAll should not be running'); - assert.equal( - base.SpyPromise.unsettledCount, 0, - 'base.SpyPromise.unsettledCount should be zero ' + - 'before/after any test finishes'); -} - -/** - * @param {!QUnit.Assert} assert - * @return {!Promise} - */ -function finish(assert) { - return base.SpyPromise.settleAll().then(function() { - assert.equal( - base.SpyPromise.unsettledCount, 0, - 'base.SpyPromise.unsettledCount should be zero ' + - 'after settleAll finishes.'); - }); -} - -QUnit.test('run', function(assert) { - var done = assert.async(); - assert.notEqual(base.SpyPromise, originalGlobalPromise); - return base.SpyPromise.run(function() { - assert.equal(Promise, base.SpyPromise); - assert.equal(base.SpyPromise.unsettledCount, 0); - var dummy1 = new Promise(function(resolve) { resolve(null); }); - assert.equal(base.SpyPromise.unsettledCount, 1); - }).then(function() { - assert.equal(Promise, originalGlobalPromise); - assert.equal(base.SpyPromise.unsettledCount, 0); - done(); - }); -}); - -QUnit.test('activate/restore', function(assert) { - assert.notEqual(base.SpyPromise, originalGlobalPromise); - base.SpyPromise.activate(); - assert.notEqual(base.SpyPromise, originalGlobalPromise); - assert.equal(base.SpyPromise.unsettledCount, 0); - var dummy1 = new Promise(function(resolve) { resolve(null); }); - assert.equal(base.SpyPromise.unsettledCount, 1); - base.SpyPromise.restore(); - assert.equal(Promise, originalGlobalPromise); - return finish(assert); -}); - -QUnit.test('new/then', function(assert) { - var done = assert.async(); - new base.SpyPromise(function(resolve, reject) { - resolve('hello'); - }).then(function(/**string*/ value) { - assert.equal(base.SpyPromise.unsettledCount, 0); - assert.equal(value, 'hello'); - done(); - }); - assert.equal(base.SpyPromise.unsettledCount, 1); - return finish(assert); -}); - -QUnit.test('new/catch', function(assert) { - var done = assert.async(); - new base.SpyPromise(function(resolve, reject) { - reject('hello'); - }).catch(function(/**string*/ value) { - assert.equal(base.SpyPromise.unsettledCount, 0); - assert.equal(value, 'hello'); - done(); - }); - assert.equal(base.SpyPromise.unsettledCount, 1); - return finish(assert); -}); - -QUnit.test('new+throw/catch', function(assert) { - var done = assert.async(); - new base.SpyPromise(function(resolve, reject) { - throw 'hello'; - }).catch(function(/**string*/ value) { - assert.equal(base.SpyPromise.unsettledCount, 0); - assert.equal(value, 'hello'); - done(); - }); - assert.equal(base.SpyPromise.unsettledCount, 1); - return finish(assert); -}); - -QUnit.test('resolve/then', function(assert) { - var done = assert.async(); - base.SpyPromise.resolve('hello').then(function(/**string*/ value) { - assert.equal(base.SpyPromise.unsettledCount, 0); - assert.equal(value, 'hello'); - done(); - }); - assert.equal(base.SpyPromise.unsettledCount, 1); - return finish(assert); -}); - -QUnit.test('reject/then', function(assert) { - var done = assert.async(); - base.SpyPromise.reject('hello').then(null, function(/**string*/ value) { - assert.equal(base.SpyPromise.unsettledCount, 0); - assert.equal(value, 'hello'); - done(); - }); - assert.equal(base.SpyPromise.unsettledCount, 1); - return finish(assert); -}); - -QUnit.test('reject/catch', function(assert) { - var done = assert.async(); - base.SpyPromise.reject('hello').catch(function(/**string*/ value) { - assert.equal(base.SpyPromise.unsettledCount, 0); - assert.equal(value, 'hello'); - done(); - }); - assert.equal(base.SpyPromise.unsettledCount, 1); - return finish(assert); -}); - -QUnit.test('all', function(assert) { - var done = assert.async(); - base.SpyPromise.all([Promise.resolve(1), Promise.resolve(2)]). - then( - /** @param {string} value */ - function(value) { - assert.equal(base.SpyPromise.unsettledCount, 0); - assert.deepEqual(value, [1, 2]); - done(); - }); - assert.equal(base.SpyPromise.unsettledCount, 1); - return finish(assert); -}); - -QUnit.test('race', function(assert) { - var done = assert.async(); - var fast = Promise.resolve('fast'); - var slow = new Promise(function() {}); // never settled - base.SpyPromise.race([fast, slow]). - then(function(/**string*/ value) { - assert.equal(base.SpyPromise.unsettledCount, 0); - assert.equal(value, 'fast'); - done(); - }); - assert.equal(base.SpyPromise.unsettledCount, 1); - return finish(assert); -}); - -QUnit.test('resolve/then/then', function(assert) { - var done = assert.async(); - base.SpyPromise.resolve('hello').then(function(/**string*/ value) { - assert.equal(value, 'hello'); - return 'goodbye'; - }).then(function(/**string*/ value) { - assert.equal(value, 'goodbye'); - done(); - }); - return finish(assert); -}); - - -QUnit.test('resolve/then+throw/catch', function(assert) { - var done = assert.async(); - base.SpyPromise.resolve('hello').then(function(/**string*/ value) { - assert.equal(value, 'hello'); - throw 'goodbye'; - }).catch(function(/**string*/ value) { - assert.equal(value, 'goodbye'); - done(); - }); - return finish(assert); -}); - -QUnit.test('reject/catch/then', function(assert) { - var done = assert.async(); - base.SpyPromise.reject('hello').catch(function(/**string*/ value) { - assert.equal(value, 'hello'); - return 'goodbye'; - }).then(function(/**string*/ value) { - assert.equal(value, 'goodbye'); - done(); - }); - return finish(assert); -}); - - -QUnit.test('reject/catch+throw/catch', function(assert) { - var done = assert.async(); - base.SpyPromise.reject('hello').catch(function(/**string*/ value) { - assert.equal(value, 'hello'); - throw 'goodbye'; - }).catch(function(/**string*/ value) { - assert.equal(value, 'goodbye'); - done(); - }); - return finish(assert); -}); - -QUnit.test('settleAll timeout = 100', function(assert) { - var done = assert.async(); - var startTime = Date.now(); - var neverResolved = new base.SpyPromise(function() {}); - return base.SpyPromise.settleAll(100).catch(function(error) { - assert.ok(error instanceof Error); - assert.ok(startTime + 200 < Date.now()); - done(); - }); -}); - -QUnit.test('settleAll timeout = 500', function(assert) { - var done = assert.async(); - var startTime = Date.now(); - var neverResolved = new base.SpyPromise(function() {}); - return base.SpyPromise.settleAll(500).catch(function(error) { - assert.ok(startTime + 750 < Date.now()); - done(); - }); -}); - -QUnit.test('settleAll timeout = 1000', function(assert) { - var done = assert.async(); - var startTime = Date.now(); - var neverResolved = new base.SpyPromise(function() {}); - return base.SpyPromise.settleAll(1000).catch(function(error) { - assert.ok(startTime + 1500 < Date.now()); - done(); - }); -}); - -})();
\ No newline at end of file |
