Commit 05e09ef3 authored by Stefan Penner's avatar Stefan Penner

Merge pull request #68 from stefanpenner/self_resolution

promise.resolve(promise) === fulfillment
parents 46bce2f6 557ffb79
......@@ -369,7 +369,13 @@ define("rsvp/promise",
var config = __dependency1__.config;
var EventTarget = __dependency2__.EventTarget;
var noop = function() {};
function objectOrFunction(x) {
return isFunction(x) || (typeof x === "object" && x !== null);
}
function isFunction(x){
return typeof x === "function";
}
var Promise = function(resolver) {
var promise = this,
......@@ -407,7 +413,7 @@ define("rsvp/promise",
};
var invokeCallback = function(type, promise, callback, event) {
var hasCallback = typeof callback === 'function',
var hasCallback = isFunction(callback),
value, error, succeeded, failed;
if (hasCallback) {
......@@ -423,7 +429,7 @@ define("rsvp/promise",
succeeded = true;
}
if (value && typeof value.then === 'function') {
if (objectOrFunction(value) && isFunction(value.then)) {
value.then(function(value) {
resolve(promise, value);
}, function(error) {
......@@ -473,9 +479,13 @@ define("rsvp/promise",
EventTarget.mixin(Promise.prototype);
function resolve(promise, value) {
if (value && typeof value.then === 'function') {
if (objectOrFunction(value) && isFunction(value.then)) {
value.then(function(val) {
resolve(promise, val);
if (value !== val) {
resolve(promise, val);
} else {
fulfill(promise, val);
}
}, function(val) {
reject(promise, val);
});
......
This diff is collapsed.
......@@ -5,7 +5,13 @@ define(
var config = __dependency1__.config;
var EventTarget = __dependency2__.EventTarget;
var noop = function() {};
function objectOrFunction(x) {
return isFunction(x) || (typeof x === "object" && x !== null);
}
function isFunction(x){
return typeof x === "function";
}
var Promise = function(resolver) {
var promise = this,
......@@ -43,7 +49,7 @@ define(
};
var invokeCallback = function(type, promise, callback, event) {
var hasCallback = typeof callback === 'function',
var hasCallback = isFunction(callback),
value, error, succeeded, failed;
if (hasCallback) {
......@@ -59,7 +65,7 @@ define(
succeeded = true;
}
if (value && typeof value.then === 'function') {
if (objectOrFunction(value) && isFunction(value.then)) {
value.then(function(value) {
resolve(promise, value);
}, function(error) {
......@@ -109,9 +115,13 @@ define(
EventTarget.mixin(Promise.prototype);
function resolve(promise, value) {
if (value && typeof value.then === 'function') {
if (objectOrFunction(value) && isFunction(value.then)) {
value.then(function(val) {
resolve(promise, val);
if (value !== val) {
resolve(promise, val);
} else {
fulfill(promise, val);
}
}, function(val) {
reject(promise, val);
});
......
import { config } from "rsvp/config";
import { EventTarget } from "rsvp/events";
function objectOrFunction(x) {
return isFunction(x) || (typeof x === "object" && x !== null);
}
function isFunction(x){
return typeof x === "function";
}
var Promise = function(resolver) {
var promise = this,
resolved = false;
......@@ -37,7 +45,7 @@ var Promise = function(resolver) {
};
var invokeCallback = function(type, promise, callback, event) {
var hasCallback = typeof callback === 'function',
var hasCallback = isFunction(callback),
value, error, succeeded, failed;
if (hasCallback) {
......@@ -53,7 +61,7 @@ var invokeCallback = function(type, promise, callback, event) {
succeeded = true;
}
if (value && typeof value.then === 'function') {
if (objectOrFunction(value) && isFunction(value.then)) {
value.then(function(value) {
resolve(promise, value);
}, function(error) {
......@@ -103,9 +111,13 @@ Promise.prototype = {
EventTarget.mixin(Promise.prototype);
function resolve(promise, value) {
if (value && typeof value.then === 'function') {
if (objectOrFunction(value) && isFunction(value.then)) {
value.then(function(val) {
resolve(promise, val);
if (value !== val) {
resolve(promise, val);
} else {
fulfill(promise, val);
}
}, function(val) {
reject(promise, val);
});
......
/*global RSVP, describe, specify, it, assert */
describe("RSVP extensions", function() {
describe("self fulfillment", function(){
it("treats self fulfillment as the recursive base case", function(done){
var aDefer = new RSVP.defer(),
bDefer = new RSVP.defer();
aDefer.promise.then(function(a){
setTimeout(function(){
bDefer.resolve(bDefer.promise);
}, 1);
return bDefer.promise;
});
bDefer.promise.then(function(c){
done();
})
aDefer.resolve(aDefer.promise);
});
});
describe("Promise constructor", function() {
it('should exist and have length 1', function() {
assert(RSVP.Promise);
......@@ -113,6 +134,27 @@ describe("RSVP extensions", function() {
});
});
it('should assimilate two levels deep, for fulfillment of self fulfilling promises', function(done) {
var originalPromise, promise;
originalPromise = new RSVP.Promise(function(resolve) {
setTimeout(function() {
resolve(originalPromise);
}, 0)
});
promise = new RSVP.Promise(function(resolve) {
setTimeout(function() {
resolve(originalPromise);
}, 0);
});
promise.then(function(value) {
assert.equal(value, originalPromise);
done();
});
});
it('should assimilate two levels deep, for fulfillment', function(done) {
var originalPromise = new RSVP.Promise(function(resolve) { resolve('original value'); });
var nextPromise = new RSVP.Promise(function(resolve) { resolve(originalPromise); });
......
This diff is collapsed.
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