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