[Pkg-javascript-commits] [node-es6-promise] 01/01: Imported Upstream version 3.2.2+ds
Julien Puydt
julien.puydt at laposte.net
Tue Aug 2 21:22:26 UTC 2016
This is an automated email from the git hooks/post-receive script.
jpuydt-guest pushed a commit to annotated tag upstream/3.2.2+ds
in repository node-es6-promise.
commit 843f27725aa1f83706a555567fa96b6e15ef663b
Author: Julien Puydt <julien.puydt at laposte.net>
Date: Tue Aug 2 07:23:01 2016 +0200
Imported Upstream version 3.2.2+ds
---
.DS_Store | Bin 6148 -> 0 bytes
.eslintrc | 31 ++++++
.gitignore | 4 +-
.release.json | 15 +--
.travis.yml | 6 +
Brocfile.js | 2 +-
CHANGELOG.md | 47 +++++++-
README.md | 21 +++-
bower.json | 2 +-
lib/es6-promise/-internal.js | 33 +++++-
lib/es6-promise/asap.js | 3 +-
lib/es6-promise/enumerator.js | 105 +++++++++---------
lib/es6-promise/promise.js | 49 ++------
lib/es6-promise/promise/race.js | 38 ++-----
lib/es6-promise/then.js | 34 ++++++
package.json | 24 ++--
test/extension-test.js | 239 +++++++++++++++++++++++++++++++++++++++-
17 files changed, 492 insertions(+), 161 deletions(-)
diff --git a/.DS_Store b/.DS_Store
deleted file mode 100644
index 0e1992e..0000000
Binary files a/.DS_Store and /dev/null differ
diff --git a/.eslintrc b/.eslintrc
new file mode 100644
index 0000000..401ea40
--- /dev/null
+++ b/.eslintrc
@@ -0,0 +1,31 @@
+{
+ "extends": "ember",
+
+ "parser": "babel-eslint",
+
+ "ecmaFeatures": {
+ modules: true,
+ blockBindings: true,
+ arrowFunctions: true,
+ objectLiteralShorthandMethods: true,
+ objectLiteralShorthandProperties: true,
+ templateStrings: true
+ },
+
+ "rules": {
+ "indent": [ 2, "tab", { "SwitchCase": 1 } ],
+ "object-shorthand": [ 2, "always" ],
+ "prefer-const": 0,
+ "comma-dangle": 0,
+ "spaced-comment": 1,
+ "object-curly-spacing": [2, "always"],
+ "arrow-spacing": [ 1, { before: true, after: true } ],
+ "array-bracket-spacing": [ 2, "always" ],
+ "no-restricted-syntax": 0,
+ "no-warning-comments": [ 0, { "terms": [ "todo", "fixme", "xxx" ], "location": "start" } ],
+ "no-ternary": 0,
+ "no-nested-ternary": 2,
+ "brace-style": [ 2, "stroustrup" ],
+ "no-else-return": 0
+ }
+}
diff --git a/.gitignore b/.gitignore
index 8b81193..8fa9f24 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,6 @@
/main.js
/tmp
/docs
-/dist/test
\ No newline at end of file
+/dist/test
+!/dist/es6-promise.js
+!/dist/es6-promise.min.js
\ No newline at end of file
diff --git a/.release.json b/.release.json
index dee8cbc..0bf6c4f 100644
--- a/.release.json
+++ b/.release.json
@@ -6,12 +6,13 @@
"pkgFiles": ["package.json", "bower.json"],
"increment": "patch",
"commitMessage": "Release %s",
- "tagName": "%s",
+ "tagName": "v%s",
"tagAnnotation": "Release %s",
- "buildCommand": "npm run-script build-all",
- "distRepo": "git at github.com:components/rsvp.js.git",
- "distStageDir": "tmp/stage",
- "distBase": "dist",
- "distFiles": ["**/*", "../package.json", "../bower.json"],
- "publish": false
+ "buildCommand": "npm run-script build:production",
+ "dist": {
+ "repo": "git at github.com:components/es6-promise.git",
+ "stageDir": "tmp/stage",
+ "base": "dist",
+ "files": ["**/*", "../package.json", "../bower.json"]
+ }
}
diff --git a/.travis.yml b/.travis.yml
index 9e9d1e9..634f6db 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,8 +2,14 @@
language: node_js
node_js:
- '0.10'
+
+sudo: false
+
after_success:
- "./bin/publish_to_s3.js"
+before_install:
+ - export PATH=/usr/local/phantomjs-2.0.0/bin:$PATH
+
env:
global:
- secure: |-
diff --git a/Brocfile.js b/Brocfile.js
index 89a3903..29acbfe 100644
--- a/Brocfile.js
+++ b/Brocfile.js
@@ -41,7 +41,7 @@ var dist = es6Promise;
env('production', function() {
dist = merge([
- rename(uglify(dist), '.js', '.min.js'),
+ rename(uglify(dist, { mangle: true, compress: true }), '.js', '.min.js'),
dist
]);
});
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fbe4053..65b4a19 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,25 @@
# Master
-# 3.0.2
+# 3.2.0
-* correctly bump both bower and package.json versions
+* improve tamper resistence of Promise.all Promise.race and
+ Promise.prototype.then (note, this isn't complete, but addresses an exception
+ when used \w core-js, follow up work will address entirely)
+* remove spec incompatible then chaining fast-path
+* add eslint
+* update build deps
+
+# 3.1.2
+
+* fix node detection issues with NWJS/electron
+
+# 3.1.0
+
+* improve performance of Promise.all when it encounters a non-promise input object input
+* then/resolve tamper protection
+* reduce AST size of promise constructor, to facilitate more inlining
+* Update README.md with details about PhantomJS requirement for running tests
+* Mangle and compress the minified version
# 3.0.1
@@ -10,16 +27,36 @@
# 3.0.0
-* use nextTick() instead of setImmediate() to schedule microtasks with node 0.10. Later versions of
- nodes are not affected as they were already using nextTick(). Note that using nextTick() might
+* use nextTick() instead of setImmediate() to schedule microtasks with node 0.10. Later versions of
+ nodes are not affected as they were already using nextTick(). Note that using nextTick() might
trigger a depreciation warning on 0.10 as described at https://github.com/cujojs/when/issues/410.
- The reason why nextTick() is preferred is that is setImmediate() would schedule a macrotask
+ The reason why nextTick() is preferred is that is setImmediate() would schedule a macrotask
instead of a microtask and might result in a different scheduling.
If needed you can revert to the former behavior as follow:
var Promise = require('es6-promise').Promise;
Promise._setScheduler(setImmediate);
+# 2.3.0
+
+* #121: Ability to override the internal asap implementation
+* #120: Use an ascii character for an apostrophe, for source maps
+
+# 2.2.0
+
+* #116: Expose asap() and a way to override the scheduling mechanism on Promise
+* Lock to v0.2.3 of ember-cli
+
+# 2.1.1
+
+* Fix #100 via #105: tell browserify to ignore vertx require
+* Fix #101 via #102: "follow thenable state, not own state"
+
+# 2.1.0
+
+* #59: Automatic polyfill. No need to invoke `ES6Promise.polyfill()` anymore.
+* ... (see the commit log)
+
# 2.0.0
* re-sync with RSVP. Many large performance improvements and bugfixes.
diff --git a/README.md b/README.md
index d952fa7..16739ca 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,13 @@
# ES6-Promise (subset of [rsvp.js](https://github.com/tildeio/rsvp.js))
-This is a polyfill of the [ES6 Promise](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-constructor). The implementation is a subset of [rsvp.js](https://github.com/tildeio/rsvp.js), if you're wanting extra features and more debugging options, check out the [full library](https://github.com/tildeio/rsvp.js).
+This is a polyfill of the [ES6 Promise](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-constructor). The implementation is a subset of [rsvp.js](https://github.com/tildeio/rsvp.js) extracted by @jakearchibald, if you're wanting extra features and more debugging options, check out the [full library](https://github.com/tildeio/rsvp.js).
For API details and how to use promises, see the <a href="http://www.html5rocks.com/en/tutorials/es6/promises/">JavaScript Promises HTML5Rocks article</a>.
## Downloads
-* [es6-promise](https://raw.githubusercontent.com/jakearchibald/es6-promise/master/dist/es6-promise.js)
-* [es6-promise-min](https://raw.githubusercontent.com/jakearchibald/es6-promise/master/dist/es6-promise.min.js)
+* [es6-promise](https://raw.githubusercontent.com/stefanpenner/es6-promise/master/dist/es6-promise.js)
+* [es6-promise-min](https://raw.githubusercontent.com/stefanpenner/es6-promise/master/dist/es6-promise.min.js)
## Node.js
@@ -23,6 +23,15 @@ To use:
var Promise = require('es6-promise').Promise;
```
+## Bower
+
+To install:
+
+```sh
+bower install es6-promise --save
+```
+
+
## Usage in IE<9
`catch` is a reserved word in IE<9, meaning `promise.catch(func)` throws a syntax error. To work around this, you can use a string to access the property as shown in the following example.
@@ -55,7 +64,11 @@ Notice that we don't assign the result of `polyfill()` to any variable. The `pol
## Building & Testing
+You will need to have PhantomJS installed globally in order to run the tests.
+
+`npm install -g phantomjs`
+
* `npm run build` to build
* `npm test` to run tests
-* `npm start` to run a build watcher, and webserver to test
+* `npm start` to run a build watcher, and webserver to test
* `npm run test:server` for a testem test runner and watching builder
diff --git a/bower.json b/bower.json
index c699782..572f09c 100644
--- a/bower.json
+++ b/bower.json
@@ -1,7 +1,7 @@
{
"name": "es6-promise",
"namespace": "Promise",
- "version": "3.0.2",
+ "version": "3.2.2",
"description": "A polyfill for ES6-style Promises, tracking rsvp",
"authors": [
"Stefan Penner <stefan.penner at gmail.com>"
diff --git a/lib/es6-promise/-internal.js b/lib/es6-promise/-internal.js
index 720448f..aeebf57 100644
--- a/lib/es6-promise/-internal.js
+++ b/lib/es6-promise/-internal.js
@@ -7,6 +7,11 @@ import {
asap
} from './asap';
+import originalThen from './then';
+import originalResolve from './promise/resolve';
+
+export var PROMISE_ID = Math.random().toString(36).substring(16);
+
function noop() {}
var PENDING = void 0;
@@ -79,12 +84,12 @@ function handleOwnThenable(promise, thenable) {
}
}
-function handleMaybeThenable(promise, maybeThenable) {
- if (maybeThenable.constructor === promise.constructor) {
+function handleMaybeThenable(promise, maybeThenable, then) {
+ if (maybeThenable.constructor === promise.constructor &&
+ then === originalThen &&
+ constructor.resolve === originalResolve) {
handleOwnThenable(promise, maybeThenable);
} else {
- var then = getThen(maybeThenable);
-
if (then === GET_THEN_ERROR) {
reject(promise, GET_THEN_ERROR.error);
} else if (then === undefined) {
@@ -101,7 +106,7 @@ function resolve(promise, value) {
if (promise === value) {
reject(promise, selfFulfillment());
} else if (objectOrFunction(value)) {
- handleMaybeThenable(promise, value);
+ handleMaybeThenable(promise, value, getThen(value));
} else {
fulfill(promise, value);
}
@@ -236,7 +241,22 @@ function initializePromise(promise, resolver) {
}
}
+var id = 0;
+function nextId() {
+ return id++;
+}
+
+function makePromise(promise) {
+ promise[PROMISE_ID] = id++;
+ promise._state = undefined;
+ promise._result = undefined;
+ promise._subscribers = [];
+}
+
export {
+ nextId,
+ makePromise,
+ getThen,
noop,
resolve,
reject,
@@ -248,5 +268,6 @@ export {
invokeCallback,
FULFILLED,
REJECTED,
- PENDING
+ PENDING,
+ handleMaybeThenable
};
diff --git a/lib/es6-promise/asap.js b/lib/es6-promise/asap.js
index 56a65a5..40f1d25 100644
--- a/lib/es6-promise/asap.js
+++ b/lib/es6-promise/asap.js
@@ -1,5 +1,4 @@
var len = 0;
-var toString = {}.toString;
var vertxNext;
var customSchedulerFn;
@@ -30,7 +29,7 @@ export function setAsap(asapFn) {
var browserWindow = (typeof window !== 'undefined') ? window : undefined;
var browserGlobal = browserWindow || {};
var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
-var isNode = typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
+var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
// test for web worker but not in IE10
var isWorker = typeof Uint8ClampedArray !== 'undefined' &&
diff --git a/lib/es6-promise/enumerator.js b/lib/es6-promise/enumerator.js
index 03fdf8c..2a7a28f 100644
--- a/lib/es6-promise/enumerator.js
+++ b/lib/es6-promise/enumerator.js
@@ -10,95 +10,100 @@ import {
subscribe,
FULFILLED,
REJECTED,
- PENDING
+ PENDING,
+ getThen,
+ handleMaybeThenable
} from './-internal';
+import then from './then';
+import Promise from './promise';
+import originalResolve from './promise/resolve';
+import originalThen from './then';
+import { makePromise, PROMISE_ID } from './-internal';
+
+export default Enumerator;
function Enumerator(Constructor, input) {
- var enumerator = this;
+ this._instanceConstructor = Constructor;
+ this.promise = new Constructor(noop);
- enumerator._instanceConstructor = Constructor;
- enumerator.promise = new Constructor(noop);
+ if (!this.promise[PROMISE_ID]) {
+ makePromise(this.promise);
+ }
- if (enumerator._validateInput(input)) {
- enumerator._input = input;
- enumerator.length = input.length;
- enumerator._remaining = input.length;
+ if (isArray(input)) {
+ this._input = input;
+ this.length = input.length;
+ this._remaining = input.length;
- enumerator._init();
+ this._result = new Array(this.length);
- if (enumerator.length === 0) {
- fulfill(enumerator.promise, enumerator._result);
+ if (this.length === 0) {
+ fulfill(this.promise, this._result);
} else {
- enumerator.length = enumerator.length || 0;
- enumerator._enumerate();
- if (enumerator._remaining === 0) {
- fulfill(enumerator.promise, enumerator._result);
+ this.length = this.length || 0;
+ this._enumerate();
+ if (this._remaining === 0) {
+ fulfill(this.promise, this._result);
}
}
} else {
- reject(enumerator.promise, enumerator._validationError());
+ reject(this.promise, validationError());
}
}
-Enumerator.prototype._validateInput = function(input) {
- return isArray(input);
-};
-
-Enumerator.prototype._validationError = function() {
+function validationError() {
return new Error('Array Methods must be provided an Array');
};
-Enumerator.prototype._init = function() {
- this._result = new Array(this.length);
-};
-
-export default Enumerator;
-
Enumerator.prototype._enumerate = function() {
- var enumerator = this;
-
- var length = enumerator.length;
- var promise = enumerator.promise;
- var input = enumerator._input;
+ var length = this.length;
+ var input = this._input;
- for (var i = 0; promise._state === PENDING && i < length; i++) {
- enumerator._eachEntry(input[i], i);
+ for (var i = 0; this._state === PENDING && i < length; i++) {
+ this._eachEntry(input[i], i);
}
};
Enumerator.prototype._eachEntry = function(entry, i) {
- var enumerator = this;
- var c = enumerator._instanceConstructor;
-
- if (isMaybeThenable(entry)) {
- if (entry.constructor === c && entry._state !== PENDING) {
- entry._onerror = null;
- enumerator._settledAt(entry._state, i, entry._result);
+ var c = this._instanceConstructor;
+ var resolve = c.resolve;
+
+ if (resolve === originalResolve) {
+ var then = getThen(entry);
+
+ if (then === originalThen &&
+ entry._state !== PENDING) {
+ this._settledAt(entry._state, i, entry._result);
+ } else if (typeof then !== 'function') {
+ this._remaining--;
+ this._result[i] = entry;
+ } else if (c === Promise) {
+ var promise = new c(noop);
+ handleMaybeThenable(promise, entry, then);
+ this._willSettleAt(promise, i);
} else {
- enumerator._willSettleAt(c.resolve(entry), i);
+ this._willSettleAt(new c(function(resolve) { resolve(entry); }), i);
}
} else {
- enumerator._remaining--;
- enumerator._result[i] = entry;
+ this._willSettleAt(resolve(entry), i);
}
};
Enumerator.prototype._settledAt = function(state, i, value) {
- var enumerator = this;
- var promise = enumerator.promise;
+ var promise = this.promise;
if (promise._state === PENDING) {
- enumerator._remaining--;
+ this._remaining--;
if (state === REJECTED) {
reject(promise, value);
} else {
- enumerator._result[i] = value;
+ this._result[i] = value;
}
}
- if (enumerator._remaining === 0) {
- fulfill(promise, enumerator._result);
+ if (this._remaining === 0) {
+ fulfill(promise, this._result);
}
};
diff --git a/lib/es6-promise/promise.js b/lib/es6-promise/promise.js
index 8b1688b..d95951e 100644
--- a/lib/es6-promise/promise.js
+++ b/lib/es6-promise/promise.js
@@ -4,11 +4,9 @@ import {
import {
noop,
- subscribe,
- initializePromise,
- invokeCallback,
- FULFILLED,
- REJECTED
+ nextId,
+ PROMISE_ID,
+ initializePromise
} from './-internal';
import {
@@ -21,8 +19,8 @@ import all from './promise/all';
import race from './promise/race';
import Resolve from './promise/resolve';
import Reject from './promise/reject';
+import then from './then';
-var counter = 0;
function needsResolver() {
throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
@@ -137,21 +135,13 @@ export default Promise;
@constructor
*/
function Promise(resolver) {
- this._id = counter++;
- this._state = undefined;
- this._result = undefined;
+ this[PROMISE_ID] = nextId();
+ this._result = this._state = undefined;
this._subscribers = [];
if (noop !== resolver) {
- if (!isFunction(resolver)) {
- needsResolver();
- }
-
- if (!(this instanceof Promise)) {
- needsNew();
- }
-
- initializePromise(this, resolver);
+ typeof resolver !== 'function' && needsResolver();
+ this instanceof Promise ? initializePromise(this, resolver) : needsNew();
}
}
@@ -359,28 +349,7 @@ Promise.prototype = {
Useful for tooling.
@return {Promise}
*/
- then: function(onFulfillment, onRejection) {
- var parent = this;
- var state = parent._state;
-
- if (state === FULFILLED && !onFulfillment || state === REJECTED && !onRejection) {
- return this;
- }
-
- var child = new this.constructor(noop);
- var result = parent._result;
-
- if (state) {
- var callback = arguments[state - 1];
- asap(function(){
- invokeCallback(state, child, callback, result);
- });
- } else {
- subscribe(parent, child, onFulfillment, onRejection);
- }
-
- return child;
- },
+ then: then,
/**
`catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
diff --git a/lib/es6-promise/promise/race.js b/lib/es6-promise/promise/race.js
index 0d7ff13..8c922e3 100644
--- a/lib/es6-promise/promise/race.js
+++ b/lib/es6-promise/promise/race.js
@@ -2,14 +2,6 @@ import {
isArray
} from "../utils";
-import {
- noop,
- resolve,
- reject,
- subscribe,
- PENDING
-} from '../-internal';
-
/**
`Promise.race` returns a new promise which is settled in the same way as the
first passed promise to settle.
@@ -79,26 +71,16 @@ export default function race(entries) {
/*jshint validthis:true */
var Constructor = this;
- var promise = new Constructor(noop);
-
if (!isArray(entries)) {
- reject(promise, new TypeError('You must pass an array to race.'));
- return promise;
- }
-
- var length = entries.length;
-
- function onFulfillment(value) {
- resolve(promise, value);
+ return new Constructor(function(resolve, reject) {
+ reject(new TypeError('You must pass an array to race.'));
+ });
+ } else {
+ return new Constructor(function(resolve, reject) {
+ var length = entries.length;
+ for (var i = 0; i < length; i++) {
+ Constructor.resolve(entries[i]).then(resolve, reject);
+ }
+ });
}
-
- function onRejection(reason) {
- reject(promise, reason);
- }
-
- for (var i = 0; promise._state === PENDING && i < length; i++) {
- subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection);
- }
-
- return promise;
}
diff --git a/lib/es6-promise/then.js b/lib/es6-promise/then.js
new file mode 100644
index 0000000..f97e946
--- /dev/null
+++ b/lib/es6-promise/then.js
@@ -0,0 +1,34 @@
+import {
+ invokeCallback,
+ subscribe,
+ FULFILLED,
+ REJECTED,
+ noop,
+ makePromise,
+ PROMISE_ID
+} from './-internal';
+
+import { asap } from './asap';
+
+export default function then(onFulfillment, onRejection) {
+ var parent = this;
+
+ var child = new this.constructor(noop);
+
+ if (child[PROMISE_ID] === undefined) {
+ makePromise(child);
+ }
+
+ var state = parent._state;
+
+ if (state) {
+ var callback = arguments[state - 1];
+ asap(function(){
+ invokeCallback(state, child, callback, parent._result);
+ });
+ } else {
+ subscribe(parent, child, onFulfillment, onRejection);
+ }
+
+ return child;
+}
diff --git a/package.json b/package.json
index 920d501..6e4cb75 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "es6-promise",
"namespace": "es6-promise",
- "version": "3.0.2",
+ "version": "3.2.2",
"description": "A lightweight library that provides tools for organizing asynchronous code",
"main": "dist/es6-promise.js",
"directories": {
@@ -13,27 +13,25 @@
"!dist/test"
],
"devDependencies": {
- "bower": "^1.3.9",
- "brfs": "0.0.8",
- "broccoli-es3-safe-recast": "0.0.8",
+ "babel-eslint": "^6.0.0",
"broccoli-es6-module-transpiler": "^0.5.0",
- "broccoli-jshint": "^0.5.1",
- "broccoli-merge-trees": "^0.1.4",
- "broccoli-replace": "^0.2.0",
- "broccoli-stew": "0.0.6",
+ "broccoli-jshint": "^2.1.0",
+ "broccoli-merge-trees": "^1.1.1",
+ "broccoli-replace": "^0.12.0",
+ "broccoli-stew": "^1.2.0",
"broccoli-uglify-js": "^0.1.3",
"broccoli-watchify": "^0.2.0",
- "ember-cli": "0.2.3",
+ "ember-cli": "2.5.0",
"ember-publisher": "0.0.7",
- "git-repo-version": "0.0.2",
+ "git-repo-version": "0.3.0",
"json3": "^3.3.2",
- "minimatch": "^2.0.1",
- "mocha": "^1.20.1",
+ "mocha": "^2.4.5",
"promises-aplus-tests-phantom": "^2.1.0-revise",
- "release-it": "0.0.10"
+ "release-it": "2.3.1"
},
"scripts": {
"build": "ember build",
+ "build:production": "ember build --environment production",
"start": "ember s",
"test": "ember test",
"test:server": "ember test --server",
diff --git a/test/extension-test.js b/test/extension-test.js
index 51bd242..f490d45 100644
--- a/test/extension-test.js
+++ b/test/extension-test.js
@@ -42,6 +42,230 @@ function objectEquals(obj1, obj2) {
}
return true;
}
+describe('tampering', function() {
+ var resolve = Promise.resolve;
+
+ afterEach(function() {
+ Promise.resolve = resolve;
+ });
+
+ describe('then assimilation', function() {
+ it('tampered resolved and then', function() {
+ var one = Promise.resolve(1);
+ var two = Promise.resolve(2);
+ var thenCalled = 0;
+ var resolveCalled = 0;
+
+ two.then = function() {
+ thenCalled++;
+ return Promise.prototype.then.apply(this, arguments);
+ };
+
+ Promise.resolve = function(x) {
+ resolveCalled++;
+ return new Promise(function(resolve) { resolve(x); });
+ };
+
+ return one.then(function() {
+ return two;
+ }).then(function(value) {
+ assert.equal(thenCalled, 1, 'expected then to be called once');
+ assert.equal(resolveCalled, 0, 'expected resolve to be called once');
+ assert.equal(value, 2, 'expected fulfillment value to be 2');
+ });
+ });
+
+ describe('alternative constructor', function() {
+ it('tampered resolved and then', function() {
+ var one = Promise.resolve(1);
+ var two = Promise.resolve(2);
+ var thenCalled = 0;
+ var resolveCalled = 0;
+ var invokedAlternativeConstructor = 0;
+
+ two.then = function() {
+ thenCalled++;
+ return Promise.prototype.then.apply(this, arguments);
+ };
+
+ function AlternativeConstructor(executor) {
+ invokedAlternativeConstructor++;
+ var followers = this.followers = [];
+ executor(function(value) {
+ followers.forEach(function(onFulfillment) {
+ onFulfillment(value)
+ });
+ }, function() {
+ throw TypeError('No Rejections supported');
+ });
+ }
+
+ AlternativeConstructor.resolve = function(x) {
+ resolveCalled++;
+ return new Promise(function(resolve) { resolve(x); });
+ };
+
+ AlternativeConstructor.prototype.then = function(onFulfillment, onRejection) {
+ this.followers.push(onFulfillment);
+ };
+
+ AlternativeConstructor.resolve = function(x) {
+ resolveCalled++;
+ return new Promise(function(resolve) { resolve(x); });
+ };
+
+ one.constructor = AlternativeConstructor
+
+ return one.then(function() {
+ return two;
+ }).then(function(value) {
+
+ assert.equal(invokedAlternativeConstructor, 1, 'expected AlternativeConstructor to be invoked once');
+ assert.equal(thenCalled, 1, 'expected then to be called once');
+ assert.equal(resolveCalled, 0, 'expected resolve to be called once');
+ assert.equal(value, 2, 'expected fulfillment value to be 2');
+ });
+ });
+ });
+
+ describe('Promise.all', function() {
+ it('tampered resolved and then', function() {
+ var two = Promise.resolve(2);
+ var thenCalled = 0;
+ var resolveCalled = 0;
+
+ two.then = function() {
+ thenCalled++;
+ return Promise.prototype.then.apply(this, arguments);
+ };
+
+ Promise.resolve = function(x) {
+ resolveCalled++;
+ return new Promise(function(resolve) { resolve(x); });
+ };
+
+ return Promise.all([two]).then(function(value) {
+ assert.equal(thenCalled, 1);
+ assert.equal(resolveCalled, 1);
+ assert.deepEqual(value, [2]);
+ });
+ });
+
+ it('alternative constructor and tampered then', function() {
+ var two = Promise.resolve(2);
+ var thenCalled = 0;
+ var resolveCalled = 0;
+
+ two.then = function() {
+ thenCalled++;
+ return Promise.prototype.then.apply(this, arguments);
+ };
+
+ function AlternativeConstructor(executor) {
+ var followers = this.followers = [];
+ executor(function(value) {
+ followers.forEach(function(onFulfillment) {
+ onFulfillment(value)
+ });
+ }, function() {
+ throw TypeError('No Rejections supported');
+ });
+ }
+
+ AlternativeConstructor.resolve = function(x) {
+ resolveCalled++;
+ return new Promise(function(resolve) { resolve(x); });
+ };
+
+ AlternativeConstructor.prototype.then = function(onFulfillment, onRejection) {
+ this.followers.push(onFulfillment);
+ };
+
+ return Promise.all.call(AlternativeConstructor, [two]).then(function(value) {
+ assert.equal(thenCalled, 1);
+ assert.equal(resolveCalled, 1);
+ assert.deepEqual(value, [2]);
+ });
+ });
+ });
+
+ describe('core-js species test', function() {
+ it('foreign thenable has correct internal slots', function() {
+ var p = Promise.resolve();
+
+ function NewConstructor(it) {
+ it(function(){}, function(){})
+ }
+
+ p.constructor = NewConstructor;
+
+ var f = p.then(function(){});
+ assert(f instanceof NewConstructor);
+ });
+ });
+ describe('Promise.race', function() {
+ it('tampered resolved and then', function() {
+ var two = Promise.resolve(2);
+ var thenCalled = 0;
+ var resolveCalled = 0;
+
+ two.then = function() {
+ thenCalled++;
+ return Promise.prototype.then.apply(this, arguments);
+ };
+
+ Promise.resolve = function(x) {
+ resolveCalled++;
+ return new Promise(function(resolve) { resolve(x); });
+ };
+
+ return Promise.race([two]).then(function(value) {
+ assert.equal(thenCalled, 1);
+ assert.equal(resolveCalled, 1);
+ assert.deepEqual(value, 2);
+ });
+ });
+
+ it('alternative constructor and tampered then', function() {
+ var two = Promise.resolve(2);
+ var thenCalled = 0;
+ var resolveCalled = 0;
+
+ two.then = function() {
+ thenCalled++;
+ return Promise.prototype.then.apply(this, arguments);
+ };
+
+ function AlternativeConstructor(executor) {
+ var followers = this.followers = [];
+ executor(function(value) {
+ followers.forEach(function(onFulfillment) {
+ onFulfillment(value)
+ });
+ }, function() {
+ throw TypeError('No Rejections supported');
+ });
+ }
+
+ AlternativeConstructor.resolve = function(x) {
+ resolveCalled++;
+ return new Promise(function(resolve) { resolve(x); });
+ };
+
+ AlternativeConstructor.prototype.then = function(onFulfillment, onRejection) {
+ this.followers.push(onFulfillment);
+ };
+
+ return Promise.race.call(AlternativeConstructor, [two]).then(function(value) {
+ assert.equal(thenCalled, 1);
+ assert.equal(resolveCalled, 1);
+ assert.deepEqual(value, 2);
+ });
+ });
+ });
+
+ });
+});
describe("extensions", function() {
describe("Promise constructor", function() {
@@ -284,7 +508,7 @@ describe("extensions", function() {
});
});
- describe("Promise.all", function() {
+ describe('Promise.all', function() {
testAll(function(){
return Promise.all.apply(Promise, arguments);
});
@@ -295,6 +519,15 @@ describe("extensions", function() {
assert(all);
});
+ it('works with plan pojo input', function(done) {
+ all([
+ {}
+ ]).then(function(result) {
+ assert.deepEqual(result, [{}]);
+ done();
+ });
+ });
+
it('throws when not passed an array', function(done) {
var nothing = assertRejection(all());
var string = assertRejection(all(''));
@@ -890,11 +1123,11 @@ describe("extensions", function() {
});
});
- if (typeof Worker !== 'undefined') {
+ if (typeof Worker !== 'undefined' && navigator.userAgent.indexOf('PhantomJS') < 1) {
describe('web worker', function () {
it('should work', function (done) {
this.timeout(2000);
- var worker = new Worker('worker.js');
+ var worker = new Worker('./worker.js');
worker.addEventListener('error', function(reason) {
done(new Error("Test failed:" + reason));
});
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-es6-promise.git
More information about the Pkg-javascript-commits
mailing list