Commit 08ff89d4 authored by Gabriel Monnerat's avatar Gabriel Monnerat Committed by Romain Courteaud

cancel: propagate message

parent e18484cb
...@@ -7,14 +7,14 @@ function promiseAtLeast(expected_count, promises) { ...@@ -7,14 +7,14 @@ function promiseAtLeast(expected_count, promises) {
throw new TypeError('You must pass an array to all.'); throw new TypeError('You must pass an array to all.');
} }
function canceller() { function canceller(msg) {
var promise; var promise;
for (var i = 0; i < promises.length; i++) { for (var i = 0; i < promises.length; i++) {
promise = promises[i]; promise = promises[i];
if (promise && typeof promise.then === 'function' && if (promise && typeof promise.then === 'function' &&
typeof promise.cancel === 'function') { typeof promise.cancel === 'function') {
promise.cancel(); promise.cancel(msg);
} }
} }
} }
......
...@@ -12,7 +12,7 @@ function size(object) { ...@@ -12,7 +12,7 @@ function size(object) {
function hash(promises) { function hash(promises) {
function canceller() { function canceller(msg) {
var promise, var promise,
key; key;
for (key in promises) { for (key in promises) {
...@@ -21,7 +21,7 @@ function hash(promises) { ...@@ -21,7 +21,7 @@ function hash(promises) {
if (promise && typeof promise.then === 'function' && if (promise && typeof promise.then === 'function' &&
typeof promise.cancel === 'function') { typeof promise.cancel === 'function') {
promise.cancel(); promise.cancel(msg);
} }
} }
} }
......
...@@ -45,21 +45,21 @@ var Promise = function(resolver, canceller) { ...@@ -45,21 +45,21 @@ var Promise = function(resolver, canceller) {
this.on('error', onerror); this.on('error', onerror);
this.cancel = function () { this.cancel = function (msg) {
// For now, simply reject the promise and does not propagate the cancel // For now, simply reject the promise and does not propagate the cancel
// to parent or children // to parent or children
if (resolved) { return; } if (resolved) { return; }
promise.isCancelled = true; promise.isCancelled = true;
if (canceller !== undefined) { if (canceller !== undefined) {
try { try {
canceller(); canceller(msg);
} catch (e) { } catch (e) {
rejectPromise(e); rejectPromise(e);
return; return;
} }
} }
// Trigger cancel? // Trigger cancel?
rejectPromise(new CancellationError()); rejectPromise(new CancellationError(msg));
}; };
try { try {
......
...@@ -24,9 +24,9 @@ var Queue = function(thenable) { ...@@ -24,9 +24,9 @@ var Queue = function(thenable) {
return new Queue(thenable); return new Queue(thenable);
} }
function canceller() { function canceller(msg) {
for (var i = promise_list.length; i > 0; i--) { for (var i = promise_list.length; i > 0; i--) {
promise_list[i - 1].cancel(); promise_list[i - 1].cancel(msg);
} }
} }
...@@ -69,10 +69,10 @@ var Queue = function(thenable) { ...@@ -69,10 +69,10 @@ var Queue = function(thenable) {
checkPromise(resolve(thenable)); checkPromise(resolve(thenable));
queue.cancel = function () { queue.cancel = function (msg) {
if (resolved) {return;} if (resolved) {return;}
resolved = true; resolved = true;
promise.cancel(); promise.cancel(msg);
promise.fail(function (rejectedReason) { promise.fail(function (rejectedReason) {
queue.isRejected = true; queue.isRejected = true;
queue.rejectedReason = rejectedReason; queue.rejectedReason = rejectedReason;
......
...@@ -9,9 +9,9 @@ function resolve(thenable) { ...@@ -9,9 +9,9 @@ function resolve(thenable) {
} }
} }
return resolve(thenable); return resolve(thenable);
}, function () { }, function (msg) {
if ((thenable !== undefined) && (thenable.cancel !== undefined)) { if ((thenable !== undefined) && (thenable.cancel !== undefined)) {
thenable.cancel(); thenable.cancel(msg);
} }
}); });
} }
......
...@@ -565,7 +565,7 @@ describe("RSVP extensions", function() { ...@@ -565,7 +565,7 @@ describe("RSVP extensions", function() {
}); });
specify('cancel the array of promise as soon as cancelled', function(done) { specify('cancel the array of promise as soon as cancelled', function(done) {
var firstResolver, secondResolver; var error, firstResolver, secondResolver;
var first = new RSVP.Promise(function(resolve, reject) { var first = new RSVP.Promise(function(resolve, reject) {
firstResolver = { resolve: resolve, reject: reject }; firstResolver = { resolve: resolve, reject: reject };
...@@ -585,13 +585,17 @@ describe("RSVP extensions", function() { ...@@ -585,13 +585,17 @@ describe("RSVP extensions", function() {
var all_promise = RSVP.hash({one: "nonPromiseValue", two: first, three: second}); var all_promise = RSVP.hash({one: "nonPromiseValue", two: first, three: second});
all_promise.cancel(); all_promise.cancel("Foo");
all_promise.fail(function (e) {
error = e;
});
setTimeout(function() { setTimeout(function() {
assert(first.isRejected); assert(first.isRejected);
assert(first.rejectedReason instanceof RSVP.CancellationError); assert(first.rejectedReason instanceof RSVP.CancellationError);
assert(second.isRejected); assert(second.isRejected);
assert(second.rejectedReason instanceof RSVP.CancellationError); assert(second.rejectedReason instanceof RSVP.CancellationError);
assert.equal(error.message, "Foo");
done(); done();
}, 20); }, 20);
}); });
...@@ -649,13 +653,15 @@ describe("RSVP extensions", function() { ...@@ -649,13 +653,15 @@ describe("RSVP extensions", function() {
return; return;
}}, two: first, three: second}); }}, two: first, three: second});
all_promise.cancel(); all_promise.cancel("Foo");
setTimeout(function() { setTimeout(function() {
assert(first.isRejected); assert(first.isRejected);
assert(first.rejectedReason instanceof RSVP.CancellationError); assert(first.rejectedReason instanceof RSVP.CancellationError);
assert.equal(first.rejectedReason.message, "Foo");
assert(second.isRejected); assert(second.isRejected);
assert(second.rejectedReason instanceof RSVP.CancellationError); assert(second.rejectedReason instanceof RSVP.CancellationError);
assert.equal(second.rejectedReason.message, "Foo");
done(); done();
}, 20); }, 20);
}); });
...@@ -789,7 +795,7 @@ describe("RSVP extensions", function() { ...@@ -789,7 +795,7 @@ describe("RSVP extensions", function() {
}); });
specify('cancel the array of promise as soon as cancelled', function(done) { specify('cancel the array of promise as soon as cancelled', function(done) {
var firstResolver, secondResolver; var error, firstResolver, secondResolver;
var first = new RSVP.Promise(function(resolve, reject) { var first = new RSVP.Promise(function(resolve, reject) {
firstResolver = { resolve: resolve, reject: reject }; firstResolver = { resolve: resolve, reject: reject };
...@@ -809,13 +815,17 @@ describe("RSVP extensions", function() { ...@@ -809,13 +815,17 @@ describe("RSVP extensions", function() {
var all_promise = RSVP.all(["nonPromiseValue", first, second]); var all_promise = RSVP.all(["nonPromiseValue", first, second]);
all_promise.cancel(); all_promise.cancel("Foo");
all_promise.fail(function (e) {
error = e;
})
setTimeout(function() { setTimeout(function() {
assert(first.isRejected); assert(first.isRejected);
assert(first.rejectedReason instanceof RSVP.CancellationError); assert(first.rejectedReason instanceof RSVP.CancellationError);
assert(second.isRejected); assert(second.isRejected);
assert(second.rejectedReason instanceof RSVP.CancellationError); assert(second.rejectedReason instanceof RSVP.CancellationError);
assert.equal(error.message, "Foo");
done(); done();
}, 20); }, 20);
}); });
...@@ -873,13 +883,15 @@ describe("RSVP extensions", function() { ...@@ -873,13 +883,15 @@ describe("RSVP extensions", function() {
return; return;
}}, first, second]); }}, first, second]);
all_promise.cancel(); all_promise.cancel("Foo");
setTimeout(function() { setTimeout(function() {
assert(first.isRejected); assert(first.isRejected);
assert(first.rejectedReason instanceof RSVP.CancellationError); assert(first.rejectedReason instanceof RSVP.CancellationError);
assert.equal(first.rejectedReason.message, "Foo");
assert(second.isRejected); assert(second.isRejected);
assert(second.rejectedReason instanceof RSVP.CancellationError); assert(second.rejectedReason instanceof RSVP.CancellationError);
assert.equal(second.rejectedReason.message, "Foo");
done(); done();
}, 20); }, 20);
}); });
...@@ -1046,13 +1058,15 @@ describe("RSVP extensions", function() { ...@@ -1046,13 +1058,15 @@ describe("RSVP extensions", function() {
var all_promise = RSVP.any([first, second]); var all_promise = RSVP.any([first, second]);
all_promise.cancel(); all_promise.cancel("Foo");
setTimeout(function() { setTimeout(function() {
assert(first.isRejected); assert(first.isRejected);
assert(first.rejectedReason instanceof RSVP.CancellationError); assert(first.rejectedReason instanceof RSVP.CancellationError);
assert.equal(first.rejectedReason.message, "Foo");
assert(second.isRejected); assert(second.isRejected);
assert(second.rejectedReason instanceof RSVP.CancellationError); assert(second.rejectedReason instanceof RSVP.CancellationError);
assert.equal(second.rejectedReason.message, "Foo");
done(); done();
}, 20); }, 20);
}); });
...@@ -1110,13 +1124,15 @@ describe("RSVP extensions", function() { ...@@ -1110,13 +1124,15 @@ describe("RSVP extensions", function() {
return; return;
}}, first, second]); }}, first, second]);
all_promise.cancel(); all_promise.cancel("Foo");
setTimeout(function() { setTimeout(function() {
assert(first.isRejected); assert(first.isRejected);
assert(first.rejectedReason instanceof RSVP.CancellationError); assert(first.rejectedReason instanceof RSVP.CancellationError);
assert.equal(first.rejectedReason.message, "Foo");
assert(second.isRejected); assert(second.isRejected);
assert(second.rejectedReason instanceof RSVP.CancellationError); assert(second.rejectedReason instanceof RSVP.CancellationError);
assert.equal(second.rejectedReason.message, "Foo");
done(); done();
}, 20); }, 20);
}); });
...@@ -1508,10 +1524,11 @@ describe("RSVP extensions", function() { ...@@ -1508,10 +1524,11 @@ describe("RSVP extensions", function() {
thenable.fail(function(error){ thenable.fail(function(error){
assert(error instanceof RSVP.CancellationError, 'expected CancellationError'); assert(error instanceof RSVP.CancellationError, 'expected CancellationError');
assert.equal(error.message, "Foo");
done(); done();
}); });
wrapped.cancel(); wrapped.cancel("Foo");
}); });
}); });
...@@ -1705,7 +1722,7 @@ describe("`cancel` on directly created promise", function () { ...@@ -1705,7 +1722,7 @@ describe("`cancel` on directly created promise", function () {
promise.then(null, function(e) { promise.then(null, function(e) {
error = e; error = e;
}); });
promise.cancel(); promise.cancel("Foo");
setTimeout(function() { setTimeout(function() {
assert.equal(error, 'bar error'); assert.equal(error, 'bar error');
done(); done();
...@@ -1718,9 +1735,10 @@ describe("`cancel` on directly created promise", function () { ...@@ -1718,9 +1735,10 @@ describe("`cancel` on directly created promise", function () {
promise.then(null, function(e) { promise.then(null, function(e) {
error = e; error = e;
}); });
promise.cancel(); promise.cancel("Foo");
setTimeout(function() { setTimeout(function() {
assert(error instanceof RSVP.CancellationError); assert(error instanceof RSVP.CancellationError);
assert.equal(error.message, "Foo");
done(); done();
}, 20); }, 20);
}); });
...@@ -1780,6 +1798,27 @@ describe("`cancel` on promise created by then", function () { ...@@ -1780,6 +1798,27 @@ describe("`cancel` on promise created by then", function () {
}, 20); }, 20);
}); });
it('should propagate cancel message', function (done) {
var cancel_called = false,
promise = new RSVP.Promise(
function () {
return;
}, function (e) {
error = e;
cancel_called = true;
error = e;
}),
error;
promise.cancel("Propagate Message");
setTimeout(function() {
assert(promise.rejectedReason instanceof RSVP.CancellationError);
assert(cancel_called);
assert.equal(error, "Propagate Message");
done();
}, 20);
});
it('should cancel the pending fulfilled promise', function (done) { it('should cancel the pending fulfilled promise', function (done) {
var cancel_called = false, var cancel_called = false,
promise = new RSVP.Promise(function (resolve) {resolve();}), promise = new RSVP.Promise(function (resolve) {resolve();}),
...@@ -1993,10 +2032,11 @@ describe("`RSVP.delay`", function () { ...@@ -1993,10 +2032,11 @@ describe("`RSVP.delay`", function () {
it('should allow to cancel the setTimeout', function (done) { it('should allow to cancel the setTimeout', function (done) {
var promise = RSVP.delay(); var promise = RSVP.delay();
promise.cancel(); promise.cancel("Foo");
setTimeout(function() { setTimeout(function() {
// XXX How to check that clearTimeout is called? // XXX How to check that clearTimeout is called?
assert.equal(promise.isRejected, true); assert.equal(promise.isRejected, true);
assert.equal(promise.rejectedReason.message, "Foo");
done(); done();
}, 20); }, 20);
}); });
...@@ -2069,10 +2109,11 @@ describe("`RSVP.timeout`", function () { ...@@ -2069,10 +2109,11 @@ describe("`RSVP.timeout`", function () {
it('should allow to cancel the setTimeout', function (done) { it('should allow to cancel the setTimeout', function (done) {
var promise = RSVP.timeout(); var promise = RSVP.timeout();
promise.cancel(); promise.cancel("Foo");
setTimeout(function() { setTimeout(function() {
// XXX How to check that clearTimeout is called? // XXX How to check that clearTimeout is called?
assert.equal(promise.isRejected, true); assert.equal(promise.isRejected, true);
assert.equal(promise.rejectedReason.message, "Foo");
done(); done();
}, 20); }, 20);
}); });
...@@ -2425,11 +2466,13 @@ describe("`RSVP.Queue`", function () { ...@@ -2425,11 +2466,13 @@ describe("`RSVP.Queue`", function () {
queue.then(null, function(e) { queue.then(null, function(e) {
error = e; error = e;
}); });
queue.cancel(); queue.cancel("Foo");
setTimeout(function() { setTimeout(function() {
assert(error instanceof RSVP.CancellationError); assert(error instanceof RSVP.CancellationError);
assert.equal(error.message, "Foo");
assert.equal(queue.isRejected, true); assert.equal(queue.isRejected, true);
assert(queue.rejectedReason instanceof RSVP.CancellationError); assert(queue.rejectedReason instanceof RSVP.CancellationError);
assert.equal(queue.rejectedReason.message, "Foo");
done(); done();
}, 20); }, 20);
}); });
...@@ -2516,7 +2559,7 @@ describe("`RSVP.Queue`", function () { ...@@ -2516,7 +2559,7 @@ describe("`RSVP.Queue`", function () {
assert.equal(queue.isRejected, undefined); assert.equal(queue.isRejected, undefined);
assert.equal(queue.isFulfilled, undefined); assert.equal(queue.isFulfilled, undefined);
assert.equal(thenable_ongoing, true); assert.equal(thenable_ongoing, true);
queue.cancel(); queue.cancel("Foo");
assert.equal(thenable_cancel_called, true); assert.equal(thenable_cancel_called, true);
setTimeout(function() { setTimeout(function() {
...@@ -2525,6 +2568,7 @@ describe("`RSVP.Queue`", function () { ...@@ -2525,6 +2568,7 @@ describe("`RSVP.Queue`", function () {
assert(queue.rejectedReason instanceof RSVP.CancellationError); assert(queue.rejectedReason instanceof RSVP.CancellationError);
assert.equal(result, 'MARKER1'); assert.equal(result, 'MARKER1');
assert(error instanceof RSVP.CancellationError); assert(error instanceof RSVP.CancellationError);
assert.equal(error.message, "Foo");
assert.equal(later_success_thenable_called, false); assert.equal(later_success_thenable_called, false);
assert.equal(later_error_thenable_called, false); assert.equal(later_error_thenable_called, false);
done(); done();
...@@ -2564,15 +2608,17 @@ describe("`RSVP.Queue`", function () { ...@@ -2564,15 +2608,17 @@ describe("`RSVP.Queue`", function () {
assert.equal(queue.isRejected, undefined); assert.equal(queue.isRejected, undefined);
assert.equal(queue.isFulfilled, undefined); assert.equal(queue.isFulfilled, undefined);
assert.equal(thenable_ongoing, true); assert.equal(thenable_ongoing, true);
queue.cancel(); queue.cancel("Foo");
assert.equal(thenable_cancel_called, true); assert.equal(thenable_cancel_called, true);
setTimeout(function() { setTimeout(function() {
assert.equal(queue.isRejected, true); assert.equal(queue.isRejected, true);
assert.equal(queue.isFulfilled, undefined); assert.equal(queue.isFulfilled, undefined);
assert(queue.rejectedReason instanceof RSVP.CancellationError); assert(queue.rejectedReason instanceof RSVP.CancellationError);
assert.equal(queue.rejectedReason.message, "Foo");
assert.equal(result, 'MARKER1'); assert.equal(result, 'MARKER1');
assert(error instanceof RSVP.CancellationError); assert(error instanceof RSVP.CancellationError);
assert.equal(error.message, "Foo");
assert.equal(later_success_thenable_called, false); assert.equal(later_success_thenable_called, false);
assert.equal(later_error_thenable_called, false); assert.equal(later_error_thenable_called, false);
done(); done();
...@@ -2615,15 +2661,17 @@ describe("`RSVP.Queue`", function () { ...@@ -2615,15 +2661,17 @@ describe("`RSVP.Queue`", function () {
assert.equal(queue.isRejected, undefined); assert.equal(queue.isRejected, undefined);
assert.equal(queue.isFulfilled, undefined); assert.equal(queue.isFulfilled, undefined);
assert.equal(thenable_ongoing, true); assert.equal(thenable_ongoing, true);
queue.cancel(); queue.cancel("Foo");
assert.equal(thenable_cancel_called, true); assert.equal(thenable_cancel_called, true);
setTimeout(function() { setTimeout(function() {
assert.equal(queue.isRejected, true); assert.equal(queue.isRejected, true);
assert.equal(queue.isFulfilled, undefined); assert.equal(queue.isFulfilled, undefined);
assert(queue.rejectedReason instanceof RSVP.CancellationError); assert(queue.rejectedReason instanceof RSVP.CancellationError);
assert.equal(queue.rejectedReason.message, "Foo");
assert.equal(result, 'MARKER1'); assert.equal(result, 'MARKER1');
assert(error instanceof RSVP.CancellationError); assert(error instanceof RSVP.CancellationError);
assert.equal(error.message, "Foo");
assert.equal(later_success_thenable_called, false); assert.equal(later_success_thenable_called, false);
assert.equal(later_error_thenable_called, false); assert.equal(later_error_thenable_called, false);
done(); done();
...@@ -2631,5 +2679,37 @@ describe("`RSVP.Queue`", function () { ...@@ -2631,5 +2679,37 @@ describe("`RSVP.Queue`", function () {
}, 20); }, 20);
}); });
it('should `cancel` propagate message to CancellationError', function (done) {
var error,
thenable_cancel_called = false,
thenable_ongoing = false,
queue = new RSVP.Queue()
.push(function () {
return RSVP.reject(1);
})
.push(undefined, function () {
return new RSVP.Promise(
function () {
thenable_ongoing = true;
},
function () {
thenable_cancel_called = true;
});
});
queue.fail(function(e) {
error = e;
});
setTimeout(function() {
assert.equal(thenable_ongoing, true);
queue.cancel("Propagate this message");
assert.equal(thenable_cancel_called, true);
setTimeout(function() {
assert(queue.rejectedReason instanceof RSVP.CancellationError, queue.rejectedReason);
assert(error instanceof RSVP.CancellationError, error);
assert.equal(error.message, "Propagate this message");
done();
}, 20);
}, 20);
});
}); });
}); });
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment