2 teardown: moduleTeardown
5 jQuery.each( [ "", " - new operator" ], function( _, withNew ) {
7 function createDeferred( fn ) {
8 return withNew ? new jQuery.Deferred( fn ) : jQuery.Deferred( fn );
11 test( "jQuery.Deferred" + withNew, function() {
15 var defer = createDeferred();
17 ok( jQuery.isFunction( defer.pipe ), "defer.pipe is a function" );
19 createDeferred().resolve().done(function() {
20 ok( true, "Success on resolve" );
21 strictEqual( this.state(), "resolved", "Deferred is resolved (state)" );
23 ok( false, "Error on resolve" );
24 }).always(function() {
25 ok( true, "Always callback on resolve" );
28 createDeferred().reject().done(function() {
29 ok( false, "Success on reject" );
31 ok( true, "Error on reject" );
32 strictEqual( this.state(), "rejected", "Deferred is rejected (state)" );
33 }).always(function() {
34 ok( true, "Always callback on reject" );
37 createDeferred(function( defer ) {
38 ok( this === defer, "Defer passed as this & first argument" );
40 }).done(function( value ) {
41 strictEqual( value, "done", "Passed function executed" );
44 createDeferred(function( defer ) {
45 var promise = defer.promise(),
47 funcPromise = defer.promise( func );
48 strictEqual( defer.promise(), promise, "promise is always the same" );
49 strictEqual( funcPromise, func, "non objects get extended" );
50 jQuery.each( promise, function( key ) {
51 if ( !jQuery.isFunction( promise[ key ] ) ) {
52 ok( false, key + " is a function (" + jQuery.type( promise[ key ] ) + ")" );
54 if ( promise[ key ] !== func[ key ] ) {
55 strictEqual( func[ key ], promise[ key ], key + " is the same" );
60 jQuery.expandedEach = jQuery.each;
61 jQuery.expandedEach( "resolve reject".split(" "), function( _, change ) {
62 createDeferred(function( defer ) {
63 strictEqual( defer.state(), "pending", "pending after creation" );
65 defer.progress(function( value ) {
66 strictEqual( value, checked, "Progress: right value (" + value + ") received" );
68 for ( checked = 0; checked < 3; checked++ ) {
69 defer.notify( checked );
71 strictEqual( defer.state(), "pending", "pending after notification" );
73 notStrictEqual( defer.state(), "pending", "not pending after " + change );
81 test( "jQuery.Deferred - chainability", function() {
83 var defer = jQuery.Deferred();
87 jQuery.expandedEach = jQuery.each;
88 jQuery.expandedEach( "resolve reject notify resolveWith rejectWith notifyWith done fail progress always".split(" "), function( _, method ) {
92 strictEqual( object.m(), object, method + " is chainable" );
96 test( "jQuery.Deferred.then - filtering (done)", function( assert ) {
100 var value1, value2, value3,
101 defer = jQuery.Deferred(),
102 piped = defer.then(function( a, b ) {
105 done = jQuery.map( new Array( 3 ), function() { return assert.async(); } );
107 piped.done(function( result ) {
111 defer.done(function( a, b ) {
116 defer.resolve( 2, 3 ).then(function() {
117 assert.strictEqual( value1, 2, "first resolve value ok" );
118 assert.strictEqual( value2, 3, "second resolve value ok" );
119 assert.strictEqual( value3, 6, "result of filter ok" );
123 jQuery.Deferred().reject().then(function() {
124 assert.ok( false, "then should not be called on reject" );
125 }).then( null, done.pop() );
127 jQuery.Deferred().resolve().then( jQuery.noop ).done(function( value ) {
128 assert.strictEqual( value, undefined, "then done callback can return undefined/null" );
133 test( "jQuery.Deferred.then - filtering (fail)", function( assert ) {
137 var value1, value2, value3,
138 defer = jQuery.Deferred(),
139 piped = defer.then( null, function( a, b ) {
142 done = jQuery.map( new Array( 3 ), function() { return assert.async(); } );
144 piped.done(function( result ) {
148 defer.fail(function( a, b ) {
153 defer.reject( 2, 3 ).then( null, function() {
154 assert.strictEqual( value1, 2, "first reject value ok" );
155 assert.strictEqual( value2, 3, "second reject value ok" );
156 assert.strictEqual( value3, 6, "result of filter ok" );
160 jQuery.Deferred().resolve().then( null, function() {
161 assert.ok( false, "then should not be called on resolve" );
162 }).then( done.pop() );
164 jQuery.Deferred().reject().then( null, jQuery.noop ).done(function( value ) {
165 assert.strictEqual( value, undefined, "then fail callback can return undefined/null" );
170 test( "[PIPE ONLY] jQuery.Deferred.pipe - filtering (fail)", function( assert ) {
174 var value1, value2, value3,
175 defer = jQuery.Deferred(),
176 piped = defer.pipe( null, function( a, b ) {
179 done = jQuery.map( new Array( 3 ), function() { return assert.async(); } );
181 piped.fail(function( result ) {
185 defer.fail(function( a, b ) {
190 defer.reject( 2, 3 ).pipe( null, function() {
191 assert.strictEqual( value1, 2, "first reject value ok" );
192 assert.strictEqual( value2, 3, "second reject value ok" );
193 assert.strictEqual( value3, 6, "result of filter ok" );
197 jQuery.Deferred().resolve().pipe( null, function() {
198 assert.ok( false, "then should not be called on resolve" );
199 }).then( done.pop() );
201 jQuery.Deferred().reject().pipe( null, jQuery.noop ).fail(function( value ) {
202 assert.strictEqual( value, undefined, "then fail callback can return undefined/null" );
207 test( "jQuery.Deferred.then - filtering (progress)", function( assert ) {
211 var value1, value2, value3,
212 defer = jQuery.Deferred(),
213 piped = defer.then( null, null, function( a, b ) {
216 done = assert.async();
218 piped.progress(function( result ) {
222 defer.progress(function( a, b ) {
227 defer.notify( 2, 3 ).then( null, null, function() {
228 assert.strictEqual( value1, 2, "first progress value ok" );
229 assert.strictEqual( value2, 3, "second progress value ok" );
230 assert.strictEqual( value3, 6, "result of filter ok" );
235 test( "jQuery.Deferred.then - deferred (done)", function( assert ) {
239 var value1, value2, value3,
240 defer = jQuery.Deferred(),
241 piped = defer.then(function( a, b ) {
242 return jQuery.Deferred(function( defer ) {
243 defer.reject( a * b );
246 done = assert.async();
248 piped.fail(function( result ) {
252 defer.done(function( a, b ) {
257 defer.resolve( 2, 3 );
259 piped.fail(function() {
260 assert.strictEqual( value1, 2, "first resolve value ok" );
261 assert.strictEqual( value2, 3, "second resolve value ok" );
262 assert.strictEqual( value3, 6, "result of filter ok" );
267 test( "jQuery.Deferred.then - deferred (fail)", function( assert ) {
271 var value1, value2, value3,
272 defer = jQuery.Deferred(),
273 piped = defer.then( null, function( a, b ) {
274 return jQuery.Deferred(function( defer ) {
275 defer.resolve( a * b );
278 done = assert.async();
280 piped.done(function( result ) {
284 defer.fail(function( a, b ) {
289 defer.reject( 2, 3 );
291 piped.done(function() {
292 assert.strictEqual( value1, 2, "first reject value ok" );
293 assert.strictEqual( value2, 3, "second reject value ok" );
294 assert.strictEqual( value3, 6, "result of filter ok" );
299 test( "jQuery.Deferred.then - deferred (progress)", function( assert ) {
303 var value1, value2, value3,
304 defer = jQuery.Deferred(),
305 piped = defer.then( null, null, function( a, b ) {
306 return jQuery.Deferred(function( defer ) {
307 defer.resolve( a * b );
310 done = assert.async();
312 piped.progress(function( result ) {
313 return jQuery.Deferred().resolve().then(function() {
315 }).then(function( result ) {
320 defer.progress(function( a, b ) {
325 defer.notify( 2, 3 );
327 piped.then( null, null, function( result ) {
328 return jQuery.Deferred().resolve().then(function() {
331 assert.strictEqual( value1, 2, "first progress value ok" );
332 assert.strictEqual( value2, 3, "second progress value ok" );
333 assert.strictEqual( value3, 6, "result of filter ok" );
339 test( "[PIPE ONLY] jQuery.Deferred.pipe - deferred (progress)", function( assert ) {
343 var value1, value2, value3,
344 defer = jQuery.Deferred(),
345 piped = defer.pipe( null, null, function( a, b ) {
346 return jQuery.Deferred(function( defer ) {
347 defer.resolve( a * b );
350 done = assert.async();
352 piped.done(function( result ) {
356 defer.progress(function( a, b ) {
361 defer.notify( 2, 3 );
363 piped.done(function() {
364 assert.strictEqual( value1, 2, "first progress value ok" );
365 assert.strictEqual( value2, 3, "second progress value ok" );
366 assert.strictEqual( value3, 6, "result of filter ok" );
371 test( "jQuery.Deferred.then - context", function( assert ) {
375 var defer, piped, defer2, piped2,
377 done = jQuery.map( new Array( 4 ), function() { return assert.async(); } );
379 jQuery.Deferred().resolveWith( context, [ 2 ] ).then(function( value ) {
381 }).done(function( value ) {
382 assert.notStrictEqual( this, context, "custom context not propagated through .then" );
383 assert.strictEqual( value, 6, "proper value received" );
387 jQuery.Deferred().resolve().then(function() {
388 return jQuery.Deferred().resolveWith( context );
390 assert.strictEqual( this, context,
391 "custom context of returned deferred correctly propagated" );
395 defer = jQuery.Deferred();
396 piped = defer.then(function( value ) {
402 piped.done(function( value ) {
403 assert.strictEqual( this, piped,
404 "default context gets updated to latest promise in the chain" );
405 assert.strictEqual( value, 6, "proper value received" );
409 defer2 = jQuery.Deferred();
410 piped2 = defer2.then();
414 piped2.done(function( value ) {
415 assert.strictEqual( this, piped2,
416 "default context updated to latest promise in the chain (without passing function)" );
417 assert.strictEqual( value, 2, "proper value received (without passing function)" );
422 test( "[PIPE ONLY] jQuery.Deferred.pipe - context", function( assert ) {
426 var defer, piped, defer2, piped2,
428 done = jQuery.map( new Array( 4 ), function() { return assert.async(); } );
430 jQuery.Deferred().resolveWith( context, [ 2 ] ).pipe(function( value ) {
432 }).done(function( value ) {
433 assert.strictEqual( this, context, "[PIPE ONLY] custom context correctly propagated" );
434 assert.strictEqual( value, 6, "proper value received" );
438 jQuery.Deferred().resolve().pipe(function() {
439 return jQuery.Deferred().resolveWith(context);
441 assert.strictEqual( this, context,
442 "custom context of returned deferred correctly propagated" );
446 defer = jQuery.Deferred();
447 piped = defer.pipe(function( value ) {
453 piped.done(function( value ) {
454 assert.strictEqual( this, piped,
455 "default context gets updated to latest promise in the chain" );
456 assert.strictEqual( value, 6, "proper value received" );
460 defer2 = jQuery.Deferred();
461 piped2 = defer2.pipe();
465 piped2.done(function( value ) {
466 assert.strictEqual( this, piped2,
467 "default context updated to latest promise in the chain (without passing function)" );
468 assert.strictEqual( value, 2, "proper value received (without passing function)" );
473 asyncTest( "jQuery.Deferred.then - spec compatibility", function() {
477 var defer = jQuery.Deferred().done(function() {
482 defer.then(function() {
483 ok( true, "errors in .done callbacks don't stop .then handlers" );
491 test( "jQuery.Deferred - 1.x/2.x compatibility", function( assert ) {
495 var context = { id: "callback context" },
496 thenable = jQuery.Deferred().resolve( "thenable fulfillment" ).promise(),
497 done = jQuery.map( new Array( 8 ), function() { return assert.async(); } );
499 thenable.unwrapped = false;
501 jQuery.Deferred().resolve( 1, 2 ).then(function() {
502 assert.deepEqual( [].slice.call( arguments ), [ 1, 2 ],
503 ".then fulfillment callbacks receive all resolution values" );
506 jQuery.Deferred().reject( 1, 2 ).then( null, function() {
507 assert.deepEqual( [].slice.call( arguments ), [ 1, 2 ],
508 ".then rejection callbacks receive all rejection values" );
511 jQuery.Deferred().notify( 1, 2 ).then( null, null, function() {
512 assert.deepEqual( [].slice.call( arguments ), [ 1, 2 ],
513 ".then progress callbacks receive all progress values" );
517 jQuery.Deferred().resolveWith( context ).then(function() {
518 assert.deepEqual( this, context, ".then fulfillment callbacks receive context" );
521 jQuery.Deferred().rejectWith( context ).then( null, function() {
522 assert.deepEqual( this, context, ".then rejection callbacks receive context" );
525 jQuery.Deferred().notifyWith( context ).then( null, null, function() {
526 assert.deepEqual( this, context, ".then progress callbacks receive context" );
530 jQuery.Deferred().resolve( thenable ).done(function( value ) {
531 assert.strictEqual( value, thenable, ".done doesn't unwrap thenables" );
535 jQuery.Deferred().notify( thenable ).then().then( null, null, function( value ) {
536 assert.strictEqual( value, "thenable fulfillment",
537 ".then implicit progress callbacks unwrap thenables" );
542 test( "jQuery.Deferred.then - progress and thenables", function( assert ) {
546 var trigger = jQuery.Deferred().notify(),
547 expectedProgress = [ "baz", "baz" ],
548 done = jQuery.map( new Array( 2 ), function() { return assert.async(); } ),
549 failer = function( evt ) {
551 ok( false, "no unexpected " + evt );
555 trigger.then( null, null, function() {
556 var notifier = jQuery.Deferred().notify( "foo" );
557 setTimeout(function() {
558 notifier.notify( "bar" ).resolve( "baz" );
561 }).then( failer( "fulfill" ), failer( "reject" ), function( v ) {
562 assert.strictEqual( v, expectedProgress.shift(), "expected progress value" );
568 test( "jQuery.Deferred - notify and resolve", function( assert ) {
572 var notifiedResolved = jQuery.Deferred().notify( "foo" )/*xxx .resolve( "bar" )*/,
573 done = jQuery.map( new Array( 3 ), function() { return assert.async(); } );
575 notifiedResolved.progress( function( v ) {
576 assert.strictEqual( v, "foo", "progress value" );
579 notifiedResolved.pipe().progress( function( v ) {
580 assert.strictEqual( v, "foo", "piped progress value" );
583 notifiedResolved.pipe( null, null, function() {
585 } ).progress( function( v ) {
586 assert.strictEqual( v, "baz", "replaced piped progress value" );
589 notifiedResolved.pipe( null, null, function() {
590 return jQuery.Deferred().notify( "baz" ).resolve( "quux" );
591 } ).progress( function( v ) {
592 assert.strictEqual( v, "baz", "deferred replaced piped progress value" );
595 notifiedResolved.then().progress( function( v ) {
596 assert.strictEqual( v, "foo", "then'd progress value" );
600 notifiedResolved.then( null, null, function() {
602 } ).progress( function( v ) {
603 assert.strictEqual( v, "baz", "replaced then'd progress value" );
607 notifiedResolved.then( null, null, function() {
608 return jQuery.Deferred().notify( "baz" ).resolve( "quux" );
609 } ).progress( function( v ) {
610 // Progress from the surrogate deferred is ignored
611 assert.strictEqual( v, "quux", "deferred replaced then'd progress value" );
616 test( "jQuery.when", function() {
620 // Some other objects
622 "an empty string": "",
623 "a non-empty string": "some string",
625 "a number other than zero": 1,
629 "undefined": undefined,
630 "a plain object": {},
631 "an array": [ 1, 2, 3 ]
633 }, function( message, value ) {
636 jQuery.when( value ).done(function( resolveValue ) {
637 strictEqual( this, window, "Context is the global object with " + message );
638 strictEqual( resolveValue, value, "Test the promise was resolved with " + message );
641 "Test " + message + " triggers the creation of a new Promise"
647 jQuery.when().done(function( resolveValue ) {
648 strictEqual( this, window, "Test the promise was resolved with window as its context" );
649 strictEqual( resolveValue, undefined, "Test the promise was resolved with no parameter" );
652 "Test calling when with no parameter triggers the creation of a new Promise"
658 jQuery.when( jQuery.Deferred().resolveWith( context ) ).done(function() {
659 strictEqual( this, context, "when( promise ) propagates context" );
662 jQuery.each([ 1, 2, 3 ], function( k, i ) {
664 jQuery.when( cache || jQuery.Deferred(function() {
667 ).done(function( value ) {
669 strictEqual( value, 1, "Function executed" + ( i > 1 ? " only once" : "" ) );
676 test( "jQuery.when - joined", function() {
682 fulfilled: jQuery.Deferred().resolve( 1 ),
683 rejected: jQuery.Deferred().reject( 0 ),
684 notified: jQuery.Deferred().notify( true ),
685 eventuallyFulfilled: jQuery.Deferred().notify( true ),
686 eventuallyRejected: jQuery.Deferred().notify( true ),
687 fulfilledStandardPromise: Promise.resolve( 1 ),
688 rejectedStandardPromise: Promise.reject( 0 )
693 eventuallyFulfilled: true,
694 fulfilledStandardPromise: true
698 eventuallyRejected: true,
699 rejectedStandardPromise: true
703 eventuallyFulfilled: true,
704 eventuallyRejected: true
716 jQuery.each( deferreds, function( id1, defer1 ) {
717 jQuery.each( deferreds, function( id2, defer2 ) {
718 var shouldResolve = willSucceed[ id1 ] && willSucceed[ id2 ],
719 shouldError = willError[ id1 ] || willError[ id2 ],
720 shouldNotify = willNotify[ id1 ] || willNotify[ id2 ],
721 expected = shouldResolve ? [ 1, 1 ] : [ 0, undefined ],
722 expectedNotify = shouldNotify && [ willNotify[ id1 ], willNotify[ id2 ] ],
723 code = "jQuery.when( " + id1 + ", " + id2 + " )",
724 context1 = defer1 && jQuery.isFunction( defer1.promise ) ? defer1.promise() :
725 ( defer1.then ? window : undefined ),
726 context2 = defer2 && jQuery.isFunction( defer2.promise ) ? defer2.promise() :
727 ( defer2.then ? window : undefined );
729 jQuery.when( defer1, defer2 ).done(function( a, b ) {
730 if ( shouldResolve ) {
731 deepEqual( [ a, b ], expected, code + " => resolve" );
732 strictEqual( this[ 0 ], context1, code + " => first context OK" );
733 strictEqual( this[ 1 ], context2, code + " => second context OK" );
735 ok( false, code + " => resolve" );
737 }).fail(function( a, b ) {
739 deepEqual( [ a, b ], expected, code + " => reject" );
741 ok( false, code + " => reject" );
743 }).progress(function( a, b ) {
744 deepEqual( [ a, b ], expectedNotify, code + " => progress" );
745 strictEqual( this[ 0 ], expectedNotify[ 0 ] ? context1 : undefined, code + " => first context OK" );
746 strictEqual( this[ 1 ], expectedNotify[ 1 ] ? context2 : undefined, code + " => second context OK" );
747 }).always( restart );
750 deferreds.eventuallyFulfilled.resolve( 1 );
751 deferreds.eventuallyRejected.reject( 0 );
754 test( "jQuery.when - resolved", function() {
758 var a = jQuery.Deferred().notify( 1 ).resolve( 4 ),
759 b = jQuery.Deferred().notify( 2 ).resolve( 5 ),
760 c = jQuery.Deferred().notify( 3 ).resolve( 6 );
762 jQuery.when( a, b, c ).progress(function( a, b, c ) {
763 strictEqual( a, 1, "first notify value ok" );
764 strictEqual( b, 2, "second notify value ok" );
765 strictEqual( c, 3, "third notify value ok" );
766 }).done(function( a, b, c ) {
767 strictEqual( a, 4, "first resolve value ok" );
768 strictEqual( b, 5, "second resolve value ok" );
769 strictEqual( c, 6, "third resolve value ok" );
771 ok( false, "Error on resolve" );
775 test( "jQuery.when - filtering", function() {
779 function increment( x ) {
786 jQuery.Deferred().resolve( 3 ).then( increment ),
787 jQuery.Deferred().reject( 5 ).then( null, increment )
788 ).done(function( four, six ) {
789 strictEqual( four, 4, "resolved value incremented" );
790 strictEqual( six, 6, "rejected value incremented" );
795 test( "jQuery.when - exceptions", function() {
800 throw "exception thrown";
805 jQuery.Deferred().resolve().then( woops ).fail(function( doneException ) {
806 strictEqual( doneException, "exception thrown", "throwing in done handler" );
807 jQuery.Deferred().reject().then( null, woops ).fail(function( failException ) {
808 strictEqual( failException, "exception thrown", "throwing in fail handler" );
814 test( "jQuery.when - chaining", function() {
818 var defer = jQuery.Deferred();
824 function chainStandard() {
825 return Promise.resolve( "std deferred" );
831 jQuery.Deferred().resolve( 3 ).then( chain ),
832 jQuery.Deferred().reject( 5 ).then( null, chain ),
833 jQuery.Deferred().resolve( 3 ).then( chainStandard ),
834 jQuery.Deferred().reject( 5 ).then( null, chainStandard )
835 ).done(function( v1, v2, s1, s2 ) {
836 strictEqual( v1, "other deferred", "chaining in done handler" );
837 strictEqual( v2, "other deferred", "chaining in fail handler" );
838 strictEqual( s1, "std deferred", "chaining thenable in done handler" );
839 strictEqual( s2, "std deferred", "chaining thenable in fail handler" );
843 defer.resolve( "other deferred" );