From 6fb9759a75bf2b9a2aa3a8fce9cd7afc011d8c4f Mon Sep 17 00:00:00 2001 From: jaubourg Date: Thu, 30 Dec 2010 17:06:53 +0100 Subject: [PATCH] Simplified the way a Promise is tested for (removed promiseMarker). Removed isCancelled helper method from _Deferred, wasn't used nor tested. Reworked jQuery.Deferred and removed unnecessary variables. Also ensured a Promise will return itself when asked for a Promise. Finally, the jQuery.when tests have been revamped. --- src/core.js | 48 +++++++++++++++++++---------------------------- test/unit/core.js | 26 +++++++++++-------------- 2 files changed, 30 insertions(+), 44 deletions(-) diff --git a/src/core.js b/src/core.js index 3bbdce3c..0211808c 100644 --- a/src/core.js +++ b/src/core.js @@ -75,10 +75,7 @@ var jQuery = function( selector, context ) { indexOf = Array.prototype.indexOf, // [[Class]] -> type pairs - class2type = {}, - - // Marker for deferred - promiseMarker = []; + class2type = {}; jQuery.fn = jQuery.prototype = { init: function( selector, context ) { @@ -874,7 +871,7 @@ jQuery.extend({ // resolve with this as context and given arguments resolve: function() { - deferred.fire( this , arguments ); + deferred.fire( jQuery.isFunction( this.promise ) ? this.promise() : this , arguments ); return this; }, @@ -888,11 +885,6 @@ jQuery.extend({ cancelled = 1; callbacks = []; return this; - }, - - // Has this deferred been cancelled? - isCancelled: function() { - return !!cancelled; } }; @@ -903,38 +895,36 @@ jQuery.extend({ // Typical success/error system Deferred: function( func ) { - var errorDeferred = jQuery._Deferred(), - deferred = jQuery._Deferred(), - successCancel = deferred.cancel; + var deferred = jQuery._Deferred(), + failDeferred = jQuery._Deferred(); // Add errorDeferred methods and redefine cancel jQuery.extend( deferred , { - fail: errorDeferred.then, - fireReject: errorDeferred.fire, - reject: errorDeferred.resolve, - isRejected: errorDeferred.isResolved, + fail: failDeferred.then, + fireReject: failDeferred.fire, + reject: failDeferred.resolve, + isRejected: failDeferred.isResolved, // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object promise: function( obj ) { obj = obj || {}; - for ( var i in { then:1 , fail:1 , isResolved:1 , isRejected:1 , promise:1 } ) { - obj[ i ] = deferred[ i ]; - } + jQuery.each( "then fail isResolved isRejected".split( " " ) , function( _ , method ) { + obj[ method ] = deferred[ method ]; + }); + obj.promise = function() { + return obj; + }; return obj; } } ); - // Remove cancel related - delete deferred.cancel; - delete deferred.isCancelled; - - // Add promise marker - deferred.promise._ = promiseMarker; - // Make sure only one callback list will be used - deferred.then( errorDeferred.cancel ).fail( successCancel ); + deferred.then( failDeferred.cancel ).fail( deferred.cancel ); + + // Unexpose cancel + delete deferred.cancel; // Call given func if any if ( func ) { @@ -946,7 +936,7 @@ jQuery.extend({ // Deferred helper when: function( object ) { - object = object && object.promise && object.promise._ === promiseMarker ? + object = object && jQuery.isFunction( object.promise ) ? object : jQuery.Deferred().resolve( object ); return object.promise(); diff --git a/test/unit/core.js b/test/unit/core.js index 1cd41a67..9367ab10 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -1024,30 +1024,26 @@ test("jQuery.Deferred()", function() { test("jQuery.when()", function() { - expect( 14 ); - - var fakeDeferred = { then: function() { return this; } }; - - fakeDeferred.then._ = []; + expect( 21 ); // Some other objects jQuery.each( { - "Object with then & no marker": { then: jQuery.noop }, - "Object with then & marker": fakeDeferred, - "string 1/2": "", - "string 2/2": "some string", - "number 1/2": 0, - "number 2/2": 1, - "boolean 1/2": true, - "boolean 2/2": false, + "an empty string": "", + "a non-empty string": "some string", + "zero": 0, + "a number other than zero": 1, + "true": true, + "false": false, "null": null, "undefined": undefined, - "custom method name not found automagically": {custom: jQuery._Deferred().then} + "a plain object": {} } , function( message , value ) { - notStrictEqual( jQuery.when( value ) , value , message ); + ok( jQuery.isFunction( jQuery.when( value ).then( function( resolveValue ) { + strictEqual( resolveValue , value , "Test the promise was resolved with " + message ); + } ).promise ) , "Test " + message + " triggers the creation of a new Promise" ); } );