UNPKG

ember-app-scheduler

Version:

Ember addon to schedule work at different phases of app life cycle.

675 lines (583 loc) 18 kB
var assert = require('assert'), Promise = require('../lib/Promise'); describe ('Promise', function () { describe('construction', function () { it('should throw an error when constructed without handler', function () { assert.throws(function () {new Promise();}, SyntaxError); }); it('should construct a promise with handler and resolve it', function (done) { new Promise(function (resolve, reject) { resolve(2) }) .then(function (result) { assert.equal(result, 2); done(); }); }); it('should construct a promise with handler and reject it', function (done) { new Promise(function (resolve, reject) { reject(2) }) .catch(function (error) { assert.equal(error, 2); done(); }); }); it('should throw an error when constructed without new keyword', function () { assert.throws(function () {Promise()}, /Error/); }); }); describe('then', function () { it('should call onSuccess when resolved', function (done) { new Promise(function (resolve, reject) { setTimeout(function () { resolve('foo'); }, 0); }).then(function (result) { assert.equal(result, 'foo'); done(); }); }); it('should call onSuccess when resolved before then is attached', function (done) { var promise = new Promise(function (resolve, reject) { resolve('foo'); }); promise.then(function (result) { assert.equal(result, 'foo'); done(); }); }); it('should throw an error when resolving a promise twice', function (done) { new Promise(function (resolve, reject) { resolve('foo'); assert.throws(function () {resolve('foo')}, Error); done(); }); }); it('should not call onFail when resolved', function (done) { var promise = new Promise(function (resolve, reject) { setTimeout(function () { resolve('foo'); }, 0); }); promise.then(function (result) { assert.equal(result, 'foo'); done(); }, function (err) { assert.ok(false, 'shouldn\'t throw an error'); }); }); it('should not call onSuccess when rejected', function (done) { var promise = new Promise(function (resolve, reject) { setTimeout(function () { reject('err'); }, 0); }); promise.then(function () { assert.ok(false, 'should not resolve'); }, function (err) { assert.equal(err, 'err'); done(); }); }); }); describe('catch', function () { it('should call onFail when rejected', function (done) { var promise = new Promise(function (resolve, reject) { setTimeout(function () { reject('err'); }, 0); }); promise.catch(function (err) { assert.equal(err, 'err'); done(); }); }); it('should throw an error when rejecting a promise twice', function (done) { var promise = new Promise(function (resolve, reject) { reject('foo'); assert.throws(function() {reject('foo')}, Error); done(); }); }); it('should not propagate an error when caught', function (done) { var log = []; var promise = new Promise(function (resolve, reject) { setTimeout(function () { reject(new Error('My Error')); assert.deepEqual(log, ['catch', 'then']); done(); }, 0); }); promise.catch(function (err) { assert.equal(err, 'Error: My Error'); log.push('catch'); }) .then(function (result) { assert.strictEqual(result, undefined); log.push('then'); }) .catch(function (err) { assert.ok(false, 'should not catch error another time'); log.push('catch2') }); }); it('should rethrow an error', function (done) { var promise = new Promise(function (resolve, reject) { setTimeout(function () { reject(new Error('My Error')); }, 0); }); promise.catch(function (err) { assert.equal(err, 'Error: My Error'); throw new Error('My Error 2'); }) .catch(function (err) { assert.equal(err, 'Error: My Error 2'); done(); }); }); it('should pass onFail to chained promises', function (done) { new Promise(function (resolve, reject) { setTimeout(function () { reject(new Error('My Error')); }, 0); }) .then(function () { assert.ok(false, 'should not call onSuccess'); }) .catch(function (err) { assert.equal(err, 'Error: My Error'); done(); }); }); }); describe('always', function () { it('should call always when resolved', function (done) { var promise = new Promise(function (resolve, reject) { setTimeout(function () { resolve('foo'); }, 0); }); promise.always(function (result) { assert.equal(result, 'foo'); done(); }); }); it('should call always when rejected', function (done) { var promise = new Promise(function (resolve, reject) { setTimeout(function () { reject('err'); }, 0); }); promise.always(function (result) { assert.equal(result, 'err'); done(); }); }); }); describe('status', function () { it('should have correct status before and after being resolved', function (done) { var p = new Promise(function (resolve, reject) { setTimeout(function () { resolve(1); assert.equal(p.resolved, true); assert.equal(p.rejected, false); assert.equal(p.pending, false); done(); }, 0); }); assert.equal(p.resolved, false); assert.equal(p.rejected, false); assert.equal(p.pending, true); }); it('should have correct status before and after being rejected', function (done) { var p = new Promise(function (resolve, reject) { setTimeout(function () { reject(1); assert.equal(p.resolved, false); assert.equal(p.rejected, true); assert.equal(p.pending, false); done(); }, 0); }); assert.equal(p.resolved, false); assert.equal(p.rejected, false); assert.equal(p.pending, true); }); }); it('should resolve a promise returned by a onSuccess callback', function (done) { new Promise(function (resolve, reject) { resolve(1) }) .then(function (result) { assert.equal(result, 1); return new Promise(function (resolve, reject) { resolve(2); }); }) .then(function (result) { assert.equal(result, 2); done(); }); }); it('should resolve a promise returned by an onFail callback', function (done) { new Promise(function (resolve, reject) { reject(1) }) .catch(function (err) { assert.equal(err, 1); return new Promise(function (resolve, reject) { resolve(2) }); }) .then(function (result) { assert.equal(result, 2); done(); }); }); it('should resolve a rejected error from a returned promise (2)', function (done) { new Promise(function (resolve, reject) { reject(1) }) .catch(function (err) { assert.equal(err, 1); return new Promise(function (resolve, reject) { reject(2); }); }) .catch(function (err) { assert.equal(err, 2); done(); }); }); it('should catch an error thrown by an onSuccess callback', function (done) { new Promise(function (resolve, reject) { resolve(1) }) .then(function (result) { assert.equal(result, 1); throw new Error('2'); }) .catch(function (err) { assert.equal(err.toString(), 'Error: 2'); done(); }); }); it('should catch an error thrown by an onFail callback', function (done) { new Promise(function (resolve, reject) { reject(new Error(1)) }) .catch(function (err) { assert.equal(err.toString(), 'Error: 1'); throw new Error('2'); }) .catch(function (err) { assert.equal(err.toString(), 'Error: 2'); done(); }); }); it('should pass arguments through the promise chain which is already resolved', function (done) { var log = []; var promise = new Promise(function (resolve, reject) { resolve(1); }); // first chain promise .then(function (res){ log.push(res); assert.equal(res, 1); }); // second chain promise.then(function (res){ log.push(res); assert.equal(res, 1); return new Promise(function (resolve, reject) { reject(2) }); }) .then(function (){ assert.ok(false, 'should not resolve') }) .catch(function (res) { assert.equal(res, 2); log.push(res); throw 3; }) .catch(function (err) { log.push(err); assert.equal(err, 3); return new Promise(function (resolve, reject) { reject(4) }) }) .then(null, function (err){ log.push(err); assert.equal(err, 4); return new Promise(function (resolve, reject) { resolve(5) }); }) .then(function (res) { log.push(res); assert.equal(res, 5); }) .catch(function (){ log.push('fail') }); assert.equal(log.join(','), '1,1,2,3,4,5'); done(); }); it('should pass arguments through the promise chain which is not yet resolved', function (done) { var log = []; var promise = new Promise(function (resolve, reject) { setTimeout(function () { resolve(1) assert.equal(log.join(','), '1,1,2,3,4,5'); done(); }, 0) }); // first chain promise .then(function (res){ log.push(res); assert.equal(res, 1); }); // second chain promise .then(function (res){ log.push(res); assert.equal(res, 1); return new Promise(function (resolve, reject) { reject(2) }) }) .then(function (){ assert.ok(false, 'should not resolve') }) .catch(function (res) { assert.equal(res, 2); log.push(res); throw 3; }) .catch(function (err) { log.push(err); assert.equal(err, 3); return new Promise(function (resolve, reject) { reject(4) }) }) .then(null, function (err){ log.push(err); assert.equal(err, 4); return new Promise(function (resolve, reject) { resolve(5) }) }) .then(function (res) { log.push(res); assert.equal(res, 5); }) .catch(function (){ log.push('fail') }); }); describe('cancel', function () { it('should cancel a promise', function (done) { var p = new Promise(function (resolve, reject) {}) .catch(function (err) { assert(err instanceof Promise.CancellationError); done(); }); setTimeout(function () { p.cancel(); }, 10); }); it('should cancel a promise and catch afterwards', function (done) { var p = new Promise(function (resolve, reject) {}).cancel(); p.catch(function (err) { assert(err instanceof Promise.CancellationError); done(); }) }); it('should propagate cancellation of a promise to the promise parent', function (done) { var p = new Promise(function (resolve, reject) {}); var processing = 2; function next() { processing--; if (processing == 0) done(); } var p1 = p.catch(function (err) { assert(err instanceof Promise.CancellationError); next(); }); var p2 = p.catch(function (err) { assert(err instanceof Promise.CancellationError); next(); }); p1.cancel(); }); }); describe('timeout', function () { it('should timeout a promise', function (done) { new Promise(function (resolve, reject) {}) .timeout(30) .catch(function (err) { assert(err instanceof Promise.TimeoutError); done(); }) }); it('should timeout a promise afterwards', function (done) { var p = new Promise(function (resolve, reject) {}) .catch(function (err) { assert(err instanceof Promise.TimeoutError); done(); }); p.timeout(30) }); it('timeout should be stopped when promise resolves', function (done) { new Promise(function (resolve, reject) { setTimeout(function () { resolve(1); }, 0); }) .timeout(30) .then(function (result) { assert.equal(result, 1); done(); }) .catch(function (err) { assert.ok(false, 'should not throw an error'); }); }); it('timeout should be stopped when promise rejects', function (done) { new Promise(function (resolve, reject) { setTimeout(function () { reject(new Error('My Error')); }, 0); }) .timeout(30) .catch(function (err) { assert.equal(err.toString(), 'Error: My Error'); done(); }); }); it('timeout should be propagated to parent promise', function (done) { new Promise(function (resolve, reject) {}) .then() // force creation of a child promise .catch(function (err) { assert(err instanceof Promise.TimeoutError); done(); }) .timeout(30); }); }); describe('defer', function () { it('should create a resolver and resolve it', function (done) { var resolver = Promise.defer(); resolver.promise.then(function (result) { assert.equal(result, 3); done(); }); resolver.resolve(3); }); it('should create a resolver and reject it', function (done) { var resolver = Promise.defer(); resolver.promise.catch(function (err) { assert.equal(err.toString(), 'Error: My Error'); done(); }); resolver.reject(new Error('My Error')); }) }); describe('all', function () { it('should resolve "all" when all promises are resolved', function (done) { var foo = new Promise(function (resolve, reject) { setTimeout(function () { resolve('foo'); }, 25); }), bar = new Promise(function (resolve, reject) { resolve('bar'); }), baz = new Promise(function (resolve, reject) { setTimeout(function () { resolve('baz'); }, 40); }), qux = new Promise(function (resolve, reject) { resolve('qux'); }); Promise.all([foo, bar, baz, qux]) .then(function (results) { assert.ok(true, 'then'); assert.deepEqual(results, ['foo', 'bar', 'baz', 'qux']); done(); }) .catch(function (){ assert.ok(false, 'catch'); }); }); it('should reject "all" when any of the promises failed', function (done) { var foo = new Promise(function (resolve, reject) { setTimeout(function () { resolve('foo'); }, 40); }), bar = new Promise(function (resolve, reject) { resolve('bar'); }), baz = new Promise(function (resolve, reject) { setTimeout(function () { reject('The Error'); }, 25); }), qux = new Promise(function (resolve, reject) { resolve('qux'); }); Promise.all([foo, bar, baz, qux]) .then(function (result){ assert.ok(false, 'should not resolve'); }) .catch(function (err){ assert.ok(true, 'catch'); assert.equal(err, 'The Error'); done(); }); }); it('should resolve "all" when all of the promises are already resolved', function (done) { var foo = new Promise(function (resolve, reject) { resolve('foo'); }), bar = new Promise(function (resolve, reject) { resolve('bar'); }), baz = new Promise(function (resolve, reject) { resolve('baz'); }), qux = new Promise(function (resolve, reject) { resolve('qux'); }); Promise.all([foo, bar, baz, qux]) .then(function (results) { assert.ok(true, 'then'); assert.deepEqual(results, ['foo', 'bar', 'baz', 'qux']); done(); }) .catch(function (){ assert.ok(false, 'catch'); }); }); it('should resolve "all" when empty', function (done) { Promise.all([]) .then(function (results) { assert.ok(true, 'then'); assert.deepEqual(results, []); done(); }) .catch(function (){ assert.ok(false, 'catch'); }); }); }); });