|
| 1 | +( function() { |
| 2 | + |
| 3 | +// Can't test what ain't there |
| 4 | +if ( !jQuery.fx ) { |
| 5 | + return; |
| 6 | +} |
| 7 | + |
| 8 | +var oldRaf = window.requestAnimationFrame, |
| 9 | + defaultPrefilter = jQuery.Animation.prefilters[ 0 ], |
| 10 | + defaultTweener = jQuery.Animation.tweeners[ "*" ][ 0 ], |
| 11 | + startTime = 505877050; |
| 12 | + |
| 13 | +// This module tests jQuery.Animation and the corresponding 1.8+ effects APIs |
| 14 | +module( "animation", { |
| 15 | + setup: function() { |
| 16 | + window.requestAnimationFrame = null; |
| 17 | + this.sandbox = sinon.sandbox.create(); |
| 18 | + this.clock = this.sandbox.useFakeTimers( startTime ); |
| 19 | + this._oldInterval = jQuery.fx.interval; |
| 20 | + jQuery.fx.step = {}; |
| 21 | + jQuery.fx.interval = 10; |
| 22 | + jQuery.now = Date.now; |
| 23 | + jQuery.Animation.prefilters = [ defaultPrefilter ]; |
| 24 | + jQuery.Animation.tweeners = { "*": [ defaultTweener ] }; |
| 25 | + }, |
| 26 | + teardown: function() { |
| 27 | + this.sandbox.restore(); |
| 28 | + jQuery.now = Date.now; |
| 29 | + jQuery.fx.stop(); |
| 30 | + jQuery.fx.interval = this._oldInterval; |
| 31 | + window.requestAnimationFrame = oldRaf; |
| 32 | + return moduleTeardown.apply( this, arguments ); |
| 33 | + } |
| 34 | +} ); |
| 35 | + |
| 36 | +test( "Animation( subject, props, opts ) - shape", function() { |
| 37 | + expect( 20 ); |
| 38 | + |
| 39 | + var subject = { test: 0 }, |
| 40 | + props = { test: 1 }, |
| 41 | + opts = { queue: "fx", duration: 100 }, |
| 42 | + animation = jQuery.Animation( subject, props, opts ); |
| 43 | + |
| 44 | + equal( animation.elem, subject, ".elem is set to the exact object passed" ); |
| 45 | + equal( animation.originalOptions, opts, ".originalOptions is set to options passed" ); |
| 46 | + equal( animation.originalProperties, props, ".originalProperties is set to props passed" ); |
| 47 | + |
| 48 | + notEqual( animation.props, props, ".props is not the original however" ); |
| 49 | + deepEqual( animation.props, props, ".props is a copy of the original" ); |
| 50 | + |
| 51 | + deepEqual( animation.opts, { |
| 52 | + duration: 100, |
| 53 | + queue: "fx", |
| 54 | + specialEasing: { test: undefined }, |
| 55 | + easing: jQuery.easing._default |
| 56 | + }, ".options is filled with default easing and specialEasing" ); |
| 57 | + |
| 58 | + equal( animation.startTime, startTime, "startTime was set" ); |
| 59 | + equal( animation.duration, 100, ".duration is set" ); |
| 60 | + |
| 61 | + equal( animation.tweens.length, 1, ".tweens has one Tween" ); |
| 62 | + equal( typeof animation.tweens[ 0 ].run, "function", "which has a .run function" ); |
| 63 | + |
| 64 | + equal( typeof animation.createTween, "function", ".createTween is a function" ); |
| 65 | + equal( typeof animation.stop, "function", ".stop is a function" ); |
| 66 | + |
| 67 | + equal( typeof animation.done, "function", ".done is a function" ); |
| 68 | + equal( typeof animation.fail, "function", ".fail is a function" ); |
| 69 | + equal( typeof animation.always, "function", ".always is a function" ); |
| 70 | + equal( typeof animation.progress, "function", ".progress is a function" ); |
| 71 | + |
| 72 | + equal( jQuery.timers.length, 1, "Added a timers function" ); |
| 73 | + equal( jQuery.timers[ 0 ].elem, subject, "...with .elem as the subject" ); |
| 74 | + equal( jQuery.timers[ 0 ].anim, animation, "...with .anim as the animation" ); |
| 75 | + equal( jQuery.timers[ 0 ].queue, opts.queue, "...with .queue" ); |
| 76 | + |
| 77 | + // Cleanup after ourselves by ticking to the end |
| 78 | + this.clock.tick( 100 ); |
| 79 | +} ); |
| 80 | + |
| 81 | +test( "Animation.prefilter( fn ) - calls prefilter after defaultPrefilter", function() { |
| 82 | + expect( 1 ); |
| 83 | + |
| 84 | + var prefilter = this.sandbox.stub(), |
| 85 | + defaultSpy = this.sandbox.spy( jQuery.Animation.prefilters, 0 ); |
| 86 | + |
| 87 | + jQuery.Animation.prefilter( prefilter ); |
| 88 | + |
| 89 | + jQuery.Animation( {}, {}, {} ); |
| 90 | + ok( prefilter.calledAfter( defaultSpy ), "our prefilter called after" ); |
| 91 | +} ); |
| 92 | + |
| 93 | +test( "Animation.prefilter( fn, true ) - calls prefilter before defaultPrefilter", function() { |
| 94 | + expect( 1 ); |
| 95 | + |
| 96 | + var prefilter = this.sandbox.stub(), |
| 97 | + defaultSpy = this.sandbox.spy( jQuery.Animation.prefilters, 0 ); |
| 98 | + |
| 99 | + jQuery.Animation.prefilter( prefilter, true ); |
| 100 | + |
| 101 | + jQuery.Animation( {}, {}, {} ); |
| 102 | + ok( prefilter.calledBefore( defaultSpy ), "our prefilter called before" ); |
| 103 | +} ); |
| 104 | + |
| 105 | +test( "Animation.prefilter - prefilter return hooks", function() { |
| 106 | + expect( 34 ); |
| 107 | + |
| 108 | + var animation, realAnimation, element, |
| 109 | + sandbox = this.sandbox, |
| 110 | + ourAnimation = { stop: this.sandbox.spy() }, |
| 111 | + target = { height: 50 }, |
| 112 | + props = { height: 100 }, |
| 113 | + opts = { duration: 100 }, |
| 114 | + prefilter = this.sandbox.spy( function() { |
| 115 | + realAnimation = this; |
| 116 | + sandbox.spy( realAnimation, "createTween" ); |
| 117 | + |
| 118 | + deepEqual( realAnimation.originalProperties, props, "originalProperties" ); |
| 119 | + equal( arguments[ 0 ], this.elem, "first param elem" ); |
| 120 | + equal( arguments[ 1 ], this.props, "second param props" ); |
| 121 | + equal( arguments[ 2 ], this.opts, "third param opts" ); |
| 122 | + return ourAnimation; |
| 123 | + } ), |
| 124 | + defaultSpy = sandbox.spy( jQuery.Animation.prefilters, 0 ), |
| 125 | + queueSpy = sandbox.spy( function( next ) { |
| 126 | + next(); |
| 127 | + } ), |
| 128 | + TweenSpy = sandbox.spy( jQuery, "Tween" ); |
| 129 | + |
| 130 | + jQuery.Animation.prefilter( prefilter, true ); |
| 131 | + |
| 132 | + sandbox.stub( jQuery.fx, "timer" ); |
| 133 | + |
| 134 | + animation = jQuery.Animation( target, props, opts ); |
| 135 | + |
| 136 | + equal( prefilter.callCount, 1, "Called prefilter" ); |
| 137 | + |
| 138 | + equal( defaultSpy.callCount, 0, |
| 139 | + "Returning something from a prefilter caused remaining prefilters to not run" ); |
| 140 | + equal( jQuery.fx.timer.callCount, 0, "Returning something never queues a timer" ); |
| 141 | + equal( animation, ourAnimation, "Returning something returned it from jQuery.Animation" ); |
| 142 | + equal( realAnimation.createTween.callCount, 0, "Returning something never creates tweens" ); |
| 143 | + equal( TweenSpy.callCount, 0, "Returning something never creates tweens" ); |
| 144 | + |
| 145 | + // Test overriden usage on queues: |
| 146 | + prefilter.reset(); |
| 147 | + element = jQuery( "<div>" ) |
| 148 | + .css( "height", 50 ) |
| 149 | + .animate( props, 100 ) |
| 150 | + .queue( queueSpy ) |
| 151 | + .animate( props, 100 ) |
| 152 | + .queue( queueSpy ) |
| 153 | + .animate( props, 100 ) |
| 154 | + .queue( queueSpy ); |
| 155 | + |
| 156 | + equal( prefilter.callCount, 1, "Called prefilter" ); |
| 157 | + equal( queueSpy.callCount, 0, "Next function in queue not called" ); |
| 158 | + |
| 159 | + realAnimation.opts.complete.call( realAnimation.elem ); |
| 160 | + equal( queueSpy.callCount, 1, "Next function in queue called after complete" ); |
| 161 | + |
| 162 | + equal( prefilter.callCount, 2, "Called prefilter again - animation #2" ); |
| 163 | + equal( ourAnimation.stop.callCount, 0, ".stop() on our animation hasn't been called" ); |
| 164 | + |
| 165 | + element.stop(); |
| 166 | + equal( ourAnimation.stop.callCount, 1, ".stop() called ourAnimation.stop()" ); |
| 167 | + ok( !ourAnimation.stop.args[ 0 ][ 0 ], ".stop( falsy ) (undefined or false are both valid)" ); |
| 168 | + |
| 169 | + equal( queueSpy.callCount, 2, "Next queue function called" ); |
| 170 | + ok( queueSpy.calledAfter( ourAnimation.stop ), "After our animation was told to stop" ); |
| 171 | + |
| 172 | + // ourAnimation.stop.reset(); |
| 173 | + equal( prefilter.callCount, 3, "Got the next animation" ); |
| 174 | + |
| 175 | + ourAnimation.stop.reset(); |
| 176 | + |
| 177 | + // do not clear queue, gotoEnd |
| 178 | + element.stop( false, true ); |
| 179 | + ok( ourAnimation.stop.calledWith( true ), ".stop(true) calls .stop(true)" ); |
| 180 | + ok( queueSpy.calledAfter( ourAnimation.stop ), |
| 181 | + "and the next queue function ran after we were told" ); |
| 182 | +} ); |
| 183 | + |
| 184 | +test( "Animation.tweener( fn ) - unshifts a * tweener", function() { |
| 185 | + expect( 2 ); |
| 186 | + var starTweeners = jQuery.Animation.tweeners[ "*" ]; |
| 187 | + |
| 188 | + jQuery.Animation.tweener( jQuery.noop ); |
| 189 | + equal( starTweeners.length, 2 ); |
| 190 | + deepEqual( starTweeners, [ jQuery.noop, defaultTweener ] ); |
| 191 | +} ); |
| 192 | + |
| 193 | +test( "Animation.tweener( 'prop', fn ) - unshifts a 'prop' tweener", function() { |
| 194 | + expect( 4 ); |
| 195 | + var tweeners = jQuery.Animation.tweeners, |
| 196 | + fn = function() {}; |
| 197 | + |
| 198 | + jQuery.Animation.tweener( "prop", jQuery.noop ); |
| 199 | + equal( tweeners.prop.length, 1 ); |
| 200 | + deepEqual( tweeners.prop, [ jQuery.noop ] ); |
| 201 | + |
| 202 | + jQuery.Animation.tweener( "prop", fn ); |
| 203 | + equal( tweeners.prop.length, 2 ); |
| 204 | + deepEqual( tweeners.prop, [ fn, jQuery.noop ] ); |
| 205 | +} ); |
| 206 | + |
| 207 | +test( "Animation.tweener( 'list of props', fn ) - unshifts a tweener to each prop", function() { |
| 208 | + expect( 2 ); |
| 209 | + var tweeners = jQuery.Animation.tweeners, |
| 210 | + fn = function() {}; |
| 211 | + |
| 212 | + jQuery.Animation.tweener( "list of props", jQuery.noop ); |
| 213 | + deepEqual( tweeners, { |
| 214 | + list: [ jQuery.noop ], |
| 215 | + of: [ jQuery.noop ], |
| 216 | + props: [ jQuery.noop ], |
| 217 | + "*": [ defaultTweener ] |
| 218 | + } ); |
| 219 | + |
| 220 | + // Test with extra whitespaces |
| 221 | + jQuery.Animation.tweener( " list\t of \tprops\n*", fn ); |
| 222 | + deepEqual( tweeners, { |
| 223 | + list: [ fn, jQuery.noop ], |
| 224 | + of: [ fn, jQuery.noop ], |
| 225 | + props: [ fn, jQuery.noop ], |
| 226 | + "*": [ fn, defaultTweener ] |
| 227 | + } ); |
| 228 | +} ); |
| 229 | + |
| 230 | +} )(); |
0 commit comments