define( [ "qunit", "jquery", "lib/common", "lib/helper", "ui/widget" ], function( QUnit, $, common, helper ) { "use strict"; QUnit.module( "widget factory", { afterEach: function() { if ( $.ui ) { delete $.ui.testWidget; delete $.fn.testWidget; } return helper.moduleAfterEach.apply( this, arguments ); } } ); QUnit.test( "widget creation", function( assert ) { assert.expect( 5 ); var method, myPrototype = { _create: function() { assert.equal( method, "_create", "create function is copied over" ); }, creationTest: function() { assert.equal( method, "creationTest", "random function is copied over" ); } }; $.widget( "ui.testWidget", myPrototype ); assert.ok( typeof $.ui.testWidget === "function", "constructor was created" ); assert.equal( typeof $.ui.testWidget.prototype, "object", "prototype was created" ); method = "_create"; $.ui.testWidget.prototype._create(); method = "creationTest"; $.ui.testWidget.prototype.creationTest(); assert.equal( $.ui.testWidget.prototype.option, $.Widget.prototype.option, "option method copied over from base widget" ); } ); QUnit.test( "element normalization", function( assert ) { assert.expect( 11 ); var elem; $.widget( "ui.testWidget", {} ); $.ui.testWidget.prototype._create = function() { // Workaround for core ticket #8381 this.element.appendTo( "#qunit-fixture" ); assert.ok( this.element.is( "div" ), "generated div" ); assert.deepEqual( this.element.testWidget( "instance" ), this, "instance stored in .data()" ); }; $.ui.testWidget(); $.ui.testWidget.prototype.defaultElement = ""; $.ui.testWidget.prototype._create = function() { assert.ok( this.element.is( "span[data-test=pass]" ), "generated span with properties" ); assert.deepEqual( this.element.testWidget( "instance" ), this, "instance stored in .data()" ); }; $.ui.testWidget(); elem = $( "" ); $.ui.testWidget.prototype._create = function() { assert.deepEqual( this.element[ 0 ], elem[ 0 ], "from element" ); assert.deepEqual( elem.testWidget( "instance" ), this, "instance stored in .data()" ); }; $.ui.testWidget( {}, elem[ 0 ] ); elem = $( "
hello world
hello world
" ); this.child = this.target.children(); this._on( this.target, { "keyup": "handlerDirect", "keyup strong": "handlerDelegated" } ); this.child.trigger( "keyup" ); }, handlerDirect: function( event ) { assert.deepEqual( event.currentTarget, this.target[ 0 ] ); assert.deepEqual( event.target, this.child[ 0 ] ); }, handlerDelegated: function( event ) { assert.deepEqual( event.currentTarget, this.child[ 0 ] ); assert.deepEqual( event.target, this.child[ 0 ] ); } } ); $.ui.testWidget(); } ); QUnit.test( "_on() to common element", function( assert ) { assert.expect( 4 ); $.widget( "ui.testWidget", { _create: function() { this._on( this.document, { "customevent": "_handler", "with:colons": "_colonHandler", "with-dashes": "_dashHandler", "with-dashes:and-colons": "_commbinedHandler" } ); }, _handler: function() { assert.ok( true, "handler triggered" ); }, _colonHandler: function() { assert.ok( true, "colon handler triggered" ); }, _dashHandler: function() { assert.ok( true, "dash handler triggered" ); }, _commbinedHandler: function() { assert.ok( true, "combined handler triggered" ); } } ); var widget = $( "#widget" ).testWidget().testWidget( "instance" ); $( "#widget-wrapper" ).testWidget(); widget.destroy(); $( document ).trigger( "customevent" ); $( document ).trigger( "with:colons" ); $( document ).trigger( "with-dashes" ); $( document ).trigger( "with-dashes:and-colons" ); } ); QUnit.test( "_off() - single event", function( assert ) { assert.expect( 3 ); $.widget( "ui.testWidget", {} ); var shouldTriggerWidget, shouldTriggerOther, element = $( "#widget" ), widget = element.testWidget().testWidget( "instance" ); widget._on( element, { foo: function() { assert.ok( shouldTriggerWidget, "foo called from _on" ); } } ); element.on( "foo", function() { assert.ok( shouldTriggerOther, "foo called from bind" ); } ); shouldTriggerWidget = true; shouldTriggerOther = true; element.trigger( "foo" ); shouldTriggerWidget = false; widget._off( element, "foo" ); element.trigger( "foo" ); } ); QUnit.test( "_off() - multiple events", function( assert ) { assert.expect( 6 ); $.widget( "ui.testWidget", {} ); var shouldTriggerWidget, shouldTriggerOther, element = $( "#widget" ), widget = element.testWidget().testWidget( "instance" ); widget._on( element, { foo: function() { assert.ok( shouldTriggerWidget, "foo called from _on" ); }, bar: function() { assert.ok( shouldTriggerWidget, "bar called from _on" ); } } ); element.on( "foo bar", function( event ) { assert.ok( shouldTriggerOther, event.type + " called from bind" ); } ); shouldTriggerWidget = true; shouldTriggerOther = true; element.trigger( "foo" ); element.trigger( "bar" ); shouldTriggerWidget = false; widget._off( element, "foo bar" ); element.trigger( "foo" ); element.trigger( "bar" ); } ); QUnit.test( "_off() - all events", function( assert ) { assert.expect( 6 ); $.widget( "ui.testWidget", {} ); var shouldTriggerWidget, shouldTriggerOther, element = $( "#widget" ), widget = element.testWidget().testWidget( "instance" ); widget._on( element, { foo: function() { assert.ok( shouldTriggerWidget, "foo called from _on" ); }, bar: function() { assert.ok( shouldTriggerWidget, "bar called from _on" ); } } ); element.on( "foo bar", function( event ) { assert.ok( shouldTriggerOther, event.type + " called from bind" ); } ); shouldTriggerWidget = true; shouldTriggerOther = true; element.trigger( "foo" ); element.trigger( "bar" ); shouldTriggerWidget = false; widget._off( element ); element.trigger( "foo" ); element.trigger( "bar" ); } ); QUnit.test( "._hoverable()", function( assert ) { assert.expect( 10 ); $.widget( "ui.testWidget", { _create: function() { this._hoverable( this.element.children() ); } } ); var div = $( "#widget" ).testWidget().children(); assert.lacksClasses( div, "ui-state-hover", "not hovered on init" ); div.trigger( "mouseenter" ); assert.hasClasses( div, "ui-state-hover", "hovered after mouseenter" ); div.trigger( "mouseleave" ); assert.lacksClasses( div, "ui-state-hover", "not hovered after mouseleave" ); div.trigger( "mouseenter" ); assert.hasClasses( div, "ui-state-hover", "hovered after mouseenter" ); $( "#widget" ).testWidget( "disable" ); assert.lacksClasses( div, "ui-state-hover", "not hovered while disabled" ); div.trigger( "mouseenter" ); assert.lacksClasses( div, "ui-state-hover", "can't hover while disabled" ); $( "#widget" ).testWidget( "enable" ); assert.lacksClasses( div, "ui-state-hover", "enabling doesn't reset hover" ); div.trigger( "mouseenter" ); assert.hasClasses( div, "ui-state-hover", "hovered after mouseenter" ); $( "#widget" ).testWidget( "destroy" ); assert.lacksClasses( div, "ui-state-hover", "not hovered after destroy" ); div.trigger( "mouseenter" ); assert.lacksClasses( div, "ui-state-hover", "event handler removed on destroy" ); } ); QUnit.test( "._focusable()", function( assert ) { assert.expect( 10 ); $.widget( "ui.testWidget", { _create: function() { this._focusable( this.element.children() ); } } ); var div = $( "#widget" ).testWidget().children(); assert.lacksClasses( div, "ui-state-focus", "not focused on init" ); div.trigger( "focusin" ); assert.hasClasses( div, "ui-state-focus", "focused after explicit focus" ); div.trigger( "focusout" ); assert.lacksClasses( div, "ui-state-focus", "not focused after blur" ); div.trigger( "focusin" ); assert.hasClasses( div, "ui-state-focus", "focused after explicit focus" ); $( "#widget" ).testWidget( "disable" ); assert.lacksClasses( div, "ui-state-focus", "not focused while disabled" ); div.trigger( "focusin" ); assert.lacksClasses( div, "ui-state-focus", "can't focus while disabled" ); $( "#widget" ).testWidget( "enable" ); assert.lacksClasses( div, "ui-state-focus", "enabling doesn't reset focus" ); div.trigger( "focusin" ); assert.hasClasses( div, "ui-state-focus", "focused after explicit focus" ); $( "#widget" ).testWidget( "destroy" ); assert.lacksClasses( div, "ui-state-focus", "not focused after destroy" ); div.trigger( "focusin" ); assert.lacksClasses( div, "ui-state-focus", "event handler removed on destroy" ); } ); QUnit.test( "._trigger() - no event, no ui", function( assert ) { assert.expect( 7 ); var handlers = []; $.widget( "ui.testWidget", { _create: function() {} } ); $( "#widget" ).testWidget( { foo: function( event, ui ) { assert.deepEqual( event.type, "testwidgetfoo", "correct event type in callback" ); assert.deepEqual( ui, {}, "empty ui hash passed" ); handlers.push( "callback" ); } } ); $( document ).add( "#widget-wrapper" ).add( "#widget" ) .on( "testwidgetfoo", function( event, ui ) { assert.deepEqual( ui, {}, "empty ui hash passed" ); handlers.push( this ); } ); assert.deepEqual( $( "#widget" ).testWidget( "instance" )._trigger( "foo" ), true, "_trigger returns true when event is not cancelled" ); assert.deepEqual( handlers, [ $( "#widget" )[ 0 ], $( "#widget-wrapper" )[ 0 ], document, "callback" ], "event bubbles and then invokes callback" ); $( document ).off( "testwidgetfoo" ); } ); QUnit.test( "._trigger() - cancelled event", function( assert ) { assert.expect( 3 ); $.widget( "ui.testWidget", { _create: function() {} } ); $( "#widget" ).testWidget( { foo: function() { assert.ok( true, "callback invoked even if event is cancelled" ); } } ) .on( "testwidgetfoo", function() { assert.ok( true, "event was triggered" ); return false; } ); assert.deepEqual( $( "#widget" ).testWidget( "instance" )._trigger( "foo" ), false, "_trigger returns false when event is cancelled" ); } ); QUnit.test( "._trigger() - cancelled callback", function( assert ) { assert.expect( 1 ); $.widget( "ui.testWidget", { _create: function() {} } ); $( "#widget" ).testWidget( { foo: function() { return false; } } ); assert.deepEqual( $( "#widget" ).testWidget( "instance" )._trigger( "foo" ), false, "_trigger returns false when callback returns false" ); } ); QUnit.test( "._trigger() - provide event and ui", function( assert ) { assert.expect( 7 ); var originalEvent = $.Event( "originalTest" ); $.widget( "ui.testWidget", { _create: function() {}, testEvent: function() { var ui = { foo: "bar", baz: { qux: 5, quux: 20 } }; this._trigger( "foo", originalEvent, ui ); assert.deepEqual( ui, { foo: "notbar", baz: { qux: 10, quux: "jQuery" } }, "ui object modified" ); } } ); $( "#widget" ).on( "testwidgetfoo", function( event, ui ) { assert.equal( event.originalEvent, originalEvent, "original event object passed" ); assert.deepEqual( ui, { foo: "bar", baz: { qux: 5, quux: 20 } }, "ui hash passed" ); ui.foo = "notbar"; } ); $( "#widget-wrapper" ).on( "testwidgetfoo", function( event, ui ) { assert.equal( event.originalEvent, originalEvent, "original event object passed" ); assert.deepEqual( ui, { foo: "notbar", baz: { qux: 5, quux: 20 } }, "modified ui hash passed" ); ui.baz.qux = 10; } ); $( "#widget" ).testWidget( { foo: function( event, ui ) { assert.equal( event.originalEvent, originalEvent, "original event object passed" ); assert.deepEqual( ui, { foo: "notbar", baz: { qux: 10, quux: 20 } }, "modified ui hash passed" ); ui.baz.quux = "jQuery"; } } ) .testWidget( "testEvent" ); } ); QUnit.test( "._trigger() - array as ui", function( assert ) { // #6795 - Widget: handle array arguments to _trigger consistently assert.expect( 4 ); $.widget( "ui.testWidget", { _create: function() {}, testEvent: function() { var ui = { foo: "bar", baz: { qux: 5, quux: 20 } }, extra = { bar: 5 }; this._trigger( "foo", null, [ ui, extra ] ); } } ); $( "#widget" ).on( "testwidgetfoo", function( event, ui, extra ) { assert.deepEqual( ui, { foo: "bar", baz: { qux: 5, quux: 20 } }, "event: ui hash passed" ); assert.deepEqual( extra, { bar: 5 }, "event: extra argument passed" ); } ); $( "#widget" ).testWidget( { foo: function( event, ui, extra ) { assert.deepEqual( ui, { foo: "bar", baz: { qux: 5, quux: 20 } }, "callback: ui hash passed" ); assert.deepEqual( extra, { bar: 5 }, "callback: extra argument passed" ); } } ) .testWidget( "testEvent" ); } ); QUnit.test( "._trigger() - instance as element", function( assert ) { assert.expect( 4 ); $.widget( "ui.testWidget", { defaultElement: null, testEvent: function() { this._trigger( "foo", null, { foo: "bar" } ); } } ); var instance = $.ui.testWidget( { foo: function( event, ui ) { assert.equal( event.type, "testwidgetfoo", "event object passed to callback" ); assert.deepEqual( ui, { foo: "bar" }, "ui object passed to callback" ); } } ); $( instance ).on( "testwidgetfoo", function( event, ui ) { assert.equal( event.type, "testwidgetfoo", "event object passed to event handler" ); assert.deepEqual( ui, { foo: "bar" }, "ui object passed to event handler" ); } ); instance.testEvent(); } ); ( function() { function shouldDestroy( assert, expected, callback ) { assert.expect( 1 ); var destroyed = false; $.widget( "ui.testWidget", { _create: function() {}, destroy: function() { destroyed = true; } } ); callback(); assert.equal( destroyed, expected ); } QUnit.test( "auto-destroy - .remove()", function( assert ) { shouldDestroy( assert, true, function() { $( "#widget" ).testWidget().remove(); } ); } ); QUnit.test( "auto-destroy - .remove() when disabled", function( assert ) { shouldDestroy( assert, true, function() { $( "#widget" ).testWidget( { disabled: true } ).remove(); } ); } ); QUnit.test( "auto-destroy - .remove() on parent", function( assert ) { shouldDestroy( assert, true, function() { $( "#widget" ).testWidget().parent().remove(); } ); } ); QUnit.test( "auto-destroy - .remove() on child", function( assert ) { shouldDestroy( assert, false, function() { $( "#widget" ).testWidget().children().remove(); } ); } ); QUnit.test( "auto-destroy - .empty()", function( assert ) { shouldDestroy( assert, false, function() { $( "#widget" ).testWidget().empty(); } ); } ); QUnit.test( "auto-destroy - .empty() on parent", function( assert ) { shouldDestroy( assert, true, function() { $( "#widget" ).testWidget().parent().empty(); } ); } ); QUnit.test( "auto-destroy - .detach()", function( assert ) { shouldDestroy( assert, false, function() { $( "#widget" ).testWidget().detach(); } ); } ); QUnit.test( "destroy - remove event bubbling", function( assert ) { shouldDestroy( assert, false, function() { $( "