diff --git a/src/promise.js b/src/promise.js index f2439fbb4..c1f5d251d 100644 --- a/src/promise.js +++ b/src/promise.js @@ -489,6 +489,7 @@ Promise.prototype._resolveCallback = function(value, shouldBind) { if (shouldBind) this._propagateFrom(maybePromise, PROPAGATE_BIND); + var promise = maybePromise._target(); if (promise === this) { @@ -505,7 +506,7 @@ Promise.prototype._resolveCallback = function(value, shouldBind) { } this._setFollowing(); this._setLength(0); - this._setFollowee(promise); + this._setFollowee(maybePromise); } else if (BIT_FIELD_CHECK(IS_FULFILLED)) { this._fulfill(promise._value()); } else if (BIT_FIELD_CHECK(IS_REJECTED)) { diff --git a/test/mocha/cancel.js b/test/mocha/cancel.js index 54448868d..03d172eb4 100644 --- a/test/mocha/cancel.js +++ b/test/mocha/cancel.js @@ -281,6 +281,35 @@ describe("Cancellation", function() { }); }); + specify("cancels the followee, calling all onCancel callbacks", function() { + var called = 0; + + var promise = new Promise(function(_, __, onCancel) { + onCancel(function() { + called++; + }); + }) + + var promise2 = new Promise(function(resolve, reject, onCancel) { + resolve(promise); + onCancel(function() { + called++; + }); + }); + + var promise3 = new Promise(function(resolve, reject, onCancel) { + resolve(promise2); + onCancel(function() { + called++; + }); + }); + + promise3.cancel(); + return awaitLateQueue(function() { + assert.equal(3, called); + }); + }); + specify("can be used for breaking chains early", function() { var called = false; var p = Promise.resolve(1) diff --git a/tools/test.js b/tools/test.js index d2735dd14..27f53554c 100644 --- a/tools/test.js +++ b/tools/test.js @@ -18,7 +18,8 @@ jobRunner.setVerbose(0); // Random slowness after tests complete function getTests(options) { var g; - if (options.testName === "all") { + + if (options.testName === "all" || options.testName.indexOf("no") === 0) { g = "./test/mocha/*.js"; } else if (options.testName === "aplus") { g = "./test/mocha/[0-9].[0-9].[0-9].js"; @@ -28,11 +29,24 @@ function getTests(options) { var testName = options.testName.replace(/^(\d)(\d)(\d)$/, "$1.$2.$3"); g = "./test/mocha/" + testName + ".js"; } + + var excludes = []; + if (options.testName.indexOf("no") === 0) { + excludes = options.testName.slice(2).split(","); + } + return glob(g).then(function(matches) { return matches.filter(function(match) { if (match.indexOf("generator") >= 0) { return options.generators; } + + for (var i = 0; i < excludes.length; ++i) { + if (match.indexOf(excludes[i]) >= 0) { + return false; + } + } + return true; }) }).tap(function(m) { @@ -144,7 +158,7 @@ if ("run" in argv) { if (testName.indexOf("*") === -1) { testName = testName.toLowerCase() .replace( /\.js$/, "" ) - .replace( /[^a-zA-Z0-9_\-.]/g, "" ); + .replace( /[^,a-zA-Z0-9_\-.]/g, "" ); } }