Commit 6876cc30 authored by Stefan Penner's avatar Stefan Penner

Merge pull request #63 from stefanpenner/wrapit

WIP RSVP#wrap -> RSVP#resolve (A+ compliant)
parents 8a24804f 60f83a3b
define(
["rsvp/events","rsvp/promise","rsvp/node","rsvp/all","rsvp/hash","rsvp/defer","rsvp/config","exports"],
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) {
["rsvp/events","rsvp/promise","rsvp/node","rsvp/all","rsvp/hash","rsvp/defer","rsvp/config","rsvp/resolve","exports"],
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) {
"use strict";
var EventTarget = __dependency1__.EventTarget;
var Promise = __dependency2__.Promise;
......@@ -9,11 +9,13 @@ define(
var hash = __dependency5__.hash;
var defer = __dependency6__.defer;
var config = __dependency7__.config;
var resolve = __dependency8__.resolve;
function configure(name, value) {
config[name] = value;
}
__exports__.Promise = Promise;
__exports__.EventTarget = EventTarget;
__exports__.all = all;
......@@ -21,4 +23,5 @@ define(
__exports__.defer = defer;
__exports__.denodeify = denodeify;
__exports__.configure = configure;
__exports__.resolve = resolve;
});
......@@ -372,7 +372,8 @@ define("rsvp/promise",
var noop = function() {};
var Promise = function(resolver) {
var promise = this;
var promise = this,
resolved = false;
if (typeof resolver !== 'function') {
throw new TypeError('You must pass a resolver function as the sole argument to the promise constructor');
......@@ -383,15 +384,15 @@ define("rsvp/promise",
}
var resolvePromise = function(value) {
if (resolved) { return; }
resolved = true;
resolve(promise, value);
resolvePromise = noop;
rejectPromise = noop;
};
var rejectPromise = function(value) {
if (resolved) { return; }
resolved = true;
reject(promise, value);
resolvePromise = noop;
rejectPromise = noop;
};
this.on('promise:resolved', function(event) {
......@@ -499,12 +500,54 @@ define("rsvp/promise",
});
}
__exports__.Promise = Promise;
});
define("rsvp/resolve",
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function objectOrFunction(x) {
return typeof x === "function" || (typeof x === "object" && x !== null);
}
function resolve(thenable){
var promise = new Promise(function(resolve, reject){
var then;
try {
if ( objectOrFunction(thenable) ) {
then = thenable.then;
if (typeof then === "function") {
then.call(thenable, resolve, reject);
} else {
resolve(thenable);
}
} else {
resolve(thenable);
}
} catch(error) {
reject(error);
}
});
return promise;
}
__exports__.resolve = resolve;
});
define("rsvp",
["rsvp/events","rsvp/promise","rsvp/node","rsvp/all","rsvp/hash","rsvp/defer","rsvp/config","exports"],
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) {
["rsvp/events","rsvp/promise","rsvp/node","rsvp/all","rsvp/hash","rsvp/defer","rsvp/config","rsvp/resolve","exports"],
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__, __exports__) {
"use strict";
var EventTarget = __dependency1__.EventTarget;
var Promise = __dependency2__.Promise;
......@@ -513,11 +556,13 @@ define("rsvp",
var hash = __dependency5__.hash;
var defer = __dependency6__.defer;
var config = __dependency7__.config;
var resolve = __dependency8__.resolve;
function configure(name, value) {
config[name] = value;
}
__exports__.Promise = Promise;
__exports__.EventTarget = EventTarget;
__exports__.all = all;
......@@ -525,6 +570,7 @@ define("rsvp",
__exports__.defer = defer;
__exports__.denodeify = denodeify;
__exports__.configure = configure;
__exports__.resolve = resolve;
});
window.RSVP = requireModule('rsvp');
......
(function(){var e,t;(function(){var n={},r={};e=function(e,t,r){n[e]={deps:t,callback:r}};t=function(e){if(r[e]){return r[e]}r[e]={};var i=n[e],o=i.deps,s=i.callback,f=[],c;for(var a=0,u=o.length;a<u;a++){if(o[a]==="exports"){f.push(c={})}else{f.push(t(o[a]))}}var v=s.apply(this,f);return r[e]=c||v}})();e("rsvp/all",["rsvp/defer","exports"],function(e,t){"use strict";var n=e.defer;function r(e){var t=[],r=n(),i=e.length;if(i===0){r.resolve([])}var o=function(e){return function(t){s(e,t)}};var s=function(e,n){t[e]=n;if(--i===0){r.resolve(t)}};var f=function(e){r.reject(e)};for(var c=0;c<e.length;c++){if(e[c]&&typeof e[c].then==="function"){e[c].then(o(c),f)}else{s(c,e[c])}}return r.promise}t.all=r});e("rsvp/async",["exports"],function(e){"use strict";var t=typeof window!=="undefined"?window:{};var n=t.MutationObserver||t.WebKitMutationObserver;var r;if(typeof process!=="undefined"&&{}.toString.call(process)==="[object process]"){r=function(e,t){process.nextTick(function(){e.call(t)})}}else if(n){var i=[];var o=new n(function(){var e=i.slice();i=[];e.forEach(function(e){var t=e[0],n=e[1];t.call(n)})});var s=document.createElement("div");o.observe(s,{attributes:true});window.addEventListener("unload",function(){o.disconnect();o=null});r=function(e,t){i.push([e,t]);s.setAttribute("drainQueue","drainQueue")}}else{r=function(e,t){setTimeout(function(){e.call(t)},1)}}e.async=r});e("rsvp/config",["rsvp/async","exports"],function(e,t){"use strict";var n=e.async;var r={};r.async=n;t.config=r});e("rsvp/defer",["rsvp/promise","exports"],function(e,t){"use strict";var n=e.Promise;function r(){var e={};var t=new n(function(t,n){e.resolve=t;e.reject=n});e.promise=t;return e}t.defer=r});e("rsvp/events",["exports"],function(e){"use strict";var t=function(e,t){this.type=e;for(var n in t){if(!t.hasOwnProperty(n)){continue}this[n]=t[n]}};var n=function(e,t){for(var n=0,r=e.length;n<r;n++){if(e[n][0]===t){return n}}return-1};var r=function(e){var t=e._promiseCallbacks;if(!t){t=e._promiseCallbacks={}}return t};var i={mixin:function(e){e.on=this.on;e.off=this.off;e.trigger=this.trigger;return e},on:function(e,t,i){var o=r(this),s,f;e=e.split(/\s+/);i=i||this;while(f=e.shift()){s=o[f];if(!s){s=o[f]=[]}if(n(s,t)===-1){s.push([t,i])}}},off:function(e,t){var i=r(this),o,s,f;e=e.split(/\s+/);while(s=e.shift()){if(!t){i[s]=[];continue}o=i[s];f=n(o,t);if(f!==-1){o.splice(f,1)}}},trigger:function(e,n){var i=r(this),o,s,f,c,a;if(o=i[e]){for(var u=0;u<o.length;u++){s=o[u];f=s[0];c=s[1];if(typeof n!=="object"){n={detail:n}}a=new t(e,n);f.call(c,a)}}}};e.EventTarget=i});e("rsvp/hash",["rsvp/defer","exports"],function(e,t){"use strict";var n=e.defer;function r(e){var t=0;for(var n in e){t++}return t}function i(e){var t={},i=n(),o=r(e);if(o===0){i.resolve({})}var s=function(e){return function(t){f(e,t)}};var f=function(e,n){t[e]=n;if(--o===0){i.resolve(t)}};var c=function(e){i.reject(e)};for(var a in e){if(e[a]&&typeof e[a].then==="function"){e[a].then(s(a),c)}else{f(a,e[a])}}return i.promise}t.hash=i});e("rsvp/node",["rsvp/promise","rsvp/all","exports"],function(e,t,n){"use strict";var r=e.Promise;var i=t.all;function o(e,t){return function(n,r){if(n){t(n)}else if(arguments.length>2){e(Array.prototype.slice.call(arguments,1))}else{e(r)}}}function s(e){return function(){var t=Array.prototype.slice.call(arguments),n,s;var f=new r(function(e,t){n=e;s=t});i(t).then(function(t){t.push(o(n,s));try{e.apply(this,t)}catch(r){s(r)}});return f}}n.denodeify=s});e("rsvp/promise",["rsvp/config","rsvp/events","exports"],function(e,t,n){"use strict";var r=e.config;var i=t.EventTarget;var o=function(){};var s=function(e){var t=this;if(typeof e!=="function"){throw new TypeError("You must pass a resolver function as the sole argument to the promise constructor")}if(!(t instanceof s)){return new s(e)}var n=function(e){c(t,e);n=o;r=o};var r=function(e){u(t,e);n=o;r=o};this.on("promise:resolved",function(e){this.trigger("success",{detail:e.detail})},this);this.on("promise:failed",function(e){this.trigger("error",{detail:e.detail})},this);e(n,r)};var f=function(e,t,n,r){var i=typeof n==="function",o,s,f,a;if(i){try{o=n(r.detail);f=true}catch(v){a=true;s=v}}else{o=r.detail;f=true}if(o&&typeof o.then==="function"){o.then(function(e){c(t,e)},function(e){u(t,e)})}else if(i&&f){c(t,o)}else if(a){u(t,s)}else if(e==="resolve"){c(t,o)}else if(e==="reject"){u(t,o)}};s.prototype={constructor:s,then:function(e,t){var n=new s(function(){});if(this.isFulfilled){r.async(function(){f("resolve",n,e,{detail:this.fulfillmentValue})},this)}if(this.isRejected){r.async(function(){f("reject",n,t,{detail:this.rejectedReason})},this)}this.on("promise:resolved",function(t){f("resolve",n,e,t)});this.on("promise:failed",function(e){f("reject",n,t,e)});return n}};i.mixin(s.prototype);function c(e,t){if(t&&typeof t.then==="function"){t.then(function(t){c(e,t)},function(t){u(e,t)})}else{a(e,t)}}function a(e,t){r.async(function(){e.trigger("promise:resolved",{detail:t});e.isFulfilled=true;e.fulfillmentValue=t})}function u(e,t){r.async(function(){e.trigger("promise:failed",{detail:t});e.isRejected=true;e.rejectedReason=t})}n.Promise=s});e("rsvp",["rsvp/events","rsvp/promise","rsvp/node","rsvp/all","rsvp/hash","rsvp/defer","rsvp/config","exports"],function(e,t,n,r,i,o,s,f){"use strict";var c=e.EventTarget;var a=t.Promise;var u=n.denodeify;var v=r.all;var l=i.hash;var p=o.defer;var h=s.config;function d(e,t){h[e]=t}f.Promise=a;f.EventTarget=c;f.all=v;f.hash=l;f.defer=p;f.denodeify=u;f.configure=d});window.RSVP=t("rsvp")})();
(function(){var e,t;(function(){var r={},n={};e=function(e,t,n){r[e]={deps:t,callback:n}};t=function(e){if(n[e]){return n[e]}n[e]={};var i=r[e],o=i.deps,s=i.callback,f=[],c;for(var u=0,a=o.length;u<a;u++){if(o[u]==="exports"){f.push(c={})}else{f.push(t(o[u]))}}var v=s.apply(this,f);return n[e]=c||v}})();e("rsvp/all",["rsvp/defer","exports"],function(e,t){"use strict";var r=e.defer;function n(e){var t=[],n=r(),i=e.length;if(i===0){n.resolve([])}var o=function(e){return function(t){s(e,t)}};var s=function(e,r){t[e]=r;if(--i===0){n.resolve(t)}};var f=function(e){n.reject(e)};for(var c=0;c<e.length;c++){if(e[c]&&typeof e[c].then==="function"){e[c].then(o(c),f)}else{s(c,e[c])}}return n.promise}t.all=n});e("rsvp/async",["exports"],function(e){"use strict";var t=typeof window!=="undefined"?window:{};var r=t.MutationObserver||t.WebKitMutationObserver;var n;if(typeof process!=="undefined"&&{}.toString.call(process)==="[object process]"){n=function(e,t){process.nextTick(function(){e.call(t)})}}else if(r){var i=[];var o=new r(function(){var e=i.slice();i=[];e.forEach(function(e){var t=e[0],r=e[1];t.call(r)})});var s=document.createElement("div");o.observe(s,{attributes:true});window.addEventListener("unload",function(){o.disconnect();o=null});n=function(e,t){i.push([e,t]);s.setAttribute("drainQueue","drainQueue")}}else{n=function(e,t){setTimeout(function(){e.call(t)},1)}}e.async=n});e("rsvp/config",["rsvp/async","exports"],function(e,t){"use strict";var r=e.async;var n={};n.async=r;t.config=n});e("rsvp/defer",["rsvp/promise","exports"],function(e,t){"use strict";var r=e.Promise;function n(){var e={};var t=new r(function(t,r){e.resolve=t;e.reject=r});e.promise=t;return e}t.defer=n});e("rsvp/events",["exports"],function(e){"use strict";var t=function(e,t){this.type=e;for(var r in t){if(!t.hasOwnProperty(r)){continue}this[r]=t[r]}};var r=function(e,t){for(var r=0,n=e.length;r<n;r++){if(e[r][0]===t){return r}}return-1};var n=function(e){var t=e._promiseCallbacks;if(!t){t=e._promiseCallbacks={}}return t};var i={mixin:function(e){e.on=this.on;e.off=this.off;e.trigger=this.trigger;return e},on:function(e,t,i){var o=n(this),s,f;e=e.split(/\s+/);i=i||this;while(f=e.shift()){s=o[f];if(!s){s=o[f]=[]}if(r(s,t)===-1){s.push([t,i])}}},off:function(e,t){var i=n(this),o,s,f;e=e.split(/\s+/);while(s=e.shift()){if(!t){i[s]=[];continue}o=i[s];f=r(o,t);if(f!==-1){o.splice(f,1)}}},trigger:function(e,r){var i=n(this),o,s,f,c,u;if(o=i[e]){for(var a=0;a<o.length;a++){s=o[a];f=s[0];c=s[1];if(typeof r!=="object"){r={detail:r}}u=new t(e,r);f.call(c,u)}}}};e.EventTarget=i});e("rsvp/hash",["rsvp/defer","exports"],function(e,t){"use strict";var r=e.defer;function n(e){var t=0;for(var r in e){t++}return t}function i(e){var t={},i=r(),o=n(e);if(o===0){i.resolve({})}var s=function(e){return function(t){f(e,t)}};var f=function(e,r){t[e]=r;if(--o===0){i.resolve(t)}};var c=function(e){i.reject(e)};for(var u in e){if(e[u]&&typeof e[u].then==="function"){e[u].then(s(u),c)}else{f(u,e[u])}}return i.promise}t.hash=i});e("rsvp/node",["rsvp/promise","rsvp/all","exports"],function(e,t,r){"use strict";var n=e.Promise;var i=t.all;function o(e,t){return function(r,n){if(r){t(r)}else if(arguments.length>2){e(Array.prototype.slice.call(arguments,1))}else{e(n)}}}function s(e){return function(){var t=Array.prototype.slice.call(arguments),r,s;var f=new n(function(e,t){r=e;s=t});i(t).then(function(t){t.push(o(r,s));try{e.apply(this,t)}catch(n){s(n)}});return f}}r.denodeify=s});e("rsvp/promise",["rsvp/config","rsvp/events","exports"],function(e,t,r){"use strict";var n=e.config;var i=t.EventTarget;var o=function(){};var s=function(e){var t=this,r=false;if(typeof e!=="function"){throw new TypeError("You must pass a resolver function as the sole argument to the promise constructor")}if(!(t instanceof s)){return new s(e)}var n=function(e){if(r){return}r=true;c(t,e)};var i=function(e){if(r){return}r=true;a(t,e)};this.on("promise:resolved",function(e){this.trigger("success",{detail:e.detail})},this);this.on("promise:failed",function(e){this.trigger("error",{detail:e.detail})},this);e(n,i)};var f=function(e,t,r,n){var i=typeof r==="function",o,s,f,u;if(i){try{o=r(n.detail);f=true}catch(v){u=true;s=v}}else{o=n.detail;f=true}if(o&&typeof o.then==="function"){o.then(function(e){c(t,e)},function(e){a(t,e)})}else if(i&&f){c(t,o)}else if(u){a(t,s)}else if(e==="resolve"){c(t,o)}else if(e==="reject"){a(t,o)}};s.prototype={constructor:s,then:function(e,t){var r=new s(function(){});if(this.isFulfilled){n.async(function(){f("resolve",r,e,{detail:this.fulfillmentValue})},this)}if(this.isRejected){n.async(function(){f("reject",r,t,{detail:this.rejectedReason})},this)}this.on("promise:resolved",function(t){f("resolve",r,e,t)});this.on("promise:failed",function(e){f("reject",r,t,e)});return r}};i.mixin(s.prototype);function c(e,t){if(t&&typeof t.then==="function"){t.then(function(t){c(e,t)},function(t){a(e,t)})}else{u(e,t)}}function u(e,t){n.async(function(){e.trigger("promise:resolved",{detail:t});e.isFulfilled=true;e.fulfillmentValue=t})}function a(e,t){n.async(function(){e.trigger("promise:failed",{detail:t});e.isRejected=true;e.rejectedReason=t})}r.Promise=s});e("rsvp/resolve",["rsvp/promise","exports"],function(e,t){"use strict";var r=e.Promise;function n(e){return typeof e==="function"||typeof e==="object"&&e!==null}function i(e){var t=new r(function(t,r){var i;try{if(n(e)){i=e.then;if(typeof i==="function"){i.call(e,t,r)}else{t(e)}}else{t(e)}}catch(o){r(o)}});return t}t.resolve=i});e("rsvp",["rsvp/events","rsvp/promise","rsvp/node","rsvp/all","rsvp/hash","rsvp/defer","rsvp/config","rsvp/resolve","exports"],function(e,t,r,n,i,o,s,f,c){"use strict";var u=e.EventTarget;var a=t.Promise;var v=r.denodeify;var l=n.all;var p=i.hash;var h=o.defer;var d=s.config;var y=f.resolve;function g(e,t){d[e]=t}c.Promise=a;c.EventTarget=u;c.all=l;c.hash=p;c.defer=h;c.denodeify=v;c.configure=g;c.resolve=y});window.RSVP=t("rsvp")})();
......@@ -8,7 +8,8 @@ define(
var noop = function() {};
var Promise = function(resolver) {
var promise = this;
var promise = this,
resolved = false;
if (typeof resolver !== 'function') {
throw new TypeError('You must pass a resolver function as the sole argument to the promise constructor');
......@@ -19,15 +20,15 @@ define(
}
var resolvePromise = function(value) {
if (resolved) { return; }
resolved = true;
resolve(promise, value);
resolvePromise = noop;
rejectPromise = noop;
};
var rejectPromise = function(value) {
if (resolved) { return; }
resolved = true;
reject(promise, value);
resolvePromise = noop;
rejectPromise = noop;
};
this.on('promise:resolved', function(event) {
......@@ -135,5 +136,6 @@ define(
});
}
__exports__.Promise = Promise;
});
define(
["rsvp/promise","exports"],
function(__dependency1__, __exports__) {
"use strict";
var Promise = __dependency1__.Promise;
function objectOrFunction(x) {
return typeof x === "function" || (typeof x === "object" && x !== null);
}
function resolve(thenable){
var promise = new Promise(function(resolve, reject){
var then;
try {
if ( objectOrFunction(thenable) ) {
then = thenable.then;
if (typeof then === "function") {
then.call(thenable, resolve, reject);
} else {
resolve(thenable);
}
} else {
resolve(thenable);
}
} catch(error) {
reject(error);
}
});
return promise;
}
__exports__.resolve = resolve;
});
......@@ -5,9 +5,10 @@ import { all } from "rsvp/all";
import { hash } from "rsvp/hash";
import { defer } from "rsvp/defer";
import { config } from "rsvp/config";
import { resolve } from "rsvp/resolve";
function configure(name, value) {
config[name] = value;
}
export { Promise, EventTarget, all, hash, defer, denodeify, configure };
\ No newline at end of file
export { Promise, EventTarget, all, hash, defer, denodeify, configure, resolve };
import { config } from "rsvp/config";
import { EventTarget } from "rsvp/events";
var noop = function() {};
var Promise = function(resolver) {
var promise = this;
var promise = this,
resolved = false;
if (typeof resolver !== 'function') {
throw new TypeError('You must pass a resolver function as the sole argument to the promise constructor');
......@@ -15,15 +14,15 @@ var Promise = function(resolver) {
}
var resolvePromise = function(value) {
if (resolved) { return; }
resolved = true;
resolve(promise, value);
resolvePromise = noop;
rejectPromise = noop;
};
var rejectPromise = function(value) {
if (resolved) { return; }
resolved = true;
reject(promise, value);
resolvePromise = noop;
rejectPromise = noop;
};
this.on('promise:resolved', function(event) {
......@@ -131,4 +130,4 @@ function reject(promise, value) {
});
}
export { Promise };
\ No newline at end of file
export { Promise };
import { Promise } from "rsvp/promise";
function objectOrFunction(x) {
return typeof x === "function" || (typeof x === "object" && x !== null);
}
function resolve(thenable){
var promise = new Promise(function(resolve, reject){
var then;
try {
if ( objectOrFunction(thenable) ) {
then = thenable.then;
if (typeof then === "function") {
then.call(thenable, resolve, reject);
} else {
resolve(thenable);
}
} else {
resolve(thenable);
}
} catch(error) {
reject(error);
}
});
return promise;
}
export { resolve };
......@@ -520,4 +520,286 @@ describe("RSVP extensions", function() {
});
});
});
describe("RSVP.resolve", function(){
specify("it should exist", function(){
assert(RSVP.resolve);
});
describe("1. If x is a promise, adopt its state ", function(){
specify("1.1 If x is pending, promise must remain pending until x is fulfilled or rejected.", function(done){
var expectedValue, resolver, thenable, wrapped;
expectedValue = 'the value';
thenable = {
then: function(resolve, reject){
resolver = resolve;
}
};
wrapped = RSVP.resolve(thenable);
wrapped.then(function(value){
assert(value === expectedValue);
done();
})
resolver(expectedValue);
});
specify("1.2 If/when x is fulfilled, fulfill promise with the same value.", function(done){
var expectedValue, thenable, wrapped;
expectedValue = 'the value';
thenable = {
then: function(resolve, reject){
resolve(expectedValue);
}
};
wrapped = RSVP.resolve(thenable);
wrapped.then(function(value){
assert(value === expectedValue);
done();
})
});
specify("1.3 If/when x is rejected, reject promise with the same reason.", function(done){
var expectedError, thenable, wrapped;
expectedError = new Error();
thenable = {
then: function(resolve, reject){
reject(expectedError);
}
};
wrapped = RSVP.resolve(thenable);
wrapped.then(null, function(error){
assert(error === expectedError);
done();
});
});
});
describe("2. Otherwise, if x is an object or function,", function(){
specify("2.1 Let then x.then", function(done){
var accessCount, resolver, wrapped, thenable;
accessCount = 0;
thenable = { };
Object.defineProperty(thenable, 'then', {
get: function(){
accessCount++;
if (accessCount > 1) {
throw new Error();
}
return function(){ };
}
});
assert(accessCount === 0);
wrapped = RSVP.resolve(thenable);
assert(accessCount === 1);
done();
});
specify("2.2 If retrieving the property x.then results in a thrown exception e, reject promise with e as the reason.", function(done){
var wrapped, thenable, expectedError;
expectedError = new Error();
thenable = { };
Object.defineProperty(thenable, 'then', {
get: function(){
throw expectedError;
}
});
wrapped = RSVP.resolve(thenable);
wrapped.then(null, function(error){
assert(error === expectedError, 'incorrect exception was thrown');
done();
});
});
describe('2.3. If then is a function, call it with x as this, first argument resolvePromise, and second argument rejectPromise, where', function(){
specify('2.3.1 If/when resolvePromise is called with a value y, run Resolve(promise, y)', function(done){
var expectedSuccess, resolver, rejector, thenable, wrapped, calledThis;
thenable = {
then: function(resolve, reject){
calledThis = this;
resolver = resolve;
rejector = reject;
}
};
expectedSuccess = 'success';
wrapped = RSVP.resolve(thenable);
wrapped.then(function(success){
assert(calledThis === thenable, 'this must be the thenable');
assert(success === expectedSuccess, 'rejected promise with x');
done();
});
resolver(expectedSuccess);
});
specify('2.3.2 If/when rejectPromise is called with a reason r, reject promise with r.', function(done){
var expectedError, resolver, rejector, thenable, wrapped, calledThis,
thenable = {
then: function(resolve, reject){
calledThis = this;
resolver = resolve;
rejector = reject;
}
};
expectedError = new Error();
wrapped = RSVP.resolve(thenable);
wrapped.then(null, function(error){
assert(error === expectedError, 'rejected promise with x');
done();
});
rejector(expectedError);
});
specify("2.3.3 If both resolvePromise and rejectPromise are called, or multiple calls to the same argument are made, the first call takes precedence, and any further calls are ignored", function(done){
var expectedError, expectedSuccess, resolver, rejector, thenable, wrapped, calledThis,
calledRejected, calledResolved;
calledRejected = 0;
calledResolved = 0;
thenable = {
then: function(resolve, reject){
calledThis = this;
resolver = resolve;
rejector = reject;
}
};
expectedError = new Error();
wrapped = RSVP.resolve(thenable);
wrapped.then(function(){
calledResolved++;
}, function(error){
calledRejected++;
assert(calledResolved === 0, 'never resolved');
assert(calledRejected === 1, 'rejected only once');
assert(error === expectedError, 'rejected promise with x');
});
rejector(expectedError);
rejector(expectedError);
rejector('foo');
resolver('bar');
resolver('baz');
setTimeout(function(){
assert(calledRejected === 1, 'only rejected once');
assert(calledResolved === 0, 'never resolved');
done();
}, 50);
});
describe("2.3.4 If calling then throws an exception e", function(){
specify("2.3.4.1 If resolvePromise or rejectPromise have been called, ignore it.", function(done){
var expectedSuccess, resolver, rejector, thenable, wrapped, calledThis,
calledRejected, calledResolved;
expectedSuccess = 'success';
thenable = {
then: function(resolve, reject){
resolve(expectedSuccess);
throw expectedError;
}
};
wrapped = RSVP.resolve(thenable);
wrapped.then(function(success){
assert(success === expectedSuccess, 'resolved not errored');
done();
});
});
specify("2.3.4.2 Otherwise, reject promise with e as the reason.", function(done) {
var expectedError, resolver, rejector, thenable, wrapped, calledThis, callCount;
expectedError = new Error();
callCount = 0;
thenable = { then: function() { throw expectedError; } };
wrapped = RSVP.resolve(thenable);
wrapped.then(null, function(error){
callCount++;
assert(expectedError === error, 'expected the correct error to be rejected');
done();
});
assert(callCount === 0, 'expected async, was sync');
});
});
});
specify("2.4 If then is not a function, fulfill promise with x", function(done){
var expectedError, resolver, rejector, thenable, wrapped, calledThis, callCount;
thenable = { then: 3 };
callCount = 0;
wrapped = RSVP.resolve(thenable);
wrapped.then(function(success){
callCount++;
assert(thenable === success, 'fulfilled promise with x');
done();
});
assert(callCount === 0, 'expected async, was sync');
});
});
describe("3. If x is not an object or function, ", function(){
specify("fulfill promise with x.", function(done){
var thenable, callCount, wrapped;
thenable = null;
callCount = 0;
wrapped = RSVP.resolve(thenable);
wrapped.then(function(success){
callCount++;
assert(success === thenable, 'fulfilled promise with x');
done();
}, function(a){
assert(false, 'should not also reject');
});
assert(callCount === 0, 'expected async, was sync');
});
});
});
});
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