[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