3 // Can't test what ain't there
8 var oldRaf = window.requestAnimationFrame;
10 QUnit.module( "tween", {
11 beforeEach: function() {
12 this.sandbox = sinon.createSandbox();
13 this.clock = this.sandbox.useFakeTimers( 505877050 );
14 this._oldInterval = jQuery.fx.interval;
15 window.requestAnimationFrame = null;
17 jQuery.fx.interval = 10;
19 afterEach: function() {
20 this.sandbox.restore();
22 jQuery.fx.interval = this._oldInterval;
23 window.requestAnimationFrame = oldRaf;
24 return moduleTeardown.apply( this, arguments );
28 QUnit.test( "jQuery.Tween - Default propHooks on plain objects", function( assert ) {
30 var propHooks, defaultHook, testObject, fakeTween, stepSpy;
32 propHooks = jQuery.Tween.propHooks;
33 assert.equal( typeof propHooks, "object", "jQuery.Tween.propHooks exists" );
35 defaultHook = propHooks._default;
36 assert.ok( defaultHook, "_default propHook exists" );
38 testObject = { test: 0 };
39 fakeTween = { elem: testObject, prop: "test", now: 10, unit: "px" };
41 assert.equal( defaultHook.get( fakeTween ), 0, "Can get property of object" );
43 fakeTween.prop = "testMissing";
44 assert.equal( defaultHook.get( fakeTween ), undefined, "Can get missing property on object" );
46 defaultHook.set( fakeTween );
47 assert.equal( testObject.testMissing, 10, "Sets missing value properly on plain object" );
49 fakeTween.prop = "opacity";
50 defaultHook.set( fakeTween );
51 assert.equal( testObject.opacity, 10, "Correctly set opacity on plain object" );
53 fakeTween.prop = "test";
54 stepSpy = jQuery.fx.step.test = this.sandbox.spy();
56 defaultHook.set( fakeTween );
57 assert.ok( stepSpy.calledWith( fakeTween ), "Step function called with Tween" );
58 assert.equal( testObject.test, 0, "Because step didn't set, value is unchanged" );
61 QUnit.test( "jQuery.Tween - Default propHooks on elements", function( assert ) {
63 var propHooks, defaultHook, testElement, fakeTween, cssStub, styleStub, stepSpy;
65 propHooks = jQuery.Tween.propHooks;
66 assert.equal( typeof propHooks, "object", "jQuery.Tween.propHooks exists" );
68 defaultHook = propHooks._default;
69 assert.ok( defaultHook, "_default propHook exists" );
71 testElement = jQuery( "<div>" )[ 0 ];
72 fakeTween = { elem: testElement, prop: "height", now: 10, unit: "px" };
74 cssStub = this.sandbox.stub( jQuery, "css" ).returns( 10 );
76 assert.equal( defaultHook.get( fakeTween ), 10, "Gets expected style value" );
77 assert.ok( cssStub.calledWith( testElement, "height", "" ), "Calls jQuery.css correctly" );
79 fakeTween.prop = "testOpti";
80 testElement.testOpti = 15;
81 cssStub.resetHistory();
83 assert.equal( defaultHook.get( fakeTween ), 15, "Gets expected value not defined on style" );
84 assert.equal( cssStub.callCount, 0, "Did not call jQuery.css" );
86 fakeTween.prop = "testMissing";
87 assert.equal( defaultHook.get( fakeTween ), 10, "Can get missing property on element" );
88 assert.ok( cssStub.calledWith( testElement, "testMissing", "" ), "...using jQuery.css" );
90 cssStub.returns( "" );
91 assert.equal( defaultHook.get( fakeTween ), 0, "Uses 0 for empty string" );
93 cssStub.returns( "auto" );
94 assert.equal( defaultHook.get( fakeTween ), 0, "Uses 0 for 'auto'" );
96 cssStub.returns( null );
97 assert.equal( defaultHook.get( fakeTween ), 0, "Uses 0 for null" );
99 cssStub.returns( undefined );
100 assert.equal( defaultHook.get( fakeTween ), 0, "Uses 0 for undefined" );
102 cssStub.resetHistory();
105 styleStub = this.sandbox.stub( jQuery, "style" );
106 fakeTween.prop = "height";
108 defaultHook.set( fakeTween );
109 assert.ok( styleStub.calledWith( testElement, "height", "10px" ),
110 "Calls jQuery.style with elem, prop, now+unit" );
112 styleStub.resetHistory();
113 fakeTween.prop = "testMissing";
115 defaultHook.set( fakeTween );
116 assert.equal( styleStub.callCount, 0, "Did not call jQuery.style for non css property" );
117 assert.equal( testElement.testMissing, 10, "Instead, set value on element directly" );
119 jQuery.cssHooks.testMissing = jQuery.noop;
122 defaultHook.set( fakeTween );
123 delete jQuery.cssHooks.testMissing;
125 assert.ok( styleStub.calledWith( testElement, "testMissing", "11px" ),
126 "Presence of cssHooks causes jQuery.style with elem, prop, now+unit" );
127 assert.equal( testElement.testMissing, 10, "And value was unchanged" );
129 stepSpy = jQuery.fx.step.test = this.sandbox.spy();
130 styleStub.resetHistory();
132 fakeTween.prop = "test";
133 defaultHook.set( fakeTween );
134 assert.ok( stepSpy.calledWith( fakeTween ), "Step function called with Tween" );
135 assert.equal( styleStub.callCount, 0, "Did not call jQuery.style" );
138 QUnit.test( "jQuery.Tween - Plain Object", function( assert ) {
140 var testObject = { test: 100 },
141 testOptions = { duration: 100 },
144 tween = jQuery.Tween( testObject, testOptions, "test", 0, "linear" );
145 assert.equal( tween.elem, testObject, "Sets .element" );
146 assert.equal( tween.options, testOptions, "sets .options" );
147 assert.equal( tween.prop, "test", "sets .prop" );
148 assert.equal( tween.end, 0, "sets .end" );
150 assert.equal( tween.easing, "linear", "sets .easing when provided" );
152 assert.equal( tween.start, 100, "Reads .start value during construction" );
153 assert.equal( tween.now, 100, "Reads .now value during construction" );
155 easingSpy = this.sandbox.spy( jQuery.easing, "linear" );
157 assert.equal( tween.run( 0.1 ), tween, ".run() returns this" );
159 assert.equal( tween.now, 90, "Calculated tween" );
161 assert.ok( easingSpy.calledWith( 0.1, 0.1 * testOptions.duration, 0, 1, testOptions.duration ),
162 "...using jQuery.easing.linear with back-compat arguments" );
163 assert.equal( testObject.test, 90, "Set value" );
166 assert.equal( testObject.test, 0, "Checking another value" );
169 assert.equal( testObject.test, 100, "Can even go back in time" );
172 QUnit.test( "jQuery.Tween - Element", function( assert ) {
174 var testElement = jQuery( "<div>" ).css( "height", 100 )[ 0 ],
175 testOptions = { duration: 100 },
176 tween, easingSpy, eased;
178 tween = jQuery.Tween( testElement, testOptions, "height", 0 );
179 assert.equal( tween.elem, testElement, "Sets .element" );
180 assert.equal( tween.options, testOptions, "sets .options" );
181 assert.equal( tween.prop, "height", "sets .prop" );
182 assert.equal( tween.end, 0, "sets .end" );
186 jQuery.easing._default,
187 "sets .easing to default when not provided"
189 assert.equal( tween.unit, "px", "sets .unit to px when not provided" );
191 assert.equal( tween.start, 100, "Reads .start value during construction" );
192 assert.equal( tween.now, 100, "Reads .now value during construction" );
194 easingSpy = this.sandbox.spy( jQuery.easing, "swing" );
196 assert.equal( tween.run( 0.1 ), tween, ".run() returns this" );
197 assert.equal( tween.pos, jQuery.easing.swing( 0.1 ), "set .pos" );
198 eased = 100 - ( jQuery.easing.swing( 0.1 ) * 100 );
199 assert.equal( tween.now, eased, "Calculated tween" );
202 easingSpy.calledWith( 0.1, 0.1 * testOptions.duration, 0, 1, testOptions.duration ),
203 "...using jQuery.easing.linear with back-compat arguments"
206 parseFloat( testElement.style.height ).toFixed( 2 ),
207 eased.toFixed( 2 ), "Set value"
211 assert.equal( testElement.style.height, "0px", "Checking another value" );
214 assert.equal( testElement.style.height, "100px", "Can even go back in time" );
217 QUnit.test( "jQuery.Tween - No duration", function( assert ) {
220 var testObject = { test: 100 },
221 testOptions = { duration: 0 },
224 tween = jQuery.Tween( testObject, testOptions, "test", 0 );
225 easingSpy = this.sandbox.spy( jQuery.easing, "swing" );
228 assert.equal( tween.pos, 0.5, "set .pos correctly" );
229 assert.equal( testObject.test, 50, "set value on object correctly" );
230 assert.equal( easingSpy.callCount, 0, "didn't ease the value" );
233 QUnit.test( "jQuery.Tween - step function option", function( assert ) {
236 var testObject = { test: 100 },
237 testOptions = { duration: 100, step: this.sandbox.spy() },
240 propHookSpy = this.sandbox.spy( jQuery.Tween.propHooks._default, "set" );
242 tween = jQuery.Tween( testObject, testOptions, "test", 0, "linear" );
243 assert.equal( testOptions.step.callCount, 0, "didn't call step on create" );
247 testOptions.step.calledOn( testObject ),
248 "Called step function in context of animated object"
251 testOptions.step.calledWith( 50, tween ),
252 "Called step function with correct parameters"
255 testOptions.step.calledBefore( propHookSpy ),
256 "Called step function before calling propHook.set"
261 QUnit.test( "jQuery.Tween - custom propHooks", function( assert ) {
265 testOptions = { duration: 100, step: this.sandbox.spy() },
267 get: sinon.stub().returns( 100 ),
272 jQuery.Tween.propHooks.testHooked = propHook;
274 tween = jQuery.Tween( testObject, testOptions, "testHooked", 0, "linear" );
275 assert.ok( propHook.get.calledWith( tween ), "called propHook.get on create" );
276 assert.equal( tween.now, 100, "Used return value from propHook.get" );
280 propHook.set.calledWith( tween ),
281 "Called propHook.set function with correct parameters"
284 delete jQuery.Tween.propHooks.testHooked;
287 QUnit.test( "jQuery.Tween - custom propHooks - advanced values", function( assert ) {
291 testOptions = { duration: 100, step: this.sandbox.spy() },
293 get: sinon.stub().returns( [ 0, 0 ] ),
298 jQuery.Tween.propHooks.testHooked = propHook;
300 tween = jQuery.Tween( testObject, testOptions, "testHooked", [ 1, 1 ], "linear" );
301 assert.ok( propHook.get.calledWith( tween ), "called propHook.get on create" );
302 assert.deepEqual( tween.start, [ 0, 0 ], "Used return value from get" );
306 // Some day this NaN assumption might change - perhaps add a "calc" helper to the hooks?
307 assert.ok( isNaN( tween.now ), "Used return value from propHook.get" );
308 assert.equal( tween.pos, 0.5, "But the eased percent is still available" );
310 propHook.set.calledWith( tween ),
311 "Called propHook.set function with correct parameters"
314 delete jQuery.Tween.propHooks.testHooked;