diff --git a/tests/lib/qunit-assert-dateequal.js b/tests/lib/qunit-assert-dateequal.js new file mode 100644 index 00000000000..7a997003bf9 --- /dev/null +++ b/tests/lib/qunit-assert-dateequal.js @@ -0,0 +1,22 @@ +/* + * Assertion for comparing Date objects by day, month and year. + */ +define( [ + "qunit" +], function( QUnit ) { + +QUnit.assert.dateEqual = function( value, expected, message ) { + + if ( !value || !expected ) { + this.push( false, value, expected, + "dateEqual failed, missing date object, message was: " + message ); + return; + } + + var newValue = new Date( value.getFullYear(), value.getMonth(), value.getDate() ), + newExpected = new Date( expected.getFullYear(), expected.getMonth(), expected.getDate() ); + + this.push( ( newValue.toString() === newExpected.toString() ), value, expected, message ); +}; + +} ); diff --git a/tests/lib/qunit.js b/tests/lib/qunit.js index e2a6e85c7f4..fe5c1d746c5 100644 --- a/tests/lib/qunit.js +++ b/tests/lib/qunit.js @@ -4,6 +4,7 @@ define( [ "qunit-assert-classes", "qunit-assert-close", "lib/qunit-assert-domequal", + "lib/qunit-assert-dateequal", "phantom-bridge" ], function( QUnit, $ ) { diff --git a/tests/unit/calendar/common.js b/tests/unit/calendar/common.js index b6807ec84ef..ea637a9b8d0 100644 --- a/tests/unit/calendar/common.js +++ b/tests/unit/calendar/common.js @@ -35,6 +35,7 @@ common.testWidget( "calendar", { value: null, // callbacks + change: null, create: null, select: null } diff --git a/tests/unit/calendar/core.js b/tests/unit/calendar/core.js index 65daf1bd458..97f8a43b713 100644 --- a/tests/unit/calendar/core.js +++ b/tests/unit/calendar/core.js @@ -4,27 +4,34 @@ define( [ "ui/widgets/calendar" ], function( $, testHelper ) { -module( "calendar: core" ); +module( "calendar: core", { + setup: function() { + this.element = $( "#calendar" ).calendar(); + this.widget = this.element.calendar( "widget" ); + }, + teardown: function() { + this.element.calendar( "destroy" ); + } +} ); -test( "base structure", function() { - expect( 28 ); +test( "base structure", function( assert ) { + assert.expect( 28 ); - var buttons, header, title, table, thead, week, child, buttonpane, - element = $( "#calendar" ).calendar(), - dp = element.calendar( "widget" ); + var that = this, + buttons, header, title, table, thead, week, child, buttonpane; function step1() { - ok( !dp.is( ".ui-calendar-rtl" ), "Structure - not right-to-left" ); - ok( !dp.is( ".ui-calendar-multi" ), "Structure - not multi-month" ); - equal( dp.children().length, 3, "Structure - child count (header, calendar)" ); + ok( !that.widget.is( ".ui-calendar-rtl" ), "Structure - not right-to-left" ); + ok( !that.widget.is( ".ui-calendar-multi" ), "Structure - not multi-month" ); + equal( that.widget.children().length, 3, "Structure - child count (header, calendar)" ); - buttons = dp.children( ":first" ); + buttons = that.widget.children( ":first" ); ok( buttons.is( "div.ui-calendar-header-buttons" ), "Structure - header button division" ); equal( buttons.children().length, 2, "Structure - header buttons child count" ); ok( buttons.children( ":first" ).is( ".ui-calendar-prev" ) && buttons.children( ":first" ).html() !== "", "Structure - prev link" ); ok( buttons.children( ":last" ).is( ".ui-calendar-next" ) && buttons.children( ":last" ).html() !== "", "Structure - next link" ); - header = dp.children( ":eq(1)" ); + header = that.widget.children( ":eq(1)" ); ok( header.is( "div.ui-calendar-header" ), "Structure - header division" ); equal( header.children().length, 1, "Structure - header child count" ); @@ -34,7 +41,7 @@ test( "base structure", function() { ok( title.children( ":first" ).is( "span.ui-calendar-month" ) && title.children( ":first" ).text() !== "", "Structure - month text" ); ok( title.children( ":last" ).is( "span.ui-calendar-year" ) && title.children( ":last" ).text() !== "", "Structure - year text" ); - table = dp.children( ":eq(2)" ); + table = that.widget.children( ":eq(2)" ); ok( table.is( "table.ui-calendar-calendar" ), "Structure - month table" ); ok( table.children( ":first" ).is( "thead" ), "Structure - month table thead" ); @@ -52,44 +59,41 @@ test( "base structure", function() { } function step2() { - element.calendar( "option", "buttons", { + that.element.calendar( "option", "buttons", { "test": function() {}, "test button": function() {} } ); - equal( dp.children().length, 4, "Structure buttons - child count (header buttons, header, calendar, buttonpane)" ); + equal( that.widget.children().length, 4, "Structure buttons - child count (header buttons, header, calendar, buttonpane)" ); - buttonpane = dp.children( ".ui-calendar-buttonpane" ); + buttonpane = that.widget.children( ".ui-calendar-buttonpane" ); equal( buttonpane.children( "div.ui-calendar-buttonset" ).length, 1, "Structure buttons - buttonset" ); equal( buttonpane.find( "button.ui-button:first" ).text(), "test", "Structure buttons - buttonset" ); equal( buttonpane.find( "button.ui-button:eq(1)" ).text(), "test button", "Structure buttons - buttonset" ); - element.calendar( "destroy" ); + that.element.calendar( "destroy" ); step3(); } function step3() { // Multi-month 2 - element = $( "#calendar" ).calendar( { numberOfMonths: 2 } ); - dp = element.calendar( "widget" ); + that.element.calendar( { numberOfMonths: 2 } ); - ok( dp.is( ".ui-calendar-multi" ), "Structure multi [2] - multi-month" ); - equal( dp.children().length, 4, "Structure multi [2] - child count" ); + ok( that.widget.is( ".ui-calendar-multi" ), "Structure multi [2] - multi-month" ); + equal( that.widget.children().length, 4, "Structure multi [2] - child count" ); - child = dp.children( ":eq(3)" ); + child = that.widget.children( ":eq(3)" ); ok( child.is( "div.ui-calendar-row-break" ), "Structure multi [2] - row break" ); - - element.calendar( "destroy" ); } step1(); } ); -test( "Localization", function() { - expect( 10 ); +test( "Localization", function( assert ) { + assert.expect( 10 ); - var element = $( "#calendar" ), + var that = this, date = new Date( 2014, 0, 1 ), optionsDe = { locale: "de", @@ -99,76 +103,76 @@ test( "Localization", function() { } }, initCalendar = function( options ) { - element + that.element .calendar( options ) .calendar( "valueAsDate", date ); }, testLocalization = function( message ) { equal( - element.find( ".ui-calendar-month" ).text(), + that.element.find( ".ui-calendar-month" ).text(), "Januar", message + "titlebar year" ); equal( - element.find( "thead th:first" ).text(), + that.element.find( "thead th:first" ).text(), "Mo.", message + "teader first day" ); equal( - element.find( "thead th:last" ).text(), + that.element.find( "thead th:last" ).text(), "So.", message + "header last day" ); equal( - element.find( ".ui-calendar-prev" ).text(), + that.element.find( ".ui-calendar-prev" ).text(), "Zurück", message + "header prev" ); equal( - element.find( ".ui-calendar-next" ).text(), + that.element.find( ".ui-calendar-next" ).text(), "Vor", message + "header next" ); }; initCalendar( optionsDe ); testLocalization( "Init: " ); - element.calendar( "destroy" ); + that.element.calendar( "destroy" ); initCalendar( {} ); - element + that.element .calendar( "option", optionsDe ) .calendar( "refresh" ); testLocalization( "After init: " ); } ); -asyncTest( "keyboard handling", function() { - expect( 10 ); +asyncTest( "keyboard handling", function( assert ) { + assert.expect( 10 ); - var element = $( "#calendar" ); + var that = this; function step1() { - element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); + that.element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); testHelper - .focusGrid( element ) + .focusGrid( that.element ) .simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } ); setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), + assert.dateEqual( + that.element.calendar( "valueAsDate" ), new Date( 2013, 12 - 1, 31 ), "Keystroke left to switch to previous day" ); - element.calendar( "destroy" ); + that.element.calendar( "destroy" ); step2(); }, 50 ); } function step2() { - element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); + that.element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); - testHelper.focusGrid( element ) + testHelper.focusGrid( that.element ) .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), + assert.dateEqual( + that.element.calendar( "valueAsDate" ), new Date( 2014, 1 - 1, 2 ), "Keystroke right to switch to next day" ); @@ -176,132 +180,131 @@ asyncTest( "keyboard handling", function() { } function step3() { - element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); + that.element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); - testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); + testHelper.focusGrid( that.element ).simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), + assert.dateEqual( + that.element.calendar( "valueAsDate" ), new Date( 2013, 12 - 1, 25 ), "Keystroke up to move to the previous week" ); - element.calendar( "destroy" ); + that.element.calendar( "destroy" ); step4(); }, 50 ); } function step4() { - element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); + that.element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); - testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + testHelper.focusGrid( that.element ).simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), + assert.dateEqual( + that.element.calendar( "valueAsDate" ), new Date( 2014, 1 - 1, 8 ), "Keystroke down to move to the next week" ); - element.calendar( "destroy" ); + that.element.calendar( "destroy" ); step5(); }, 50 ); } function step5() { - element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); + that.element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); - testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ); + testHelper.focusGrid( that.element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ); setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), + assert.dateEqual( + that.element.calendar( "valueAsDate" ), new Date( 2013, 12 - 1, 1 ), "Keystroke Page Up moves date to previous month" ); - element.calendar( "destroy" ); + that.element.calendar( "destroy" ); step6(); }, 50 ); } function step6() { - element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); + that.element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); - testHelper.focusGrid( element ) + testHelper.focusGrid( that.element ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP, altKey: true } ); setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), + assert.dateEqual( + that.element.calendar( "valueAsDate" ), new Date( 2013, 1 - 1, 1 ), "Keystroke Page Up + ALT moves date to previous year" ); - element.calendar( "destroy" ); + that.element.calendar( "destroy" ); step7(); }, 50 ); } function step7() { - element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); + that.element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); - testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); + testHelper.focusGrid( that.element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), + assert.dateEqual( + that.element.calendar( "valueAsDate" ), new Date( 2014, 2 - 1, 1 ), "Keystroke Page Down moves date to next month" ); - element.calendar( "destroy" ); + that.element.calendar( "destroy" ); step8(); }, 50 ); } function step8() { - element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); + that.element.calendar( { value: new Date( 2014, 1 - 1, 1 ) } ); - testHelper.focusGrid( element ) + testHelper.focusGrid( that.element ) .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN, altKey: true } ); setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), + assert.dateEqual( + that.element.calendar( "valueAsDate" ), new Date( 2015, 1 - 1, 1 ), "Keystroke Page Down + ALT moves date to next year" ); - element.calendar( "destroy" ); + that.element.calendar( "destroy" ); step9(); }, 50 ); } // Check for moving to short months function step9() { - element.calendar( { value: new Date( 2014, 3 - 1, 31 ) } ); + that.element.calendar( { value: new Date( 2014, 3 - 1, 31 ) } ); - testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ); + testHelper.focusGrid( that.element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ); setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), + assert.dateEqual( + that.element.calendar( "valueAsDate" ), new Date( 2014, 2 - 1, 28 ), "Keystroke Page Up and short months" ); - element.calendar( "destroy" ); + that.element.calendar( "destroy" ); step10(); }, 50 ); } function step10() { - element.calendar( { value: new Date( 2016, 1 - 1, 30 ) } ); + that.element.calendar( { value: new Date( 2016, 1 - 1, 30 ) } ); - testHelper.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); + testHelper.focusGrid( that.element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), + assert.dateEqual( + that.element.calendar( "valueAsDate" ), new Date( 2016, 2 - 1, 29 ), "Keystroke Page Down and leap years" ); - element.calendar( "destroy" ); start(); }, 50 ); } @@ -309,44 +312,44 @@ asyncTest( "keyboard handling", function() { step1(); } ); -asyncTest( "mouse", function() { - expect( 6 ); +asyncTest( "mouse", function( assert ) { + assert.expect( 6 ); - var element = $( "#calendar" ).calendar(), + var that = this, date = new Date(); function step1() { - $( "tbody button:contains(10)", element ).simulate( "mousedown" ); + $( "tbody button:contains(10)", that.element ).simulate( "mousedown" ); date.setDate( 10 ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), + assert.dateEqual( + that.element.calendar( "valueAsDate" ), date, "Mouse click" ); - element.calendar( "option", "value", new Date( 2008, 2 - 1, 4 ) ); - $( ".ui-calendar-calendar tbody button:contains(12)", element ).simulate( "mousedown" ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), + that.element.calendar( "option", "value", new Date( 2008, 2 - 1, 4 ) ); + $( ".ui-calendar-calendar tbody button:contains(12)", that.element ).simulate( "mousedown" ); + assert.dateEqual( + that.element.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 12 ), "Mouse click - preset" ); // Previous/next - element.calendar( "option", "value", new Date( 2008, 2 - 1, 4 ) ); - $( ".ui-calendar-prev", element ).simulate( "click" ); - $( ".ui-calendar-calendar tbody button:contains(16)", element ).simulate( "mousedown" ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), + that.element.calendar( "option", "value", new Date( 2008, 2 - 1, 4 ) ); + $( ".ui-calendar-prev", that.element ).simulate( "click" ); + $( ".ui-calendar-calendar tbody button:contains(16)", that.element ).simulate( "mousedown" ); + assert.dateEqual( + that.element.calendar( "valueAsDate" ), new Date( 2008, 1 - 1, 16 ), "Mouse click - previous" ); - element.calendar( "option", "value", new Date( 2008, 2 - 1, 4 ) ); - $( ".ui-calendar-next", element ).simulate( "click" ); - $( ".ui-calendar-calendar tbody button:contains(18)", element ).simulate( "mousedown" ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), + that.element.calendar( "option", "value", new Date( 2008, 2 - 1, 4 ) ); + $( ".ui-calendar-next", that.element ).simulate( "click" ); + $( ".ui-calendar-calendar tbody button:contains(18)", that.element ).simulate( "mousedown" ); + assert.dateEqual( + that.element.calendar( "valueAsDate" ), new Date( 2008, 3 - 1, 18 ), "Mouse click - next" ); @@ -356,17 +359,17 @@ asyncTest( "mouse", function() { // Previous/next with minimum/maximum function step2() { - element.calendar( "destroy" ); - element.calendar( { + that.element.calendar( "destroy" ); + that.element.calendar( { value: new Date( 2008, 3 - 1, 4 ), min: new Date( 2008, 2 - 1, 2 ), max: new Date( 2008, 2 - 1, 26 ) } ); - $( ".ui-calendar-prev", element ).simulate( "click" ); - $( "tbody button:contains(16)", element ).simulate( "mousedown" ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), + $( ".ui-calendar-prev", that.element ).simulate( "click" ); + $( "tbody button:contains(16)", that.element ).simulate( "mousedown" ); + assert.dateEqual( + that.element.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 16 ), "Mouse click - previous + min/max" ); @@ -374,17 +377,17 @@ asyncTest( "mouse", function() { } function step3() { - element.calendar( "destroy" ); - element.calendar( { + that.element.calendar( "destroy" ); + that.element.calendar( { value: new Date( 2008, 1 - 1, 4 ), min: new Date( 2008, 2 - 1, 2 ), max: new Date( 2008, 2 - 1, 26 ) } ); - $( ".ui-calendar-next", element ).simulate( "click" ); - $( "tbody button:contains(18)", element ).simulate( "mousedown" ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), + $( ".ui-calendar-next", that.element ).simulate( "click" ); + $( "tbody button:contains(18)", that.element ).simulate( "mousedown" ); + assert.dateEqual( + that.element.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 18 ), "Mouse click - next + min/max" ); diff --git a/tests/unit/calendar/events.js b/tests/unit/calendar/events.js index e69de29bb2d..87df2d8e041 100644 --- a/tests/unit/calendar/events.js +++ b/tests/unit/calendar/events.js @@ -0,0 +1,97 @@ +define( [ + "jquery", + "./helper", + "ui/widgets/calendar" +], function( $, testHelper ) { + +module( "calendar: events", { + setup: function() { + this.element = $( "#calendar" ).calendar(); + } +} ); + +test( "change", function( assert ) { + assert.expect( 6 ); + + var shouldFire, eventType; + + this.element.calendar( { + change: function( event ) { + ok( shouldFire, "change event fired" ); + equal( + event.type, + "calendarchange", + "change event" + ); + equal( + event.originalEvent.type, + eventType, + "change originalEvent on calendar button " + eventType + ); + } + } ); + + shouldFire = true; + eventType = "mousedown"; + this.element.find( "tbody button" ).last().simulate( eventType ); + + shouldFire = true; + eventType = "keydown"; + testHelper.focusGrid( this.element ) + .simulate( eventType, { keyCode: $.ui.keyCode.HOME } ) + .simulate( eventType, { keyCode: $.ui.keyCode.ENTER } ); + + shouldFire = false; + eventType = "mousedown"; + this.element.find( "tbody button" ).first().simulate( eventType ); +} ); + +asyncTest( "select", function( assert ) { + assert.expect( 6 ); + + var that = this, + message, eventType; + + this.element.calendar( { + select: function( event ) { + ok( true, "select event fired " + message ); + equal( + event.type, + "calendarselect", + "select event " + message + ); + equal( + event.originalEvent.type, + eventType, + "select originalEvent " + message + ); + } + } ); + + function step1() { + eventType = "mousedown"; + message = "on calendar button " + eventType; + that.element.find( "table button:eq(1)" ).simulate( eventType ); + setTimeout( step2, 50 ); + } + + function step2() { + eventType = "keydown"; + message = "on calendar button " + eventType; + testHelper.focusGrid( that.element ) + .simulate( eventType, { keyCode: $.ui.keyCode.END } ) + .simulate( eventType, { keyCode: $.ui.keyCode.ENTER } ); + setTimeout( step3, 50 ); + } + + // This should not trigger another event + function step3() { + that.element.calendar( "disable" ); + that.element.find( "table button:eq(10)" ).simulate( "mousedown" ); + setTimeout( start, 50 ); + } + + step1(); +} ); + +} ); diff --git a/tests/unit/calendar/helper.js b/tests/unit/calendar/helper.js index a82e96705a3..b5feff5a67b 100644 --- a/tests/unit/calendar/helper.js +++ b/tests/unit/calendar/helper.js @@ -4,21 +4,6 @@ define( [ ], function( $, helper ) { return $.extend( helper, { - addMonths: function( date, offset ) { - var maxDay = 32 - new Date( date.getFullYear(), date.getMonth() + offset, 32 ).getDate(); - date.setDate( Math.min( date.getDate(), maxDay ) ); - date.setMonth( date.getMonth() + offset ); - return date; - }, - equalsDate: function( d1, d2, message ) { - if ( !d1 || !d2 ) { - ok( false, message + " - missing date" ); - return; - } - d1 = new Date( d1.getFullYear(), d1.getMonth(), d1.getDate() ); - d2 = new Date( d2.getFullYear(), d2.getMonth(), d2.getDate() ); - equal( d1.toString(), d2.toString(), message ); - }, focusGrid: function( element ) { element.find( ":tabbable" ).last().simulate( "focus" ); $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB } ); diff --git a/tests/unit/calendar/methods.js b/tests/unit/calendar/methods.js index 84e26571076..964d6c18684 100644 --- a/tests/unit/calendar/methods.js +++ b/tests/unit/calendar/methods.js @@ -1,140 +1,140 @@ define( [ "jquery", - "./helper", "ui/widgets/calendar" -], function( $, testHelper ) { - -module( "calendar: methods" ); +], function( $ ) { + +module( "calendar: methods", { + setup: function() { + this.element = $( "#calendar" ).calendar(); + this.widget = this.element.calendar( "widget" ); + }, + teardown: function() { + this.element.calendar( "destroy" ); + } +} ); test( "destroy", function( assert ) { - expect( 1 ); + assert.expect( 1 ); + + var div = $( "
" ).appendTo( "#qunit-fixture" ); - assert.domEqual( "#calendar", function() { - $( "#calendar" ).calendar().calendar( "destroy" ); + assert.domEqual( div, function() { + div.calendar().calendar( "destroy" ); } ); } ); -test( "enable / disable", function() { - expect( 8 ); +test( "enable / disable", function( assert ) { + assert.expect( 8 ); - var element = $( "#calendar" ).calendar(); + this.element.calendar( "disable" ); + ok( this.element.calendar( "option", "disabled" ), "disabled option is set" ); + ok( this.element.hasClass( "ui-calendar-disabled" ), "has disabled widget class name" ); + ok( this.element.hasClass( "ui-state-disabled" ), "has disabled state class name" ); + equal( this.element.attr( "aria-disabled" ), "true", "has ARIA disabled" ); - element.calendar( "disable" ); - ok( element.calendar( "option", "disabled" ), "disabled option is set" ); - ok( element.hasClass( "ui-calendar-disabled" ), "has disabled widget class name" ); - ok( element.hasClass( "ui-state-disabled" ), "has disabled state class name" ); - equal( element.attr( "aria-disabled" ), "true", "has ARIA disabled" ); - - element.calendar( "enable" ); - ok( !element.calendar( "option", "disabled" ), "enabled after enable() call" ); - ok( !element.hasClass( "ui-calendar-disabled" ), "no longer has disabled widget class name" ); - ok( !element.hasClass( "ui-state-disabled" ), "no longer has disabled state class name" ); - equal( element.attr( "aria-disabled" ), "false", "no longer has ARIA disabled" ); + this.element.calendar( "enable" ); + ok( !this.element.calendar( "option", "disabled" ), "enabled after enable() call" ); + ok( !this.element.hasClass( "ui-calendar-disabled" ), "no longer has disabled widget class name" ); + ok( !this.element.hasClass( "ui-state-disabled" ), "no longer has disabled state class name" ); + equal( this.element.attr( "aria-disabled" ), "false", "no longer has ARIA disabled" ); } ); -test( "widget", function() { - expect( 1 ); - - var element = $( "#calendar" ).calendar(), - widget = element.calendar( "widget" ); +test( "widget", function( assert ) { + assert.expect( 1 ); - strictEqual( widget[ 0 ], element[ 0 ] ); + strictEqual( this.widget[ 0 ], this.element[ 0 ] ); } ); -test( "value", function() { - expect( 3 ); - var element = $( "#calendar" ).calendar(); +test( "value", function( assert ) { + assert.expect( 3 ); - element.calendar( "value", "1/1/14" ); - ok( element.find( "button[data-timestamp]:first" ) + this.element.calendar( "value", "1/1/14" ); + ok( this.element.find( "button[data-ui-calendar-timestamp]:first" ) .hasClass( "ui-state-active" ), "first day marked as selected" ); - equal( element.calendar( "value" ), "1/1/14", "getter" ); + equal( this.element.calendar( "value" ), "1/1/14", "getter" ); - element.calendar( "value", "abc" ); - equal( element.calendar( "value" ), "1/1/14", "Setting invalid values should be ignored." ); + this.element.calendar( "value", "abc" ); + equal( this.element.calendar( "value" ), null, "Setting invalid values." ); } ); -test( "valueAsDate", function() { - expect( 11 ); +test( "valueAsDate", function( assert ) { + assert.expect( 11 ); var minDate, maxDate, dateAndTimeToSet, dateAndTimeClone, - element = $( "#calendar" ).calendar(), date1 = new Date( 2008, 6 - 1, 4 ), date2; - element.calendar( "valueAsDate", new Date( 2014, 0, 1 ) ); - ok( element.find( "button[data-timestamp]:first" ) + this.element.calendar( "valueAsDate", new Date( 2014, 0, 1 ) ); + ok( this.element.find( "button[data-ui-calendar-timestamp]:first" ) .hasClass( "ui-state-active" ), "First day marked as selected" ); - testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2014, 0, 1 ), "Getter" ); - - element.calendar( "destroy" ); + assert.dateEqual( this.element.calendar( "valueAsDate" ), new Date( 2014, 0, 1 ), "Getter" ); - element.calendar(); - equal( element.calendar( "valueAsDate" ), null, "Set date - default" ); + this.element.calendar( "destroy" ); + this.element.calendar(); + equal( this.element.calendar( "valueAsDate" ), null, "Set date - default" ); - element.calendar( "valueAsDate", date1 ); - testHelper.equalsDate( element.calendar( "valueAsDate" ), date1, "Set date - 2008-06-04" ); + this.element.calendar( "valueAsDate", date1 ); + assert.dateEqual( this.element.calendar( "valueAsDate" ), date1, "Set date - 2008-06-04" ); - // With minimum/maximum - element = $( "#calendar" ).calendar(); + // With minimum / maximum date1 = new Date( 2008, 1 - 1, 4 ); date2 = new Date( 2008, 6 - 1, 4 ); minDate = new Date( 2008, 2 - 1, 29 ); maxDate = new Date( 2008, 3 - 1, 28 ); - element + this.element .calendar( "option", { min: minDate } ) .calendar( "valueAsDate", date2 ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), + assert.dateEqual( + this.element.calendar( "valueAsDate" ), date2, "Set date min/max - value > min" ); - element.calendar( "valueAsDate", date1 ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), - date2, + this.element.calendar( "valueAsDate", date1 ); + equal( + this.element.calendar( "valueAsDate" ), + null, "Set date min/max - value < min" ); - element + this.element .calendar( "option", { max: maxDate, min: null } ) .calendar( "valueAsDate", date1 ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), + assert.dateEqual( + this.element.calendar( "valueAsDate" ), date1, "Set date min/max - value < max" ); - element.calendar( "valueAsDate", date2 ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), - date1, + this.element.calendar( "valueAsDate", date2 ); + equal( + this.element.calendar( "valueAsDate" ), + null, "Set date min/max - value > max" ); - element + this.element .calendar( "option", { min: minDate } ) .calendar( "valueAsDate", date1 ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), - date1, + equal( + this.element.calendar( "valueAsDate" ), + null, "Set date min/max - value < min" ); - element.calendar( "valueAsDate", date2 ); - testHelper.equalsDate( - element.calendar( "valueAsDate" ), - date1, "Set date min/max - value > max" + this.element.calendar( "valueAsDate", date2 ); + equal( + this.element.calendar( "valueAsDate" ), + null, "Set date min/max - value > max" ); dateAndTimeToSet = new Date( 2008, 3 - 1, 28, 1, 11, 0 ); dateAndTimeClone = new Date( 2008, 3 - 1, 28, 1, 11, 0 ); - element.calendar( "valueAsDate", dateAndTimeToSet ); + this.element.calendar( "valueAsDate", dateAndTimeToSet ); equal( dateAndTimeToSet.getTime(), dateAndTimeClone.getTime(), diff --git a/tests/unit/calendar/options.js b/tests/unit/calendar/options.js index c407f096a73..0afbfaf69cf 100644 --- a/tests/unit/calendar/options.js +++ b/tests/unit/calendar/options.js @@ -1,30 +1,38 @@ define( [ "jquery", - "./helper", "ui/widgets/calendar" -], function( $, testHelper ) { - -module( "calendar: options" ); +], function( $ ) { + +module( "calendar: options", { + setup: function() { + this.element = $( "#calendar" ).calendar(); + this.widget = this.element.calendar( "widget" ); + }, + teardown: function() { + this.element.calendar( "destroy" ); + } +} ); -test( "buttons", function() { - expect( 21 ); +test( "buttons", function( assert ) { + assert.expect( 21 ); var button, i, newButtons, + that = this, buttons = { "Ok": function( event ) { ok( true, "button click fires callback" ); - equal( this, element[ 0 ], "context of callback" ); + equal( this, that.element[ 0 ], "context of callback" ); equal( event.target, button[ 0 ], "event target" ); }, "Cancel": function( event ) { ok( true, "button click fires callback" ); - equal( this, element[ 0 ], "context of callback" ); + equal( this, that.element[ 0 ], "context of callback" ); equal( event.target, button[ 1 ], "event target" ); } - }, - element = $( "#calendar" ).calendar( { buttons: buttons } ); + }; - button = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" ); + this.element.calendar( { buttons: buttons } ); + button = this.widget.find( ".ui-calendar-buttonpane button" ); equal( button.length, 2, "number of buttons" ); i = 0; @@ -35,7 +43,7 @@ test( "buttons", function() { ok( button.parent().hasClass( "ui-calendar-buttonset" ), "buttons in container" ); ok( - element.calendar( "widget" ).hasClass( "ui-calendar-buttons" ), + this.element.calendar( "widget" ).hasClass( "ui-calendar-buttons" ), "calendar wrapper adds class about having buttons" ); @@ -44,24 +52,24 @@ test( "buttons", function() { newButtons = { "Close": function( event ) { ok( true, "button click fires callback" ); - equal( this, element[ 0 ], "context of callback" ); + equal( this, that.element[ 0 ], "context of callback" ); equal( event.target, button[ 0 ], "event target" ); } }; deepEqual( - element.calendar( "option", "buttons" ), + this.element.calendar( "option", "buttons" ), buttons, ".calendar('option', 'buttons') getter" ); - element.calendar( "option", "buttons", newButtons ); + this.element.calendar( "option", "buttons", newButtons ); deepEqual( - element.calendar( "option", "buttons" ), + this.element.calendar( "option", "buttons" ), newButtons, ".calendar('option', 'buttons', ...) setter" ); - button = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" ); + button = this.element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" ); equal( button.length, 1, "number of buttons after setter" ); button.trigger( "click" ); @@ -71,33 +79,33 @@ test( "buttons", function() { i += 1; } ); - element.calendar( "option", "buttons", null ); - button = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" ); + this.element.calendar( "option", "buttons", null ); + button = this.widget.find( ".ui-calendar-buttonpane button" ); equal( button.length, 0, "all buttons have been removed" ); - equal( element.find( ".ui-calendar-buttonset" ).length, 0, "buttonset has been removed" ); - equal( element.hasClass( "ui-calendar-buttons" ), false, "calendar element removes class about having buttons" ); - - element.remove(); + equal( this.element.find( ".ui-calendar-buttonset" ).length, 0, "buttonset has been removed" ); + equal( this.element.hasClass( "ui-calendar-buttons" ), false, "calendar element removes class about having buttons" ); } ); -test( "buttons - advanced", function() { - expect( 7 ); +test( "buttons - advanced", function( assert ) { + assert.expect( 7 ); - var buttons, - element = $( "#calendar" ).calendar( { - buttons: [ { - text: "a button", - "class": "additional-class", - id: "my-button-id", - click: function() { - equal( this, element[ 0 ], "correct context" ); - }, - icon: "ui-icon-cancel", - showLabel: false - } ] - } ); + var that = this, + buttons; + + this.element.calendar( { + buttons: [ { + text: "a button", + "class": "additional-class", + id: "my-button-id", + click: function() { + equal( this, that.element[ 0 ], "correct context" ); + }, + icon: "ui-icon-cancel", + showLabel: false + } ] + } ); - buttons = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" ); + buttons = this.widget.find( ".ui-calendar-buttonpane button" ); equal( buttons.length, 1, "correct number of buttons" ); equal( buttons.attr( "id" ), "my-button-id", "correct id" ); equal ( $.trim( buttons.text() ), "a button", "correct label" ); @@ -105,149 +113,145 @@ test( "buttons - advanced", function() { equal( buttons.button( "option", "icon" ), "ui-icon-cancel" ); equal( buttons.button( "option", "showLabel" ), false ); buttons.click(); - - element.remove(); } ); -test( "dateFormat", function() { - expect( 2 ); - var element = $( "#calendar" ).calendar(); +test( "dateFormat", function( assert ) { + assert.expect( 2 ); - element.calendar( "value", "1/1/14" ); + this.element.calendar( "value", "1/1/14" ); - element.calendar( "widget" ).find( "td[id]:first button" ).trigger( "mousedown" ); - equal( element.calendar( "value" ), "1/1/14", "default formatting" ); + this.widget.find( "td[id]:first button" ).trigger( "mousedown" ); + equal( this.element.calendar( "value" ), "1/1/14", "default formatting" ); - element.calendar( "option", "dateFormat", { date: "full" } ); - equal( element.calendar( "value" ), "Wednesday, January 1, 2014", "updated formatting" ); + this.element.calendar( "option", "dateFormat", { date: "full" } ); + equal( this.element.calendar( "value" ), "Wednesday, January 1, 2014", "updated formatting" ); } ); -test( "eachDay", function() { - expect( 5 ); +test( "eachDay", function( assert ) { + assert.expect( 5 ); + var timestamp, - input = $( "#calendar" ).calendar(), - picker = input.calendar( "widget" ), - firstCell = picker.find( "td[id]:first" ); + firstCell = this.widget.find( "td[id]:first" ); equal( firstCell.find( "button" ).length, 1, "days are selectable by default" ); - timestamp = parseInt( firstCell.find( "button" ).attr( "data-timestamp" ), 10 ); + timestamp = parseInt( firstCell.find( "button" ).attr( "data-ui-calendar-timestamp" ), 10 ); equal( new Date( timestamp ).getDate(), 1, "first available day is the 1st by default" ); // Do not render the 1st of the month - input.calendar( "option", "eachDay", function( day ) { + this.element.calendar( "option", "eachDay", function( day ) { if ( day.date === 1 ) { day.render = false; } } ); - firstCell = picker.find( "td[id]:first" ); - timestamp = parseInt( firstCell.find( "button" ).attr( "data-timestamp" ), 10 ); + firstCell = this.widget.find( "td[id]:first" ); + timestamp = parseInt( firstCell.find( "button" ).attr( "data-ui-calendar-timestamp" ), 10 ); equal( new Date( timestamp ).getDate(), 2, "first available day is the 2nd" ); // Display the 1st of the month but make it not selectable. - input.calendar( "option", "eachDay", function( day ) { + this.element.calendar( "option", "eachDay", function( day ) { if ( day.date === 1 ) { day.selectable = false; } } ); - firstCell = picker.find( "td[id]:first" ); + firstCell = this.widget.find( "td[id]:first" ); ok( firstCell.find( "button" ).prop( "disabled" ), "the 1st is not selectable" ); - input.calendar( "option", "eachDay", function( day ) { + this.element.calendar( "option", "eachDay", function( day ) { if ( day.date === 1 ) { day.extraClasses = "ui-custom"; } } ); - ok( picker.find( "td[id]:first button" ).hasClass( "ui-custom" ), "extraClasses applied" ); - - input.calendar( "destroy" ); + ok( this.widget.find( "td[id]:first button" ).hasClass( "ui-custom" ), "extraClasses applied" ); } ); test( "showWeek", function() { expect( 7 ); - var input = $( "#calendar" ).calendar(), - container = input.calendar( "widget" ); - equal( container.find( "thead th" ).length, 7, "just 7 days, no column cell" ); - equal( container.find( ".ui-calendar-week-col" ).length, 0, + equal( this.widget.find( "thead th" ).length, 7, "just 7 days, no column cell" ); + equal( this.widget.find( ".ui-calendar-week-col" ).length, 0, "no week column cells present" ); - input.calendar( "destroy" ); + this.element.calendar( "destroy" ); - input = $( "#calendar" ).calendar( { showWeek: true } ); - container = input.calendar( "widget" ); - equal( container.find( "thead th" ).length, 8, "7 days + a column cell" ); - ok( container.find( "thead th:first" ).is( ".ui-calendar-week-col" ), + this.element.calendar( { showWeek: true } ); + equal( this.widget.find( "thead th" ).length, 8, "7 days + a column cell" ); + ok( this.widget.find( "thead th:first" ).is( ".ui-calendar-week-col" ), "first cell should have ui-datepicker-week-col class name" ); - equal( container.find( ".ui-calendar-week-col" ).length, - container.find( "tr" ).length, "one week cell for each week" ); - input.calendar( "destroy" ); - - input = $( "#calendar" ).calendar(); - container = input.calendar( "widget" ); - equal( container.find( "thead th" ).length, 7, "no week column" ); - input.calendar( "option", "showWeek", true ); - equal( container.find( "thead th" ).length, 8, "supports changing option after init" ); + equal( this.widget.find( ".ui-calendar-week-col" ).length, + this.widget.find( "tr" ).length, "one week cell for each week" ); + this.element.calendar( "destroy" ); + + this.element.calendar(); + equal( this.widget.find( "thead th" ).length, 7, "no week column" ); + this.element.calendar( "option", "showWeek", true ); + equal( this.widget.find( "thead th" ).length, 8, "supports changing option after init" ); } ); -test( "min / max", function() { - expect( 17 ); +test( "min / max", function( assert ) { + assert.expect( 19 ); // With existing date - var element = $( "#calendar" ).calendar(), - container = element.calendar( "widget" ), - prevButton = container.find( ".ui-calendar-prev" ), - nextButton = container.find( ".ui-calendar-next" ), + var prevButton = this.widget.find( ".ui-calendar-prev" ), + nextButton = this.widget.find( ".ui-calendar-next" ), minDate = new Date( 2008, 2 - 1, 29 ), maxDate = new Date( 2008, 12 - 1, 7 ); - element + this.element .calendar( "option", { min: minDate } ) .calendar( "value", "6/4/08" ); - testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > min" ); + assert.dateEqual( this.element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > min" ); - element + this.element .calendar( "option", { min: minDate } ) .calendar( "value", "1/4/08" ); - testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value < min" ); + equal( this.element.calendar( "valueAsDate" ), null, "Min/max - value < min" ); - element + this.element .calendar( "option", { min: null } ) .calendar( "value", "6/4/08" ) .calendar( "option", { max: maxDate } ); - testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value < max" ); + assert.dateEqual( this.element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value < max" ); - element + this.element .calendar( "option", { max: maxDate } ) .calendar( "value", "1/4/09" ); - testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - setDate > max" ); + equal( this.element.calendar( "valueAsDate" ), null, "Min/max - setDate > max" ); - element + this.element .calendar( "option", { min: minDate, max: maxDate } ) .calendar( "value", "1/4/08" ); - testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value < min" ); + equal( this.element.calendar( "valueAsDate" ), null, "Min/max - value < min" ); - element + this.element .calendar( "option", { min: minDate, max: maxDate } ) .calendar( "value", "6/4/08" ); - testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > min, < max" ); + assert.dateEqual( this.element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > min, < max" ); - element + this.element .calendar( "option", { min: minDate, max: maxDate } ) .calendar( "value", "1/4/09" ); - testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > max" ); + equal( this.element.calendar( "valueAsDate" ), null, "Min/max - value > max" ); + + this.element.calendar( "option", { min: minDate } ); + this.element.calendar( "option", { min: "invalid" } ); + equal( this.element.calendar( "option", "min" ), null, "Min/max - invalid" ); - element + this.element.calendar( "option", { min: maxDate } ); + this.element.calendar( "option", { max: null } ); + equal( this.element.calendar( "option", "max" ), null, "Min/max - null" ); + + this.element .calendar( "option", { min: minDate, max: maxDate } ) .calendar( "value", "3/4/08" ); ok( !prevButton.hasClass( "ui-state-disabled" ), "Prev button enabled" ); prevButton.simulate( "click" ); ok( prevButton.hasClass( "ui-state-disabled" ), "Prev button disabled" ); - element.calendar( "value", "11/4/08" ); + this.element.calendar( "value", "11/4/08" ); ok( !nextButton.hasClass( "ui-state-disabled" ), "Next button enabled" ); nextButton.simulate( "click" ); ok( nextButton.hasClass( "ui-state-disabled" ), "Next button disabled" ); - element + this.element .calendar( "option", { max: null } ) .calendar( "value", "1/4/09" ) .calendar( "option", { min: minDate, max: maxDate } ); @@ -257,7 +261,7 @@ test( "min / max", function() { prevButton.simulate( "click" ); ok( !nextButton.hasClass( "ui-state-disabled" ), "Other year above max: Next button enabled after click" ); - element + this.element .calendar( "option", { min: null } ) .calendar( "value", "1/4/08" ) .calendar( "option", { min: minDate, max: maxDate } ); @@ -268,48 +272,71 @@ test( "min / max", function() { ok( !prevButton.hasClass( "ui-state-disabled" ), "Other year below min: Prev button enabled after click" ); } ); -test( "numberOfMonths", function() { - expect( 6 ); - var date = new Date( 2015, 8 - 1, 1 ), - input = $( "#calendar" ).calendar( { +test( "numberOfMonths", function( assert ) { + assert.expect( 6 ); + + var date = new Date( 2015, 8 - 1, 1 ); + + // Number of month option does not work after init + this.element + .calendar( "destroy" ) + .calendar( { numberOfMonths: 3, value: date - } ), - container = input.calendar( "widget" ); + } ); - equal( container.find( ".ui-calendar-group" ).length, 3, "3 calendar grids" ); + equal( this.widget.find( ".ui-calendar-group" ).length, 3, "3 calendar grids" ); equal( - container.find( "tbody:first td[id]:first" ).attr( "id" ), + this.widget.find( "tbody:first td[id]:first" ).attr( "id" ), "calendar-2015-7-1", "Correct id set for first day of first grid" ); equal( - container.find( "tbody:last td[id]:last" ).attr( "id" ), + this.widget.find( "tbody:last td[id]:last" ).attr( "id" ), "calendar-2015-9-31", "Correct id set for last day of third grid" ); // Test for jumping in weekday rendering after click on last day of last grid - container.find( "tbody:last td[id]:last button" ).trigger( "mousedown" ); - equal( container.find( "thead:last th:last" ).text(), "Sa", + this.widget.find( "tbody:last td[id]:last button" ).trigger( "mousedown" ); + equal( this.widget.find( "thead:last th:last" ).text(), "Sa", "After mousedown last month: Last day is Saturday" ); // Test if using cursor to go to the next / prev month advances three month // Focus doesn't work here so we use an additional mouse down event - container.find( "tbody:first td[id]:first button" ).trigger( "mousedown" ); + this.widget.find( "tbody:first td[id]:first button" ).trigger( "mousedown" ); $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } ); - equal( container.find( ".ui-calendar-month:first" ).text(), "May", + equal( this.widget.find( ".ui-calendar-month:first" ).text(), "May", "After move to previous month: First month is May" ); - container.find( "tbody:last td[id]:last button" ).trigger( "mousedown" ); + this.widget.find( "tbody:last td[id]:last button" ).trigger( "mousedown" ); $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ); - equal( container.find( ".ui-calendar-month:last" ).text(), "October", + equal( this.widget.find( ".ui-calendar-month:last" ).text(), "October", "After move to next month: Last month is October" ); } ); +test( "value", function( assert ) { + assert.expect( 4 ); + + var date = new Date( 2016, 5 - 1, 23 ); + + assert.equal( this.element.calendar( "option", "value" ), null, "Initial value" ); + + this.element.calendar( "option", "value", date ); + assert.dateEqual( this.element.calendar( "option", "value" ), date, "Value set" ); + assert.dateEqual( + new Date( this.widget.find( "table button.ui-state-active" ).data( "ui-calendar-timestamp" ) ), + new Date( 1463972400000 ), + "Active button timestamp" + ); + + this.element.calendar( "option", "value", "invalid" ); + equal( this.element.calendar( "option", "value" ), null, "Value after invalid parameter" ); +} ); + /* // TODO: Move this to $.date, Globalize or calendar widget test( "daylightSaving", function() { diff --git a/tests/unit/datepicker/common.js b/tests/unit/datepicker/common.js index 9074b78e6c5..527ddcbf341 100644 --- a/tests/unit/datepicker/common.js +++ b/tests/unit/datepicker/common.js @@ -42,6 +42,7 @@ common.testWidget( "datepicker", { // callbacks beforeOpen: null, + change: null, close: null, create: null, open: null, diff --git a/tests/unit/datepicker/core.js b/tests/unit/datepicker/core.js index 3370320753f..88e327b8b28 100644 --- a/tests/unit/datepicker/core.js +++ b/tests/unit/datepicker/core.js @@ -1,126 +1,122 @@ define( [ "jquery", - "./helper", "ui/widgets/datepicker" -], function( $, testHelper ) { - -module( "datepicker: core" ); - -test( "input's value determines starting date", function() { - expect( 3 ); +], function( $ ) { + +module( "datepicker: core", { + setup: function() { + this.element = $( "#datepicker" ).datepicker( { show: false, hide: false } ); + this.widget = this.element.datepicker( "widget" ); + }, + teardown: function() { + this.element.datepicker( "destroy" ).val( "" ); + } +} ); - var input = $( "#datepicker" ).val( "1/1/14" ).datepicker(), - picker = input.datepicker( "widget" ); +test( "input's value determines starting date", function( assert ) { + assert.expect( 3 ); - input.datepicker( "open" ); + this.element = $( "" ).appendTo( "#qunit-fixture" ); + this.element.val( "1/1/14" ).datepicker(); + this.widget = this.element.datepicker( "widget" ); - equal( picker.find( ".ui-calendar-month" ).html(), "January", "correct month displayed" ); - equal( picker.find( ".ui-calendar-year" ).html(), "2014", "correct year displayed" ); - equal( picker.find( ".ui-state-active" ).html(), "1", "correct day highlighted" ); + this.element.datepicker( "open" ); - input.val( "" ).datepicker( "destroy" ); + equal( this.widget.find( ".ui-calendar-month" ).html(), "January", "correct month displayed" ); + equal( this.widget.find( ".ui-calendar-year" ).html(), "2014", "correct year displayed" ); + equal( this.widget.find( ".ui-state-active" ).html(), "1", "correct day highlighted" ); } ); -asyncTest( "base structure", function() { - expect( 5 ); +asyncTest( "base structure", function( assert ) { + assert.expect( 5 ); - var input = testHelper.initNewInput(), - widget = input.datepicker( "widget" ); + var that = this; - input.focus(); + this.element.focus(); setTimeout( function() { - ok( widget.is( ":visible" ), "Datepicker visible" ); - equal( widget.children().length, 3, "Child count" ); - ok( widget.is( ".ui-calendar" ), "Class ui-calendar" ); - ok( widget.is( ".ui-datepicker" ), "Class ui-datepicker" ); - ok( widget.is( ".ui-front" ), "Class ui-front" ); + ok( that.widget.is( ":visible" ), "Datepicker visible" ); + equal( that.widget.children().length, 3, "Child count" ); + ok( that.widget.is( ".ui-calendar" ), "Class ui-calendar" ); + ok( that.widget.is( ".ui-datepicker" ), "Class ui-datepicker" ); + ok( that.widget.is( ".ui-front" ), "Class ui-front" ); - input.datepicker( "close" ); + that.element.datepicker( "close" ); start(); }, 50 ); } ); -asyncTest( "Keyboard handling: input", function() { - expect( 10 ); - var picker, instance, - input = $( "#datepicker" ).datepicker(); +asyncTest( "Keyboard handling: focus", function( assert ) { + assert.expect( 2 ); - function step1() { - testHelper.init( input ); - picker = input.datepicker( "widget" ); + var that = this; - ok( !picker.is( ":visible" ), "datepicker closed" ); + ok( !this.widget.is( ":visible" ), "datepicker closed" ); - input.val( "" ).focus(); - setTimeout( function() { - ok( picker.is( ":visible" ), "Datepicker opens when receiving focus" ); - input.datepicker( "destroy" ); - step2(); - }, 100 ); - } + this.element.focus(); + setTimeout( function() { + ok( that.widget.is( ":visible" ), "Datepicker opens when receiving focus" ); + start(); + }, 100 ); +} ); - function step2() { - testHelper.init( input ); - picker = input.datepicker( "widget" ); +asyncTest( "Keyboard handling: keystroke up", function( assert ) { + assert.expect( 2 ); - ok( !picker.is( ":visible" ), "datepicker closed" ); + var that = this; - input.val( "" ).simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); - setTimeout( function() { - ok( picker.is( ":visible" ), "Keystroke up opens datepicker" ); - input.datepicker( "destroy" ); - step3(); - }, 100 ); - } + ok( !this.widget.is( ":visible" ), "datepicker closed" ); - function step3() { - testHelper.init( input ); - instance = input.datepicker( "instance" ); - - // Enter = Select preset date - input - .val( "1/1/14" ) - .datepicker( "refresh" ) - .datepicker( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), - "Keystroke enter - preset" ); - - input - .val( "" ) - .datepicker( "open" ); - ok( instance.isOpen, "datepicker is open before escape" ); - - input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - ok( !instance.isOpen, "escape closes the datepicker" ); - - input - .val( "1/1/14" ) - .datepicker( "open" ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - testHelper.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), - "Keystroke esc - preset" ); - - input - .val( "1/1/14" ) - .datepicker( "open" ) - .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ) - .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - testHelper.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), - "Keystroke esc - abandoned" ); - - input - .val( "1/2/14" ) - .simulate( "keyup" ); - testHelper.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 2 ), - "Picker updated as user types into input" ); - - input.datepicker( "destroy" ); + this.element.simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); + setTimeout( function() { + ok( that.widget.is( ":visible" ), "Keystroke up opens datepicker" ); start(); - } + }, 100 ); +} ); - step1(); +test( "Keyboard handling: input", function( assert ) { + assert.expect( 6 ); + + var that = this, + instance = that.element.datepicker( "instance" ); + + // Enter = Select preset date + that.element + .val( "1/1/14" ) + .datepicker( "refresh" ) + .datepicker( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + assert.dateEqual( that.element.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), + "Keystroke enter - preset" ); + + that.element + .val( "" ) + .datepicker( "open" ); + ok( instance.isOpen, "datepicker is open before escape" ); + + that.element.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + ok( !instance.isOpen, "escape closes the datepicker" ); + + that.element + .val( "1/1/14" ) + .datepicker( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + assert.dateEqual( that.element.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), + "Keystroke esc - preset" ); + + that.element + .val( "1/1/14" ) + .datepicker( "open" ) + .simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + assert.dateEqual( that.element.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), + "Keystroke esc - abandoned" ); + + that.element + .val( "1/2/14" ) + .simulate( "keyup" ); + assert.dateEqual( that.element.datepicker( "valueAsDate" ), new Date( 2014, 0, 2 ), + "Picker updated as user types into input" ); } ); // TODO: implement @@ -128,40 +124,39 @@ test( "ARIA", function() { expect( 0 ); } ); -asyncTest( "mouse", function() { - expect( 4 ); +asyncTest( "mouse", function( assert ) { + assert.expect( 4 ); - var input = testHelper.init( $( "#datepicker" ).val( "" ) ), - picker = input.datepicker( "widget" ); + var that = this; - input.datepicker( "open" ); + this.element.datepicker( "open" ); setTimeout( function() { - input.val( "4/4/08" ).datepicker( "refresh" ).datepicker( "open" ); - $( ".ui-calendar-calendar tbody button:contains(12)", picker ).simulate( "mousedown", {} ); - testHelper.equalsDate( - input.datepicker( "valueAsDate" ), + that.element.val( "4/4/08" ).datepicker( "refresh" ).datepicker( "open" ); + $( ".ui-calendar-calendar tbody button:contains(12)", that.widget ).simulate( "mousedown", {} ); + assert.dateEqual( + that.element.datepicker( "valueAsDate" ), new Date( 2008, 4 - 1, 12 ), "Mouse click - preset" ); - input.val( "" ).datepicker( "refresh" ); - input.simulate( "click" ); - strictEqual( input.datepicker( "valueAsDate" ), null, "Mouse click - close" ); + that.element.val( "" ).datepicker( "refresh" ); + that.element.simulate( "click" ); + strictEqual( that.element.datepicker( "valueAsDate" ), null, "Mouse click - close" ); - input.val( "4/4/08" ).datepicker( "refresh" ).datepicker( "open" ); - input.simulate( "click" ); - testHelper.equalsDate( - input.datepicker( "valueAsDate" ), + that.element.val( "4/4/08" ).datepicker( "refresh" ).datepicker( "open" ); + that.element.simulate( "click" ); + assert.dateEqual( + that.element.datepicker( "valueAsDate" ), new Date( 2008, 4 - 1, 4 ), "Mouse click - close + preset" ); - input.val( "4/4/08" ).datepicker( "refresh" ).datepicker( "open" ); - picker.find( "a.ui-calendar-prev" ).simulate( "click" ); - input.simulate( "click" ); - testHelper.equalsDate( - input.datepicker( "valueAsDate" ), + that.element.val( "4/4/08" ).datepicker( "refresh" ).datepicker( "open" ); + that.widget.find( "a.ui-calendar-prev" ).simulate( "click" ); + that.element.simulate( "click" ); + assert.dateEqual( + that.element.datepicker( "valueAsDate" ), new Date( 2008, 4 - 1, 4 ), "Mouse click - abandoned" ); diff --git a/tests/unit/datepicker/datepicker.html b/tests/unit/datepicker/datepicker.html index 3b20272b13c..ae93487009f 100644 --- a/tests/unit/datepicker/datepicker.html +++ b/tests/unit/datepicker/datepicker.html @@ -14,7 +14,6 @@
-
diff --git a/tests/unit/datepicker/events.js b/tests/unit/datepicker/events.js index 902896f2a2a..cf10020843b 100644 --- a/tests/unit/datepicker/events.js +++ b/tests/unit/datepicker/events.js @@ -1,25 +1,34 @@ define( [ "jquery", - "./helper", "ui/widgets/datepicker" -], function( $, testHelper ) { +], function( $ ) { + +module( "datepicker: events", { + setup: function() { + this.element = $( "#datepicker" ).datepicker( { show: false, hide: false } ); + this.widget = this.element.datepicker( "widget" ); + }, + teardown: function() { + this.element.datepicker( "destroy" ).val( "" ); + } +} ); -module( "datepicker: events" ); +test( "beforeOpen", function( assert ) { + assert.expect( 3 ); -test( "beforeOpen", function() { - expect( 3 ); + var that = this; - var input = testHelper.init( "#datepicker", { - beforeOpen: function() { - ok( true, "beforeOpen event fired before open" ); - ok( input.datepicker( "widget" ).is( ":hidden" ), "calendar hidden on beforeOpen" ); - }, - open: function() { - ok( input.datepicker( "widget" ).is( ":visible" ), "calendar open on open" ); - } - } ); + this.element.datepicker( { + beforeOpen: function() { + ok( true, "beforeOpen event fired before open" ); + ok( that.element.datepicker( "widget" ).is( ":hidden" ), "calendar hidden on beforeOpen" ); + }, + open: function() { + ok( that.element.datepicker( "widget" ).is( ":visible" ), "calendar open on open" ); + } + } ); - input + this.element .datepicker( "open" ) .datepicker( "close" ) .datepicker( "option", { @@ -33,101 +42,133 @@ test( "beforeOpen", function() { .datepicker( "open" ); } ); -test( "close", function() { - expect( 4 ); +test( "change", function( assert ) { + assert.expect( 4 ); - var shouldFire, - input = testHelper.init( "#datepicker", { - close: function() { - ok( shouldFire, "close event fired" ); - } - } ); + var shouldFire; + + this.element.datepicker( { + change: function( event ) { + ok( shouldFire, "change event fired" ); + equal( + event.type, + "datepickerchange", + "change event" + ); + } + } ); + + shouldFire = true; + this.element.datepicker( "open" ); + this.widget.find( "tbody button" ).eq( 1 ).simulate( "mousedown" ); + + shouldFire = false; + this.element.datepicker( "open" ); + this.widget.find( "tbody button" ).eq( 1 ).simulate( "mousedown" ); + + shouldFire = true; + this.element.datepicker( "open" ); + this.widget.find( "tbody button" ).eq( 2 ).simulate( "mousedown" ); +} ); + +test( "close", function( assert ) { + assert.expect( 4 ); + + var shouldFire; + + this.element.datepicker( { + close: function() { + ok( shouldFire, "close event fired" ); + } + } ); shouldFire = false; - input.datepicker( "open" ); + this.element.datepicker( "open" ); shouldFire = true; - input.datepicker( "close" ); + this.element.datepicker( "close" ); shouldFire = false; - input.datepicker( "open" ); + this.element.datepicker( "open" ); shouldFire = true; $( "body" ).trigger( "mousedown" ); shouldFire = false; - input.datepicker( "open" ); + this.element.datepicker( "open" ); shouldFire = true; - input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + this.element.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); shouldFire = false; - input.datepicker( "open" ); + this.element.datepicker( "open" ); shouldFire = true; - input.datepicker( "widget" ).find( "tbody tr:first button:first" ).simulate( "mousedown" ); + this.widget.find( "tbody tr:first button:first" ).simulate( "mousedown" ); } ); -test( "open", function() { - expect( 2 ); +test( "open", function( assert ) { + assert.expect( 2 ); - var input = testHelper.init( "#datepicker", { - open: function() { - ok( true, "open event fired on open" ); - ok( widget.is( ":visible" ), "calendar open on open" ); - } - } ), - widget = input.datepicker( "widget" ); + var that = this; + + this.element.datepicker( { + open: function() { + ok( true, "open event fired on open" ); + ok( that.widget.is( ":visible" ), "calendar open on open" ); + } + } ); - input.datepicker( "open" ); + this.element.datepicker( "open" ); } ); -asyncTest( "select", function() { - expect( 4 ); - - var input = testHelper.init( "#datepicker", { - select: function( event ) { - ok( true, "select event fired " + message ); - equal( - event.originalEvent.type, - "calendarselect", - "select originalEvent " + message - ); - } - } ), - widget = input.datepicker( "widget" ), - message = ""; +asyncTest( "select", function( assert ) { + assert.expect( 4 ); + + var message = "", + that = this; + + this.element.datepicker( { + select: function( event ) { + ok( true, "select event fired " + message ); + equal( + event.originalEvent.type, + "calendarselect", + "select originalEvent " + message + ); + } + } ); function step1() { message = "on calendar cell click"; - input + that.element .simulate( "focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout( function() { - widget.find( "tbody tr:first button:first" ).simulate( "mousedown" ); - input.datepicker( "close" ); + that.widget.find( "tbody tr:first button:first" ).simulate( "mousedown" ); + that.element.datepicker( "close" ); step2(); }, 100 ); } function step2() { message = "on calendar cell enter"; - input + that.element .simulate( "focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout( function() { $( document.activeElement ) .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ) .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - input.datepicker( "close" ); + that.element.datepicker( "close" ); step3(); }, 100 ); } function step3() { message = "on calendar escape (not expected)"; - input + that.element .simulate( "focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout( function() { $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - input.datepicker( "close" ); + that.element.datepicker( "close" ); start(); }, 100 ); } diff --git a/tests/unit/datepicker/helper.js b/tests/unit/datepicker/helper.js deleted file mode 100644 index 81fdd9d0031..00000000000 --- a/tests/unit/datepicker/helper.js +++ /dev/null @@ -1,34 +0,0 @@ -define( [ - "jquery", - "lib/helper", - "ui/widgets/datepicker" -], function( $, helper ) { - -return $.extend( helper, { - addMonths: function( date, offset ) { - var maxDay = 32 - new Date( date.getFullYear(), date.getMonth() + offset, 32 ).getDate(); - date.setDate( Math.min( date.getDate(), maxDay ) ); - date.setMonth( date.getMonth() + offset ); - return date; - }, - equalsDate: function( d1, d2, message ) { - if ( !d1 || !d2 ) { - ok( false, message + " - missing date" ); - return; - } - d1 = new Date( d1.getFullYear(), d1.getMonth(), d1.getDate() ); - d2 = new Date( d2.getFullYear(), d2.getMonth(), d2.getDate() ); - equal( d1.toString(), d2.toString(), message ); - }, - init: function( id, options ) { - options = $.extend( { show: false, hide: false }, options || {} ); - return $( id ).datepicker( options ); - }, - initNewInput: function( options ) { - options = $.extend( { show: false, hide: false }, options || {} ); - return $( "" ).datepicker( options ) - .appendTo( "#qunit-fixture" ); - } -} ); - -} ); diff --git a/tests/unit/datepicker/methods.js b/tests/unit/datepicker/methods.js index 2cf83569819..161af1946f2 100644 --- a/tests/unit/datepicker/methods.js +++ b/tests/unit/datepicker/methods.js @@ -1,15 +1,23 @@ define( [ "jquery", - "./helper", "ui/widgets/datepicker" -], function( $, testHelper ) { - -module( "datepicker: methods" ); +], function( $ ) { + +module( "datepicker: methods", { + setup: function() { + this.element = $( "#datepicker" ).datepicker( { show: false, hide: false } ); + this.widget = this.element.datepicker( "widget" ); + }, + teardown: function() { + this.element.datepicker( "destroy" ).val( "" ); + } +} ); test( "destroy", function( assert ) { - expect( 3 ); + assert.expect( 3 ); + + var input = $( "" ).appendTo( "#qunit-fixture" ); - var input = $( "#datepicker" ); assert.domEqual( input, function() { input.datepicker(); ok( input.attr( "aria-owns" ), "aria-owns attribute added" ); @@ -18,111 +26,89 @@ test( "destroy", function( assert ) { } ); } ); -test( "enable / disable", function() { - expect( 10 ); - - var input = testHelper.init( "#datepicker" ), - calendar = input.datepicker( "widget" ); - - input.datepicker( "disable" ); - ok( input.datepicker( "option", "disabled" ), "disabled option is set" ); - ok( calendar.hasClass( "ui-datepicker-disabled" ), "has disabled widget class name" ); - ok( input.hasClass( "ui-state-disabled" ), "has disabled state class name" ); - equal( input.attr( "aria-disabled" ), "true", "has ARIA disabled" ); - equal( input.attr( "disabled" ), "disabled", "input disabled" ); - - input.datepicker( "enable" ); - ok( !input.datepicker( "option", "disabled" ), "enabled after enable() call" ); - ok( !calendar.hasClass( "ui-datepicker-disabled" ), "no longer has disabled widget class name" ); - ok( !input.hasClass( "ui-state-disabled" ), "no longer has disabled state class name" ); - equal( input.attr( "aria-disabled" ), "false", "no longer has ARIA disabled" ); - equal( input.attr( "disabled" ), undefined, "input no longer disabled" ); +test( "enable / disable", function( assert ) { + assert.expect( 10 ); + + this.element.datepicker( "disable" ); + ok( this.element.datepicker( "option", "disabled" ), "disabled option is set" ); + ok( this.widget.hasClass( "ui-datepicker-disabled" ), "has disabled widget class name" ); + ok( this.element.hasClass( "ui-state-disabled" ), "has disabled state class name" ); + equal( this.element.attr( "aria-disabled" ), "true", "has ARIA disabled" ); + equal( this.element.attr( "disabled" ), "disabled", "input disabled" ); + + this.element.datepicker( "enable" ); + ok( !this.element.datepicker( "option", "disabled" ), "enabled after enable() call" ); + ok( !this.widget.hasClass( "ui-datepicker-disabled" ), "no longer has disabled widget class name" ); + ok( !this.element.hasClass( "ui-state-disabled" ), "no longer has disabled state class name" ); + equal( this.element.attr( "aria-disabled" ), "false", "no longer has ARIA disabled" ); + equal( this.element.attr( "disabled" ), undefined, "input no longer disabled" ); } ); -test( "widget", function() { - expect( 1 ); +test( "widget", function( assert ) { + assert.expect( 1 ); - var actual = $( "#datepicker" ).datepicker().datepicker( "widget" ); - deepEqual( $( "body > .ui-front" )[ 0 ], actual[ 0 ] ); - actual.remove(); + deepEqual( $( "body > .ui-front" )[ 0 ], this.widget[ 0 ] ); + this.widget.remove(); } ); -test( "open / close", function() { - expect( 7 ); - - var input = testHelper.initNewInput( { show: false, hide: false } ), - calendar = input.datepicker( "widget" ); +test( "open / close", function( assert ) { + assert.expect( 7 ); - ok( calendar.is( ":hidden" ), "calendar hidden on init" ); + ok( this.widget.is( ":hidden" ), "calendar hidden on init" ); - input.datepicker( "open" ); - ok( calendar.is( ":visible" ), "open: calendar visible" ); - equal( calendar.attr( "aria-hidden" ), "false", "open: calendar aria-hidden" ); - equal( calendar.attr( "aria-expanded" ), "true", "close: calendar aria-expanded" ); + this.element.datepicker( "open" ); + ok( this.widget.is( ":visible" ), "open: calendar visible" ); + equal( this.widget.attr( "aria-hidden" ), "false", "open: calendar aria-hidden" ); + equal( this.widget.attr( "aria-expanded" ), "true", "close: calendar aria-expanded" ); - input.datepicker( "close" ); - ok( !calendar.is( ":visible" ), "close: calendar hidden" ); - equal( calendar.attr( "aria-hidden" ), "true", "close: calendar aria-hidden" ); - equal( calendar.attr( "aria-expanded" ), "false", "close: calendar aria-expanded" ); + this.element.datepicker( "close" ); + ok( !this.widget.is( ":visible" ), "close: calendar hidden" ); + equal( this.widget.attr( "aria-hidden" ), "true", "close: calendar aria-hidden" ); + equal( this.widget.attr( "aria-expanded" ), "false", "close: calendar aria-expanded" ); } ); -test( "value", function() { - expect( 4 ); +test( "value", function( assert ) { + assert.expect( 4 ); - var input = $( "#datepicker" ).datepicker(), - picker = input.datepicker( "widget" ); + this.element.datepicker( "value", "1/1/14" ); + equal( this.element.val(), "1/1/14", "input's value set" ); - input.datepicker( "value", "1/1/14" ); - equal( input.val(), "1/1/14", "input's value set" ); - - input.datepicker( "open" ); + this.element.datepicker( "open" ); ok( - picker.find( "button[data-timestamp]" ).eq( 0 ).hasClass( "ui-state-active" ), + this.widget.find( "button[data-ui-calendar-timestamp]" ).eq( 0 ).hasClass( "ui-state-active" ), "first day marked as selected" ); - equal( input.datepicker( "value" ), "1/1/14", "getter" ); + equal( this.element.datepicker( "value" ), "1/1/14", "getter" ); - input.val( "abc" ); - strictEqual( input.datepicker( "value" ), null, "Invalid values should return null." ); + this.element.val( "abc" ); + strictEqual( this.element.datepicker( "value" ), null, "Invalid values should return null." ); } ); -test( "valueAsDate", function() { - expect( 6 ); +test( "valueAsDate", function( assert ) { + assert.expect( 5 ); - var input = testHelper.init( "#datepicker" ), - picker = input.datepicker( "widget" ), - date1 = new Date( 2008, 6 - 1, 4 ); + strictEqual( this.element.datepicker( "valueAsDate" ), null, "Default" ); - input.datepicker( "valueAsDate", new Date( 2014, 0, 1 ) ); - equal( input.val(), "1/1/14", "Input's value set" ); + this.element.datepicker( "valueAsDate", new Date( 2014, 0, 1 ) ); + equal( this.element.val(), "1/1/14", "Input's value set" ); ok( - picker.find( "button[data-timestamp]" ).eq( 0 ).hasClass( "ui-state-active" ), + this.widget.find( "button[data-ui-calendar-timestamp]" ).eq( 0 ).hasClass( "ui-state-active" ), "First day marked as selected" ); - testHelper.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Getter" ); - - input.val( "a/b/c" ); - equal( input.datepicker( "valueAsDate" ), null, "Invalid dates return null" ); + assert.dateEqual( this.element.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Getter" ); - input.val( "" ).datepicker( "destroy" ); - input = testHelper.init( "#datepicker" ); - - strictEqual( input.datepicker( "valueAsDate" ), null, "Set date - default" ); - input.datepicker( "valueAsDate", date1 ); - testHelper.equalsDate( input.datepicker( "valueAsDate" ), date1, "Set date - 2008-06-04" ); + this.element.val( "a/b/c" ); + equal( this.element.datepicker( "valueAsDate" ), null, "Invalid dates return null" ); } ); -test( "isValid", function() { - expect( 2 ); - var input = $( "#datepicker" ).datepicker(); - - input.val( "1/1/14" ); - ok( input.datepicker( "isValid" ) ); +test( "isValid", function( assert ) { + assert.expect( 2 ); - input.val( "1/1/abc" ); - ok( !input.datepicker( "isValid" ) ); + this.element.val( "1/1/14" ); + ok( this.element.datepicker( "isValid" ) ); - input.datepicker( "destroy" ); + this.element.val( "1/1/abc" ); + ok( !this.element.datepicker( "isValid" ) ); } ); } ); diff --git a/tests/unit/datepicker/options.js b/tests/unit/datepicker/options.js index 6021f1b7e5c..b6e0cb13eae 100644 --- a/tests/unit/datepicker/options.js +++ b/tests/unit/datepicker/options.js @@ -1,51 +1,94 @@ define( [ "jquery", - "./helper", "ui/widgets/datepicker" -], function( $, testHelper ) { +], function( $ ) { + +module( "datepicker: options", { + setup: function() { + this.element = $( "#datepicker" ).datepicker( { show: false, hide: false } ); + this.widget = this.element.datepicker( "widget" ); + }, + teardown: function() { + this.element.datepicker( "destroy" ).val( "" ); + } +} ); -module( "datepicker: options" ); +test( "appendTo", function( assert ) { + assert.expect( 6 ); -test( "appendTo", function() { - expect( 6 ); - var container, - detached = $( "
" ), - input = $( "#datepicker" ); + var container = this.widget.parent()[ 0 ], + detached = $( "
" ); - input.datepicker(); - container = input.datepicker( "widget" ).parent()[ 0 ]; equal( container, document.body, "defaults to body" ); - input.datepicker( "destroy" ); + this.element.datepicker( "destroy" ); - input.datepicker( { appendTo: "#qunit-fixture" } ); - container = input.datepicker( "widget" ).parent()[ 0 ]; + this.element.datepicker( { appendTo: "#qunit-fixture" } ); + container = this.element.datepicker( "widget" ).parent()[ 0 ]; equal( container, $( "#qunit-fixture" )[ 0 ], "child of specified element" ); - input.datepicker( "destroy" ); + this.element.datepicker( "destroy" ); - input.datepicker( { appendTo: "#does-not-exist" } ); - container = input.datepicker( "widget" ).parent()[ 0 ]; + this.element.datepicker( { appendTo: "#does-not-exist" } ); + container = this.element.datepicker( "widget" ).parent()[ 0 ]; equal( container, document.body, "set to body if element does not exist" ); - input.datepicker( "destroy" ); + this.element.datepicker( "destroy" ); - input.datepicker() + this.element.datepicker() .datepicker( "option", "appendTo", "#qunit-fixture" ); - container = input.datepicker( "widget" ).parent()[ 0 ]; + container = this.element.datepicker( "widget" ).parent()[ 0 ]; equal( container, $( "#qunit-fixture" )[ 0 ], "modified after init" ); - input.datepicker( "destroy" ); + this.element.datepicker( "destroy" ); - input.datepicker( { appendTo: detached } ); - container = input.datepicker( "widget" ).parent()[ 0 ]; + this.element.datepicker( { appendTo: detached } ); + container = this.element.datepicker( "widget" ).parent()[ 0 ]; equal( container, detached[ 0 ], "detached jQuery object" ); - input.datepicker( "destroy" ); + this.element.datepicker( "destroy" ); - input.datepicker( { appendTo: detached[ 0 ] } ); - container = input.datepicker( "widget" ).parent()[ 0 ]; + this.element.datepicker( { appendTo: detached[ 0 ] } ); + container = this.element.datepicker( "widget" ).parent()[ 0 ]; equal( container, detached[ 0 ], "detached DOM element" ); - input.datepicker( "destroy" ); } ); -test( "Pass-through options", function() { - expect( 11 ); +test( "min / max", function( assert ) { + assert.expect( 10 ); + + var min, max; + + this.element.datepicker( "option", { min: "10/20/08", max: "10/25/08" } ); + assert.dateEqual( this.element.datepicker( "option", "min" ), new Date( 2008, 10 - 1, 20 ), "Set min option as string" ); + assert.dateEqual( this.element.datepicker( "option", "max" ), new Date( 2008, 10 - 1, 25 ), "Set max option as string" ); + + min = new Date( 2009, 10 - 1, 20 ); + max = new Date( 2009, 10 - 1, 25 ); + this.element.datepicker( "option", { min: min, max: max } ); + assert.dateEqual( this.element.datepicker( "option", "min" ), min, "Set min option as date object" ); + assert.dateEqual( this.element.datepicker( "option", "max" ), max, "Set max option as date object" ); + + this.element + .datepicker( "destroy" ) + .attr( "min", "2010-10-20" ) + .attr( "max", "2010-10-25" ) + .datepicker(); + assert.dateEqual( this.element.datepicker( "option", "min" ), new Date( 2010, 10 - 1, 20 ), "Set min option as attribute" ); + assert.dateEqual( this.element.datepicker( "option", "max" ), new Date( 2010, 10 - 1, 25 ), "Set max option as attribute" ); + + min = new Date( 2011, 10 - 1, 20 ); + max = new Date( 2011, 10 - 1, 25 ); + this.element + .datepicker( "destroy" ) + .datepicker( { min: min, max: max } ); + assert.dateEqual( this.element.datepicker( "option", "min" ), new Date( 2011, 10 - 1, 20 ), "Set min option as date object on init" ); + assert.dateEqual( this.element.datepicker( "option", "max" ), new Date( 2011, 10 - 1, 25 ), "Set max option as date object on init" ); + + this.element + .datepicker( "destroy" ) + .datepicker( { min: "10/20/12", max: "10/25/12" } ); + assert.dateEqual( this.element.datepicker( "option", "min" ), new Date( 2012, 10 - 1, 20 ), "Set min option as string on init" ); + assert.dateEqual( this.element.datepicker( "option", "max" ), new Date( 2012, 10 - 1, 25 ), "Set max option as string on init" ); + +} ); + +test( "Pass-through options", function( assert ) { + assert.expect( 11 ); var options = { buttons: { "Test": $.noop }, @@ -58,14 +101,14 @@ test( "Pass-through options", function() { numberOfMonths: 3, showWeek: true }, - input = $( "#datepicker" ).val( "1/1/14" ).datepicker(), - datepickerInstance = input.datepicker( "instance" ); + input = $( "" ).val( "1/1/14" ).appendTo( "#qunit-fixture" ).datepicker(), + instance = input.datepicker( "instance" ); $.each( options, function( key, value ) { input.datepicker( "option", key, value ); deepEqual( - datepickerInstance.calendar.calendar( "option", key ), + instance.calendar.calendar( "option", key ), value, "option " + key + ": correct value" ); @@ -81,7 +124,8 @@ test( "Pass-through options", function() { } ); asyncTest( "position", function( assert ) { - expect( 3 ); + assert.expect( 3 ); + var input = $( "" ).datepicker().appendTo( "body" ).css( { position: "absolute", top: 0, @@ -108,34 +152,39 @@ asyncTest( "position", function( assert ) { } ); } ); -test( "Stop datepicker from appearing with beforeOpen event handler", function() { - expect( 3 ); +test( "Stop datepicker from appearing with beforeOpen event handler - nothing", function( assert ) { + assert.expect( 1 ); - var input = testHelper.init( "#datepicker", { + this.element.datepicker( { beforeOpen: function() {} } ); - input.datepicker( "open" ); - ok( input.datepicker( "widget" ).is( ":visible" ), "beforeOpen returns nothing" ); - input.datepicker( "close" ).datepicker( "destroy" ); + this.element.datepicker( "open" ); + ok( this.element.datepicker( "widget" ).is( ":visible" ), "beforeOpen returns nothing" ); +} ); + +test( "Stop datepicker from appearing with beforeOpen event handler - true", function( assert ) { + assert.expect( 1 ); - input = testHelper.init( "#datepicker", { + this.element.datepicker( { beforeOpen: function() { return true; } } ); - input.datepicker( "open" ); - ok( input.datepicker( "widget" ).is( ":visible" ), "beforeOpen returns true" ); - input.datepicker( "close" ).datepicker( "destroy" ); + this.element.datepicker( "open" ); + ok( this.element.datepicker( "widget" ).is( ":visible" ), "beforeOpen returns true" ); +} ); + +test( "Stop datepicker from appearing with beforeOpen event handler - false", function( assert ) { + assert.expect( 1 ); - input = testHelper.init( "#datepicker", { + this.element.datepicker( { beforeOpen: function() { return false; } } ); - input.datepicker( "open" ); - ok( !input.datepicker( "widget" ).is( ":visible" ), "beforeOpen returns false" ); - input.datepicker( "destroy" ); + this.element.datepicker( "open" ); + ok( !this.element.datepicker( "widget" ).is( ":visible" ), "beforeOpen returns false" ); } ); } ); diff --git a/ui/widgets/calendar.js b/ui/widgets/calendar.js index 4c9a0354568..7e40313e724 100644 --- a/ui/widgets/calendar.js +++ b/ui/widgets/calendar.js @@ -72,6 +72,7 @@ return $.widget( "ui.calendar", { value: null, // callbacks + change: null, select: null }, @@ -108,16 +109,7 @@ return $.widget( "ui.calendar", { this.date.adjust( "M", this.options.numberOfMonths ); this._updateView(); }, - "mousedown .ui-calendar-calendar button": function( event ) { - this._setOption( "value", new Date( $( event.currentTarget ).data( "timestamp" ) ) ); - this._updateDayElement( "ui-state-active" ); - - // Allow datepicker to handle focus - if ( this._trigger( "select", event ) !== false ) { - this.activeDescendant.closest( this.grid ).focus(); - event.preventDefault(); - } - }, + "mousedown .ui-calendar-calendar button": "_select", "mouseenter .ui-calendar-header-buttons button": "_hover", "mouseleave .ui-calendar-header-buttons button": "_hover", "mouseenter .ui-calendar-calendar button": "_hover", @@ -133,12 +125,31 @@ return $.widget( "ui.calendar", { this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); }, + _select: function( event ) { + var oldValue = this.options.value ? this.options.value.getTime() : ""; + + this._setOption( "value", new Date( $( event.currentTarget ).data( "ui-calendar-timestamp" ) ) ); + this._updateDayElement( "ui-state-active" ); + + // Allow datepicker to handle focus + if ( this._trigger( "select", event ) !== false ) { + this.activeDescendant.closest( this.grid ).focus(); + event.preventDefault(); + } + + if ( oldValue !== this.options.value.getTime() ) { + this._trigger( "change", event ); + } + }, + _handleKeydown: function( event ) { var pageAltKey = ( event.altKey || event.ctrlKey && event.shiftKey ); switch ( event.keyCode ) { case $.ui.keyCode.ENTER: - this.activeDescendant.mousedown(); + this._select( + $.Event( event, { currentTarget: this.activeDescendant[ 0 ] } ) + ); return; case $.ui.keyCode.PAGE_UP: this.date.adjust( pageAltKey ? "Y" : "M", -1 ); @@ -478,7 +489,7 @@ return $.widget( "ui.calendar", { attributes = " class='" + classes.join( " " ) + "'"; if ( selectable ) { - attributes += " tabindex='-1' data-timestamp='" + day.timestamp + "'"; + attributes += " tabindex='-1' data-ui-calendar-timestamp='" + day.timestamp + "'"; } else { attributes += " disabled='disabled'"; } @@ -635,7 +646,8 @@ return $.widget( "ui.calendar", { if ( arguments.length ) { this.valueAsDate( this._parse( value ) ); } else { - return this._format( this.option( "value" ) ); + return this.option( "value" ) === null ? + null : this._format( this.option( "value" ) ); } }, @@ -705,13 +717,15 @@ return $.widget( "ui.calendar", { if ( key === "value" ) { if ( this._isValid( value ) ) { this.date.setTime( value.getTime() ); - this._super( key, value ); + } else { + value = null; } - return; } if ( key === "max" || key === "min" ) { - if ( $.type( value ) === "date" || value === null ) { + if ( $.type( value ) !== "date" || value === null ) { + this._super( key, null ); + } else { this._super( key, value ); } return; diff --git a/ui/widgets/datepicker.js b/ui/widgets/datepicker.js index 95bc0aa3365..6e1f5be737e 100644 --- a/ui/widgets/datepicker.js +++ b/ui/widgets/datepicker.js @@ -51,6 +51,7 @@ var widget = $.widget( "ui.datepicker", { // callbacks beforeOpen: null, + change: null, close: null, open: null, select: null @@ -61,12 +62,13 @@ var widget = $.widget( "ui.datepicker", { _create: function() { this.suppressExpandOnFocus = false; + this._parse = new Globalize( this.options.locale ).dateParser( this.options.dateFormat ); if ( $.type( this.options.max ) === "string" ) { - this.options.max = Globalize.parseDate( this.options.max, { raw: "yyyy-MM-dd" } ); + this.options.max = this._parse( this.options.max ); } if ( $.type( this.options.min ) === "string" ) { - this.options.min = Globalize.parseDate( this.options.min, { raw: "yyyy-MM-dd" } ); + this.options.min = this._parse( this.options.min ); } this._createCalendar(); @@ -79,22 +81,26 @@ var widget = $.widget( "ui.datepicker", { _getCreateOptions: function() { var max = this.element.attr( "max" ), min = this.element.attr( "min" ), + parser = function( value ) { + var exploded = value.split( "-" ); + + return new Date( exploded[ 0 ], exploded[ 1 ] - 1, exploded[ 2 ] ); + }, options = {}; if ( max !== undefined ) { - options.max = Globalize.parseDate( max, { raw: "yyyy-MM-dd" } ); + options.max = parser( max ); } if ( min !== undefined ) { - options.min = Globalize.parseDate( min, { raw: "yyyy-MM-dd" } ); + options.min = parser( min ); } return options; }, _createCalendar: function() { - var that = this, - globalize = new Globalize( this.options.locale ); + var that = this; this.calendar = $( "
" ).appendTo( this._appendTo() ); this._addClass( this.calendar, "ui-datepicker", "ui-front" ); @@ -102,7 +108,10 @@ var widget = $.widget( "ui.datepicker", { // Initialize calendar widget this.calendarInstance = this.calendar .calendar( $.extend( {}, this.options, { - value: globalize.dateParser( this.options.dateFormat )( this.element.val() ), + value: this._parse( this.element.val() ), + change: function( event ) { + that._trigger( "change", event ); + }, select: function( event ) { that.element.val( that.calendarInstance.value() ); that.close(); @@ -118,7 +127,6 @@ var widget = $.widget( "ui.datepicker", { this.calendarInstance.buttonClickContext = that.element[ 0 ]; this._setHiddenPicker(); - this.element.attr( { "aria-haspopup": true, "aria-owns": this.calendar.attr( "id" ) @@ -172,6 +180,9 @@ var widget = $.widget( "ui.datepicker", { }, blur: function() { this.suppressExpandOnFocus = false; + }, + change: function( event ) { + this._trigger( "change", event ); } }, @@ -302,7 +313,7 @@ var widget = $.widget( "ui.datepicker", { value: function( value ) { if ( arguments.length ) { - this.valueAsDate( this.calendarInstance._parse( value ) ); + this.valueAsDate( this._parse( value ) ); } else { return this._getParsedValue() ? this.element.val() : null; } @@ -334,10 +345,16 @@ var widget = $.widget( "ui.datepicker", { }, _getParsedValue: function() { - return this.calendarInstance._parse( this.element.val() ); + return this._parse( this.element.val() ); }, _setOption: function( key, value ) { + if ( key === "max" || key === "min" ) { + if ( typeof value === "string" ) { + value = this._parse( value ); + } + } + this._super( key, value ); if ( $.inArray( key, this.calendarOptions ) !== -1 ) {