From 9fd1776fbfffb1d19e66cc25f24d979ae7465d73 Mon Sep 17 00:00:00 2001 From: Lucian Lature Date: Sun, 10 Feb 2013 15:05:26 +0000 Subject: [PATCH] Fixed a bug when used one single item array for _then function --- test/deferred.js | 78 ++++++++++++++++++++++++++++++++++++++++-- underscore.deferred.js | 14 +++++--- 2 files changed, 84 insertions(+), 8 deletions(-) diff --git a/test/deferred.js b/test/deferred.js index 7bbb8c9..e87e4cc 100644 --- a/test/deferred.js +++ b/test/deferred.js @@ -417,6 +417,80 @@ test( "_.when" , function() { }); +test( "_.when - one item array as argument" , function() { + + expect( 33 ); + + var win = typeof window === "undefined" ? global : window; + + // Some other objects + _.each( { + + "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, + "a plain object": {} + + } , function( value, message ) { + + ok( _.isFunction( _.when( value ).done(function( resolveValue ) { + strictEqual( this, win, "Context is the global object with " + message ); + strictEqual( resolveValue , value , "Test the promise was resolved with " + message ); + }).promise ) , "Test " + message + " triggers the creation of a new Promise" ); + + } ); + + ok( _.isFunction( _.when().done(function( resolveValue ) { + strictEqual( this, win, "Test the promise was resolved with window as its context" ); + strictEqual( resolveValue, undefined, "Test the promise was resolved with no parameter" ); + }).promise ) , "Test calling when with no parameter triggers the creation of a new Promise" ); + + var context = {}; + + _.when( _.Deferred().resolveWith( context ) ).done(function() { + strictEqual( this, context, "when( promise ) propagates context" ); + }); + + var cache; + + _.each([ 1 ], function(i, k) { + + _.when( cache || _.Deferred( function() { + this.resolve( i ); + }) + ).done(function( value ) { + + strictEqual( value, 1 , "Function executed" + ( i > 1 ? " only once" : "" ) ); + cache = value; + }); + + }); + + // Will apply the contents of an array if it has a single item + var dfds = [ _.Deferred() ]; + + var promises = _.map(dfds, function(dfd){ + return dfd.promise(); + }); + + _.each( dfds, function( dfd, index ){ + dfd.resolve( "Promise "+ (index + 1) ); + }); + + _.when( promises ).done(function(){ + var args = [].slice.call(arguments); + _.each([ 1 ], function(i, k){ + equal( args[k], "Promise "+ i ); + }); + }); + +}); + test("_.when - joined", function() { expect( 119 ); @@ -478,6 +552,4 @@ test("_.when - joined", function() { } ); deferreds.futureSuccess.resolve( 1 ); deferreds.futureError.reject( 0 ); - -}); - +}); \ No newline at end of file diff --git a/underscore.deferred.js b/underscore.deferred.js index abb8bb0..0ac57ee 100644 --- a/underscore.deferred.js +++ b/underscore.deferred.js @@ -377,14 +377,18 @@ }; // Deferred helper - _d.when = function( subordinate /* , ..., subordinateN */ ) { + _d.when = function( subordinate /* , ..., subordinateN */ ) { + var i = 0, - resolveValues = _type(subordinate) === 'array' && arguments.length === 1 ? - subordinate : slice.call( arguments ), - length = resolveValues.length, + resolveValues = ( _type(subordinate) === 'array' && arguments.length === 1 ) ? subordinate : slice.call( arguments ), + length = resolveValues.length; + + if ( _type(subordinate) === 'array' && subordinate.length === 1 ) { + subordinate = subordinate[ 0 ]; + } // the count of uncompleted subordinates - remaining = length !== 1 || ( subordinate && _isFunction( subordinate.promise ) ) ? length : 0, + var remaining = length !== 1 || ( subordinate && _isFunction( subordinate.promise ) ) ? length : 0, // the master Deferred. If resolveValues consist of only a single Deferred, just use that. deferred = remaining === 1 ? subordinate : _d.Deferred(),