From 7fa0da08b88534e486ddb7eb3752ef76467fb7dd Mon Sep 17 00:00:00 2001 From: jaubourg Date: Mon, 2 Apr 2012 01:03:34 +0200 Subject: [PATCH] Allows traditional options object for $.Callbacks flags. Fixes #11011. Unit tests added. --- src/callbacks.js | 4 +- test/unit/callbacks.js | 276 ++++++++++++++++++++++------------------- 2 files changed, 151 insertions(+), 129 deletions(-) diff --git a/src/callbacks.js b/src/callbacks.js index 387868604..20422c35a 100644 --- a/src/callbacks.js +++ b/src/callbacks.js @@ -38,9 +38,9 @@ function createFlags( flags ) { */ jQuery.Callbacks = function( flags ) { - // Convert flags from String-formatted to Object-formatted + // Convert flags from String-formatted to Object-formatted if needed // (we check in cache first) - flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; + flags = typeof flags === "string" ? ( flagsCache[ flags ] || createFlags( flags ) ) : ( flags || {} ); var // Actual callback list list = [], diff --git a/test/unit/callbacks.js b/test/unit/callbacks.js index acc88f2c2..acc61f32c 100644 --- a/test/unit/callbacks.js +++ b/test/unit/callbacks.js @@ -33,149 +33,171 @@ var output, } }; -jQuery.each( tests, function( flags, resultString ) { + function showFlags( flags ) { + if ( typeof flags === "string" ) { + return '"' + flags + '"'; + } + var output = [], key; + for ( key in flags ) { + output.push( '"' + key + '": ' + flags[ key ] ); + } + return "{ " + output.join( ", " ) + " }"; + } + +jQuery.each( tests, function( strFlags, resultString ) { + + var objectFlags = {}; + + jQuery.each( strFlags.split( " " ), function() { + if ( this.length ) { + objectFlags[ this ] = true; + } + }); jQuery.each( filters, function( filterLabel, filter ) { - test( "jQuery.Callbacks( \"" + flags + "\" ) - " + filterLabel, function() { + jQuery.each( { "string": strFlags, "object": objectFlags }, function( flagsTypes, flags ) { - expect( 20 ); + test( "jQuery.Callbacks( " + showFlags( flags ) + " ) - " + filterLabel, function() { - // Give qunit a little breathing room - stop(); - setTimeout( start, 0 ); + expect( 20 ); - var cblist; - results = resultString.split( /\s+/ ); + // Give qunit a little breathing room + stop(); + setTimeout( start, 0 ); - // Basic binding and firing - output = "X"; - cblist = jQuery.Callbacks( flags ); - cblist.add(function( str ) { - output += str; - }); - cblist.fire( "A" ); - strictEqual( output, "XA", "Basic binding and firing" ); - strictEqual( cblist.fired(), true, ".fired() detects firing" ); - output = "X"; - cblist.disable(); - cblist.add(function( str ) { - output += str; - }); - strictEqual( output, "X", "Adding a callback after disabling" ); - cblist.fire( "A" ); - strictEqual( output, "X", "Firing after disabling" ); + var cblist; + results = resultString.split( /\s+/ ); - // Basic binding and firing (context, arguments) - output = "X"; - cblist = jQuery.Callbacks( flags ); - cblist.add(function() { - equal( this, window, "Basic binding and firing (context)" ); - output += Array.prototype.join.call( arguments, "" ); - }); - cblist.fireWith( window, [ "A", "B" ] ); - strictEqual( output, "XAB", "Basic binding and firing (arguments)" ); + // Basic binding and firing + output = "X"; + cblist = jQuery.Callbacks( flags ); + cblist.add(function( str ) { + output += str; + }); + cblist.fire( "A" ); + strictEqual( output, "XA", "Basic binding and firing" ); + strictEqual( cblist.fired(), true, ".fired() detects firing" ); + output = "X"; + cblist.disable(); + cblist.add(function( str ) { + output += str; + }); + strictEqual( output, "X", "Adding a callback after disabling" ); + cblist.fire( "A" ); + strictEqual( output, "X", "Firing after disabling" ); - // fireWith with no arguments - output = ""; - cblist = jQuery.Callbacks( flags ); - cblist.add(function() { - equal( this, window, "fireWith with no arguments (context is window)" ); - strictEqual( arguments.length, 0, "fireWith with no arguments (no arguments)" ); - }); - cblist.fireWith(); + // Basic binding and firing (context, arguments) + output = "X"; + cblist = jQuery.Callbacks( flags ); + cblist.add(function() { + equal( this, window, "Basic binding and firing (context)" ); + output += Array.prototype.join.call( arguments, "" ); + }); + cblist.fireWith( window, [ "A", "B" ] ); + strictEqual( output, "XAB", "Basic binding and firing (arguments)" ); - // Basic binding, removing and firing - output = "X"; - cblist = jQuery.Callbacks( flags ); - cblist.add( outputA, outputB, outputC ); - cblist.remove( outputB, outputC ); - cblist.fire(); - strictEqual( output, "XA", "Basic binding, removing and firing" ); + // fireWith with no arguments + output = ""; + cblist = jQuery.Callbacks( flags ); + cblist.add(function() { + equal( this, window, "fireWith with no arguments (context is window)" ); + strictEqual( arguments.length, 0, "fireWith with no arguments (no arguments)" ); + }); + cblist.fireWith(); - // Empty - output = "X"; - cblist = jQuery.Callbacks( flags ); - cblist.add( outputA ); - cblist.add( outputB ); - cblist.add( outputC ); - cblist.empty(); - cblist.fire(); - strictEqual( output, "X", "Empty" ); + // Basic binding, removing and firing + output = "X"; + cblist = jQuery.Callbacks( flags ); + cblist.add( outputA, outputB, outputC ); + cblist.remove( outputB, outputC ); + cblist.fire(); + strictEqual( output, "XA", "Basic binding, removing and firing" ); - // Locking - output = "X"; - cblist = jQuery.Callbacks( flags ); - cblist.add( function( str ) { - output += str; - }); - cblist.lock(); - cblist.add( function( str ) { - output += str; - }); - cblist.fire( "A" ); - cblist.add( function( str ) { - output += str; - }); - strictEqual( output, "X", "Lock early" ); - - // Ordering - output = "X"; - cblist = jQuery.Callbacks( flags ); - cblist.add( function() { + // Empty + output = "X"; + cblist = jQuery.Callbacks( flags ); + cblist.add( outputA ); + cblist.add( outputB ); cblist.add( outputC ); - outputA(); - }, outputB ); - cblist.fire(); - strictEqual( output, results.shift(), "Proper ordering" ); + cblist.empty(); + cblist.fire(); + strictEqual( output, "X", "Empty" ); - // Add and fire again - output = "X"; - cblist.add( function() { + // Locking + output = "X"; + cblist = jQuery.Callbacks( flags ); + cblist.add( function( str ) { + output += str; + }); + cblist.lock(); + cblist.add( function( str ) { + output += str; + }); + cblist.fire( "A" ); + cblist.add( function( str ) { + output += str; + }); + strictEqual( output, "X", "Lock early" ); + + // Ordering + output = "X"; + cblist = jQuery.Callbacks( flags ); + cblist.add( function() { + cblist.add( outputC ); + outputA(); + }, outputB ); + cblist.fire(); + strictEqual( output, results.shift(), "Proper ordering" ); + + // Add and fire again + output = "X"; + cblist.add( function() { + cblist.add( outputC ); + outputA(); + }, outputB ); + strictEqual( output, results.shift(), "Add after fire" ); + + output = "X"; + cblist.fire(); + strictEqual( output, results.shift(), "Fire again" ); + + // Multiple fire + output = "X"; + cblist = jQuery.Callbacks( flags ); + cblist.add( function( str ) { + output += str; + } ); + cblist.fire( "A" ); + strictEqual( output, "XA", "Multiple fire (first fire)" ); + output = "X"; + cblist.add( function( str ) { + output += str; + } ); + strictEqual( output, results.shift(), "Multiple fire (first new callback)" ); + output = "X"; + cblist.fire( "B" ); + strictEqual( output, results.shift(), "Multiple fire (second fire)" ); + output = "X"; + cblist.add( function( str ) { + output += str; + } ); + strictEqual( output, results.shift(), "Multiple fire (second new callback)" ); + + // Return false + output = "X"; + cblist = jQuery.Callbacks( flags ); + cblist.add( outputA, function() { return false; }, outputB ); + cblist.add( outputA ); + cblist.fire(); + strictEqual( output, results.shift(), "Callback returning false" ); + + // Add another callback (to control lists with memory do not fire anymore) + output = "X"; cblist.add( outputC ); - outputA(); - }, outputB ); - strictEqual( output, results.shift(), "Add after fire" ); - - output = "X"; - cblist.fire(); - strictEqual( output, results.shift(), "Fire again" ); - - // Multiple fire - output = "X"; - cblist = jQuery.Callbacks( flags ); - cblist.add( function( str ) { - output += str; - } ); - cblist.fire( "A" ); - strictEqual( output, "XA", "Multiple fire (first fire)" ); - output = "X"; - cblist.add( function( str ) { - output += str; - } ); - strictEqual( output, results.shift(), "Multiple fire (first new callback)" ); - output = "X"; - cblist.fire( "B" ); - strictEqual( output, results.shift(), "Multiple fire (second fire)" ); - output = "X"; - cblist.add( function( str ) { - output += str; - } ); - strictEqual( output, results.shift(), "Multiple fire (second new callback)" ); - - // Return false - output = "X"; - cblist = jQuery.Callbacks( flags ); - cblist.add( outputA, function() { return false; }, outputB ); - cblist.add( outputA ); - cblist.fire(); - strictEqual( output, results.shift(), "Callback returning false" ); - - // Add another callback (to control lists with memory do not fire anymore) - output = "X"; - cblist.add( outputC ); - strictEqual( output, results.shift(), "Adding a callback after one returned false" ); + strictEqual( output, results.shift(), "Adding a callback after one returned false" ); + }); }); }); });