pax_global_header 0000666 0000000 0000000 00000000064 13131504212 0014502 g ustar 00root root 0000000 0000000 52 comment=d141e6438615f836f26176c5f350458de9e2770c
promise-8.0.1/ 0000775 0000000 0000000 00000000000 13131504212 0013166 5 ustar 00root root 0000000 0000000 promise-8.0.1/.gitignore 0000664 0000000 0000000 00000000124 13131504212 0015153 0 ustar 00root root 0000000 0000000 components
build
node_modules
/lib
/domains
/setimmediate
coverage
package-lock.json promise-8.0.1/.jshintrc 0000664 0000000 0000000 00000000064 13131504212 0015013 0 ustar 00root root 0000000 0000000 {
"asi": true,
"node": true,
"strict": true
}
promise-8.0.1/.npmignore 0000664 0000000 0000000 00000000114 13131504212 0015161 0 ustar 00root root 0000000 0000000 components
node_modules
test
.gitignore
.travis.yml
component.json
coverage
promise-8.0.1/.travis.yml 0000664 0000000 0000000 00000000253 13131504212 0015277 0 ustar 00root root 0000000 0000000 language: node_js
sudo: false
node_js:
- "0.10"
- "0.12"
- "iojs"
after_success:
- npm run coverage
- npm i coveralls
- cat ./coverage/lcov.info | coveralls
promise-8.0.1/LICENSE 0000664 0000000 0000000 00000002043 13131504212 0014172 0 ustar 00root root 0000000 0000000 Copyright (c) 2014 Forbes Lindesay
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
promise-8.0.1/Readme.md 0000664 0000000 0000000 00000022112 13131504212 0014703 0 ustar 00root root 0000000 0000000
# promise
This is a simple implementation of Promises. It is a super set of ES6 Promises designed to have readable, performant code and to provide just the extensions that are absolutely necessary for using promises today.
For detailed tutorials on its use, see www.promisejs.org
**N.B.** This promise exposes internals via underscore (`_`) prefixed properties. If you use these, your code will break with each new release.
[![travis][travis-image]][travis-url]
[![dep][dep-image]][dep-url]
[![npm][npm-image]][npm-url]
[![downloads][downloads-image]][downloads-url]
[travis-image]: https://img.shields.io/travis/then/promise.svg?style=flat
[travis-url]: https://travis-ci.org/then/promise
[dep-image]: https://img.shields.io/david/then/promise.svg?style=flat
[dep-url]: https://david-dm.org/then/promise
[npm-image]: https://img.shields.io/npm/v/promise.svg?style=flat
[npm-url]: https://npmjs.org/package/promise
[downloads-image]: https://img.shields.io/npm/dm/promise.svg?style=flat
[downloads-url]: https://npmjs.org/package/promise
## Installation
**Server:**
$ npm install promise
**Client:**
You can use browserify on the client, or use the pre-compiled script that acts as a polyfill.
```html
```
Note that the [es5-shim](https://github.com/es-shims/es5-shim) must be loaded before this library to support browsers pre IE9.
```html
```
## Usage
The example below shows how you can load the promise library (in a way that works on both client and server using node or browserify). It then demonstrates creating a promise from scratch. You simply call `new Promise(fn)`. There is a complete specification for what is returned by this method in [Promises/A+](http://promises-aplus.github.com/promises-spec/).
```javascript
var Promise = require('promise');
var promise = new Promise(function (resolve, reject) {
get('http://www.google.com', function (err, res) {
if (err) reject(err);
else resolve(res);
});
});
```
If you need [domains](https://iojs.org/api/domain.html) support, you should instead use:
```js
var Promise = require('promise/domains');
```
If you are in an environment that implements `setImmediate` and don't want the optimisations provided by asap, you can use:
```js
var Promise = require('promise/setimmediate');
```
If you only want part of the features, e.g. just a pure ES6 polyfill:
```js
var Promise = require('promise/lib/es6-extensions');
// or require('promise/domains/es6-extensions');
// or require('promise/setimmediate/es6-extensions');
```
## Unhandled Rejections
By default, promises silence any unhandled rejections.
You can enable logging of unhandled ReferenceErrors and TypeErrors via:
```js
require('promise/lib/rejection-tracking').enable();
```
Due to the performance cost, you should only do this during development.
You can enable logging of all unhandled rejections if you need to debug an exception you think is being swallowed by promises:
```js
require('promise/lib/rejection-tracking').enable(
{allRejections: true}
);
```
Due to the high probability of false positives, I only recommend using this when debugging specific issues that you think may be being swallowed. For the preferred debugging method, see `Promise#done(onFulfilled, onRejected)`.
`rejection-tracking.enable(options)` takes the following options:
- allRejections (`boolean`) - track all exceptions, not just reference errors and type errors. Note that this has a high probability of resulting in false positives if your code loads data optimisticly
- whitelist (`Array`) - this defaults to `[ReferenceError, TypeError]` but you can override it with your own list of error constructors to track.
- `onUnhandled(id, error)` and `onHandled(id, error)` - you can use these to provide your own customised display for errors. Note that if possible you should indicate that the error was a false positive if `onHandled` is called. `onHandled` is only called if `onUnhandled` has already been called.
To reduce the chance of false-positives there is a delay of up to 2 seconds before errors are logged. This means that if you attach an error handler within 2 seconds, it won't be logged as a false positive. ReferenceErrors and TypeErrors are only subject to a 100ms delay due to the higher likelihood that the error is due to programmer error.
## API
Before all examples, you will need:
```js
var Promise = require('promise');
```
### new Promise(resolver)
This creates and returns a new promise. `resolver` must be a function. The `resolver` function is passed two arguments:
1. `resolve` should be called with a single argument. If it is called with a non-promise value then the promise is fulfilled with that value. If it is called with a promise (A) then the returned promise takes on the state of that new promise (A).
2. `reject` should be called with a single argument. The returned promise will be rejected with that argument.
### Static Functions
These methods are invoked by calling `Promise.methodName`.
#### Promise.resolve(value)
(deprecated aliases: `Promise.from(value)`, `Promise.cast(value)`)
Converts values and foreign promises into Promises/A+ promises. If you pass it a value then it returns a Promise for that value. If you pass it something that is close to a promise (such as a jQuery attempt at a promise) it returns a Promise that takes on the state of `value` (rejected or fulfilled).
#### Promise.reject(value)
Returns a rejected promise with the given value.
#### Promise.all(array)
Returns a promise for an array. If it is called with a single argument that `Array.isArray` then this returns a promise for a copy of that array with any promises replaced by their fulfilled values. e.g.
```js
Promise.all([Promise.resolve('a'), 'b', Promise.resolve('c')])
.then(function (res) {
assert(res[0] === 'a')
assert(res[1] === 'b')
assert(res[2] === 'c')
})
```
#### Promise.denodeify(fn)
_Non Standard_
Takes a function which accepts a node style callback and returns a new function that returns a promise instead.
e.g.
```javascript
var fs = require('fs')
var read = Promise.denodeify(fs.readFile)
var write = Promise.denodeify(fs.writeFile)
var p = read('foo.json', 'utf8')
.then(function (str) {
return write('foo.json', JSON.stringify(JSON.parse(str), null, ' '), 'utf8')
})
```
#### Promise.nodeify(fn)
_Non Standard_
The twin to `denodeify` is useful when you want to export an API that can be used by people who haven't learnt about the brilliance of promises yet.
```javascript
module.exports = Promise.nodeify(awesomeAPI)
function awesomeAPI(a, b) {
return download(a, b)
}
```
If the last argument passed to `module.exports` is a function, then it will be treated like a node.js callback and not parsed on to the child function, otherwise the API will just return a promise.
### Prototype Methods
These methods are invoked on a promise instance by calling `myPromise.methodName`
### Promise#then(onFulfilled, onRejected)
This method follows the [Promises/A+ spec](http://promises-aplus.github.io/promises-spec/). It explains things very clearly so I recommend you read it.
Either `onFulfilled` or `onRejected` will be called and they will not be called more than once. They will be passed a single argument and will always be called asynchronously (in the next turn of the event loop).
If the promise is fulfilled then `onFulfilled` is called. If the promise is rejected then `onRejected` is called.
The call to `.then` also returns a promise. If the handler that is called returns a promise, the promise returned by `.then` takes on the state of that returned promise. If the handler that is called returns a value that is not a promise, the promise returned by `.then` will be fulfilled with that value. If the handler that is called throws an exception then the promise returned by `.then` is rejected with that exception.
#### Promise#catch(onRejected)
Sugar for `Promise#then(null, onRejected)`, to mirror `catch` in synchronous code.
#### Promise#done(onFulfilled, onRejected)
_Non Standard_
The same semantics as `.then` except that it does not return a promise and any exceptions are re-thrown so that they can be logged (crashing the application in non-browser environments)
#### Promise#nodeify(callback)
_Non Standard_
If `callback` is `null` or `undefined` it just returns `this`. If `callback` is a function it is called with rejection reason as the first argument and result as the second argument (as per the node.js convention).
This lets you write API functions that look like:
```javascript
function awesomeAPI(foo, bar, callback) {
return internalAPI(foo, bar)
.then(parseResult)
.then(null, retryErrors)
.nodeify(callback)
}
```
People who use typical node.js style callbacks will be able to just pass a callback and get the expected behavior. The enlightened people can not pass a callback and will get awesome promises.
## License
MIT
promise-8.0.1/build.js 0000664 0000000 0000000 00000004026 13131504212 0014625 0 ustar 00root root 0000000 0000000 'use strict';
var fs = require('fs');
var rimraf = require('rimraf');
var acorn = require('acorn');
var walk = require('acorn/dist/walk');
var ids = [];
var names = {};
function getIdFor(name) {
if (name in names) return names[name];
var id;
do {
id = '_' + Math.floor(Math.random() * 100);
} while (ids.indexOf(id) !== -1)
ids.push(id);
names[name] = id;
return id;
}
function fixup(src) {
var ast = acorn.parse(src);
src = src.split('');
walk.simple(ast, {
MemberExpression: function (node) {
if (node.computed) return;
if (node.property.type !== 'Identifier') return;
if (node.property.name[0] !== '_') return;
replace(node.property, getIdFor(node.property.name));
}
});
function source(node) {
return src.slice(node.start, node.end).join('');
}
function replace(node, str) {
for (var i = node.start; i < node.end; i++) {
src[i] = '';
}
src[node.start] = str;
}
return src.join('');
}
rimraf.sync(__dirname + '/lib/');
fs.mkdirSync(__dirname + '/lib/');
fs.readdirSync(__dirname + '/src').forEach(function (filename) {
var src = fs.readFileSync(__dirname + '/src/' + filename, 'utf8');
var out = fixup(src);
fs.writeFileSync(__dirname + '/lib/' + filename, out);
});
rimraf.sync(__dirname + '/domains/');
fs.mkdirSync(__dirname + '/domains/');
fs.readdirSync(__dirname + '/src').forEach(function (filename) {
var src = fs.readFileSync(__dirname + '/src/' + filename, 'utf8');
var out = fixup(src);
out = out.replace(/require\(\'asap\/raw\'\)/g, "require('asap')");
fs.writeFileSync(__dirname + '/domains/' + filename, out);
});
rimraf.sync(__dirname + '/setimmediate/');
fs.mkdirSync(__dirname + '/setimmediate/');
fs.readdirSync(__dirname + '/src').forEach(function (filename) {
var src = fs.readFileSync(__dirname + '/src/' + filename, 'utf8');
var out = fixup(src);
out = out.replace(/var asap \= require\(\'([a-z\/]+)\'\);/g, '');
out = out.replace(/asap/g, "setImmediate");
fs.writeFileSync(__dirname + '/setimmediate/' + filename, out);
});
promise-8.0.1/component.json 0000664 0000000 0000000 00000000650 13131504212 0016064 0 ustar 00root root 0000000 0000000 {
"name": "promise",
"repo": "then/promise",
"description": "Bare bones Promises/A+ implementation",
"version": "8.0.1",
"keywords": [],
"dependencies": {
"johntron/asap": "*"
},
"development": {},
"license": "MIT",
"main": "index.js",
"scripts": [
"index.js",
"lib/core.js",
"lib/done.js",
"lib/es6-extensions.js",
"lib/node-extensions.js"
],
"twitter": "@ForbesLindesay"
} promise-8.0.1/core.js 0000664 0000000 0000000 00000000235 13131504212 0014454 0 ustar 00root root 0000000 0000000 'use strict';
module.exports = require('./lib/core.js');
console.error('require("promise/core") is deprecated, use require("promise/lib/core") instead.');
promise-8.0.1/index.d.ts 0000664 0000000 0000000 00000027131 13131504212 0015073 0 ustar 00root root 0000000 0000000 /**
* Represents the completion of an asynchronous operation
*/
interface ThenPromise extends Promise {
/**
* Attaches callbacks for the resolution and/or rejection of the ThenPromise.
* @param onfulfilled The callback to execute when the ThenPromise is resolved.
* @param onrejected The callback to execute when the ThenPromise is rejected.
* @returns A ThenPromise for the completion of which ever callback is executed.
*/
then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): ThenPromise;
/**
* Attaches a callback for only the rejection of the ThenPromise.
* @param onrejected The callback to execute when the ThenPromise is rejected.
* @returns A ThenPromise for the completion of the callback.
*/
catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): ThenPromise;
// Extensions specific to then/promise
/**
* Attaches callbacks for the resolution and/or rejection of the ThenPromise, without returning a new promise.
* @param onfulfilled The callback to execute when the ThenPromise is resolved.
* @param onrejected The callback to execute when the ThenPromise is rejected.
*/
done(onfulfilled?: ((value: T) => any) | undefined | null, onrejected?: ((reason: any) => any) | undefined | null): void;
/**
* Calls a node.js style callback. If none is provided, the promise is returned.
*/
nodeify(callback: void | null): ThenPromise;
nodeify(callback: (err: Error, value: T) => void): void;
}
interface ThenPromiseConstructor {
/**
* A reference to the prototype.
*/
readonly prototype: ThenPromise;
/**
* Creates a new ThenPromise.
* @param executor A callback used to initialize the promise. This callback is passed two arguments:
* a resolve callback used resolve the promise with a value or the result of another promise,
* and a reject callback used to reject the promise with a provided reason or error.
*/
new (executor: (resolve: (value?: T | PromiseLike) => void, reject: (reason?: any) => void) => any): ThenPromise;
/**
* Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
* resolve, or rejected when any ThenPromise is rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): ThenPromise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>;
/**
* Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
* resolve, or rejected when any ThenPromise is rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): ThenPromise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>;
/**
* Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
* resolve, or rejected when any ThenPromise is rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): ThenPromise<[T1, T2, T3, T4, T5, T6, T7, T8]>;
/**
* Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
* resolve, or rejected when any ThenPromise is rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): ThenPromise<[T1, T2, T3, T4, T5, T6, T7]>;
/**
* Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
* resolve, or rejected when any ThenPromise is rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike]): ThenPromise<[T1, T2, T3, T4, T5, T6]>;
/**
* Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
* resolve, or rejected when any ThenPromise is rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike]): ThenPromise<[T1, T2, T3, T4, T5]>;
/**
* Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
* resolve, or rejected when any ThenPromise is rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike ]): ThenPromise<[T1, T2, T3, T4]>;
/**
* Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
* resolve, or rejected when any ThenPromise is rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): ThenPromise<[T1, T2, T3]>;
/**
* Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
* resolve, or rejected when any ThenPromise is rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
all(values: [T1 | PromiseLike, T2 | PromiseLike]): ThenPromise<[T1, T2]>;
/**
* Creates a ThenPromise that is resolved with an array of results when all of the provided Promises
* resolve, or rejected when any ThenPromise is rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
all(values: (T | PromiseLike)[]): ThenPromise;
/**
* Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): ThenPromise;
/**
* Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): ThenPromise;
/**
* Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): ThenPromise;
/**
* Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): ThenPromise;
/**
* Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike]): ThenPromise;
/**
* Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike]): ThenPromise;
/**
* Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike]): ThenPromise;
/**
* Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
race(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): ThenPromise;
/**
* Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
race(values: [T1 | PromiseLike, T2 | PromiseLike]): ThenPromise;
/**
* Creates a ThenPromise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
* @param values An array of Promises.
* @returns A new ThenPromise.
*/
race(values: (T | PromiseLike)[]): ThenPromise;
/**
* Creates a new rejected promise for the provided reason.
* @param reason The reason the promise was rejected.
* @returns A new rejected ThenPromise.
*/
reject(reason: any): ThenPromise;
/**
* Creates a new rejected promise for the provided reason.
* @param reason The reason the promise was rejected.
* @returns A new rejected ThenPromise.
*/
reject(reason: any): ThenPromise;
/**
* Creates a new resolved promise for the provided value.
* @param value A promise.
* @returns A promise whose internal state matches the provided promise.
*/
resolve(value: T | PromiseLike): ThenPromise;
/**
* Creates a new resolved promise .
* @returns A resolved promise.
*/
resolve(): ThenPromise;
// Extensions specific to then/promise
denodeify: (fn: Function) => (...args: any[]) => ThenPromise;
nodeify: (fn: Function) => Function;
}
declare var ThenPromise: ThenPromiseConstructor;
export = ThenPromise; promise-8.0.1/index.js 0000664 0000000 0000000 00000000061 13131504212 0014630 0 ustar 00root root 0000000 0000000 'use strict';
module.exports = require('./lib')
promise-8.0.1/index.js.flow 0000664 0000000 0000000 00000002722 13131504212 0015604 0 ustar 00root root 0000000 0000000 // @flow
declare class ThenPromise<+R> extends Promise {
constructor(callback: (
resolve: (result: Promise | R) => void,
reject: (error: any) => void
) => mixed): void;
then(
onFulfill?: (value: R) => Promise | U,
onReject?: (error: any) => Promise | U
): ThenPromise;
catch(
onReject?: (error: any) => Promise | U
): ThenPromise;
// Extensions specific to then/promise
/**
* Attaches callbacks for the resolution and/or rejection of the ThenPromise, without returning a new promise.
* @param onfulfilled The callback to execute when the ThenPromise is resolved.
* @param onrejected The callback to execute when the ThenPromise is rejected.
*/
done(onfulfilled?: (value: R) => any, onrejected?: (reason: any) => any): void;
/**
* Calls a node.js style callback. If none is provided, the promise is returned.
*/
nodeify(callback: void | null): ThenPromise;
nodeify(callback: (err: Error, value: R) => void): void;
static resolve(object: Promise | T): ThenPromise;
static reject(error?: any): ThenPromise;
static all>(promises: T): ThenPromise<$TupleMap>;
static race | T>(promises: Array): ThenPromise;
// Extensions specific to then/promise
static denodeify(fn: Function): (...args: any[]) => ThenPromise;
static nodeify(fn: Function): Function;
}
module.exports = ThenPromise;
promise-8.0.1/package.json 0000664 0000000 0000000 00000002133 13131504212 0015453 0 ustar 00root root 0000000 0000000 {
"name": "promise",
"version": "8.0.1",
"description": "Bare bones Promises/A+ implementation",
"main": "index.js",
"scripts": {
"prepublish": "node build",
"pretest": "node build",
"pretest-resolve": "node build",
"pretest-extensions": "node build",
"pretest-memory-leak": "node build",
"test": "mocha --bail --timeout 200 --slow 99999 -R dot && npm run test-memory-leak",
"test-resolve": "mocha test/resolver-tests.js --timeout 200 --slow 999999",
"test-extensions": "mocha test/extensions-tests.js --timeout 200 --slow 999999",
"test-memory-leak": "node --expose-gc test/memory-leak.js",
"coverage": "istanbul cover node_modules/mocha/bin/_mocha -- --bail --timeout 200 --slow 99999 -R dot"
},
"repository": {
"type": "git",
"url": "https://github.com/then/promise.git"
},
"author": "ForbesLindesay",
"license": "MIT",
"devDependencies": {
"acorn": "^1.0.1",
"better-assert": "*",
"istanbul": "^0.3.13",
"mocha": "*",
"promises-aplus-tests": "*",
"rimraf": "^2.3.2"
},
"dependencies": {
"asap": "~2.0.3"
}
} promise-8.0.1/polyfill-done.js 0000664 0000000 0000000 00000000536 13131504212 0016305 0 ustar 00root root 0000000 0000000 // should work in any browser without browserify
if (typeof Promise.prototype.done !== 'function') {
Promise.prototype.done = function (onFulfilled, onRejected) {
var self = arguments.length ? this.then.apply(this, arguments) : this
self.then(null, function (err) {
setTimeout(function () {
throw err
}, 0)
})
}
} promise-8.0.1/polyfill.js 0000664 0000000 0000000 00000000347 13131504212 0015362 0 ustar 00root root 0000000 0000000 // not "use strict" so we can declare global "Promise"
var asap = require('asap');
if (typeof Promise === 'undefined') {
Promise = require('./lib/core.js')
require('./lib/es6-extensions.js')
}
require('./polyfill-done.js');
promise-8.0.1/src/ 0000775 0000000 0000000 00000000000 13131504212 0013755 5 ustar 00root root 0000000 0000000 promise-8.0.1/src/core.js 0000664 0000000 0000000 00000011747 13131504212 0015255 0 ustar 00root root 0000000 0000000 'use strict';
var asap = require('asap/raw');
function noop() {}
// States:
//
// 0 - pending
// 1 - fulfilled with _value
// 2 - rejected with _value
// 3 - adopted the state of another promise, _value
//
// once the state is no longer pending (0) it is immutable
// All `_` prefixed properties will be reduced to `_{random number}`
// at build time to obfuscate them and discourage their use.
// We don't use symbols or Object.defineProperty to fully hide them
// because the performance isn't good enough.
// to avoid using try/catch inside critical functions, we
// extract them to here.
var LAST_ERROR = null;
var IS_ERROR = {};
function getThen(obj) {
try {
return obj.then;
} catch (ex) {
LAST_ERROR = ex;
return IS_ERROR;
}
}
function tryCallOne(fn, a) {
try {
return fn(a);
} catch (ex) {
LAST_ERROR = ex;
return IS_ERROR;
}
}
function tryCallTwo(fn, a, b) {
try {
fn(a, b);
} catch (ex) {
LAST_ERROR = ex;
return IS_ERROR;
}
}
module.exports = Promise;
function Promise(fn) {
if (typeof this !== 'object') {
throw new TypeError('Promises must be constructed via new');
}
if (typeof fn !== 'function') {
throw new TypeError('Promise constructor\'s argument is not a function');
}
this._deferredState = 0;
this._state = 0;
this._value = null;
this._deferreds = null;
if (fn === noop) return;
doResolve(fn, this);
}
Promise._onHandle = null;
Promise._onReject = null;
Promise._noop = noop;
Promise.prototype.then = function(onFulfilled, onRejected) {
if (this.constructor !== Promise) {
return safeThen(this, onFulfilled, onRejected);
}
var res = new Promise(noop);
handle(this, new Handler(onFulfilled, onRejected, res));
return res;
};
function safeThen(self, onFulfilled, onRejected) {
return new self.constructor(function (resolve, reject) {
var res = new Promise(noop);
res.then(resolve, reject);
handle(self, new Handler(onFulfilled, onRejected, res));
});
}
function handle(self, deferred) {
while (self._state === 3) {
self = self._value;
}
if (Promise._onHandle) {
Promise._onHandle(self);
}
if (self._state === 0) {
if (self._deferredState === 0) {
self._deferredState = 1;
self._deferreds = deferred;
return;
}
if (self._deferredState === 1) {
self._deferredState = 2;
self._deferreds = [self._deferreds, deferred];
return;
}
self._deferreds.push(deferred);
return;
}
handleResolved(self, deferred);
}
function handleResolved(self, deferred) {
asap(function() {
var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
if (cb === null) {
if (self._state === 1) {
resolve(deferred.promise, self._value);
} else {
reject(deferred.promise, self._value);
}
return;
}
var ret = tryCallOne(cb, self._value);
if (ret === IS_ERROR) {
reject(deferred.promise, LAST_ERROR);
} else {
resolve(deferred.promise, ret);
}
});
}
function resolve(self, newValue) {
// Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
if (newValue === self) {
return reject(
self,
new TypeError('A promise cannot be resolved with itself.')
);
}
if (
newValue &&
(typeof newValue === 'object' || typeof newValue === 'function')
) {
var then = getThen(newValue);
if (then === IS_ERROR) {
return reject(self, LAST_ERROR);
}
if (
then === self.then &&
newValue instanceof Promise
) {
self._state = 3;
self._value = newValue;
finale(self);
return;
} else if (typeof then === 'function') {
doResolve(then.bind(newValue), self);
return;
}
}
self._state = 1;
self._value = newValue;
finale(self);
}
function reject(self, newValue) {
self._state = 2;
self._value = newValue;
if (Promise._onReject) {
Promise._onReject(self, newValue);
}
finale(self);
}
function finale(self) {
if (self._deferredState === 1) {
handle(self, self._deferreds);
self._deferreds = null;
}
if (self._deferredState === 2) {
for (var i = 0; i < self._deferreds.length; i++) {
handle(self, self._deferreds[i]);
}
self._deferreds = null;
}
}
function Handler(onFulfilled, onRejected, promise){
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
this.onRejected = typeof onRejected === 'function' ? onRejected : null;
this.promise = promise;
}
/**
* Take a potentially misbehaving resolver function and make sure
* onFulfilled and onRejected are only called once.
*
* Makes no guarantees about asynchrony.
*/
function doResolve(fn, promise) {
var done = false;
var res = tryCallTwo(fn, function (value) {
if (done) return;
done = true;
resolve(promise, value);
}, function (reason) {
if (done) return;
done = true;
reject(promise, reason);
});
if (!done && res === IS_ERROR) {
done = true;
reject(promise, LAST_ERROR);
}
}
promise-8.0.1/src/done.js 0000664 0000000 0000000 00000000472 13131504212 0015243 0 ustar 00root root 0000000 0000000 'use strict';
var Promise = require('./core.js');
module.exports = Promise;
Promise.prototype.done = function (onFulfilled, onRejected) {
var self = arguments.length ? this.then.apply(this, arguments) : this;
self.then(null, function (err) {
setTimeout(function () {
throw err;
}, 0);
});
};
promise-8.0.1/src/es6-extensions.js 0000664 0000000 0000000 00000005214 13131504212 0017207 0 ustar 00root root 0000000 0000000 'use strict';
//This file contains the ES6 extensions to the core Promises/A+ API
var Promise = require('./core.js');
module.exports = Promise;
/* Static Functions */
var TRUE = valuePromise(true);
var FALSE = valuePromise(false);
var NULL = valuePromise(null);
var UNDEFINED = valuePromise(undefined);
var ZERO = valuePromise(0);
var EMPTYSTRING = valuePromise('');
function valuePromise(value) {
var p = new Promise(Promise._noop);
p._state = 1;
p._value = value;
return p;
}
Promise.resolve = function (value) {
if (value instanceof Promise) return value;
if (value === null) return NULL;
if (value === undefined) return UNDEFINED;
if (value === true) return TRUE;
if (value === false) return FALSE;
if (value === 0) return ZERO;
if (value === '') return EMPTYSTRING;
if (typeof value === 'object' || typeof value === 'function') {
try {
var then = value.then;
if (typeof then === 'function') {
return new Promise(then.bind(value));
}
} catch (ex) {
return new Promise(function (resolve, reject) {
reject(ex);
});
}
}
return valuePromise(value);
};
Promise.all = function (arr) {
var args = Array.prototype.slice.call(arr);
return new Promise(function (resolve, reject) {
if (args.length === 0) return resolve([]);
var remaining = args.length;
function res(i, val) {
if (val && (typeof val === 'object' || typeof val === 'function')) {
if (val instanceof Promise && val.then === Promise.prototype.then) {
while (val._state === 3) {
val = val._value;
}
if (val._state === 1) return res(i, val._value);
if (val._state === 2) reject(val._value);
val.then(function (val) {
res(i, val);
}, reject);
return;
} else {
var then = val.then;
if (typeof then === 'function') {
var p = new Promise(then.bind(val));
p.then(function (val) {
res(i, val);
}, reject);
return;
}
}
}
args[i] = val;
if (--remaining === 0) {
resolve(args);
}
}
for (var i = 0; i < args.length; i++) {
res(i, args[i]);
}
});
};
Promise.reject = function (value) {
return new Promise(function (resolve, reject) {
reject(value);
});
};
Promise.race = function (values) {
return new Promise(function (resolve, reject) {
values.forEach(function(value){
Promise.resolve(value).then(resolve, reject);
});
});
};
/* Prototype Methods */
Promise.prototype['catch'] = function (onRejected) {
return this.then(null, onRejected);
};
promise-8.0.1/src/finally.js 0000664 0000000 0000000 00000000534 13131504212 0015753 0 ustar 00root root 0000000 0000000 'use strict';
var Promise = require('./core.js');
module.exports = Promise;
Promise.prototype['finally'] = function (f) {
return this.then(function (value) {
return Promise.resolve(f()).then(function () {
return value;
});
}, function (err) {
return Promise.resolve(f()).then(function () {
throw err;
});
});
};
promise-8.0.1/src/index.js 0000664 0000000 0000000 00000000303 13131504212 0015416 0 ustar 00root root 0000000 0000000 'use strict';
module.exports = require('./core.js');
require('./done.js');
require('./finally.js');
require('./es6-extensions.js');
require('./node-extensions.js');
require('./synchronous.js');
promise-8.0.1/src/node-extensions.js 0000664 0000000 0000000 00000006307 13131504212 0017443 0 ustar 00root root 0000000 0000000 'use strict';
// This file contains then/promise specific extensions that are only useful
// for node.js interop
var Promise = require('./core.js');
var asap = require('asap');
module.exports = Promise;
/* Static Functions */
Promise.denodeify = function (fn, argumentCount) {
if (
typeof argumentCount === 'number' && argumentCount !== Infinity
) {
return denodeifyWithCount(fn, argumentCount);
} else {
return denodeifyWithoutCount(fn);
}
};
var callbackFn = (
'function (err, res) {' +
'if (err) { rj(err); } else { rs(res); }' +
'}'
);
function denodeifyWithCount(fn, argumentCount) {
var args = [];
for (var i = 0; i < argumentCount; i++) {
args.push('a' + i);
}
var body = [
'return function (' + args.join(',') + ') {',
'var self = this;',
'return new Promise(function (rs, rj) {',
'var res = fn.call(',
['self'].concat(args).concat([callbackFn]).join(','),
');',
'if (res &&',
'(typeof res === "object" || typeof res === "function") &&',
'typeof res.then === "function"',
') {rs(res);}',
'});',
'};'
].join('');
return Function(['Promise', 'fn'], body)(Promise, fn);
}
function denodeifyWithoutCount(fn) {
var fnLength = Math.max(fn.length - 1, 3);
var args = [];
for (var i = 0; i < fnLength; i++) {
args.push('a' + i);
}
var body = [
'return function (' + args.join(',') + ') {',
'var self = this;',
'var args;',
'var argLength = arguments.length;',
'if (arguments.length > ' + fnLength + ') {',
'args = new Array(arguments.length + 1);',
'for (var i = 0; i < arguments.length; i++) {',
'args[i] = arguments[i];',
'}',
'}',
'return new Promise(function (rs, rj) {',
'var cb = ' + callbackFn + ';',
'var res;',
'switch (argLength) {',
args.concat(['extra']).map(function (_, index) {
return (
'case ' + (index) + ':' +
'res = fn.call(' + ['self'].concat(args.slice(0, index)).concat('cb').join(',') + ');' +
'break;'
);
}).join(''),
'default:',
'args[argLength] = cb;',
'res = fn.apply(self, args);',
'}',
'if (res &&',
'(typeof res === "object" || typeof res === "function") &&',
'typeof res.then === "function"',
') {rs(res);}',
'});',
'};'
].join('');
return Function(
['Promise', 'fn'],
body
)(Promise, fn);
}
Promise.nodeify = function (fn) {
return function () {
var args = Array.prototype.slice.call(arguments);
var callback =
typeof args[args.length - 1] === 'function' ? args.pop() : null;
var ctx = this;
try {
return fn.apply(this, arguments).nodeify(callback, ctx);
} catch (ex) {
if (callback === null || typeof callback == 'undefined') {
return new Promise(function (resolve, reject) {
reject(ex);
});
} else {
asap(function () {
callback.call(ctx, ex);
})
}
}
}
};
Promise.prototype.nodeify = function (callback, ctx) {
if (typeof callback != 'function') return this;
this.then(function (value) {
asap(function () {
callback.call(ctx, null, value);
});
}, function (err) {
asap(function () {
callback.call(ctx, err);
});
});
};
promise-8.0.1/src/rejection-tracking.js 0000664 0000000 0000000 00000005665 13131504212 0020111 0 ustar 00root root 0000000 0000000 'use strict';
var Promise = require('./core');
var DEFAULT_WHITELIST = [
ReferenceError,
TypeError,
RangeError
];
var enabled = false;
exports.disable = disable;
function disable() {
enabled = false;
Promise._onHandle = null;
Promise._onReject = null;
}
exports.enable = enable;
function enable(options) {
options = options || {};
if (enabled) disable();
enabled = true;
var id = 0;
var displayId = 0;
var rejections = {};
Promise._onHandle = function (promise) {
if (
promise._state === 2 && // IS REJECTED
rejections[promise._rejectionId]
) {
if (rejections[promise._rejectionId].logged) {
onHandled(promise._rejectionId);
} else {
clearTimeout(rejections[promise._rejectionId].timeout);
}
delete rejections[promise._rejectionId];
}
};
Promise._onReject = function (promise, err) {
if (promise._deferredState === 0) { // not yet handled
promise._rejectionId = id++;
rejections[promise._rejectionId] = {
displayId: null,
error: err,
timeout: setTimeout(
onUnhandled.bind(null, promise._rejectionId),
// For reference errors and type errors, this almost always
// means the programmer made a mistake, so log them after just
// 100ms
// otherwise, wait 2 seconds to see if they get handled
matchWhitelist(err, DEFAULT_WHITELIST)
? 100
: 2000
),
logged: false
};
}
};
function onUnhandled(id) {
if (
options.allRejections ||
matchWhitelist(
rejections[id].error,
options.whitelist || DEFAULT_WHITELIST
)
) {
rejections[id].displayId = displayId++;
if (options.onUnhandled) {
rejections[id].logged = true;
options.onUnhandled(
rejections[id].displayId,
rejections[id].error
);
} else {
rejections[id].logged = true;
logError(
rejections[id].displayId,
rejections[id].error
);
}
}
}
function onHandled(id) {
if (rejections[id].logged) {
if (options.onHandled) {
options.onHandled(rejections[id].displayId, rejections[id].error);
} else if (!rejections[id].onUnhandled) {
console.warn(
'Promise Rejection Handled (id: ' + rejections[id].displayId + '):'
);
console.warn(
' This means you can ignore any previous messages of the form "Possible Unhandled Promise Rejection" with id ' +
rejections[id].displayId + '.'
);
}
}
}
}
function logError(id, error) {
console.warn('Possible Unhandled Promise Rejection (id: ' + id + '):');
var errStr = (error && (error.stack || error)) + '';
errStr.split('\n').forEach(function (line) {
console.warn(' ' + line);
});
}
function matchWhitelist(error, list) {
return list.some(function (cls) {
return error instanceof cls;
});
} promise-8.0.1/src/synchronous.js 0000664 0000000 0000000 00000002630 13131504212 0016706 0 ustar 00root root 0000000 0000000 'use strict';
var Promise = require('./core.js');
module.exports = Promise;
Promise.enableSynchronous = function () {
Promise.prototype.isPending = function() {
return this.getState() == 0;
};
Promise.prototype.isFulfilled = function() {
return this.getState() == 1;
};
Promise.prototype.isRejected = function() {
return this.getState() == 2;
};
Promise.prototype.getValue = function () {
if (this._state === 3) {
return this._value.getValue();
}
if (!this.isFulfilled()) {
throw new Error('Cannot get a value of an unfulfilled promise.');
}
return this._value;
};
Promise.prototype.getReason = function () {
if (this._state === 3) {
return this._value.getReason();
}
if (!this.isRejected()) {
throw new Error('Cannot get a rejection reason of a non-rejected promise.');
}
return this._value;
};
Promise.prototype.getState = function () {
if (this._state === 3) {
return this._value.getState();
}
if (this._state === -1 || this._state === -2) {
return 0;
}
return this._state;
};
};
Promise.disableSynchronous = function() {
Promise.prototype.isPending = undefined;
Promise.prototype.isFulfilled = undefined;
Promise.prototype.isRejected = undefined;
Promise.prototype.getValue = undefined;
Promise.prototype.getReason = undefined;
Promise.prototype.getState = undefined;
};
promise-8.0.1/test/ 0000775 0000000 0000000 00000000000 13131504212 0014145 5 ustar 00root root 0000000 0000000 promise-8.0.1/test/adapter-a.js 0000664 0000000 0000000 00000000537 13131504212 0016346 0 ustar 00root root 0000000 0000000 var Promise = require('../');
exports.deferred = function () {
var resolve, reject;
var promise = new Promise(function (_resolve, _reject) {
resolve = _resolve;
reject = _reject;
});
return {
promise: promise,
resolve: resolve,
reject: reject
};
};
exports.resolved = Promise.resolve;
exports.rejected = Promise.reject; promise-8.0.1/test/extensions-tests.js 0000664 0000000 0000000 00000025147 13131504212 0020053 0 ustar 00root root 0000000 0000000 var assert = require('better-assert')
var Promise = require('../')
var sentinel = {}
var promise = new Promise(function (resolve) {
resolve(sentinel)
})
var thenable = {then: function (fullfilled, rejected) { fullfilled(sentinel) }}
var thenableRejected = {then: function (fullfilled, rejected) { rejected(sentinel) }}
var a = {}
var b = {}
var c = {}
var A = Promise.resolve(a)
var B = Promise.resolve(b)
var C = Promise.resolve(c)
var rejection = {}
var rejected = new Promise(function (resolve, reject) { reject(rejection) })
describe('extensions', function () {
describe('Promise.denodeify(fn, [argumentCount])', function () {
it('returns a function that uses promises instead of callbacks', function (done) {
function wrap(val, key, callback) {
return callback(null, {val: val, key: key})
}
var pwrap = Promise.denodeify(wrap)
pwrap(sentinel, 'foo')
.then(function (wrapper) {
assert(wrapper.val === sentinel)
assert(wrapper.key === 'foo')
done()
})
})
it('converts callback error arguments into rejection', function (done) {
function fail(val, key, callback) {
return callback(sentinel)
}
var pfail = Promise.denodeify(fail)
pfail(promise, 'foo')
.then(null, function (err) {
assert(err === sentinel)
done()
})
})
it('with an argumentCount it ignores extra arguments', function (done) {
function wrap(val, key, callback) {
return callback(null, {val: val, key: key})
}
var pwrap = Promise.denodeify(wrap, 2)
pwrap(sentinel, 'foo', 'wtf')
.then(function (wrapper) {
assert(wrapper.val === sentinel)
assert(wrapper.key === 'foo')
done()
})
})
it('resolves correctly when the wrapped function returns a promise anyway', function (done) {
function wrap(val, key, callback) {
return new Promise(function(resolve, reject) {
resolve({val: val, key: key})
})
}
var pwrap = Promise.denodeify(wrap)
pwrap(sentinel, 'foo')
.then(function (wrapper) {
assert(wrapper.val === sentinel)
assert(wrapper.key === 'foo')
done()
})
})
})
describe('Promise.nodeify(fn)', function () {
it('converts a promise returning function into a callback function', function (done) {
var add = Promise.nodeify(function (a, b) {
return Promise.resolve(a)
.then(function (a) {
return a + b
})
})
add(1, 2, function (err, res) {
if (err) return done(err)
assert(res === 3)
return done()
})
})
it('converts rejected promises into the first argument of the callback', function (done) {
var add = Promise.nodeify(function (a, b) {
return Promise.resolve(a)
.then(function (a) {
throw sentinel
})
})
var add2 = Promise.nodeify(function (a, b) {
throw sentinel
})
add(1, 2, function (err, res) {
assert(err === sentinel)
add2(1, 2, function (err, res){
assert(err === sentinel)
done()
})
})
})
it('passes through when no callback is provided', function (done) {
var add = Promise.nodeify(function (a, b) {
return Promise.resolve(a)
.then(function (a) {
return a + b
})
})
add(1, 2)
.then(function (res) {
assert(res === 3)
done()
})
})
it('passes through the `this` argument', function (done) {
var ctx = {}
var add = Promise.nodeify(function (a, b) {
return Promise.resolve(a)
.then(function (a) {
return a + b
})
})
add.call(ctx, 1, 2, function (err, res) {
assert(res === 3)
assert(this === ctx)
done()
})
})
})
describe('Promise.all(...)', function () {
describe('an array', function () {
describe('that is empty', function () {
it('returns a promise for an empty array', function (done) {
var res = Promise.all([])
assert(res instanceof Promise)
res.then(function (res) {
assert(Array.isArray(res))
assert(res.length === 0)
})
.nodeify(done)
})
})
describe('of objects', function () {
it('returns a promise for the array', function (done) {
var res = Promise.all([a, b, c])
assert(res instanceof Promise)
res.then(function (res) {
assert(Array.isArray(res))
assert(res[0] === a)
assert(res[1] === b)
assert(res[2] === c)
})
.nodeify(done)
})
})
describe('of promises', function () {
it('returns a promise for an array containing the fulfilled values', function (done) {
var d = {}
var resolveD
var res = Promise.all([A, B, C, new Promise(function (resolve) { resolveD = resolve })])
assert(res instanceof Promise)
res.then(function (res) {
assert(Array.isArray(res))
assert(res[0] === a)
assert(res[1] === b)
assert(res[2] === c)
assert(res[3] === d)
})
.nodeify(done)
resolveD(d)
})
})
describe('of mixed values', function () {
it('returns a promise for an array containing the fulfilled values', function (done) {
var res = Promise.all([A, b, C])
assert(res instanceof Promise)
res.then(function (res) {
assert(Array.isArray(res))
assert(res[0] === a)
assert(res[1] === b)
assert(res[2] === c)
})
.nodeify(done)
})
})
describe('containing at least one rejected promise', function () {
it('rejects the resulting promise', function (done) {
var res = Promise.all([A, rejected, C])
assert(res instanceof Promise)
res.then(function (res) {
throw new Error('Should be rejected')
},
function (err) {
assert(err === rejection)
})
.nodeify(done)
})
})
describe('containing at least one eventually rejected promise', function () {
it('rejects the resulting promise', function (done) {
var rejectB
var rejected = new Promise(function (resolve, reject) { rejectB = reject })
var res = Promise.all([A, rejected, C])
assert(res instanceof Promise)
res.then(function (res) {
throw new Error('Should be rejected')
},
function (err) {
assert(err === rejection)
})
.nodeify(done)
rejectB(rejection)
})
})
describe('with a promise that resolves twice', function () {
it('still waits for all the other promises', function (done) {
var fakePromise = {then: function (onFulfilled) { onFulfilled(1); onFulfilled(2) }}
var eventuallyRejected = {then: function (_, onRejected) { this.onRejected = onRejected }}
var res = Promise.all([fakePromise, eventuallyRejected])
assert(res instanceof Promise)
res.then(function (res) {
throw new Error('Should be rejected')
},
function (err) {
assert(err === rejection)
})
.nodeify(done)
eventuallyRejected.onRejected(rejection);
})
})
describe('when given a foreign promise', function () {
it('should provide the correct value of `this`', function (done) {
var p = {then: function (onFulfilled) { onFulfilled({self: this}); }};
Promise.all([p]).then(function (results) {
assert(p === results[0].self);
}).nodeify(done);
});
});
})
})
describe('promise.done(onFulfilled, onRejected)', function () {
it.skip('behaves like then except for not returning anything', function () {
//todo
})
it ('rethrows unhandled rejections', function (done) {
var originalTimeout = global.setTimeout
global.setTimeout = function(callback) {
try {
callback()
} catch (x) {
assert(x.message === 'It worked')
global.setTimeout = originalTimeout
return done()
}
done(new Error('Callback should have thrown an exception'))
}
Promise.resolve().done(function() {
throw new Error('It worked')
})
})
})
describe('promise.nodeify(callback)', function () {
it('converts a promise returning function into a callback function', function (done) {
function add(a, b, callback) {
return Promise.resolve(a)
.then(function (a) {
return a + b
})
.nodeify(callback)
}
add(1, 2, function (err, res) {
if (err) return done(err)
assert(res === 3)
return done()
})
})
it('converts rejected promises into the first argument of the callback', function (done) {
function add(a, b, callback) {
return Promise.resolve(a)
.then(function (a) {
throw sentinel
})
.nodeify(callback)
}
add(1, 2, function (err, res) {
assert(err === sentinel)
done()
})
})
it('passes through when no callback is provided', function (done) {
function add(a, b, callback) {
return Promise.resolve(a)
.then(function (a) {
return a + b
})
.nodeify(callback)
}
add(1, 2)
.then(function (res) {
assert(res === 3)
done()
})
})
it('accepts a `context` argument', function (done) {
var ctx = {}
function add(a, b, callback) {
return Promise.resolve(a)
.then(function (a) {
return a + b
})
.nodeify(callback, ctx)
}
add(1, 2, function (err, res) {
assert(res === 3)
assert(this === ctx)
done()
})
})
})
describe('inheritance', function () {
it('allows its prototype methods to act upon foreign constructors', function () {
function Awesome(fn) {
if (!(this instanceof Awesome)) return new Awesome(fn)
Promise.call(this, fn)
}
Awesome.prototype = Object.create(Promise.prototype)
Awesome.prototype.constructor = Awesome
var awesome = new Awesome(function () {})
assert(awesome.constructor === Awesome)
assert(awesome.then(function () {}).constructor === Awesome)
})
})
})
promise-8.0.1/test/memory-leak.js 0000664 0000000 0000000 00000001737 13131504212 0016735 0 ustar 00root root 0000000 0000000 'use strict';
var assert = require('assert')
var Promise = require('../')
var i = 0
var sampleA, sampleB
function next() {
return new Promise(function (resolve) {
i++
/*
if (i % 100000 === 0) {
global.gc()
console.dir(process.memoryUsage())
}
*/
if (i === 100000 && typeof global.gc === 'function') {
global.gc()
sampleA = process.memoryUsage()
}
if (i > 100000 * 10) {
if (typeof global.gc === 'function') {
global.gc()
sampleB = process.memoryUsage()
console.log('Memory usage at start:');
console.dir(sampleA)
console.log('Memory usage at end:');
console.dir(sampleB)
assert(sampleA.heapUsed * 1.2 > sampleB.heapUsed, 'heapUsed should not grow by more than 20%')
}
} else {
setImmediate(resolve)
}
}).then(next)
}
if (typeof global.gc !== 'function') {
console.warn('You must run with --expose-gc to test for memory leak.')
}
next().done()
promise-8.0.1/test/nested-promises.js 0000664 0000000 0000000 00000003411 13131504212 0017623 0 ustar 00root root 0000000 0000000 'use strict';
var assert = require('assert');
var Promise = require('../');
describe('nested promises', function () {
it('does not result in any wierd behaviour - 1', function (done) {
var resolveA, resolveB, resolveC;
var A = new Promise(function (resolve, reject) {
resolveA = resolve;
});
var B = new Promise(function (resolve, reject) {
resolveB = resolve;
});
var C = new Promise(function (resolve, reject) {
resolveC = resolve;
});
resolveA(B);
resolveB(C);
resolveC('foo');
A.done(function (result) {
assert(result === 'foo');
done();
});
});
it('does not result in any wierd behaviour - 2', function (done) {
var resolveA, resolveB, resolveC, resolveD;
var A = new Promise(function (resolve, reject) {
resolveA = resolve;
});
var B = new Promise(function (resolve, reject) {
resolveB = resolve;
});
var C = new Promise(function (resolve, reject) {
resolveC = resolve;
});
var D = new Promise(function (resolve, reject) {
resolveD = resolve;
});
var Athen = A.then, Bthen = B.then, Cthen = C.then, Dthen = D.then;
resolveA(B);
resolveB(C);
resolveC(D);
resolveD('foo');
A.done(function (result) {
assert(result === 'foo');
done();
});
});
it('does not result in any wierd behaviour - 2', function (done) {
var promises = [];
var resolveFns = [];
for (var i = 0; i < 100; i++) {
promises.push(new Promise(function (resolve) {
resolveFns.push(resolve);
}));
}
for (var i = 0; i < 99; i++) {
resolveFns[i](promises[i + 1]);
}
resolveFns[99]('foo');
promises[0].done(function (result) {
assert(result === 'foo');
done();
});
});
}); promise-8.0.1/test/promises-tests.js 0000664 0000000 0000000 00000000151 13131504212 0017501 0 ustar 00root root 0000000 0000000 var tests = require('promises-aplus-tests');
var adapter = require('./adapter-a');
tests.mocha(adapter); promise-8.0.1/test/rejection-tracking.js 0000664 0000000 0000000 00000005276 13131504212 0020277 0 ustar 00root root 0000000 0000000 'use strict';
var assert = require('assert');
var Promise = require('../');
var tracking = require('../lib/rejection-tracking');
describe('unhandled rejections', function () {
it('tracks rejected promises', function (done) {
this.timeout(300);
var calls = [], promise;
tracking.enable({
onUnhandled: function (id, err) {
calls.push(['unhandled', id, err]);
promise.done(null, function (err) {
assert.deepEqual(calls, [
['unhandled', 0, err],
['handled', 0, err]
]);
done();
});
},
onHandled: function (id, err) {
calls.push(['handled', id, err]);
}
});
promise = Promise.reject(new TypeError('A fake type error'));
})
it('tracks rejected promises', function (done) {
this.timeout(2200);
var calls = [], promise;
tracking.enable({
allRejections: true,
onUnhandled: function (id, err) {
calls.push(['unhandled', id, err]);
promise.done(null, function (err) {
assert.deepEqual(calls, [
['unhandled', 0, err],
['handled', 0, err]
]);
done();
});
},
onHandled: function (id, err) {
calls.push(['handled', id, err]);
}
});
promise = Promise.reject({});
})
it('tracks rejected promises', function (done) {
this.timeout(500);
var calls = [], promise;
tracking.enable({
onUnhandled: function (id, err) {
done(new Error('Expected exception to be handled in time'));
},
onHandled: function (id, err) {
}
});
promise = Promise.reject(new TypeError('A fake type error'));
var isDone = false;
setTimeout(function () {
promise.done(null, function (err) {
// ignore
isDone = true;
});
}, 50);
setTimeout(function () {
assert(isDone);
done();
}, 400);
})
it('tracks rejected promises', function (done) {
this.timeout(2300);
var warn = console.warn;
var warnings = [];
console.warn = function (str) {
warnings.push(str);
};
var expectedWarnings = [
'Possible Unhandled Promise Rejection (id: 0):',
' my',
' multi',
' line',
' error',
'Promise Rejection Handled (id: 0):',
' This means you can ignore any previous messages of the form "Possible Unhandled Promise Rejection" with id 0.'
];
tracking.enable({allRejections: true});
var promise = Promise.reject('my\nmulti\nline\nerror');
setTimeout(function () {
promise.done(null, function (err) {
console.warn = warn;
assert.deepEqual(warnings, expectedWarnings);
done();
});
}, 2100);
})
}) promise-8.0.1/test/resolver-tests.js 0000664 0000000 0000000 00000012567 13131504212 0017517 0 ustar 00root root 0000000 0000000 var assert = require('better-assert');
var Promise = require('../');
var sentinel = {};
var promise = new Promise(function (resolve) {
resolve(sentinel);
});
var _it = it;
describe('resolver-tests', function () {
describe('The Promise Constructor', function () {
it('has `Object.getPrototypeOf(promise) === Promise.prototype`', function () {
assert(Object.getPrototypeOf(promise) === Promise.prototype)
})
it('has `promise.constructor === Promise`', function () {
assert(promise.constructor === Promise)
})
it('has `promise.constructor === Promise.prototype.constructor`', function () {
assert(promise.constructor === Promise.prototype.constructor)
})
it('has `Promise.length === 1`', function () {
assert(Promise.length === 1)
})
describe('if resolver is not a function', function () {
it('must throw a `TypeError`', function () {
try {
new Promise({})
} catch (ex) {
assert(ex instanceof TypeError)
return
}
throw new Error('Should have thrown a TypeError')
})
})
describe('if resolver is a function', function () {
it('must be called with the promise\'s resolver arguments', function (done) {
new Promise(function (resolve, reject) {
assert(typeof resolve === 'function')
assert(typeof reject === 'function')
done();
})
})
it('must be called immediately, before `Promise` returns', function () {
var called = false;
new Promise(function (resolve, reject) {
called = true;
})
assert(called)
})
})
describe('Calling resolve(x)', function () {
describe('if promise is resolved', function () {
it('nothing happens', function (done) {
var thenable = {then: function (onComplete) {
setTimeout(function () {
onComplete(sentinel)
}, 50)
}};
new Promise(function (resolve) {
process.nextTick(function () {
resolve(thenable)
resolve(null)
});
})
.then(function (result) {
assert(result === sentinel)
})
.then(function () {
done()
}, function (err) {
done(err || new Error('Promise rejected'));
})
})
})
describe('otherwise', function () {
describe('if x is a thenable', function () {
it('assimilates the thenable', function () {
})
})
describe('otherwise', function () {
it('is fulfilled with x as the fulfillment value', function (done) {
new Promise(function (resolve, reject) {
resolve(sentinel)
})
.then(function (fulfillmentValue) {
assert(fulfillmentValue === sentinel)
})
.then(function () {
done()
}, function (err) {
done(err || new Error('Promise rejected'));
})
})
})
})
})
describe('Calling reject(x)', function () {
describe('if promise is resolved', function () {
it('nothing happens', function (done) {
var thenable = {then: function (onComplete) {
setTimeout(function () {
onComplete(sentinel)
}, 50)
}};
new Promise(function (resolve, reject) {
process.nextTick(function () {
resolve(thenable)
reject('foo')
});
})
.then(function (result) {
assert(result === sentinel)
})
.then(function () {
done()
}, function (err) {
done(err || new Error('Promise rejected'));
})
})
})
describe('otherwise', function () {
it('is rejected with x as the rejection reason', function (done) {
new Promise(function (resolve, reject) {
reject(sentinel)
})
.then(null, function (rejectionReason) {
assert(rejectionReason === sentinel)
})
.then(function () {
done()
}, function (err) {
done(err || new Error('Promise rejected'));
})
})
})
})
})
describe('if resolver throws', function () {
describe('if promise is resolved', function () {
it('nothing happens', function (done) {
var thenable = {then: function (onComplete) {
setTimeout(function () {
onComplete(sentinel)
}, 50)
}};
new Promise(function (resolve, reject) {
resolve(thenable)
throw new Error('foo');
})
.then(function (result) {
assert(result === sentinel)
})
.then(function () {
done()
}, function (err) {
done(err || new Error('Promise rejected'));
})
})
})
describe('otherwise', function () {
it('is rejected with e as the rejection reason', function (done) {
new Promise(function (resolve, reject) {
throw sentinel
})
.then(null, function (rejectionReason) {
assert(rejectionReason === sentinel)
})
.then(function () {
done()
}, function (err) {
done(err || new Error('Promise rejected'));
})
})
})
})
}) promise-8.0.1/test/synchronous-inspection-tests.js 0000664 0000000 0000000 00000016104 13131504212 0022410 0 ustar 00root root 0000000 0000000 var assert = require('better-assert');
var Promise = require('../');
describe('synchronous-inspection-tests', function () {
it('cannot synchronously inspect before enabling synchronous inspection', function(done) {
var finished = null;
var fulfilledPromise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve();
}, 10);
});
var rejectedPromise = new Promise(function(resolve, reject) {
setTimeout(function() {
reject();
}, 10);
});
assert(fulfilledPromise.getValue == undefined);
assert(fulfilledPromise.getReason == undefined);
assert(fulfilledPromise.isFulfilled == undefined);
assert(fulfilledPromise.isPending == undefined);
assert(fulfilledPromise.isRejected == undefined);
assert(rejectedPromise.getValue == undefined);
assert(rejectedPromise.getReason == undefined);
assert(rejectedPromise.isFulfilled == undefined);
assert(rejectedPromise.isPending == undefined);
assert(rejectedPromise.isRejected == undefined);
setTimeout(function() {
assert(fulfilledPromise.getValue == undefined);
assert(fulfilledPromise.getReason == undefined);
assert(fulfilledPromise.isFulfilled == undefined);
assert(fulfilledPromise.isPending == undefined);
assert(fulfilledPromise.isRejected == undefined);
assert(rejectedPromise.getValue == undefined);
assert(rejectedPromise.getReason == undefined);
assert(rejectedPromise.isFulfilled == undefined);
assert(rejectedPromise.isPending == undefined);
assert(rejectedPromise.isRejected == undefined);
done()
}, 30);
});
it('can poll a promise to see if it is resolved', function (done) {
Promise.enableSynchronous();
var finished = null;
var fulfilledPromise = new Promise(function(resolve, reject) {
var interval = setInterval(function() {
if (finished !== null) {
clearTimeout(interval);
if (finished) {
resolve(true);
}
else {
reject(false);
}
}
}, 10);
});
assert(fulfilledPromise.getState() === 0);
assert(fulfilledPromise.isPending());
assert(!fulfilledPromise.isFulfilled());
assert(!fulfilledPromise.isRejected());
finished = true;
setTimeout(function () {
assert(fulfilledPromise.getState() === 1);
assert(fulfilledPromise.isFulfilled());
assert(!fulfilledPromise.isRejected());
assert(fulfilledPromise.getValue());
assert(!fulfilledPromise.isPending());
done();
}, 30);
});
it('can poll a promise to see if it is rejected', function (done) {
Promise.enableSynchronous();
var finished = null;
var fulfilledPromise = new Promise(function(resolve, reject) {
var interval = setInterval(function() {
if (finished !== null) {
clearTimeout(interval);
if (finished) {
resolve(true);
}
else {
reject(false);
}
}
}, 10);
});
assert(fulfilledPromise.getState() === 0);
assert(fulfilledPromise.isPending());
assert(!fulfilledPromise.isFulfilled());
assert(!fulfilledPromise.isRejected());
finished = false;
setTimeout(function () {
assert(fulfilledPromise.getState() === 2);
assert(!fulfilledPromise.isFulfilled());
assert(fulfilledPromise.isRejected());
assert(!fulfilledPromise.getReason());
assert(!fulfilledPromise.isPending());
done();
}, 30);
});
it('will throw an error if getting a value of an unfulfilled promise', function (done) {
Promise.enableSynchronous();
var finished = null;
var fulfilledPromise = new Promise(function(resolve, reject) {
var interval = setInterval(function() {
if (finished !== null) {
clearTimeout(interval);
if (finished) {
resolve(true);
}
else {
reject(false);
}
}
}, 10);
});
assert(fulfilledPromise.isPending());
assert(!fulfilledPromise.isFulfilled());
assert(!fulfilledPromise.isRejected());
try {
fulfilledPromise.getValue();
assert(false);
}
catch (e) {
assert(true);
}
finished = false;
setTimeout(function () {
try {
fulfilledPromise.getValue();
assert(false);
}
catch (e) {
assert(true);
}
done();
}, 30);
});
it('will throw an error if getting a reason of a non-rejected promise', function (done) {
Promise.enableSynchronous();
var finished = null;
var fulfilledPromise = new Promise(function(resolve, reject) {
var interval = setInterval(function() {
if (finished !== null) {
clearTimeout(interval);
if (finished) {
resolve(true);
}
else {
reject(false);
}
}
}, 10);
});
assert(fulfilledPromise.isPending());
assert(!fulfilledPromise.isFulfilled());
assert(!fulfilledPromise.isRejected());
try {
fulfilledPromise.getReason();
assert(false);
}
catch (e) {
assert(true);
}
finished = true;
setTimeout(function () {
try {
fulfilledPromise.getReason();
assert(false);
}
catch (e) {
assert(true);
}
done()
}, 30);
});
it('can disable synchronous inspection', function() {
Promise.enableSynchronous();
var testPromise = Promise.resolve('someValue');
assert(testPromise.getValue() == 'someValue');
Promise.disableSynchronous();
assert(testPromise.getValue == undefined);
});
it('can synchronously poll a resolving promise chain', function (done) {
Promise.enableSynchronous();
var fulfilledPromise = new Promise(function(resolve, reject) {
var interval = setTimeout(function() {
resolve(Promise.resolve(true));
}, 10);
});
assert(fulfilledPromise.getState() === 0);
assert(fulfilledPromise.isPending());
assert(!fulfilledPromise.isFulfilled());
assert(!fulfilledPromise.isRejected());
setTimeout(function() {
assert(fulfilledPromise.getState() === 1);
assert(fulfilledPromise.isFulfilled());
assert(!fulfilledPromise.isRejected());
assert(fulfilledPromise.getValue());
assert(!fulfilledPromise.isPending());
done();
}, 30);
});
it('can synchronously poll a rejecting promise chain', function(done) {
Promise.enableSynchronous();
var rejectedPromise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(Promise.reject(false));
}, 10);
});
assert(rejectedPromise.getState() === 0);
assert(rejectedPromise.isPending());
assert(!rejectedPromise.isFulfilled());
assert(!rejectedPromise.isRejected());
setTimeout(function() {
assert(rejectedPromise.getState() === 2);
assert(!rejectedPromise.isFulfilled());
assert(rejectedPromise.isRejected());
assert(!rejectedPromise.getReason());
assert(!rejectedPromise.isPending());
done();
}, 30);
});
});