async-listener
Advanced tools
Comparing version 0.6.4 to 0.6.5
41
index.js
@@ -346,3 +346,3 @@ 'use strict'; | ||
* for that fulfillment to happen. This means that we need to trigger a create | ||
* when accept or reject is called and trigger before, after and error handlers | ||
* when resolve or reject is called and trigger before, after and error handlers | ||
* around the callback execution. There may be multiple callbacks for each | ||
@@ -355,4 +355,4 @@ * fulfilled promise, so handlers will behave similar to setInterval where | ||
* passed a function to wrap, which will execute the body of the async work. | ||
* The accept and reject calls can be modified fairly easily to call | ||
* `wrapCallback`, but at the time of accept and reject all the work to be done | ||
* The resolve and reject calls can be modified fairly easily to call | ||
* `wrapCallback`, but at the time of resolve and reject all the work to be done | ||
* on fulfillment may not be defined, since a call to then, chain or fetch can | ||
@@ -369,3 +369,3 @@ * be made even after the promise has been fulfilled. To get around this, we | ||
* the returned Promise has been also been resolved. When something other than | ||
* a promise is resolved the accept call for the new Promise is put in the | ||
* a promise is resolved the resolve call for the new Promise is put in the | ||
* microtask queue and asynchronously resolved. | ||
@@ -377,3 +377,3 @@ * | ||
* or another value. Fortunately we already have a wrapper function around the | ||
* callback we can use (the wrapper created by accept or reject). | ||
* callback we can use (the wrapper created by resolve or reject). | ||
* | ||
@@ -386,3 +386,3 @@ * By adding an additional argument to this wrapper, we can pass in the | ||
* wrapper needs to be invoked). Otherwise, a new wrapper can be create the | ||
* same way as in accept and reject. Since this wrapper is created | ||
* same way as in resolve and reject. Since this wrapper is created | ||
* synchronously within another wrapper, it will properly appear as a | ||
@@ -420,3 +420,3 @@ * continuation from within the callback. | ||
function wrappedExecutor(accept, reject) { | ||
function wrappedExecutor(resolve, reject) { | ||
context = this; | ||
@@ -426,6 +426,6 @@ args = [wrappedAccept, wrappedReject]; | ||
// These wrappers create a function that can be passed a function and an argument to | ||
// call as a continuation from the accept or reject. | ||
// call as a continuation from the resolve or reject. | ||
function wrappedAccept(val) { | ||
ensureAslWrapper(promise, false); | ||
return accept(val); | ||
return resolve(val); | ||
} | ||
@@ -443,2 +443,3 @@ | ||
wrap(Promise.prototype, 'then', wrapThen); | ||
// Node.js <v7 only, alias for .then | ||
if (Promise.prototype.chain) { | ||
@@ -448,6 +449,16 @@ wrap(Promise.prototype, 'chain', wrapThen); | ||
var PromiseMethods = ['accept', 'all', 'defer', 'race', 'reject', 'resolve']; | ||
var PromiseFunctions = [ | ||
'all', | ||
'race', | ||
'reject', | ||
'resolve', | ||
'accept', // Node.js <v7 only | ||
'defer' // Node.js <v7 only | ||
]; | ||
PromiseMethods.forEach(function(key) { | ||
wrappedPromise[key] = Promise[key]; | ||
PromiseFunctions.forEach(function(key) { | ||
// don't break `in` by creating a key for undefined entries | ||
if (typeof Promise[key] === 'function') { | ||
wrappedPromise[key] = Promise[key]; | ||
} | ||
}); | ||
@@ -499,6 +510,6 @@ | ||
// wrap callbacks (success, error) so that the callbacks will be called as a | ||
// continuations of the accept or reject call using the __asl_wrapper created above. | ||
// continuations of the resolve or reject call using the __asl_wrapper created above. | ||
function bind(fn) { | ||
if (typeof fn !== 'function') return fn; | ||
return function (val) { | ||
return wrapCallback(function (val) { | ||
var result = (promise.__asl_wrapper || propagateAslWrapper)(this, fn, val, next); | ||
@@ -510,3 +521,3 @@ if (result.error) { | ||
} | ||
}; | ||
}); | ||
} | ||
@@ -513,0 +524,0 @@ } |
{ | ||
"name": "async-listener", | ||
"version": "0.6.4", | ||
"version": "0.6.5", | ||
"description": "Polyfill exporting trevnorris's 0.11+ asyncListener API.", | ||
@@ -5,0 +5,0 @@ "author": "Forrest L Norvell <ogd@aoaioxxysz.net>", |
@@ -87,3 +87,3 @@ if (!global.Promise) return; | ||
{ | ||
name: 'setImmediate in root', | ||
name: 'accept', | ||
children: [], | ||
@@ -93,50 +93,8 @@ before: 1, | ||
error: 0 | ||
} | ||
], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
}); | ||
test('chain', function chainTest(t) { | ||
var listener = addListner(); | ||
var promise = new Promise(function(accept, reject) { | ||
listener.currentName = 'accept'; | ||
accept(10); | ||
}); | ||
promise.chain(function(val) { | ||
listener.currentName = 'nextTick in first chain'; | ||
process.nextTick(function() { | ||
t.strictEqual(val, 10); | ||
}); | ||
listener.currentName = 'first chain continuation'; | ||
}); | ||
listener.currentName = 'setImmediate in root'; | ||
setImmediate(function() { | ||
promise.chain(function(val) { | ||
t.strictEqual(val, 10); | ||
t.strictEqual(this, global); | ||
listener.currentName = 'setTimeout in 2nd chain'; | ||
setTimeout(function() { | ||
t.deepEqual(listener.root, expected); | ||
t.end(); | ||
}); | ||
listener.currentName = '2nd chain continuation'; | ||
}); | ||
}); | ||
process.removeAsyncListener(listener.listener); | ||
var expected = { | ||
name: 'root', | ||
children: [ | ||
}, | ||
{ | ||
name: 'accept', | ||
name: 'setImmediate in root', | ||
children: [ | ||
{ | ||
name: 'nextTick in first chain', | ||
name: 'first then continuation', | ||
children: [], | ||
@@ -146,32 +104,4 @@ before: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'first chain continuation', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'setTimeout in 2nd chain', | ||
children: [], | ||
before: 1, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: '2nd chain continuation', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
], | ||
before: 2, | ||
after: 2, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'setImmediate in root', | ||
children: [], | ||
before: 1, | ||
@@ -277,86 +207,13 @@ after: 1, | ||
name: 'setImmediate in root', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
} | ||
], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}; | ||
}); | ||
test('future chains', function futureChainTest(t) { | ||
var listener = addListner(); | ||
listener.currentName = 'resolve'; | ||
var promise = Promise.resolve(); | ||
promise | ||
.then(function() { listener.currentName = '1st then'; }) | ||
.then(function() { listener.currentName = '2nd then'; }) | ||
.then(function() { listener.currentName = '3rd then'; }); | ||
promise | ||
.chain(function() { listener.currentName = '1st chain'; }) | ||
.chain(function() { listener.currentName = '2nd chain'; }) | ||
.chain(function() { listener.currentName = '3rd chain'; }); | ||
listener.currentName = 'setTimeout'; | ||
setTimeout(function() { | ||
t.deepEqual(listener.root, expected); | ||
t.end(); | ||
}); | ||
process.removeAsyncListener(listener.listener); | ||
var expected = { | ||
name: 'root', | ||
children: [ | ||
{ | ||
name: 'resolve', | ||
children: [ | ||
{ | ||
name: '1st then', | ||
children: [ | ||
{ | ||
name: '2nd then', | ||
children: [ | ||
{ | ||
name: '3rd then', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
} | ||
], | ||
before: 1, | ||
after: 1, | ||
name: 'catch continuation', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: '1st chain', | ||
children: [ | ||
{ | ||
name: '2nd chain', | ||
children: [ | ||
{ | ||
name: '3rd chain', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
} | ||
], | ||
name: 'catch continuation', | ||
children: [], | ||
before: 1, | ||
@@ -367,11 +224,4 @@ after: 1, | ||
], | ||
before: 2, | ||
after: 2, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'setTimeout', | ||
children: [], | ||
before: 1, | ||
after: 0, | ||
after: 1, | ||
error: 0 | ||
@@ -383,3 +233,3 @@ } | ||
error: 0 | ||
} | ||
}; | ||
}); | ||
@@ -411,43 +261,6 @@ | ||
error: 0 | ||
}], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}); | ||
t.end(); | ||
}); | ||
process.removeAsyncListener(listener.listener); | ||
}); | ||
}); | ||
test('Promise.accept', function acceptTest(t) { | ||
var listener = addListner(); | ||
listener.currentName = 'accept'; | ||
var p = Promise.accept(123); | ||
p.then(function then(value) { | ||
listener.currentName = 'nextTick'; | ||
process.nextTick(function next() { | ||
t.equal(value, 123); | ||
t.deepEqual(listener.root, { | ||
name: 'root', | ||
children: [{ | ||
name: 'accept', | ||
children: [ | ||
{ | ||
name: 'nextTick', | ||
children: [], | ||
before: 1, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'then continuation', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
], | ||
}, | ||
{ | ||
name: 'resolve', | ||
children: [], | ||
before: 1, | ||
@@ -463,7 +276,4 @@ after: 1, | ||
}); | ||
listener.currentName = 'then continuation'; | ||
process.removeAsyncListener(listener.listener); | ||
}); | ||
process.removeAsyncListener(listener.listener); | ||
}); | ||
@@ -600,2 +410,37 @@ | ||
error: 0 | ||
}, | ||
{ | ||
name: 'all', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'all', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'all', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'all', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'all', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}], | ||
@@ -698,2 +543,37 @@ before: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'all', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'all', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'all', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'all', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'all', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}], | ||
@@ -773,2 +653,37 @@ before: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'race', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'race', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'race', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'race', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'race', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}], | ||
@@ -872,2 +787,37 @@ before: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'race', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'race', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'race', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'race', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'race', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}], | ||
@@ -880,54 +830,4 @@ before: 0, | ||
test('Promise.defer', function diferTest(t) { | ||
var listener = addListner(); | ||
listener.currentName = 'defer'; | ||
var p = Promise.defer(); | ||
listener.currentName = 'resolve'; | ||
p.resolve(123); | ||
listener.currentName = 'reject'; | ||
p.reject(456); | ||
p.promise.then(function then(value) { | ||
listener.currentName = 'nextTick'; | ||
process.nextTick(function next() { | ||
process.removeAsyncListener(listener.listener); | ||
t.equal(value, 123); | ||
t.deepEqual(listener.root, { | ||
name: 'root', | ||
children: [{ | ||
name: 'resolve', | ||
children: [ | ||
{ | ||
name: 'nextTick', | ||
children: [], | ||
before: 1, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'then continuation', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}); | ||
t.end(); | ||
}); | ||
listener.currentName = 'then continuation'; | ||
}); | ||
}); | ||
test('instanceof', function diferTest(t) { | ||
var p = Promise.accept(); | ||
var p = Promise.resolve(10); | ||
@@ -943,3 +843,3 @@ t.ok(p instanceof Promise, 'instanceof should work on wrapped Promise'); | ||
listener.currentName = 'accept'; | ||
var promise = Promise.accept(10); | ||
var promise = Promise.resolve(10); | ||
@@ -1025,95 +925,16 @@ promise | ||
error: 0 | ||
} | ||
], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
}); | ||
test('multi chain with promise', function(t) { | ||
var listener = addListner(); | ||
listener.currentName = 'accept'; | ||
var promise = Promise.accept(10); | ||
promise | ||
.chain(function(val) { | ||
return new Promise(function wait(accept) { | ||
listener.currentName = 'nextTick in nested promise'; | ||
process.nextTick(function() { | ||
listener.currentName = 'accept from nextTick'; | ||
accept(val); | ||
}); | ||
}); | ||
}) | ||
.chain(function validate(val) { | ||
t.strictEqual(val, 10); | ||
t.strictEqual(this, global); | ||
listener.currentName = 'setTimeout in 2nd chain'; | ||
setTimeout(function() { | ||
t.deepEqual(listener.root, expected); | ||
t.end(); | ||
}); | ||
listener.currentName = '2nd then continuation'; | ||
}); | ||
process.removeAsyncListener(listener.listener); | ||
// Promise resolution changed slightly in node v6, | ||
// now resolve/reject wraps again on completion. | ||
var children = [] | ||
if (nodeVersion[0] >= 6) { | ||
children.push({ | ||
name: 'accept from nextTick', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}) | ||
} | ||
children.push( | ||
{ | ||
name: 'setTimeout in 2nd chain', | ||
children: [], | ||
before: 1, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: '2nd then continuation', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
) | ||
var expected = { | ||
name: 'root', | ||
children: [ | ||
}, | ||
{ | ||
name: 'accept', | ||
children: [ | ||
{ | ||
name: 'nextTick in nested promise', | ||
children: [ | ||
{ | ||
name: 'accept from nextTick', | ||
children: children, | ||
before: children.length - 1, | ||
after: children.length - 1, | ||
error: 0 | ||
} | ||
], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
} | ||
], | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'accept', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
} | ||
@@ -1228,111 +1049,30 @@ ], | ||
error: 0 | ||
} | ||
], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
}); | ||
test('multi chain with rejected promise', function(t) { | ||
var listener = addListner(); | ||
listener.currentName = 'reject'; | ||
var promise = Promise.reject(10); | ||
promise | ||
.chain(fail, function(val) { | ||
return new Promise(function wait(accept, reject) { | ||
listener.currentName = 'nextTick in nested promise'; | ||
process.nextTick(function() { | ||
listener.currentName = 'reject from nextTick'; | ||
reject(val); | ||
}); | ||
}); | ||
}) | ||
.chain(fail, function validate(val) { | ||
t.strictEqual(val, 10); | ||
t.strictEqual(this, global); | ||
listener.currentName = 'setTimeout in 2nd chain'; | ||
setTimeout(function() { | ||
// some version of iojs use nextTick for some parts of its async | ||
if (listener.root.children.length === 2) { | ||
expected.children.splice(1, 0, { | ||
name: 'reject', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}) | ||
} | ||
t.deepEqual(listener.root, expected); | ||
t.end(); | ||
}); | ||
listener.currentName = '2nd chain continuation'; | ||
}); | ||
function fail() { | ||
t.fail('should not be called'); | ||
t.end(); | ||
} | ||
process.removeAsyncListener(listener.listener); | ||
// Promise resolution changed slightly in node v6, | ||
// now resolve/reject wraps again on completion. | ||
var children = [] | ||
if (nodeVersion[0] >= 6) { | ||
children.push({ | ||
name: 'reject from nextTick', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}) | ||
} | ||
children.push( | ||
{ | ||
name: 'setTimeout in 2nd chain', | ||
children: [], | ||
before: 1, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: '2nd chain continuation', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
) | ||
var expected = { | ||
name: 'root', | ||
children: [ | ||
}, | ||
{ | ||
name: 'reject', | ||
children: [ | ||
{ | ||
name: 'nextTick in nested promise', | ||
children: [ | ||
{ | ||
name: 'reject from nextTick', | ||
children: children, | ||
before: children.length - 1, | ||
after: children.length - 1, | ||
error: 0 | ||
} | ||
], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
} | ||
], | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'reject', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'reject', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'reject', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
} | ||
@@ -1442,2 +1182,16 @@ ], | ||
error: 0 | ||
}, | ||
{ | ||
name: 'reject', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'reject', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
} | ||
@@ -1465,3 +1219,3 @@ ], | ||
children: [], | ||
before: 0, | ||
before: 1, | ||
after: 0, | ||
@@ -1566,2 +1320,44 @@ error: 0 | ||
error: 0 | ||
}, | ||
{ | ||
name: 'return of 1st catch that didnt get run', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'return of 1st catch that didnt get run', | ||
children: [], | ||
before: 1, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'return of 1st catch that didnt get run', | ||
children: [], | ||
before: 1, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'return of 1st catch that didnt get run', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'return of 1st catch that didnt get run', | ||
children: [], | ||
before: 1, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'return of 1st catch that didnt get run', | ||
children: [], | ||
before: 1, | ||
after: 0, | ||
error: 0 | ||
} | ||
@@ -1595,3 +1391,22 @@ ], | ||
name: 'root', | ||
children: [], | ||
children: [{ | ||
name : 'resolve', | ||
children : [{ | ||
name : '2nd resolve', | ||
children : [], | ||
before : 1, | ||
after : 0, | ||
error : 0 | ||
}], | ||
before : 1, | ||
after : 1, | ||
error : 0 | ||
}, | ||
{ | ||
name : 'resolve', | ||
children : [], | ||
before : 1, | ||
after : 0, | ||
error : 0 | ||
}], | ||
before: 0, | ||
@@ -1629,2 +1444,29 @@ after: 0, | ||
error : 0 | ||
}, | ||
{ | ||
name : 'resolve', | ||
children : [], | ||
before : 1, | ||
after : 1, | ||
error : 0 | ||
}, | ||
{ | ||
name : 'resolve', | ||
children : [{ | ||
name : 'resolve', | ||
children : [], | ||
before : 1, | ||
after : 0, | ||
error : 0 | ||
}], | ||
before : 1, | ||
after : 1, | ||
error : 0 | ||
}, | ||
{ | ||
name : 'resolve', | ||
children : [], | ||
before : 1, | ||
after : 0, | ||
error : 0 | ||
}], | ||
@@ -1688,2 +1530,23 @@ before: 0, | ||
error : 0 | ||
}, | ||
{ | ||
name : 'unwrapped resolve', | ||
children : [], | ||
before : 1, | ||
after : 1, | ||
error : 0 | ||
}, | ||
{ | ||
name : 'unwrapped resolve', | ||
children : [], | ||
before : 1, | ||
after : 1, | ||
error : 0 | ||
}, | ||
{ | ||
name : 'unwrapped resolve', | ||
children : [], | ||
before : 1, | ||
after : 0, | ||
error : 0 | ||
}], | ||
@@ -1744,1 +1607,617 @@ before: 0, | ||
} | ||
// for the following, | ||
// | ||
// https://github.com/v8/v8/commits/master/src/js/promise-extra.js | ||
// | ||
// is helpful context -- none of these are part of ES2015 promises, and were | ||
// set up to be removed. | ||
// Node.js <v7 exposed Promise.defer as a way of getting at the raw "promise | ||
// capability", which is to say a deferred execution context that exposes the | ||
// `.resolve` and `.reject` functions. The preferred way to get direct access | ||
// to these functions is the "revealing constructor" pattern – to capture the | ||
// two callbacks when creating a new Promise. The arguments for and against | ||
// exposing these functions are somewhat arcane and subjective, but regardless, | ||
// Promise.defer isn't part of ES2015 promises, and as such was removed from V8 | ||
// in the Node.js v7 timeframe. | ||
if (typeof Promise.defer === 'function') { | ||
test('Promise.defer', function diferTest(t) { | ||
var listener = addListner(); | ||
listener.currentName = 'defer'; | ||
var p = Promise.defer(); | ||
listener.currentName = 'resolve'; | ||
p.resolve(123); | ||
listener.currentName = 'reject'; | ||
p.reject(456); | ||
p.promise.then(function then(value) { | ||
listener.currentName = 'nextTick'; | ||
process.nextTick(function next() { | ||
process.removeAsyncListener(listener.listener); | ||
t.equal(value, 123); | ||
t.deepEqual(listener.root, { | ||
name: 'root', | ||
children: [{ | ||
name: 'resolve', | ||
children: [ | ||
{ | ||
name: 'nextTick', | ||
children: [], | ||
before: 1, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'then continuation', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'reject', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}); | ||
t.end(); | ||
}); | ||
listener.currentName = 'then continuation'; | ||
}); | ||
}); | ||
} | ||
// In Node.js <v7, Promise.accept is an alias for Promise.resolve. | ||
if (typeof Promise.accept === 'function') { | ||
test('Promise.accept', function acceptTest(t) { | ||
var listener = addListner(); | ||
listener.currentName = 'accept'; | ||
var p = Promise.accept(123); | ||
p.then(function then(value) { | ||
listener.currentName = 'nextTick'; | ||
process.nextTick(function next() { | ||
t.equal(value, 123); | ||
t.deepEqual(listener.root, { | ||
name: 'root', | ||
children: [{ | ||
name: 'accept', | ||
children: [ | ||
{ | ||
name: 'nextTick', | ||
children: [], | ||
before: 1, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'then continuation', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'accept', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}); | ||
t.end(); | ||
}); | ||
listener.currentName = 'then continuation'; | ||
}); | ||
process.removeAsyncListener(listener.listener); | ||
}); | ||
} | ||
// In Node.js v6 (and possibly v4), Promise.prototype.chain is merely an alias | ||
// for Promise.prototype.then. In Node.js v7+, it has been completely removed. | ||
if (typeof Promise.prototype.chain === 'function') { | ||
test('chain', function chainTest(t) { | ||
var listener = addListner(); | ||
var promise = new Promise(function(accept, reject) { | ||
listener.currentName = 'accept'; | ||
accept(10); | ||
}); | ||
promise.chain(function(val) { | ||
listener.currentName = 'nextTick in first chain'; | ||
process.nextTick(function() { | ||
t.strictEqual(val, 10); | ||
}); | ||
listener.currentName = 'first chain continuation'; | ||
}); | ||
listener.currentName = 'setImmediate in root'; | ||
setImmediate(function() { | ||
promise.chain(function(val) { | ||
t.strictEqual(val, 10); | ||
t.strictEqual(this, global); | ||
listener.currentName = 'setTimeout in 2nd chain'; | ||
setTimeout(function() { | ||
t.deepEqual(listener.root, expected); | ||
t.end(); | ||
}); | ||
listener.currentName = '2nd chain continuation'; | ||
}); | ||
}); | ||
process.removeAsyncListener(listener.listener); | ||
var expected = { | ||
name: 'root', | ||
children: [ | ||
{ | ||
name: 'accept', | ||
children: [ | ||
{ | ||
name: 'nextTick in first chain', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'first chain continuation', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'setTimeout in 2nd chain', | ||
children: [], | ||
before: 1, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: '2nd chain continuation', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
], | ||
before: 2, | ||
after: 2, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'accept', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'setImmediate in root', | ||
children: [ | ||
{ | ||
name: 'first chain continuation', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
} | ||
], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
} | ||
], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
}); | ||
test('future chains', function futureChainTest(t) { | ||
var listener = addListner(); | ||
listener.currentName = 'resolve'; | ||
var promise = Promise.resolve(); | ||
promise | ||
.then(function() { listener.currentName = '1st then'; }) | ||
.then(function() { listener.currentName = '2nd then'; }) | ||
.then(function() { listener.currentName = '3rd then'; }); | ||
promise | ||
.chain(function() { listener.currentName = '1st chain'; }) | ||
.chain(function() { listener.currentName = '2nd chain'; }) | ||
.chain(function() { listener.currentName = '3rd chain'; }); | ||
listener.currentName = 'setTimeout'; | ||
setTimeout(function() { | ||
t.deepEqual(listener.root, expected); | ||
t.end(); | ||
}); | ||
process.removeAsyncListener(listener.listener); | ||
var expected = { | ||
name: 'root', | ||
children: [ | ||
{ | ||
name: 'resolve', | ||
children: [ | ||
{ | ||
name: '1st then', | ||
children: [ | ||
{ | ||
name: '2nd then', | ||
children: [ | ||
{ | ||
name: '3rd then', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
} | ||
], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: '1st chain', | ||
children: [ | ||
{ | ||
name: '2nd chain', | ||
children: [ | ||
{ | ||
name: '3rd chain', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
} | ||
], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
} | ||
], | ||
before: 2, | ||
after: 2, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'resolve', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'resolve', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'resolve', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'resolve', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'resolve', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'resolve', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'setTimeout', | ||
children: [], | ||
before: 1, | ||
after: 0, | ||
error: 0 | ||
} | ||
], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
}); | ||
test('multi chain with promise', function(t) { | ||
var listener = addListner(); | ||
listener.currentName = 'accept'; | ||
var promise = Promise.accept(10); | ||
promise | ||
.chain(function(val) { | ||
return new Promise(function wait(accept) { | ||
listener.currentName = 'nextTick in nested promise'; | ||
process.nextTick(function() { | ||
listener.currentName = 'accept from nextTick'; | ||
accept(val); | ||
}); | ||
}); | ||
}) | ||
.chain(function validate(val) { | ||
t.strictEqual(val, 10); | ||
t.strictEqual(this, global); | ||
listener.currentName = 'setTimeout in 2nd chain'; | ||
setTimeout(function() { | ||
t.deepEqual(listener.root, expected); | ||
t.end(); | ||
}); | ||
listener.currentName = '2nd then continuation'; | ||
}); | ||
process.removeAsyncListener(listener.listener); | ||
// Promise resolution changed slightly in node v6, | ||
// now resolve/reject wraps again on completion. | ||
var children = [] | ||
if (nodeVersion[0] >= 6) { | ||
children.push({ | ||
name: 'accept from nextTick', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}) | ||
} | ||
children.push( | ||
{ | ||
name: 'setTimeout in 2nd chain', | ||
children: [], | ||
before: 1, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: '2nd then continuation', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
) | ||
var expected = { | ||
name: 'root', | ||
children: [ | ||
{ | ||
name: 'accept', | ||
children: [ | ||
{ | ||
name: 'nextTick in nested promise', | ||
children: [ | ||
{ | ||
name: 'accept from nextTick', | ||
children: children, | ||
before: children.length - 1, | ||
after: children.length - 1, | ||
error: 0 | ||
} | ||
], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
} | ||
], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'accept', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'accept', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
} | ||
], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
}); | ||
test('multi chain with rejected promise', function(t) { | ||
var listener = addListner(); | ||
listener.currentName = 'reject'; | ||
var promise = Promise.reject(10); | ||
promise | ||
.chain(fail, function(val) { | ||
return new Promise(function wait(accept, reject) { | ||
listener.currentName = 'nextTick in nested promise'; | ||
process.nextTick(function() { | ||
listener.currentName = 'reject from nextTick'; | ||
reject(val); | ||
}); | ||
}); | ||
}) | ||
.chain(fail, function validate(val) { | ||
t.strictEqual(val, 10); | ||
t.strictEqual(this, global); | ||
listener.currentName = 'setTimeout in 2nd chain'; | ||
setTimeout(function() { | ||
// some version of iojs use nextTick for some parts of its async | ||
if (listener.root.children.length === 2) { | ||
expected.children.splice(1, 0, { | ||
name: 'reject', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}) | ||
} | ||
t.deepEqual(listener.root, expected); | ||
t.end(); | ||
}); | ||
listener.currentName = '2nd chain continuation'; | ||
}); | ||
function fail() { | ||
t.fail('should not be called'); | ||
t.end(); | ||
} | ||
process.removeAsyncListener(listener.listener); | ||
// Promise resolution changed slightly in node v6, | ||
// now resolve/reject wraps again on completion. | ||
var children = [] | ||
if (nodeVersion[0] >= 6) { | ||
children.push({ | ||
name: 'reject from nextTick', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}) | ||
} | ||
children.push( | ||
{ | ||
name: 'setTimeout in 2nd chain', | ||
children: [], | ||
before: 1, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: '2nd chain continuation', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
) | ||
var expected = { | ||
name: 'root', | ||
children: [ | ||
{ | ||
name: 'reject', | ||
children: [ | ||
{ | ||
name: 'nextTick in nested promise', | ||
children: [ | ||
{ | ||
name: 'reject from nextTick', | ||
children: children, | ||
before: children.length - 1, | ||
after: children.length - 1, | ||
error: 0 | ||
} | ||
], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
} | ||
], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'reject', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'reject', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'reject', | ||
children: [], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
}, | ||
{ | ||
name: 'reject', | ||
children: [], | ||
before: 1, | ||
after: 1, | ||
error: 0 | ||
} | ||
], | ||
before: 0, | ||
after: 0, | ||
error: 0 | ||
} | ||
}); | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
161299
5474