1 QUnit
.module( "callbacks", {
2 afterEach
: moduleTeardown
7 if ( !includesModule( "callbacks" ) ) {
14 addToOutput = function( string
) {
19 outputA
= addToOutput( "A" ),
20 outputB
= addToOutput( "B" ),
21 outputC
= addToOutput( "C" ),
23 "": "XABC X XABCABCC X XBB X XABA X XX",
24 "once": "XABC X X X X X XABA X XX",
25 "memory": "XABC XABC XABCABCCC XA XBB XB XABA XC XX",
26 "unique": "XABC X XABCA X XBB X XAB X X",
27 "stopOnFalse": "XABC X XABCABCC X XBB X XA X XX",
28 "once memory": "XABC XABC X XA X XA XABA XC XX",
29 "once unique": "XABC X X X X X XAB X X",
30 "once stopOnFalse": "XABC X X X X X XA X XX",
31 "memory unique": "XABC XA XABCA XA XBB XB XAB XC X",
32 "memory stopOnFalse": "XABC XABC XABCABCCC XA XBB XB XA X XX",
33 "unique stopOnFalse": "XABC X XABCA X XBB X XA X X"
36 "no filter": undefined,
37 "filter": function( fn
) {
39 return fn
.apply( this, arguments
);
44 function showFlags( flags
) {
45 if ( typeof flags
=== "string" ) {
46 return "'" + flags
+ "'";
49 for ( key
in flags
) {
50 output
.push( "'" + key
+ "': " + flags
[ key
] );
52 return "{ " + output
.join( ", " ) + " }";
55 jQuery
.each( tests
, function( strFlags
, resultString
) {
59 jQuery
.each( strFlags
.split( " " ), function() {
61 objectFlags
[ this ] = true;
65 jQuery
.each( filters
, function( filterLabel
) {
70 }, function( flagsTypes
, flags
) {
72 QUnit
.test( "jQuery.Callbacks( " + showFlags( flags
) + " ) - " + filterLabel
, function( assert
) {
77 results
= resultString
.split( /\s+/ );
79 // Basic binding and firing
81 cblist
= jQuery
.Callbacks( flags
);
82 assert
.strictEqual( cblist
.locked(), false, ".locked() initially false" );
83 assert
.strictEqual( cblist
.disabled(), false, ".disabled() initially false" );
84 assert
.strictEqual( cblist
.fired(), false, ".fired() initially false" );
85 cblist
.add( function( str
) {
88 assert
.strictEqual( cblist
.fired(), false, ".fired() still false after .add" );
90 assert
.strictEqual( output
, "XA", "Basic binding and firing" );
91 assert
.strictEqual( cblist
.fired(), true, ".fired() detects firing" );
94 cblist
.add( function( str
) {
97 assert
.strictEqual( output
, "X", "Adding a callback after disabling" );
99 assert
.strictEqual( output
, "X", "Firing after disabling" );
100 assert
.strictEqual( cblist
.disabled(), true, ".disabled() becomes true" );
101 assert
.strictEqual( cblist
.locked(), true, "disabling locks" );
103 // Emptying while firing (trac-13517)
104 cblist
= jQuery
.Callbacks( flags
);
105 cblist
.add( cblist
.empty
);
106 cblist
.add( function() {
107 assert
.ok( false, "not emptied" );
111 // Disabling while firing
112 cblist
= jQuery
.Callbacks( flags
);
113 cblist
.add( cblist
.disable
);
114 cblist
.add( function() {
115 assert
.ok( false, "not disabled" );
119 // Basic binding and firing (context, arguments)
121 cblist
= jQuery
.Callbacks( flags
);
122 cblist
.add( function() {
123 assert
.equal( this, window
, "Basic binding and firing (context)" );
124 output
+= Array
.prototype.join
.call( arguments
, "" );
126 cblist
.fireWith( window
, [ "A", "B" ] );
127 assert
.strictEqual( output
, "XAB", "Basic binding and firing (arguments)" );
129 // fireWith with no arguments
131 cblist
= jQuery
.Callbacks( flags
);
132 cblist
.add( function() {
133 assert
.equal( this, window
, "fireWith with no arguments (context is window)" );
134 assert
.strictEqual( arguments
.length
, 0, "fireWith with no arguments (no arguments)" );
138 // Basic binding, removing and firing
140 cblist
= jQuery
.Callbacks( flags
);
141 cblist
.add( outputA
, outputB
, outputC
);
142 cblist
.remove( outputB
, outputC
);
144 assert
.strictEqual( output
, "XA", "Basic binding, removing and firing" );
148 cblist
= jQuery
.Callbacks( flags
);
149 cblist
.add( outputA
);
150 cblist
.add( outputB
);
151 cblist
.add( outputC
);
154 assert
.strictEqual( output
, "X", "Empty" );
158 cblist
= jQuery
.Callbacks( flags
);
159 cblist
.add( function( str
) {
163 cblist
.add( function( str
) {
167 cblist
.add( function( str
) {
170 assert
.strictEqual( output
, "X", "Lock early" );
171 assert
.strictEqual( cblist
.locked(), true, "Locking reflected in accessor" );
173 // Locking while firing (gh-1990)
175 cblist
= jQuery
.Callbacks( flags
);
176 cblist
.add( cblist
.lock
);
177 cblist
.add( function( str
) {
181 assert
.strictEqual( output
, "XA", "Locking doesn't abort execution (gh-1990)" );
185 cblist
= jQuery
.Callbacks( flags
);
186 cblist
.add( function() {
187 cblist
.add( outputC
);
191 assert
.strictEqual( output
, results
.shift(), "Proper ordering" );
193 // Add and fire again
195 cblist
.add( function() {
196 cblist
.add( outputC
);
199 assert
.strictEqual( output
, results
.shift(), "Add after fire" );
203 assert
.strictEqual( output
, results
.shift(), "Fire again" );
207 cblist
= jQuery
.Callbacks( flags
);
208 cblist
.add( function( str
) {
212 assert
.strictEqual( output
, "XA", "Multiple fire (first fire)" );
214 cblist
.add( function( str
) {
217 assert
.strictEqual( output
, results
.shift(), "Multiple fire (first new callback)" );
220 assert
.strictEqual( output
, results
.shift(), "Multiple fire (second fire)" );
222 cblist
.add( function( str
) {
225 assert
.strictEqual( output
, results
.shift(), "Multiple fire (second new callback)" );
229 cblist
= jQuery
.Callbacks( flags
);
230 cblist
.add( outputA
, function() { return false; }, outputB
);
231 cblist
.add( outputA
);
233 assert
.strictEqual( output
, results
.shift(), "Callback returning false" );
235 // Add another callback (to control lists with memory do not fire anymore)
237 cblist
.add( outputC
);
238 assert
.strictEqual( output
, results
.shift(), "Adding a callback after one returned false" );
240 // Callbacks are not iterated
245 handler
.method = function() {
248 cblist
= jQuery
.Callbacks( flags
);
249 cblist
.add( handler
);
250 cblist
.add( handler
);
252 assert
.strictEqual( output
, results
.shift(), "No callback iteration" );
260 QUnit
.test( "jQuery.Callbacks( options ) - options are copied", function( assert
) {
267 cb
= jQuery
.Callbacks( options
),
270 assert
.ok( !( count
++ ), "called once" );
272 options
[ "unique" ] = false;
277 QUnit
.test( "jQuery.Callbacks.fireWith - arguments are copied", function( assert
) {
281 var cb
= jQuery
.Callbacks( "memory" ),
284 cb
.fireWith( null, args
);
287 cb
.add( function( hello
) {
288 assert
.strictEqual( hello
, "hello", "arguments are copied internally" );
292 QUnit
.test( "jQuery.Callbacks.remove - should remove all instances", function( assert
) {
296 var cb
= jQuery
.Callbacks();
299 assert
.ok( false, "function wasn't removed" );
302 cb
.add( fn
, fn
, function() {
303 assert
.ok( true, "end of test" );
304 } ).remove( fn
).fire();
307 QUnit
.test( "jQuery.Callbacks.has", function( assert
) {
311 var cb
= jQuery
.Callbacks();
321 cb
.add( getA
, getB
, getC
);
322 assert
.strictEqual( cb
.has(), true, "No arguments to .has() returns whether callback function(s) are attached or not" );
323 assert
.strictEqual( cb
.has( getA
), true, "Check if a specific callback function is in the Callbacks list" );
326 assert
.strictEqual( cb
.has( getB
), false, "Remove a specific callback function and make sure its no longer there" );
327 assert
.strictEqual( cb
.has( getA
), true, "Remove a specific callback function and make sure other callback function is still there" );
330 assert
.strictEqual( cb
.has(), false, "Empty list and make sure there are no callback function(s)" );
331 assert
.strictEqual( cb
.has( getA
), false, "Check for a specific function in an empty() list" );
333 cb
.add( getA
, getB
, function() {
334 assert
.strictEqual( cb
.has(), true, "Check if list has callback function(s) from within a callback function" );
335 assert
.strictEqual( cb
.has( getA
), true, "Check if list has a specific callback from within a callback function" );
338 assert
.strictEqual( cb
.has(), true, "Callbacks list has callback function(s) after firing" );
341 assert
.strictEqual( cb
.has(), false, "disabled() list has no callback functions (returns false)" );
342 assert
.strictEqual( cb
.has( getA
), false, "Check for a specific function in a disabled() list" );
344 cb
= jQuery
.Callbacks( "unique" );
347 assert
.strictEqual( cb
.has(), true, "Check if unique list has callback function(s) attached" );
349 assert
.strictEqual( cb
.has(), false, "locked() list is empty and returns false" );
352 QUnit
.test( "jQuery.Callbacks() - adding a string doesn't cause a stack overflow", function( assert
) {
356 jQuery
.Callbacks().add( "hello world" );
358 assert
.ok( true, "no stack overflow" );
361 QUnit
.test( "jQuery.Callbacks() - disabled callback doesn't fire (gh-1790)", function( assert
) {
365 var cb
= jQuery
.Callbacks(),
367 shot = function() { fired
= true; };
373 assert
.ok( !fired
, "Disabled callback function didn't fire" );
376 QUnit
.test( "jQuery.Callbacks() - list with memory stays locked (gh-3469)", function( assert
) {
380 var cb
= jQuery
.Callbacks( "memory" ),
382 count1 = function() { fired
+= 1; },
383 count2 = function() { fired
+= 10; };
387 assert
.equal( fired
, 1, "Pre-lock() fire" );
391 assert
.equal( fired
, 11, "Post-lock() add" );
394 assert
.equal( fired
, 11, "Post-lock() fire ignored" );