corrade-http-templates – Blame information for rev 62

Subversion Repositories:
Rev:
Rev Author Line No. Line
62 office 1 define( [
2 "qunit",
3 "jquery",
4 "lib/common",
5 "ui/widget"
6 ], function( QUnit, $, common ) {
7  
8 QUnit.module( "widget factory", {
9 afterEach: function() {
10 if ( $.ui ) {
11 delete $.ui.testWidget;
12 delete $.fn.testWidget;
13 }
14 }
15 } );
16  
17 common.testJshint( "widget" );
18  
19 QUnit.test( "widget creation", function( assert ) {
20 assert.expect( 5 );
21 var method,
22 myPrototype = {
23 _create: function() {
24 assert.equal( method, "_create", "create function is copied over" );
25 },
26 creationTest: function() {
27 assert.equal( method, "creationTest", "random function is copied over" );
28 }
29 };
30  
31 $.widget( "ui.testWidget", myPrototype );
32 assert.ok( $.isFunction( $.ui.testWidget ), "constructor was created" );
33 assert.equal( typeof $.ui.testWidget.prototype, "object", "prototype was created" );
34 method = "_create";
35 $.ui.testWidget.prototype._create();
36 method = "creationTest";
37 $.ui.testWidget.prototype.creationTest();
38 assert.equal( $.ui.testWidget.prototype.option, $.Widget.prototype.option,
39 "option method copied over from base widget" );
40 } );
41  
42 QUnit.test( "element normalization", function( assert ) {
43 assert.expect( 11 );
44 var elem;
45 $.widget( "ui.testWidget", {} );
46  
47 $.ui.testWidget.prototype._create = function() {
48  
49 // Workaround for core ticket #8381
50 this.element.appendTo( "#qunit-fixture" );
51 assert.ok( this.element.is( "div" ), "generated div" );
52 assert.deepEqual( this.element.testWidget( "instance" ), this, "instance stored in .data()" );
53 };
54 $.ui.testWidget();
55  
56 $.ui.testWidget.prototype.defaultElement = "<span data-test='pass'></span>";
57 $.ui.testWidget.prototype._create = function() {
58 assert.ok( this.element.is( "span[data-test=pass]" ), "generated span with properties" );
59 assert.deepEqual( this.element.testWidget( "instance" ), this, "instance stored in .data()" );
60 };
61 $.ui.testWidget();
62  
63 elem = $( "<input>" );
64 $.ui.testWidget.prototype._create = function() {
65 assert.deepEqual( this.element[ 0 ], elem[ 0 ], "from element" );
66 assert.deepEqual( elem.testWidget( "instance" ), this, "instance stored in .data()" );
67 };
68 $.ui.testWidget( {}, elem[ 0 ] );
69  
70 elem = $( "<div>" );
71 $.ui.testWidget.prototype._create = function() {
72 assert.deepEqual( this.element[ 0 ], elem[ 0 ], "from jQuery object" );
73 assert.deepEqual( elem.testWidget( "instance" ), this, "instance stored in .data()" );
74 };
75 $.ui.testWidget( {}, elem );
76  
77 elem = $( "<div id='element-normalization-selector'></div>" )
78 .appendTo( "#qunit-fixture" );
79 $.ui.testWidget.prototype._create = function() {
80 assert.deepEqual( this.element[ 0 ], elem[ 0 ], "from selector" );
81 assert.deepEqual( elem.testWidget( "instance" ), this, "instance stored in .data()" );
82 };
83 $.ui.testWidget( {}, "#element-normalization-selector" );
84  
85 $.ui.testWidget.prototype.defaultElement = null;
86 $.ui.testWidget.prototype._create = function() {
87  
88 // Using strictEqual throws an error (Maximum call stack size exceeded)
89 assert.ok( this.element[ 0 ] === this, "instance as element" );
90 };
91 $.ui.testWidget();
92 } );
93  
94 QUnit.test( "custom selector expression", function( assert ) {
95 assert.expect( 1 );
96 var elem = $( "<div>" ).appendTo( "#qunit-fixture" );
97 $.widget( "ui.testWidget", {} );
98 elem.testWidget();
99 assert.deepEqual( $( ":ui-testwidget" )[ 0 ], elem[ 0 ] );
100 elem.testWidget( "destroy" );
101 } );
102  
103 QUnit.test( "jQuery usage", function( assert ) {
104 assert.expect( 14 );
105  
106 var elem, instance, ret,
107 shouldCreate = false;
108  
109 $.widget( "ui.testWidget", {
110 getterSetterVal: 5,
111 _create: function() {
112 assert.ok( shouldCreate, "create called on instantiation" );
113 },
114 methodWithParams: function( param1, param2 ) {
115 assert.ok( true, "method called via .pluginName(methodName)" );
116 assert.equal( param1, "value1",
117 "parameter passed via .pluginName(methodName, param)" );
118 assert.equal( param2, "value2",
119 "multiple parameters passed via .pluginName(methodName, param, param)" );
120  
121 return this;
122 },
123 getterSetterMethod: function( val ) {
124 if ( val ) {
125 this.getterSetterVal = val;
126 } else {
127 return this.getterSetterVal;
128 }
129 },
130 jQueryObject: function() {
131 return $( "body" );
132 }
133 } );
134  
135 shouldCreate = true;
136 elem = $( "<div>" )
137 .on( "testwidgetcreate", function() {
138 assert.ok( shouldCreate, "create event triggered on instantiation" );
139 } )
140 .testWidget();
141 shouldCreate = false;
142  
143 instance = elem.testWidget( "instance" );
144 assert.equal( typeof instance, "object", "instance stored in .data(pluginName)" );
145 assert.equal( instance.element[ 0 ], elem[ 0 ], "element stored on widget" );
146 ret = elem.testWidget( "methodWithParams", "value1", "value2" );
147 assert.equal( ret, elem, "jQuery object returned from method call" );
148  
149 ret = elem.testWidget( "getterSetterMethod" );
150 assert.equal( ret, 5, "getter/setter can act as getter" );
151 ret = elem.testWidget( "getterSetterMethod", 30 );
152 assert.equal( ret, elem, "getter/setter method can be chainable" );
153 assert.equal( instance.getterSetterVal, 30, "getter/setter can act as setter" );
154 ret = elem.testWidget( "jQueryObject" );
155 assert.equal( ret[ 0 ], document.body, "returned jQuery object" );
156 assert.equal( ret.end(), elem, "stack preserved" );
157  
158 elem.testWidget( "destroy" );
159 assert.equal( elem.testWidget( "instance" ), null );
160 } );
161  
162 QUnit.test( "direct usage", function( assert ) {
163 assert.expect( 9 );
164  
165 var elem, instance, ret,
166 shouldCreate = false;
167  
168 $.widget( "ui.testWidget", {
169 getterSetterVal: 5,
170 _create: function() {
171 assert.ok( shouldCreate, "create called on instantiation" );
172 },
173 methodWithParams: function( param1, param2 ) {
174 assert.ok( true, "method called dirctly" );
175 assert.equal( param1, "value1", "parameter passed via direct call" );
176 assert.equal( param2, "value2", "multiple parameters passed via direct call" );
177  
178 return this;
179 },
180 getterSetterMethod: function( val ) {
181 if ( val ) {
182 this.getterSetterVal = val;
183 } else {
184 return this.getterSetterVal;
185 }
186 }
187 } );
188  
189 elem = $( "<div>" )[ 0 ];
190  
191 shouldCreate = true;
192 instance = new $.ui.testWidget( {}, elem );
193 shouldCreate = false;
194  
195 assert.equal( $( elem ).testWidget( "instance" ), instance,
196 "instance stored in .data(pluginName)" );
197 assert.equal( instance.element[ 0 ], elem, "element stored on widget" );
198  
199 ret = instance.methodWithParams( "value1", "value2" );
200 assert.equal( ret, instance, "plugin returned from method call" );
201  
202 ret = instance.getterSetterMethod();
203 assert.equal( ret, 5, "getter/setter can act as getter" );
204 instance.getterSetterMethod( 30 );
205 assert.equal( instance.getterSetterVal, 30, "getter/setter can act as setter" );
206 } );
207  
208 QUnit.test( "error handling", function( assert ) {
209 assert.expect( 3 );
210 var error = $.error;
211 $.widget( "ui.testWidget", {
212 _privateMethod: function() {}
213 } );
214 $.error = function( msg ) {
215 assert.equal( msg, "cannot call methods on testWidget prior to initialization; " +
216 "attempted to call method 'missing'", "method call before init" );
217 };
218 $( "<div>" ).testWidget( "missing" );
219 $.error = function( msg ) {
220 assert.equal( msg, "no such method 'missing' for testWidget widget instance",
221 "invalid method call on widget instance" );
222 };
223 $( "<div>" ).testWidget().testWidget( "missing" );
224 $.error = function( msg ) {
225 assert.equal( msg, "no such method '_privateMethod' for testWidget widget instance",
226 "invalid method call on widget instance" );
227 };
228 $( "<div>" ).testWidget().testWidget( "_privateMethod" );
229 $.error = error;
230 } );
231  
232 QUnit.test( "merge multiple option arguments", function( assert ) {
233 assert.expect( 1 );
234 $.widget( "ui.testWidget", {
235 _create: function() {
236 assert.deepEqual( this.options, {
237 classes: {},
238 create: null,
239 disabled: false,
240 option1: "value1",
241 option2: "value2",
242 option3: "value3",
243 option4: {
244 option4a: "valuea",
245 option4b: "valueb"
246 }
247 } );
248 }
249 } );
250 $( "<div>" ).testWidget( {
251 option1: "valuex",
252 option2: "valuex",
253 option3: "value3",
254 option4: {
255 option4a: "valuex"
256 }
257 }, {
258 option1: "value1",
259 option2: "value2",
260 option4: {
261 option4b: "valueb"
262 }
263 }, {
264 option4: {
265 option4a: "valuea"
266 }
267 } );
268 } );
269  
270 QUnit.test( "._getCreateOptions()", function( assert ) {
271 assert.expect( 4 );
272 $.widget( "ui.testWidget", {
273 options: {
274 option1: "valuex",
275 option2: "valuex",
276 option3: "value3"
277 },
278 _getCreateOptions: function() {
279 var superOptions = this._super();
280  
281 assert.deepEqual( superOptions, {}, "Base implementation returns empty object" );
282  
283 // Support: IE8
284 // Strict equality fails when comparing this.window in ie8
285 assert.equal( this.window[ 0 ], window, "this.window is properly defined" );
286 assert.strictEqual( this.document[ 0 ], document, "this.document is properly defined" );
287  
288 return {
289 option1: "override1",
290 option2: "overideX"
291 };
292 },
293 _create: function() {
294 assert.deepEqual( this.options, {
295 classes: {},
296 create: null,
297 disabled: false,
298 option1: "override1",
299 option2: "value2",
300 option3: "value3"
301 } );
302 }
303 } );
304 $( "<div>" ).testWidget( { option2: "value2" } );
305 } );
306  
307 QUnit.test( "._getCreateEventData()", function( assert ) {
308 assert.expect( 1 );
309 var data = { foo: "bar" };
310 $.widget( "ui.testWidget", {
311 _getCreateEventData: function() {
312 return data;
313 }
314 } );
315 $( "<div>" ).testWidget( {
316 create: function( event, ui ) {
317 assert.strictEqual( ui, data, "event data" );
318 }
319 } );
320 } );
321  
322 QUnit.test( "re-init", function( assert ) {
323 assert.expect( 3 );
324 var div = $( "<div>" ),
325 actions = [];
326  
327 $.widget( "ui.testWidget", {
328 _create: function() {
329 actions.push( "create" );
330 },
331 _init: function() {
332 actions.push( "init" );
333 },
334 _setOption: function( key ) {
335 actions.push( "option" + key );
336 }
337 } );
338  
339 actions = [];
340 div.testWidget( { foo: "bar" } );
341 assert.deepEqual( actions, [ "create", "init" ], "correct methods called on init" );
342  
343 actions = [];
344 div.testWidget();
345 assert.deepEqual( actions, [ "init" ], "correct methods call on re-init" );
346  
347 actions = [];
348 div.testWidget( { foo: "bar" } );
349 assert.deepEqual( actions, [ "optionfoo", "init" ], "correct methods called on re-init with options" );
350 } );
351  
352 QUnit.test( "redeclare", function( assert ) {
353 assert.expect( 2 );
354  
355 $.widget( "ui.testWidget", {} );
356 assert.equal( $.ui.testWidget.prototype.widgetEventPrefix, "testWidget" );
357  
358 $.widget( "ui.testWidget", {} );
359 assert.equal( $.ui.testWidget.prototype.widgetEventPrefix, "testWidget" );
360 } );
361  
362 QUnit.test( "inheritance", function( assert ) {
363 assert.expect( 6 );
364  
365 // #5830 - Widget: Using inheritance overwrites the base classes options
366 $.widget( "ui.testWidgetBase", {
367 options: {
368 obj: {
369 key1: "foo",
370 key2: "bar"
371 },
372 arr: [ "testing" ]
373 }
374 } );
375  
376 $.widget( "ui.testWidgetExtension", $.ui.testWidgetBase, {
377 options: {
378 obj: {
379 key1: "baz"
380 },
381 arr: [ "alpha", "beta" ]
382 }
383 } );
384  
385 assert.equal( $.ui.testWidgetBase.prototype.widgetEventPrefix, "testWidgetBase",
386 "base class event prefix" );
387 assert.deepEqual( $.ui.testWidgetBase.prototype.options.obj, {
388 key1: "foo",
389 key2: "bar"
390 }, "base class option object not overridden" );
391 assert.deepEqual( $.ui.testWidgetBase.prototype.options.arr, [ "testing" ],
392 "base class option array not overridden" );
393  
394 assert.equal( $.ui.testWidgetExtension.prototype.widgetEventPrefix, "testWidgetExtension",
395 "extension class event prefix" );
396 assert.deepEqual( $.ui.testWidgetExtension.prototype.options.obj, {
397 key1: "baz",
398 key2: "bar"
399 }, "extension class option object extends base" );
400 assert.deepEqual( $.ui.testWidgetExtension.prototype.options.arr, [ "alpha", "beta" ],
401 "extension class option array overwrites base" );
402  
403 delete $.ui.testWidgetBase;
404 delete $.fn.testWidgetBase;
405 delete $.ui.testWidgetExtension;
406 delete $.fn.testWidgetExtension;
407 } );
408  
409 QUnit.test( "._super()", function( assert ) {
410 assert.expect( 9 );
411 var instance;
412 $.widget( "ui.testWidget", {
413 method: function( a, b ) {
414 assert.deepEqual( this, instance, "this is correct in testWidget" );
415 assert.deepEqual( a, 5, "parameter passed to testWidget" );
416 assert.deepEqual( b, 20, "second parameter passed to testWidget" );
417 return a + b;
418 }
419 } );
420  
421 $.widget( "ui.testWidget2", $.ui.testWidget, {
422 method: function( a, b ) {
423 assert.deepEqual( this, instance, "this is correct in testWidget2" );
424 assert.deepEqual( a, 5, "parameter passed to testWidget2" );
425 assert.deepEqual( b, 10, "parameter passed to testWidget2" );
426 return this._super( a, b * 2 );
427 }
428 } );
429  
430 $.widget( "ui.testWidget3", $.ui.testWidget2, {
431 method: function( a ) {
432 assert.deepEqual( this, instance, "this is correct in testWidget3" );
433 assert.deepEqual( a, 5, "parameter passed to testWidget3" );
434 var ret = this._super( a, a * 2 );
435 assert.deepEqual( ret, 25, "super returned value" );
436 }
437 } );
438  
439 instance = $( "<div>" ).testWidget3().testWidget3( "instance" );
440 instance.method( 5 );
441 delete $.ui.testWidget3;
442 delete $.fn.testWidget3;
443 delete $.ui.testWidget2;
444 delete $.fn.testWidget2;
445 } );
446  
447 QUnit.test( "._superApply()", function( assert ) {
448 assert.expect( 10 );
449 var instance;
450 $.widget( "ui.testWidget", {
451 method: function( a, b ) {
452 assert.deepEqual( this, instance, "this is correct in testWidget" );
453 assert.deepEqual( a, 5, "parameter passed to testWidget" );
454 assert.deepEqual( b, 10, "second parameter passed to testWidget" );
455 return a + b;
456 }
457 } );
458  
459 $.widget( "ui.testWidget2", $.ui.testWidget, {
460 method: function( a, b ) {
461 assert.deepEqual( this, instance, "this is correct in testWidget2" );
462 assert.deepEqual( a, 5, "parameter passed to testWidget2" );
463 assert.deepEqual( b, 10, "second parameter passed to testWidget2" );
464 return this._superApply( arguments );
465 }
466 } );
467  
468 $.widget( "ui.testWidget3", $.ui.testWidget2, {
469 method: function( a, b ) {
470 assert.deepEqual( this, instance, "this is correct in testWidget3" );
471 assert.deepEqual( a, 5, "parameter passed to testWidget3" );
472 assert.deepEqual( b, 10, "second parameter passed to testWidget3" );
473 var ret = this._superApply( arguments );
474 assert.deepEqual( ret, 15, "super returned value" );
475 }
476 } );
477  
478 instance = $( "<div>" ).testWidget3().testWidget3( "instance" );
479 instance.method( 5, 10 );
480 delete $.ui.testWidget3;
481 delete $.fn.testWidget3;
482 delete $.ui.testWidget2;
483 delete $.fn.testWidget2;
484 } );
485  
486 QUnit.test( "mixins", function( assert ) {
487 assert.expect( 5 );
488  
489 var mixin1 = {
490 foo: function() {
491 assert.equal( method, "foo", "Methods from first mixin are copied over" );
492 }
493 };
494 var mixin2 = {
495 bar: function() {
496 assert.equal( method, "bar", "Methods from second mixin are copied over" );
497 }
498 };
499 var prototype = {
500 baz: function() {
501 assert.equal( method, "baz", "Methods from protoype are copied over" );
502 }
503 };
504 var existingBar = mixin2.bar;
505 var method;
506  
507 $.widget( "ui.testWidget", [ mixin1, mixin2, prototype ] );
508 method = "foo";
509 $.ui.testWidget.prototype.foo();
510 method = "bar";
511 $.ui.testWidget.prototype.bar();
512 method = "baz";
513 $.ui.testWidget.prototype.baz();
514  
515 mixin1.foo = function() {
516 assert.ok( false, "Changes to a mixin don't change the prototype" );
517 };
518 method = "foo";
519 $.ui.testWidget.prototype.foo();
520  
521 $.ui.testWidget.prototype.bar = function() {};
522 assert.strictEqual( mixin2.bar, existingBar, "Changes to a prototype don't change the mixin" );
523 } );
524  
525 QUnit.test( "mixins with inheritance", function( assert ) {
526 assert.expect( 4 );
527  
528 var mixin1 = {
529 foo: function() {
530 assert.equal( method, "foo", "Methods from first mixin are copied over" );
531 }
532 };
533 var mixin2 = {
534 bar: function() {
535 assert.equal( method, "bar", "Methods from second mixin are copied over" );
536 }
537 };
538 var parentPrototype = {
539 baz: function() {
540 assert.equal( method, "baz", "Methods from parent protoype are copied over" );
541 }
542 };
543 var childPrototype = {
544 qux: function() {
545 assert.equal( method, "qux", "Methods from child protoype are copied over" );
546 }
547 };
548 var method;
549  
550 $.widget( "ui.testWidget", [ mixin1, parentPrototype ] );
551 $.widget( "ui.testWidget2", $.ui.testWidget, [ mixin2, childPrototype ] );
552 method = "foo";
553 $.ui.testWidget2.prototype.foo();
554 method = "bar";
555 $.ui.testWidget2.prototype.bar();
556 method = "baz";
557 $.ui.testWidget2.prototype.baz();
558 method = "qux";
559 $.ui.testWidget2.prototype.qux();
560  
561 delete $.ui.testWidget2;
562 delete $.fn.testWidget2;
563 } );
564  
565 QUnit.test( ".option() - getter", function( assert ) {
566 assert.expect( 6 );
567 $.widget( "ui.testWidget", {
568 _create: function() {}
569 } );
570  
571 var options,
572 div = $( "<div>" ).testWidget( {
573 foo: "bar",
574 baz: 5,
575 qux: [ "quux", "quuux" ]
576 } );
577  
578 assert.deepEqual( div.testWidget( "option", "x" ), null, "non-existent option" );
579 assert.deepEqual( div.testWidget( "option", "foo" ), "bar", "single option - string" );
580 assert.deepEqual( div.testWidget( "option", "baz" ), 5, "single option - number" );
581 assert.deepEqual( div.testWidget( "option", "qux" ), [ "quux", "quuux" ],
582 "single option - array" );
583  
584 options = div.testWidget( "option" );
585 assert.deepEqual( options, {
586 baz: 5,
587 classes: {},
588 create: null,
589 disabled: false,
590 foo: "bar",
591 qux: [ "quux", "quuux" ]
592 }, "full options hash returned" );
593 options.foo = "notbar";
594 assert.deepEqual( div.testWidget( "option", "foo" ), "bar",
595 "modifying returned options hash does not modify plugin instance" );
596 } );
597  
598 QUnit.test( ".option() - deep option getter", function( assert ) {
599 assert.expect( 5 );
600 $.widget( "ui.testWidget", {} );
601 var div = $( "<div>" ).testWidget( {
602 foo: {
603 bar: "baz",
604 qux: {
605 quux: "xyzzy"
606 }
607 }
608 } );
609 assert.equal( div.testWidget( "option", "foo.bar" ), "baz", "one level deep - string" );
610 assert.deepEqual( div.testWidget( "option", "foo.qux" ), { quux: "xyzzy" },
611 "one level deep - object" );
612 assert.equal( div.testWidget( "option", "foo.qux.quux" ), "xyzzy", "two levels deep - string" );
613 assert.equal( div.testWidget( "option", "x.y" ), null, "top level non-existent" );
614 assert.equal( div.testWidget( "option", "foo.x.y" ), null, "one level deep - non-existent" );
615 } );
616  
617 QUnit.test( ".option() - delegate to ._setOptions()", function( assert ) {
618 assert.expect( 2 );
619 var div,
620 calls = [];
621 $.widget( "ui.testWidget", {
622 _create: function() {},
623 _setOptions: function( options ) {
624 calls.push( options );
625 }
626 } );
627 div = $( "<div>" ).testWidget();
628  
629 calls = [];
630 div.testWidget( "option", "foo", "bar" );
631 assert.deepEqual( calls, [ { foo: "bar" } ], "_setOptions called for single option" );
632  
633 calls = [];
634 div.testWidget( "option", {
635 bar: "qux",
636 quux: "quuux"
637 } );
638 assert.deepEqual( calls, [ { bar: "qux", quux: "quuux" } ],
639 "_setOptions called with multiple options" );
640 } );
641  
642 QUnit.test( ".option() - delegate to ._setOption()", function( assert ) {
643 assert.expect( 3 );
644 var div,
645 calls = [];
646 $.widget( "ui.testWidget", {
647 _create: function() {},
648 _setOption: function( key, val ) {
649 calls.push( {
650 key: key,
651 val: val
652 } );
653 }
654 } );
655 div = $( "<div>" ).testWidget();
656  
657 calls = [];
658 div.testWidget( "option", "foo", "bar" );
659 assert.deepEqual( calls, [ { key: "foo", val: "bar" } ],
660 "_setOption called for single option" );
661  
662 calls = [];
663 div.testWidget( "option", "foo", undefined );
664 assert.deepEqual( calls, [ { key: "foo", val: undefined } ],
665 "_setOption called for single option where value is undefined" );
666  
667 calls = [];
668 div.testWidget( "option", {
669 bar: "qux",
670 quux: "quuux"
671 } );
672 assert.deepEqual( calls, [
673 { key: "bar", val: "qux" },
674 { key: "quux", val: "quuux" }
675 ], "_setOption called with multiple options" );
676 } );
677  
678 QUnit.test( ".option() - deep option setter", function( assert ) {
679 assert.expect( 9 );
680 $.widget( "ui.testWidget", {} );
681 var result, div = $( "<div>" ).testWidget();
682 function deepOption( from, to, msg ) {
683 div.testWidget( "instance" ).options.foo = from;
684 $.ui.testWidget.prototype._setOption = function( key, value ) {
685 assert.deepEqual( key, "foo", msg + ": key" );
686 assert.deepEqual( value, to, msg + ": value" );
687 };
688 }
689  
690 deepOption( { bar: "baz" }, { bar: "qux" }, "one deep" );
691 div.testWidget( "option", "foo.bar", "qux" );
692  
693 deepOption( { bar: "baz" }, { bar: undefined }, "one deep - value = undefined" );
694  
695 result = div.testWidget( "option", "foo.bar", undefined );
696  
697 assert.deepEqual( result, div, "option should return widget on successful set operation" );
698  
699 deepOption( null, { bar: "baz" }, "null" );
700 div.testWidget( "option", "foo.bar", "baz" );
701  
702 deepOption(
703 { bar: "baz", qux: { quux: "quuux" } },
704 { bar: "baz", qux: { quux: "quuux", newOpt: "newVal" } },
705 "add property" );
706 div.testWidget( "option", "foo.qux.newOpt", "newVal" );
707 } );
708  
709 QUnit.test( ".enable()", function( assert ) {
710 assert.expect( 2 );
711 $.widget( "ui.testWidget", {
712 _create: function() {},
713 _setOption: function( key, val ) {
714 assert.deepEqual( key, "disabled", "_setOption called with disabled option" );
715 assert.deepEqual( val, false, "disabled set to false" );
716 }
717 } );
718 $( "<div>" ).testWidget().testWidget( "enable" );
719 } );
720  
721 QUnit.test( ".disable()", function( assert ) {
722 assert.expect( 2 );
723 $.widget( "ui.testWidget", {
724 _create: function() {},
725 _setOption: function( key, val ) {
726 assert.deepEqual( key, "disabled", "_setOption called with disabled option" );
727 assert.deepEqual( val, true, "disabled set to true" );
728 }
729 } );
730 $( "<div>" ).testWidget().testWidget( "disable" );
731 } );
732  
733 QUnit.test( "._setOptionDisabled()", function( assert ) {
734 assert.expect( 3 );
735  
736 var method;
737 var widget;
738  
739 $.widget( "ui.testWidget", {
740 _setOptionDisabled: function( value ) {
741 method( value );
742 }
743 } );
744  
745 method = function() {
746 assert.ok( false, "._setOptionDisabled() called on init when not disabled" );
747 };
748 $( "<div>" ).testWidget();
749  
750 method = function( value ) {
751 assert.strictEqual( value, true, "._setOptionDisabled called on init when disabled" );
752 };
753 widget = $( "<div>" ).testWidget( { disabled: true } );
754  
755 method = function( value ) {
756 assert.strictEqual( value, false, "._setOptionDisabled called when enabling" );
757 };
758 widget.testWidget( "enable" );
759  
760 method = function( value ) {
761 assert.strictEqual( value, true, "._setOptionDisabled called when disabling" );
762 };
763 widget.testWidget( "option", "disabled", true );
764 } );
765  
766 QUnit.test( ".widget() - base", function( assert ) {
767 assert.expect( 2 );
768 var constructor = $.widget( "ui.testWidget", {
769 _create: function() {}
770 } ),
771 div = $( "<div>" ).testWidget();
772 assert.deepEqual( div[ 0 ], div.testWidget( "widget" )[ 0 ] );
773 assert.deepEqual( constructor, $.ui.testWidget, "$.widget returns the constructor" );
774 } );
775  
776 QUnit.test( ".widget() - overriden", function( assert ) {
777 assert.expect( 1 );
778 var wrapper = $( "<div>" );
779 $.widget( "ui.testWidget", {
780 _create: function() {},
781 widget: function() {
782 return wrapper;
783 }
784 } );
785 assert.deepEqual( wrapper[ 0 ], $( "<div>" ).testWidget().testWidget( "widget" )[ 0 ] );
786 } );
787  
788 QUnit.test( ".instance()", function( assert ) {
789 assert.expect( 3 );
790 var div;
791  
792 $.widget( "ui.testWidget", {
793 _create: function() {}
794 } );
795  
796 div = $( "<div>" );
797 assert.equal( div.testWidget( "instance" ), undefined, "uninitialized" );
798 div.testWidget();
799 assert.equal( div.testWidget( "instance" ), div.testWidget( "instance" ), "initialized" );
800  
801 assert.equal( $().testWidget( "instance" ), undefined, "empty set" );
802 } );
803  
804 QUnit.test( "._on() to element (default)", function( assert ) {
805 assert.expect( 12 );
806 var that, widget;
807 $.widget( "ui.testWidget", {
808 _create: function() {
809 that = this;
810 this._on( {
811 keyup: this.keyup,
812 keydown: "keydown"
813 } );
814 },
815 keyup: function( event ) {
816 assert.equal( that, this );
817 assert.equal( that.element[ 0 ], event.currentTarget );
818 assert.equal( "keyup", event.type );
819 },
820 keydown: function( event ) {
821 assert.equal( that, this );
822 assert.equal( that.element[ 0 ], event.currentTarget );
823 assert.equal( "keydown", event.type );
824 }
825 } );
826 widget = $( "<div></div>" )
827 .testWidget()
828 .trigger( "keyup" )
829 .trigger( "keydown" );
830 widget
831 .testWidget( "disable" )
832 .trigger( "keyup" )
833 .trigger( "keydown" );
834 widget
835 .testWidget( "enable" )
836 .trigger( "keyup" )
837 .trigger( "keydown" );
838 widget
839 .testWidget( "destroy" )
840 .trigger( "keyup" )
841 .trigger( "keydown" );
842 } );
843  
844 QUnit.test( "._on() to element with suppressDisabledCheck", function( assert ) {
845 assert.expect( 18 );
846 var that, widget;
847 $.widget( "ui.testWidget", {
848 _create: function() {
849 that = this;
850 this._on( true, {
851 keyup: this.keyup,
852 keydown: "keydown"
853 } );
854 },
855 keyup: function( event ) {
856 assert.equal( that, this );
857 assert.equal( that.element[ 0 ], event.currentTarget );
858 assert.equal( "keyup", event.type );
859 },
860 keydown: function( event ) {
861 assert.equal( that, this );
862 assert.equal( that.element[ 0 ], event.currentTarget );
863 assert.equal( "keydown", event.type );
864 }
865 } );
866 widget = $( "<div></div>" )
867 .testWidget()
868 .trigger( "keyup" )
869 .trigger( "keydown" );
870 widget
871 .testWidget( "disable" )
872 .trigger( "keyup" )
873 .trigger( "keydown" );
874 widget
875 .testWidget( "enable" )
876 .trigger( "keyup" )
877 .trigger( "keydown" );
878 widget
879 .testWidget( "destroy" )
880 .trigger( "keyup" )
881 .trigger( "keydown" );
882 } );
883  
884 QUnit.test( "._on() to descendent", function( assert ) {
885 assert.expect( 12 );
886 var that, widget, descendant;
887 $.widget( "ui.testWidget", {
888 _create: function() {
889 that = this;
890 this._on( this.element.find( "strong" ), {
891 keyup: this.keyup,
892 keydown: "keydown"
893 } );
894 },
895 keyup: function( event ) {
896 assert.equal( that, this );
897 assert.equal( that.element.find( "strong" )[ 0 ], event.currentTarget );
898 assert.equal( "keyup", event.type );
899 },
900 keydown: function( event ) {
901 assert.equal( that, this );
902 assert.equal( that.element.find( "strong" )[ 0 ], event.currentTarget );
903 assert.equal( "keydown", event.type );
904 }
905 } );
906  
907 // Trigger events on both widget and descendent to ensure that only descendent receives them
908 widget = $( "<div><p><strong>hello</strong> world</p></div>" )
909 .testWidget()
910 .trigger( "keyup" )
911 .trigger( "keydown" );
912 descendant = widget.find( "strong" )
913 .trigger( "keyup" )
914 .trigger( "keydown" );
915 widget
916 .testWidget( "disable" )
917 .trigger( "keyup" )
918 .trigger( "keydown" );
919 descendant
920 .trigger( "keyup" )
921 .trigger( "keydown" );
922 widget
923 .testWidget( "enable" )
924 .trigger( "keyup" )
925 .trigger( "keydown" );
926 descendant
927 .trigger( "keyup" )
928 .trigger( "keydown" );
929 descendant
930 .addClass( "ui-state-disabled" )
931 .trigger( "keyup" )
932 .trigger( "keydown" );
933 widget
934 .testWidget( "destroy" )
935 .trigger( "keyup" )
936 .trigger( "keydown" );
937 descendant
938 .trigger( "keyup" )
939 .trigger( "keydown" );
940 } );
941  
942 QUnit.test( "_on() with delegate", function( assert ) {
943 assert.expect( 8 );
944 $.widget( "ui.testWidget", {
945 _create: function() {
946 var uuid = this.uuid;
947 this.element = {
948 on: function( event, handler ) {
949 assert.equal( event, "click.testWidget" + uuid );
950 assert.ok( $.isFunction( handler ) );
951 },
952 trigger: $.noop
953 };
954 this.widget = function() {
955 return {
956 on: function( event, selector, handler ) {
957 assert.equal( selector, "a" );
958 assert.equal( event, "click.testWidget" + uuid );
959 assert.ok( $.isFunction( handler ) );
960 }
961 };
962 };
963 this._on( {
964 "click": "handler",
965 "click a": "handler"
966 } );
967 this.widget = function() {
968 return {
969 on: function( event, selector, handler ) {
970 assert.equal( selector, "form fieldset > input" );
971 assert.equal( event, "change.testWidget" + uuid );
972 assert.ok( $.isFunction( handler ) );
973 }
974 };
975 };
976 this._on( {
977 "change form fieldset > input": "handler"
978 } );
979 }
980 } );
981 $.ui.testWidget();
982 } );
983  
984 QUnit.test( "_on() with delegate to descendent", function( assert ) {
985 assert.expect( 4 );
986 $.widget( "ui.testWidget", {
987 _create: function() {
988 this.target = $( "<p><strong>hello</strong> world</p>" );
989 this.child = this.target.children();
990 this._on( this.target, {
991 "keyup": "handlerDirect",
992 "keyup strong": "handlerDelegated"
993 } );
994 this.child.trigger( "keyup" );
995 },
996 handlerDirect: function( event ) {
997 assert.deepEqual( event.currentTarget, this.target[ 0 ] );
998 assert.deepEqual( event.target, this.child[ 0 ] );
999 },
1000 handlerDelegated: function( event ) {
1001 assert.deepEqual( event.currentTarget, this.child[ 0 ] );
1002 assert.deepEqual( event.target, this.child[ 0 ] );
1003 }
1004 } );
1005 $.ui.testWidget();
1006 } );
1007  
1008 QUnit.test( "_on() to common element", function( assert ) {
1009 assert.expect( 4 );
1010 $.widget( "ui.testWidget", {
1011 _create: function() {
1012 this._on( this.document, {
1013 "customevent": "_handler",
1014 "with:colons": "_colonHandler",
1015 "with-dashes": "_dashHandler",
1016 "with-dashes:and-colons": "_commbinedHandler"
1017 } );
1018 },
1019 _handler: function() {
1020 assert.ok( true, "handler triggered" );
1021 },
1022 _colonHandler: function() {
1023 assert.ok( true, "colon handler triggered" );
1024 },
1025 _dashHandler: function() {
1026 assert.ok( true, "dash handler triggered" );
1027 },
1028 _commbinedHandler: function() {
1029 assert.ok( true, "combined handler triggered" );
1030 }
1031 } );
1032 var widget = $( "#widget" ).testWidget().testWidget( "instance" );
1033 $( "#widget-wrapper" ).testWidget();
1034 widget.destroy();
1035 $( document ).trigger( "customevent" );
1036 $( document ).trigger( "with:colons" );
1037 $( document ).trigger( "with-dashes" );
1038 $( document ).trigger( "with-dashes:and-colons" );
1039 } );
1040  
1041 QUnit.test( "_off() - single event", function( assert ) {
1042 assert.expect( 3 );
1043  
1044 $.widget( "ui.testWidget", {} );
1045 var shouldTriggerWidget, shouldTriggerOther,
1046 element = $( "#widget" ),
1047 widget = element.testWidget().testWidget( "instance" );
1048 widget._on( element, { foo: function() {
1049 assert.ok( shouldTriggerWidget, "foo called from _on" );
1050 } } );
1051 element.on( "foo", function() {
1052 assert.ok( shouldTriggerOther, "foo called from bind" );
1053 } );
1054 shouldTriggerWidget = true;
1055 shouldTriggerOther = true;
1056 element.trigger( "foo" );
1057 shouldTriggerWidget = false;
1058 widget._off( element, "foo" );
1059 element.trigger( "foo" );
1060 } );
1061  
1062 QUnit.test( "_off() - multiple events", function( assert ) {
1063 assert.expect( 6 );
1064  
1065 $.widget( "ui.testWidget", {} );
1066 var shouldTriggerWidget, shouldTriggerOther,
1067 element = $( "#widget" ),
1068 widget = element.testWidget().testWidget( "instance" );
1069 widget._on( element, {
1070 foo: function() {
1071 assert.ok( shouldTriggerWidget, "foo called from _on" );
1072 },
1073 bar: function() {
1074 assert.ok( shouldTriggerWidget, "bar called from _on" );
1075 }
1076 } );
1077 element.on( "foo bar", function( event ) {
1078 assert.ok( shouldTriggerOther, event.type + " called from bind" );
1079 } );
1080 shouldTriggerWidget = true;
1081 shouldTriggerOther = true;
1082 element.trigger( "foo" );
1083 element.trigger( "bar" );
1084 shouldTriggerWidget = false;
1085 widget._off( element, "foo bar" );
1086 element.trigger( "foo" );
1087 element.trigger( "bar" );
1088 } );
1089  
1090 QUnit.test( "_off() - all events", function( assert ) {
1091 assert.expect( 6 );
1092  
1093 $.widget( "ui.testWidget", {} );
1094 var shouldTriggerWidget, shouldTriggerOther,
1095 element = $( "#widget" ),
1096 widget = element.testWidget().testWidget( "instance" );
1097 widget._on( element, {
1098 foo: function() {
1099 assert.ok( shouldTriggerWidget, "foo called from _on" );
1100 },
1101 bar: function() {
1102 assert.ok( shouldTriggerWidget, "bar called from _on" );
1103 }
1104 } );
1105 element.on( "foo bar", function( event ) {
1106 assert.ok( shouldTriggerOther, event.type + " called from bind" );
1107 } );
1108 shouldTriggerWidget = true;
1109 shouldTriggerOther = true;
1110 element.trigger( "foo" );
1111 element.trigger( "bar" );
1112 shouldTriggerWidget = false;
1113 widget._off( element );
1114 element.trigger( "foo" );
1115 element.trigger( "bar" );
1116 } );
1117  
1118 QUnit.test( "._hoverable()", function( assert ) {
1119 assert.expect( 10 );
1120 $.widget( "ui.testWidget", {
1121 _create: function() {
1122 this._hoverable( this.element.children() );
1123 }
1124 } );
1125  
1126 var div = $( "#widget" ).testWidget().children();
1127 assert.lacksClasses( div, "ui-state-hover", "not hovered on init" );
1128 div.trigger( "mouseenter" );
1129 assert.hasClasses( div, "ui-state-hover", "hovered after mouseenter" );
1130 div.trigger( "mouseleave" );
1131 assert.lacksClasses( div, "ui-state-hover", "not hovered after mouseleave" );
1132  
1133 div.trigger( "mouseenter" );
1134 assert.hasClasses( div, "ui-state-hover", "hovered after mouseenter" );
1135 $( "#widget" ).testWidget( "disable" );
1136 assert.lacksClasses( div, "ui-state-hover", "not hovered while disabled" );
1137 div.trigger( "mouseenter" );
1138 assert.lacksClasses( div, "ui-state-hover", "can't hover while disabled" );
1139 $( "#widget" ).testWidget( "enable" );
1140 assert.lacksClasses( div, "ui-state-hover", "enabling doesn't reset hover" );
1141  
1142 div.trigger( "mouseenter" );
1143 assert.hasClasses( div, "ui-state-hover", "hovered after mouseenter" );
1144 $( "#widget" ).testWidget( "destroy" );
1145 assert.lacksClasses( div, "ui-state-hover", "not hovered after destroy" );
1146 div.trigger( "mouseenter" );
1147 assert.lacksClasses( div, "ui-state-hover", "event handler removed on destroy" );
1148 } );
1149  
1150 QUnit.test( "._focusable()", function( assert ) {
1151 assert.expect( 10 );
1152 $.widget( "ui.testWidget", {
1153 _create: function() {
1154 this._focusable( this.element.children() );
1155 }
1156 } );
1157  
1158 var div = $( "#widget" ).testWidget().children();
1159 assert.lacksClasses( div, "ui-state-focus", "not focused on init" );
1160 div.trigger( "focusin" );
1161 assert.hasClasses( div, "ui-state-focus", "focused after explicit focus" );
1162 div.trigger( "focusout" );
1163 assert.lacksClasses( div, "ui-state-focus", "not focused after blur" );
1164  
1165 div.trigger( "focusin" );
1166 assert.hasClasses( div, "ui-state-focus", "focused after explicit focus" );
1167 $( "#widget" ).testWidget( "disable" );
1168 assert.lacksClasses( div, "ui-state-focus", "not focused while disabled" );
1169 div.trigger( "focusin" );
1170 assert.lacksClasses( div, "ui-state-focus", "can't focus while disabled" );
1171 $( "#widget" ).testWidget( "enable" );
1172 assert.lacksClasses( div, "ui-state-focus", "enabling doesn't reset focus" );
1173  
1174 div.trigger( "focusin" );
1175 assert.hasClasses( div, "ui-state-focus", "focused after explicit focus" );
1176 $( "#widget" ).testWidget( "destroy" );
1177 assert.lacksClasses( div, "ui-state-focus", "not focused after destroy" );
1178 div.trigger( "focusin" );
1179 assert.lacksClasses( div, "ui-state-focus", "event handler removed on destroy" );
1180 } );
1181  
1182 QUnit.test( "._trigger() - no event, no ui", function( assert ) {
1183 assert.expect( 7 );
1184 var handlers = [];
1185  
1186 $.widget( "ui.testWidget", {
1187 _create: function() {}
1188 } );
1189  
1190 $( "#widget" ).testWidget( {
1191 foo: function( event, ui ) {
1192 assert.deepEqual( event.type, "testwidgetfoo", "correct event type in callback" );
1193 assert.deepEqual( ui, {}, "empty ui hash passed" );
1194 handlers.push( "callback" );
1195 }
1196 } );
1197 $( document ).add( "#widget-wrapper" ).add( "#widget" )
1198 .on( "testwidgetfoo", function( event, ui ) {
1199 assert.deepEqual( ui, {}, "empty ui hash passed" );
1200 handlers.push( this );
1201 } );
1202 assert.deepEqual( $( "#widget" ).testWidget( "instance" )._trigger( "foo" ), true,
1203 "_trigger returns true when event is not cancelled" );
1204 assert.deepEqual( handlers, [
1205 $( "#widget" )[ 0 ],
1206 $( "#widget-wrapper" )[ 0 ],
1207 document,
1208 "callback"
1209 ], "event bubbles and then invokes callback" );
1210  
1211 $( document ).off( "testwidgetfoo" );
1212 } );
1213  
1214 QUnit.test( "._trigger() - cancelled event", function( assert ) {
1215 assert.expect( 3 );
1216  
1217 $.widget( "ui.testWidget", {
1218 _create: function() {}
1219 } );
1220  
1221 $( "#widget" ).testWidget( {
1222 foo: function() {
1223 assert.ok( true, "callback invoked even if event is cancelled" );
1224 }
1225 } )
1226 .on( "testwidgetfoo", function() {
1227 assert.ok( true, "event was triggered" );
1228 return false;
1229 } );
1230 assert.deepEqual( $( "#widget" ).testWidget( "instance" )._trigger( "foo" ), false,
1231 "_trigger returns false when event is cancelled" );
1232 } );
1233  
1234 QUnit.test( "._trigger() - cancelled callback", function( assert ) {
1235 assert.expect( 1 );
1236 $.widget( "ui.testWidget", {
1237 _create: function() {}
1238 } );
1239  
1240 $( "#widget" ).testWidget( {
1241 foo: function() {
1242 return false;
1243 }
1244 } );
1245 assert.deepEqual( $( "#widget" ).testWidget( "instance" )._trigger( "foo" ), false,
1246 "_trigger returns false when callback returns false" );
1247 } );
1248  
1249 QUnit.test( "._trigger() - provide event and ui", function( assert ) {
1250 assert.expect( 7 );
1251  
1252 var originalEvent = $.Event( "originalTest" );
1253 $.widget( "ui.testWidget", {
1254 _create: function() {},
1255 testEvent: function() {
1256 var ui = {
1257 foo: "bar",
1258 baz: {
1259 qux: 5,
1260 quux: 20
1261 }
1262 };
1263 this._trigger( "foo", originalEvent, ui );
1264 assert.deepEqual( ui, {
1265 foo: "notbar",
1266 baz: {
1267 qux: 10,
1268 quux: "jQuery"
1269 }
1270 }, "ui object modified" );
1271 }
1272 } );
1273 $( "#widget" ).on( "testwidgetfoo", function( event, ui ) {
1274 assert.equal( event.originalEvent, originalEvent, "original event object passed" );
1275 assert.deepEqual( ui, {
1276 foo: "bar",
1277 baz: {
1278 qux: 5,
1279 quux: 20
1280 }
1281 }, "ui hash passed" );
1282 ui.foo = "notbar";
1283 } );
1284 $( "#widget-wrapper" ).on( "testwidgetfoo", function( event, ui ) {
1285 assert.equal( event.originalEvent, originalEvent, "original event object passed" );
1286 assert.deepEqual( ui, {
1287 foo: "notbar",
1288 baz: {
1289 qux: 5,
1290 quux: 20
1291 }
1292 }, "modified ui hash passed" );
1293 ui.baz.qux = 10;
1294 } );
1295 $( "#widget" ).testWidget( {
1296 foo: function( event, ui ) {
1297 assert.equal( event.originalEvent, originalEvent, "original event object passed" );
1298 assert.deepEqual( ui, {
1299 foo: "notbar",
1300 baz: {
1301 qux: 10,
1302 quux: 20
1303 }
1304 }, "modified ui hash passed" );
1305 ui.baz.quux = "jQuery";
1306 }
1307 } )
1308 .testWidget( "testEvent" );
1309 } );
1310  
1311 QUnit.test( "._trigger() - array as ui", function( assert ) {
1312  
1313 // #6795 - Widget: handle array arguments to _trigger consistently
1314 assert.expect( 4 );
1315  
1316 $.widget( "ui.testWidget", {
1317 _create: function() {},
1318 testEvent: function() {
1319 var ui = {
1320 foo: "bar",
1321 baz: {
1322 qux: 5,
1323 quux: 20
1324 }
1325 },
1326 extra = {
1327 bar: 5
1328 };
1329 this._trigger( "foo", null, [ ui, extra ] );
1330 }
1331 } );
1332 $( "#widget" ).on( "testwidgetfoo", function( event, ui, extra ) {
1333 assert.deepEqual( ui, {
1334 foo: "bar",
1335 baz: {
1336 qux: 5,
1337 quux: 20
1338 }
1339 }, "event: ui hash passed" );
1340 assert.deepEqual( extra, {
1341 bar: 5
1342 }, "event: extra argument passed" );
1343 } );
1344 $( "#widget" ).testWidget( {
1345 foo: function( event, ui, extra ) {
1346 assert.deepEqual( ui, {
1347 foo: "bar",
1348 baz: {
1349 qux: 5,
1350 quux: 20
1351 }
1352 }, "callback: ui hash passed" );
1353 assert.deepEqual( extra, {
1354 bar: 5
1355 }, "callback: extra argument passed" );
1356 }
1357 } )
1358 .testWidget( "testEvent" );
1359 } );
1360  
1361 QUnit.test( "._trigger() - instance as element", function( assert ) {
1362 assert.expect( 4 );
1363 $.widget( "ui.testWidget", {
1364 defaultElement: null,
1365 testEvent: function() {
1366 this._trigger( "foo", null, { foo: "bar" } );
1367 }
1368 } );
1369 var instance = $.ui.testWidget( {
1370 foo: function( event, ui ) {
1371 assert.equal( event.type, "testwidgetfoo", "event object passed to callback" );
1372 assert.deepEqual( ui, { foo: "bar" }, "ui object passed to callback" );
1373 }
1374 } );
1375 $( instance ).on( "testwidgetfoo", function( event, ui ) {
1376 assert.equal( event.type, "testwidgetfoo", "event object passed to event handler" );
1377 assert.deepEqual( ui, { foo: "bar" }, "ui object passed to event handler" );
1378 } );
1379 instance.testEvent();
1380 } );
1381  
1382 ( function() {
1383 function shouldDestroy( assert, expected, callback ) {
1384 assert.expect( 1 );
1385 var destroyed = false;
1386 $.widget( "ui.testWidget", {
1387 _create: function() {},
1388 destroy: function() {
1389 destroyed = true;
1390 }
1391 } );
1392 callback();
1393 assert.equal( destroyed, expected );
1394 }
1395  
1396 QUnit.test( "auto-destroy - .remove()", function( assert ) {
1397 shouldDestroy( assert, true, function() {
1398 $( "#widget" ).testWidget().remove();
1399 } );
1400 } );
1401  
1402 QUnit.test( "auto-destroy - .remove() when disabled", function( assert ) {
1403 shouldDestroy( assert, true, function() {
1404 $( "#widget" ).testWidget( { disabled: true } ).remove();
1405 } );
1406 } );
1407  
1408 QUnit.test( "auto-destroy - .remove() on parent", function( assert ) {
1409 shouldDestroy( assert, true, function() {
1410 $( "#widget" ).testWidget().parent().remove();
1411 } );
1412 } );
1413  
1414 QUnit.test( "auto-destroy - .remove() on child", function( assert ) {
1415 shouldDestroy( assert, false, function() {
1416 $( "#widget" ).testWidget().children().remove();
1417 } );
1418 } );
1419  
1420 QUnit.test( "auto-destroy - .empty()", function( assert ) {
1421 shouldDestroy( assert, false, function() {
1422 $( "#widget" ).testWidget().empty();
1423 } );
1424 } );
1425  
1426 QUnit.test( "auto-destroy - .empty() on parent", function( assert ) {
1427 shouldDestroy( assert, true, function() {
1428 $( "#widget" ).testWidget().parent().empty();
1429 } );
1430 } );
1431  
1432 QUnit.test( "auto-destroy - .detach()", function( assert ) {
1433 shouldDestroy( assert, false, function() {
1434 $( "#widget" ).testWidget().detach();
1435 } );
1436 } );
1437  
1438 QUnit.test( "destroy - remove event bubbling", function( assert ) {
1439 shouldDestroy( assert, false, function() {
1440 $( "<div>child</div>" ).appendTo( $( "#widget" ).testWidget() )
1441 .trigger( "remove" );
1442 } );
1443 } );
1444 }() );
1445  
1446 QUnit.test( "redefine", function( assert ) {
1447 assert.expect( 4 );
1448 $.widget( "ui.testWidget", {
1449 method: function( str ) {
1450 assert.strictEqual( this, instance, "original invoked with correct this" );
1451 assert.equal( str, "bar", "original invoked with correct parameter" );
1452 }
1453 } );
1454 $.ui.testWidget.foo = "bar";
1455 $.widget( "ui.testWidget", $.ui.testWidget, {
1456 method: function( str ) {
1457 assert.equal( str, "foo", "new invoked with correct parameter" );
1458 this._super( "bar" );
1459 }
1460 } );
1461  
1462 var instance = new $.ui.testWidget( {} );
1463 instance.method( "foo" );
1464 assert.equal( $.ui.testWidget.foo, "bar", "static properties remain" );
1465 } );
1466  
1467 QUnit.test( "redefine deep prototype chain", function( assert ) {
1468 assert.expect( 8 );
1469 $.widget( "ui.testWidget", {
1470 method: function( str ) {
1471 assert.strictEqual( this, instance, "original invoked with correct this" );
1472 assert.equal( str, "level 4", "original invoked with correct parameter" );
1473 }
1474 } );
1475 $.widget( "ui.testWidget2", $.ui.testWidget, {
1476 method: function( str ) {
1477 assert.strictEqual( this, instance, "testWidget2 invoked with correct this" );
1478 assert.equal( str, "level 2", "testWidget2 invoked with correct parameter" );
1479 this._super( "level 3" );
1480 }
1481 } );
1482 $.widget( "ui.testWidget3", $.ui.testWidget2, {
1483 method: function( str ) {
1484 assert.strictEqual( this, instance, "testWidget3 invoked with correct this" );
1485 assert.equal( str, "level 1", "testWidget3 invoked with correct parameter" );
1486 this._super( "level 2" );
1487 }
1488 } );
1489  
1490 // Redefine testWidget after other widgets have inherited from it
1491 // this tests whether the inheriting widgets get updated prototype chains
1492 $.widget( "ui.testWidget", $.ui.testWidget, {
1493 method: function( str ) {
1494 assert.strictEqual( this, instance, "new invoked with correct this" );
1495 assert.equal( str, "level 3", "new invoked with correct parameter" );
1496 this._super( "level 4" );
1497 }
1498 } );
1499  
1500 // Redefine testWidget3 after it has been automatically redefined
1501 // this tests whether we properly handle _super() when the topmost prototype
1502 // doesn't have the method defined
1503 $.widget( "ui.testWidget3", $.ui.testWidget3, {} );
1504  
1505 var instance = new $.ui.testWidget3( {} );
1506 instance.method( "level 1" );
1507  
1508 delete $.ui.testWidget3;
1509 delete $.fn.testWidget3;
1510 delete $.ui.testWidget2;
1511 delete $.fn.testWidget2;
1512 } );
1513  
1514 QUnit.test( "redefine - widgetEventPrefix", function( assert ) {
1515 assert.expect( 2 );
1516  
1517 $.widget( "ui.testWidget", {
1518 widgetEventPrefix: "test"
1519 } );
1520 assert.equal( $.ui.testWidget.prototype.widgetEventPrefix, "test",
1521 "cusotm prefix in original" );
1522  
1523 $.widget( "ui.testWidget", $.ui.testWidget, {} );
1524 assert.equal( $.ui.testWidget.prototype.widgetEventPrefix, "test",
1525 "cusotm prefix in extension" );
1526  
1527 } );
1528  
1529 QUnit.test( "mixins", function( assert ) {
1530 assert.expect( 2 );
1531  
1532 var mixin = {
1533 method: function() {
1534 return "mixed " + this._super();
1535 }
1536 };
1537  
1538 $.widget( "ui.testWidget1", {
1539 method: function() {
1540 return "testWidget1";
1541 }
1542 } );
1543 $.widget( "ui.testWidget2", {
1544 method: function() {
1545 return "testWidget2";
1546 }
1547 } );
1548 $.widget( "ui.testWidget1", $.ui.testWidget1, mixin );
1549 $.widget( "ui.testWidget2", $.ui.testWidget2, mixin );
1550  
1551 assert.equal( $( "<div>" ).testWidget1().testWidget1( "method" ),
1552 "mixed testWidget1", "testWidget1 mixin successful" );
1553 assert.equal( $( "<div>" ).testWidget2().testWidget2( "method" ),
1554 "mixed testWidget2", "testWidget2 mixin successful" );
1555 } );
1556  
1557 QUnit.test( "_delay", function( assert ) {
1558 var ready = assert.async();
1559 assert.expect( 6 );
1560 var order = 0,
1561 that;
1562 $.widget( "ui.testWidget", {
1563 defaultElement: null,
1564 _create: function() {
1565 that = this;
1566 var timer = this._delay( function() {
1567 assert.strictEqual( this, that );
1568 assert.equal( order, 1 );
1569 ready();
1570 }, 500 );
1571 assert.ok( timer !== undefined );
1572 timer = this._delay( "callback" );
1573 assert.ok( timer !== undefined );
1574 },
1575 callback: function() {
1576 assert.strictEqual( this, that );
1577 assert.equal( order, 0 );
1578 order += 1;
1579 }
1580 } );
1581 $( "#widget" ).testWidget();
1582 } );
1583  
1584 QUnit.test( "$.widget.bridge()", function( assert ) {
1585 assert.expect( 14 );
1586  
1587 var instance, ret,
1588 elem = $( "<div>" );
1589  
1590 function TestWidget( options, element ) {
1591 assert.deepEqual( options, { foo: "bar" }, "options passed" );
1592 assert.strictEqual( element, elem[ 0 ], "element passed" );
1593 }
1594  
1595 $.extend( TestWidget.prototype, {
1596 method: function( param ) {
1597 assert.ok( true, "method called via .pluginName(methodName)" );
1598 assert.equal( param, "value1",
1599 "parameter passed via .pluginName(methodName, param)" );
1600 },
1601 getter: function() {
1602 return "qux";
1603 },
1604 option: function( options ) {
1605 assert.deepEqual( options, {} );
1606 }
1607 } );
1608  
1609 $.widget.bridge( "testWidget", TestWidget );
1610  
1611 assert.ok( $.isFunction( $.fn.testWidget ), "jQuery plugin was created" );
1612  
1613 assert.strictEqual( elem.testWidget( { foo: "bar" } ), elem, "plugin returns original jQuery object" );
1614 instance = elem.data( "testWidget" );
1615 assert.equal( typeof instance, "object", "instance stored in .data(pluginName)" );
1616 assert.equal( typeof elem.testWidget( "instance" ), "object", "also retrievable via instance method" );
1617  
1618 ret = elem.testWidget( "method", "value1" );
1619 assert.equal( ret, elem, "jQuery object returned from method call" );
1620  
1621 ret = elem.testWidget( "getter" );
1622 assert.equal( ret, "qux", "getter returns value" );
1623  
1624 elem.testWidget();
1625 assert.ok( true, "_init is optional" );
1626  
1627 TestWidget.prototype._init = function() {
1628 assert.ok( "_init", "_init now exists, so its called" );
1629 };
1630 elem.testWidget();
1631 } );
1632  
1633 QUnit.test( "$.widget.bridge() - widgetFullName", function( assert ) {
1634 assert.expect( 1 );
1635  
1636 var instance,
1637 elem = $( "<div>" );
1638  
1639 function TestWidget() {}
1640 TestWidget.prototype.widgetFullName = "custom-widget";
1641 $.widget.bridge( "testWidget", TestWidget );
1642  
1643 elem.testWidget();
1644 instance = elem.data( "custom-widget" );
1645 assert.equal( typeof instance, "object", "instance stored in .data(widgetFullName)" );
1646 } );
1647  
1648 } );