diff --git a/Gruntfile.js b/Gruntfile.js index 1aac2c45435..dbd5441d638 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -163,7 +163,12 @@ grunt.initConfig({ findNestedDependencies: true, skipModuleInsertion: true, exclude: [ "jquery" ], - include: expandFiles( [ "ui/**/*.js", "!ui/core.js", "!ui/i18n/*" ] ), + include: expandFiles( [ + "ui/**/*.js", + "!ui/widgets/calendar.js", + "!ui/widgets/datepicker.js", + "!ui/i18n/*" + ] ), out: "dist/jquery-ui.js", wrap: { start: createBanner( uiFiles ), @@ -255,6 +260,16 @@ grunt.initConfig({ destPrefix: "external" }, files: { + "cldrjs/cldr.js": "cldrjs/dist/cldr.js", + "cldrjs/cldr/event.js": "cldrjs/dist/cldr/event.js", + "cldrjs/cldr/supplemental.js": "cldrjs/dist/cldr/supplemental.js", + "cldrjs/LICENSE-MIT": "cldrjs/LICENSE-MIT", + + "globalize/globalize-runtime.js": "globalize/dist/globalize-runtime.js", + "globalize/globalize-runtime/number.js": "globalize/dist/globalize-runtime/number.js", + "globalize/globalize-runtime/date.js": "globalize/dist/globalize-runtime/date.js", + "globalize/LICENSE.txt": "globalize/LICENSE.txt", + "qunit/qunit.js": "qunit/qunit/qunit.js", "qunit/qunit.css": "qunit/qunit/qunit.css", "qunit/LICENSE.txt": "qunit/LICENSE.txt", @@ -464,6 +479,41 @@ grunt.registerTask( "update-authors", function() { }); }); +grunt.registerTask( "compile-globalize", function() { + var formatters, + Globalize = require( "globalize" ), + globalizeCompiler = require( "globalize-compiler" ), + cldrData = require( "cldr-data" ), + languages = [ "ar", "en", "de", "es", "zh" ]; + + Globalize.load( cldrData.entireMainFor.apply( this, languages ) ); + Globalize.load( cldrData.entireSupplemental() ); + + formatters = languages.reduce( function( ret, language ) { + var globalize = new Globalize( language ); + + ret = ret.concat([ + globalize.dateFormatter( { raw: "EEEEEE" } ), + globalize.dateFormatter( { raw: "EEEEE" } ), + globalize.dateFormatter( { raw: "EEEE" } ), + globalize.dateFormatter( { raw: "MMMM" } ), + globalize.dateFormatter( { raw: "w" } ), + globalize.dateFormatter( { raw: "c" } ), + globalize.dateFormatter( { date: "short" } ), + globalize.dateParser( { date: "short" } ), + globalize.dateFormatter( { date: "long" } ), + globalize.dateParser( { date: "long" } ), + globalize.dateFormatter( { date: "full" } ), + globalize.dateParser( { date: "full" } ), + globalize.numberParser() + ]); + + return ret; + }, [] ); + + grunt.file.write( "external/localization.js", globalizeCompiler.compile( formatters ) ); +}); + grunt.registerTask( "default", [ "lint", "requirejs", "test" ]); grunt.registerTask( "jenkins", [ "default", "concat" ]); grunt.registerTask( "lint", [ "asciilint", "jshint", "jscs", "csslint", "htmllint" ]); diff --git a/bower.json b/bower.json index 1af4b8eadee..77fa8ac482a 100644 --- a/bower.json +++ b/bower.json @@ -20,6 +20,7 @@ "qunit-assert-close": "JamesMGreene/qunit-assert-close#v1.1.1", "qunit-composite": "JamesMGreene/qunit-composite#v1.1.0", "requirejs": "2.1.14", + "globalize": "1.1.1", "jquery-1.7.0": "jquery#1.7.0", "jquery-1.7.1": "jquery#1.7.1", diff --git a/build/tasks/testswarm.js b/build/tasks/testswarm.js index b7f8d33bff3..0b35f7f2a93 100644 --- a/build/tasks/testswarm.js +++ b/build/tasks/testswarm.js @@ -20,6 +20,7 @@ var versions = { "Accordion": "accordion/accordion.html", "Autocomplete": "autocomplete/autocomplete.html", "Button": "button/button.html", + "Calendar": "calendar/calendar.html", "Checkboxradio": "checkboxradio/checkboxradio.html", "Controlgroup": "controlgroup/controlgroup.html", "Core": "core/core.html", diff --git a/demos/bootstrap.js b/demos/bootstrap.js index 9a82071c797..0a109ef9e55 100644 --- a/demos/bootstrap.js +++ b/demos/bootstrap.js @@ -30,6 +30,7 @@ var widgets = [ "accordion", "autocomplete", "button", + "calendar", "checkboxradio", "controlgroup", "datepicker", @@ -80,12 +81,20 @@ document.documentElement.className = "demo-loading"; require.config( { baseUrl: window.location.pathname.indexOf( "demos/" ) !== -1 ? "../../ui" : "../../../ui", paths: { + cldr: "../external/cldrjs/cldr", + "globalize-runtime": "../external/globalize/globalize-runtime", + "globalize-locales": "../external/localization", jquery: "../external/jquery/jquery", external: "../external/" }, + map: { + "*": { + "globalize": "globalize-runtime" + } + }, shim: { - "external/globalize/globalize.culture.de-DE": [ "external/globalize/globalize" ], - "external/globalize/globalize.culture.ja-JP": [ "external/globalize/globalize" ] + "external/globalize-old/globalize.culture.de-DE": [ "external/globalize-old/globalize" ], + "external/globalize-old/globalize.culture.ja-JP": [ "external/globalize-old/globalize" ] } } ); diff --git a/demos/datepicker/dropdown-month-year.html b/demos/calendar/buttonbar.html similarity index 50% rename from demos/datepicker/dropdown-month-year.html rename to demos/calendar/buttonbar.html index ab3da5d0af3..28ee693cc31 100644 --- a/demos/datepicker/dropdown-month-year.html +++ b/demos/calendar/buttonbar.html @@ -3,23 +3,26 @@ - jQuery UI Datepicker - Display month & year menus + jQuery UI Calendar - Display button bar -

Date:

+
-

Show month and year dropdowns in place of the static month/year header to facilitate navigation through large timeframes. Add the boolean changeMonth and changeYear options.

+

Display a button for selecting Today's date with the buttons option.

diff --git a/demos/datepicker/inline.html b/demos/calendar/default.html similarity index 61% rename from demos/datepicker/inline.html rename to demos/calendar/default.html index 9e802672612..1a2cfdf77f3 100644 --- a/demos/datepicker/inline.html +++ b/demos/calendar/default.html @@ -3,20 +3,20 @@ - jQuery UI Datepicker - Display inline + jQuery UI Calendar - Default functionality -Date:
+
-

Display the datepicker embedded in the page instead of in an overlay. Simply call .datepicker() on a div instead of an input.

+

The calendar is a widget for selecting a date using a visual calendar representation.

diff --git a/demos/calendar/dropdown-month-year.html b/demos/calendar/dropdown-month-year.html new file mode 100644 index 00000000000..e305e879a6a --- /dev/null +++ b/demos/calendar/dropdown-month-year.html @@ -0,0 +1,82 @@ + + + + + + jQuery UI Calendar - Display month & year menus + + + + + + + +
+ +
+

Show month and year dropdowns in place of the static month/year header to facilitate navigation through large timeframes.

+
+ + diff --git a/demos/calendar/index.html b/demos/calendar/index.html new file mode 100644 index 00000000000..751301a0057 --- /dev/null +++ b/demos/calendar/index.html @@ -0,0 +1,22 @@ + + + + + + jQuery UI Calendar Demos + + + + + + + diff --git a/demos/calendar/localization.html b/demos/calendar/localization.html new file mode 100644 index 00000000000..2c2cc2310d1 --- /dev/null +++ b/demos/calendar/localization.html @@ -0,0 +1,41 @@ + + + + + + jQuery UI Calendar - Localize calendar + + + + + + + +
+ + +
+

Localize the calendar language and format (English / Western formatting is the default). The calendar includes built-in support for languages that read right-to-left, such as Arabic and Hebrew.

+
+ + diff --git a/demos/calendar/min-max.html b/demos/calendar/min-max.html new file mode 100644 index 00000000000..b3036b8739c --- /dev/null +++ b/demos/calendar/min-max.html @@ -0,0 +1,33 @@ + + + + + jQuery UI Calendar - Restrict date range + + + + + + + +
+ +
+

Restrict the range of selectable dates with the min and max options. Set the beginning and end dates as actual dates (new Date(2009, 1 - 1, 26)).

+
+ + diff --git a/demos/datepicker/multiple-calendars.html b/demos/calendar/multiple-months.html similarity index 65% rename from demos/datepicker/multiple-calendars.html rename to demos/calendar/multiple-months.html index 033b648a279..f83da1f8206 100644 --- a/demos/datepicker/multiple-calendars.html +++ b/demos/calendar/multiple-months.html @@ -3,23 +3,22 @@ - jQuery UI Datepicker - Display multiple months + jQuery UI Calendar - Display multiple months -

Date:

+
-

Set the numberOfMonths option to an integer of 2 or more to show multiple months in a single datepicker.

+

Set the numberOfMonths option to an integer of 2 or more to show multiple months in a single calendar.

diff --git a/demos/datepicker/other-months.html b/demos/calendar/other-months.html similarity index 58% rename from demos/datepicker/other-months.html rename to demos/calendar/other-months.html index ff86006445c..2fb4dacf84c 100644 --- a/demos/datepicker/other-months.html +++ b/demos/calendar/other-months.html @@ -3,23 +3,28 @@ - jQuery UI Datepicker - Dates in other months + jQuery UI Calendar - Dates in other months -

Date:

+
-

The datepicker can show dates that come from other than the main month +

The calendar can show dates that come from other than the main month being displayed. These other dates can also be made selectable.

diff --git a/demos/calendar/show-week.html b/demos/calendar/show-week.html new file mode 100644 index 00000000000..e148b657068 --- /dev/null +++ b/demos/calendar/show-week.html @@ -0,0 +1,26 @@ + + + + + + jQuery UI Calendar - Show week of the year + + + + + + + +
+ +
+

The calendar can show the week of the year. The calculation follows + Unicode CLDR specification. + This means that some days from one year may be placed into weeks 'belonging' to another year.

+
+ + diff --git a/demos/datepicker/alt-field.html b/demos/datepicker/alt-field.html deleted file mode 100644 index 77932571944..00000000000 --- a/demos/datepicker/alt-field.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - jQuery UI Datepicker - Populate alternate field - - - - - - - -

Date:  

- -
-

Populate an alternate field with its own date format whenever a date is selected using the altField and altFormat options. This feature could be used to present a human-friendly date for user selection, while passing a more computer-friendly date through for further processing.

-
- - diff --git a/demos/datepicker/animation.html b/demos/datepicker/animation.html index 7daf4bc6ce7..d493fad5346 100644 --- a/demos/datepicker/animation.html +++ b/demos/datepicker/animation.html @@ -10,7 +10,11 @@ @@ -20,16 +24,15 @@

Animations:

diff --git a/demos/datepicker/buttonbar.html b/demos/datepicker/buttonbar.html deleted file mode 100644 index 5b48179b49e..00000000000 --- a/demos/datepicker/buttonbar.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - jQuery UI Datepicker - Display button bar - - - - - - - -

Date:

- -
-

Display a button for selecting Today's date and a Done button for closing the calendar with the boolean showButtonPanel option. Each button is enabled by default when the bar is displayed, but can be turned off with additional options. Button text is customizable.

-
- - diff --git a/demos/datepicker/date-formats.html b/demos/datepicker/date-formats.html index 5e738b4ab5e..a234e223b36 100644 --- a/demos/datepicker/date-formats.html +++ b/demos/datepicker/date-formats.html @@ -8,9 +8,17 @@ @@ -20,12 +28,9 @@

Format options:

diff --git a/demos/datepicker/date-range.html b/demos/datepicker/date-range.html deleted file mode 100644 index 17581e1eb7d..00000000000 --- a/demos/datepicker/date-range.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - jQuery UI Datepicker - Select a Date Range - - - - - - - - - - - - -
-

Select the date range to search for.

-
- - diff --git a/demos/datepicker/icon-trigger.html b/demos/datepicker/icon-trigger.html index 71d0621d46b..ef3362a117a 100644 --- a/demos/datepicker/icon-trigger.html +++ b/demos/datepicker/icon-trigger.html @@ -8,12 +8,26 @@ @@ -21,7 +35,7 @@

Date:

-

Click the icon next to the input field to show the datepicker. Set the datepicker to open on focus (default behavior), on icon click, or both.

+

Click the icon next to the input field to show the datepicker. This demo will be removed soon since its promoting bad practice. Please see our migration guide.

diff --git a/demos/datepicker/index.html b/demos/datepicker/index.html index d9c8dfc10da..a56df7bd6e1 100644 --- a/demos/datepicker/index.html +++ b/demos/datepicker/index.html @@ -9,19 +9,10 @@ diff --git a/demos/datepicker/localization.html b/demos/datepicker/localization.html index 69835931a49..9537567f7ff 100644 --- a/demos/datepicker/localization.html +++ b/demos/datepicker/localization.html @@ -7,11 +7,19 @@ - @@ -19,15 +27,15 @@

Date:  

-

Localize the datepicker calendar language and format (English / Western formatting is the default). The datepicker includes built-in support for languages that read right-to-left, such as Arabic and Hebrew.

+

Localize the datepicker calendar language and format (English / Western formatting is the default). The datepicker includes built-in support for languages that read right-to-left, such as Arabic and Hebrew.

diff --git a/demos/datepicker/min-max.html b/demos/datepicker/min-max.html deleted file mode 100644 index 13b1b569e0c..00000000000 --- a/demos/datepicker/min-max.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - jQuery UI Datepicker - Restrict date range - - - - - - - -

Date:

- -
-

Restrict the range of selectable dates with the minDate and maxDate options. Set the beginning and end dates as actual dates (new Date(2009, 1 - 1, 26)), as a numeric offset from today (-20), or as a string of periods and units ('+1M +10D'). For the last, use 'D' for days, 'W' for weeks, 'M' for months, or 'Y' for years.

-
- - diff --git a/demos/datepicker/show-week.html b/demos/datepicker/show-week.html deleted file mode 100644 index 022d0271c9f..00000000000 --- a/demos/datepicker/show-week.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - jQuery UI Datepicker - Show week of the year - - - - - - - -

Date:

- -
-

The datepicker can show the week of the year. The default calculation follows - the ISO 8601 definition: the week starts on Monday, the first week of the year - contains the first Thursday of the year. This means that some days from one - year may be placed into weeks 'belonging' to another year.

-
- - diff --git a/demos/index.html b/demos/index.html index 89375dde704..b9d2f4e7944 100644 --- a/demos/index.html +++ b/demos/index.html @@ -11,6 +11,7 @@
  • accordion
  • autocomplete
  • button
  • +
  • calendar
  • checkboxradio
  • controlgroup
  • datepicker
  • diff --git a/demos/spinner/currency.html b/demos/spinner/currency.html index 4180b12e111..ad25359df2f 100644 --- a/demos/spinner/currency.html +++ b/demos/spinner/currency.html @@ -7,7 +7,12 @@ - - - + + + + + + + + + + + +
    +
    + +
    + + diff --git a/tests/unit/calendar/calendar.html b/tests/unit/calendar/calendar.html new file mode 100644 index 00000000000..1cd3e805125 --- /dev/null +++ b/tests/unit/calendar/calendar.html @@ -0,0 +1,21 @@ + + + + + jQuery UI Calendar Test Suite + + + + + + + +
    +
    + +
    +
    + +
    + + diff --git a/tests/unit/calendar/common.js b/tests/unit/calendar/common.js new file mode 100644 index 00000000000..1f3a0fe215b --- /dev/null +++ b/tests/unit/calendar/common.js @@ -0,0 +1,45 @@ +define( [ + "lib/common", + "ui/widgets/calendar", + "globalize-locales" +], function( common ) { + +common.testWidget( "calendar", { + defaults: { + buttons: [], + classes: { + "ui-calendar": "ui-corner-all", + "ui-calendar-header-first": "ui-corner-left", + "ui-calendar-header-last": "ui-corner-right", + "ui-calendar-prev": "ui-corner-all", + "ui-calendar-next": "ui-corner-all" + }, + disabled: false, + dateFormat: { date: "short" }, + eachDay: $.noop, + icons: { + prevButton: "ui-icon-circle-triangle-w", + nextButton: "ui-icon-circle-triangle-e" + }, + labels: { + "datePickerRole": "date picker", + "nextText": "Next", + "prevText": "Prev", + "weekHeader": "Wk" + }, + locale: "en", + max: null, + min: null, + numberOfMonths: 1, + showWeek: false, + value: null, + + // callbacks + change: null, + create: null, + refresh: null, + select: null + } +} ); + +} ); diff --git a/tests/unit/calendar/core.js b/tests/unit/calendar/core.js new file mode 100644 index 00000000000..a39e7a7064d --- /dev/null +++ b/tests/unit/calendar/core.js @@ -0,0 +1,444 @@ +define( [ + "qunit", + "jquery", + "./helper", + "ui/widgets/calendar" +], function( QUnit, $, testHelper ) { + +QUnit.module( "calendar: core", { + beforeEach: function() { + this.element = $( "#calendar" ).calendar(); + this.widget = this.element.calendar( "widget" ); + }, + afterEach: function() { + this.element.calendar( "destroy" ); + } +} ); + +QUnit.test( "base structure", function( assert ) { + assert.expect( 28 ); + + var that = this, + buttons, header, title, table, thead, week, child, buttonpane; + + function step1() { + assert.ok( !that.widget.is( ".ui-calendar-rtl" ), "Structure - not right-to-left" ); + assert.ok( !that.widget.is( ".ui-calendar-multi" ), "Structure - not multi-month" ); + assert.equal( that.widget.children().length, 3, "Structure - child count (header, calendar)" ); + + buttons = that.widget.children( ":first" ); + assert.ok( buttons.is( "div.ui-calendar-header-buttons" ), "Structure - header button division" ); + assert.equal( buttons.children().length, 2, "Structure - header buttons child count" ); + assert.ok( buttons.children( ":first" ).is( ".ui-calendar-prev" ) && buttons.children( ":first" ).html() !== "", "Structure - prev link" ); + assert.ok( buttons.children( ":last" ).is( ".ui-calendar-next" ) && buttons.children( ":last" ).html() !== "", "Structure - next link" ); + + header = that.widget.children( ":eq(1)" ); + assert.ok( header.is( "div.ui-calendar-header" ), "Structure - header division" ); + assert.equal( header.children().length, 1, "Structure - header child count" ); + + title = header.children( ":last" ).children( ":first" ); + assert.ok( title.is( "div.ui-calendar-title" ) && title.html() !== "", "Structure - title division" ); + assert.equal( title.children().length, 2, "Structure - title child count" ); + assert.ok( title.children( ":first" ).is( "span.ui-calendar-month" ) && title.children( ":first" ).text() !== "", "Structure - month text" ); + assert.ok( title.children( ":last" ).is( "span.ui-calendar-year" ) && title.children( ":last" ).text() !== "", "Structure - year text" ); + + table = that.widget.children( ":eq(2)" ); + assert.ok( table.is( "table.ui-calendar-calendar" ), "Structure - month table" ); + assert.ok( table.children( ":first" ).is( "thead" ), "Structure - month table thead" ); + + thead = table.children( ":first" ).children( ":first" ); + assert.ok( thead.is( "tr" ), "Structure - month table title row" ); + assert.equal( thead.find( "th" ).length, 7, "Structure - month table title cells" ); + assert.ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure - month table body" ); + assert.ok( table.children( ":eq(1)" ).children( "tr" ).length >= 4, "Structure - month table week count" ); + + week = table.children( ":eq(1)" ).children( ":first" ); + assert.ok( week.is( "tr" ), "Structure - month table week row" ); + assert.equal( week.children().length, 7, "Structure - week child count" ); + + step2(); + } + + function step2() { + that.element.calendar( "option", "buttons", { + "test": function() {}, + "test button": function() {} + } ); + + assert.equal( that.widget.children().length, 4, "Structure buttons - child count (header buttons, header, calendar, buttonpane)" ); + + buttonpane = that.widget.children( ".ui-calendar-buttonpane" ); + assert.equal( buttonpane.children( "div.ui-calendar-buttonset" ).length, 1, "Structure buttons - buttonset" ); + assert.equal( buttonpane.find( "button.ui-button:first" ).text(), "test", "Structure buttons - buttonset" ); + assert.equal( buttonpane.find( "button.ui-button:eq(1)" ).text(), "test button", "Structure buttons - buttonset" ); + + that.element.calendar( "destroy" ); + step3(); + } + + function step3() { + + // Multi-month 2 + that.element.calendar( { numberOfMonths: 2 } ); + + assert.ok( that.widget.is( ".ui-calendar-multi" ), "Structure multi [2] - multi-month" ); + assert.equal( that.widget.children().length, 4, "Structure multi [2] - child count" ); + + child = that.widget.children( ":eq(3)" ); + assert.ok( child.is( "div.ui-calendar-row-break" ), "Structure multi [2] - row break" ); + } + + step1(); +} ); + +QUnit.test( "Localization", function( assert ) { + assert.expect( 10 ); + + var that = this, + date = testHelper.createDate( 2014, 0, 1 ), + optionsDe = { + locale: "de", + labels: { + "nextText": "Vor", + "prevText": "Zurück" + } + }, + initCalendar = function( options ) { + that.element + .calendar( options ) + .calendar( "valueAsDate", date ); + }, + testLocalization = function( message ) { + assert.equal( + that.element.find( ".ui-calendar-month" ).text(), + "Januar", message + "titlebar year" + ); + assert.equal( + that.element.find( "thead th:first" ).text(), + "Mo.", message + "teader first day" + ); + assert.equal( + that.element.find( "thead th:last" ).text(), + "So.", message + "header last day" + ); + assert.equal( + that.element.find( ".ui-calendar-prev" ).text(), + "Zurück", message + "header prev" + ); + assert.equal( + that.element.find( ".ui-calendar-next" ).text(), + "Vor", message + "header next" + ); + }; + + initCalendar( optionsDe ); + testLocalization( "Init: " ); + that.element.calendar( "destroy" ); + + initCalendar( {} ); + that.element + .calendar( "option", optionsDe ) + .calendar( "refresh" ); + testLocalization( "After init: " ); +} ); + +QUnit.test( "keyboard handling", function( assert ) { + assert.expect( 10 ); + + var ready = assert.async(), + that = this; + + function step1() { + that.element.calendar( { value: testHelper.createDate( 2014, 1 - 1, 1 ) } ); + + testHelper + .focusGrid( that.element ) + .simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } ); + setTimeout( function() { + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + assert.dateEqual( + that.element.calendar( "valueAsDate" ), + testHelper.createDate( 2013, 12 - 1, 31 ), + "Keystroke left to switch to previous day" + ); + that.element.calendar( "destroy" ); + step2(); + }, 50 ); + } + + function step2() { + that.element.calendar( { value: testHelper.createDate( 2014, 1 - 1, 1 ) } ); + + testHelper.focusGrid( that.element ) + .simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + + assert.dateEqual( + that.element.calendar( "valueAsDate" ), + testHelper.createDate( 2014, 1 - 1, 2 ), + "Keystroke right to switch to next day" + ); + step3(); + } + + function step3() { + that.element.calendar( { value: testHelper.createDate( 2014, 1 - 1, 1 ) } ); + + testHelper.focusGrid( that.element ).simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); + setTimeout( function() { + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + assert.dateEqual( + that.element.calendar( "valueAsDate" ), + testHelper.createDate( 2013, 12 - 1, 25 ), + "Keystroke up to move to the previous week" + ); + that.element.calendar( "destroy" ); + step4(); + }, 50 ); + } + + function step4() { + that.element.calendar( { value: testHelper.createDate( 2014, 1 - 1, 1 ) } ); + + testHelper.focusGrid( that.element ).simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + setTimeout( function() { + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + assert.dateEqual( + that.element.calendar( "valueAsDate" ), + testHelper.createDate( 2014, 1 - 1, 8 ), + "Keystroke down to move to the next week" + ); + that.element.calendar( "destroy" ); + step5(); + }, 50 ); + } + + function step5() { + that.element.calendar( { value: testHelper.createDate( 2014, 1 - 1, 1 ) } ); + + testHelper.focusGrid( that.element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ); + setTimeout( function() { + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + assert.dateEqual( + that.element.calendar( "valueAsDate" ), + testHelper.createDate( 2013, 12 - 1, 1 ), + "Keystroke Page Up moves date to previous month" + ); + that.element.calendar( "destroy" ); + step6(); + }, 50 ); + } + + function step6() { + that.element.calendar( { value: testHelper.createDate( 2014, 1 - 1, 1 ) } ); + + testHelper.focusGrid( that.element ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP, altKey: true } ); + setTimeout( function() { + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + assert.dateEqual( + that.element.calendar( "valueAsDate" ), + testHelper.createDate( 2013, 1 - 1, 1 ), + "Keystroke Page Up + ALT moves date to previous year" + ); + that.element.calendar( "destroy" ); + step7(); + }, 50 ); + } + + function step7() { + that.element.calendar( { value: testHelper.createDate( 2014, 1 - 1, 1 ) } ); + + testHelper.focusGrid( that.element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); + setTimeout( function() { + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + assert.dateEqual( + that.element.calendar( "valueAsDate" ), + testHelper.createDate( 2014, 2 - 1, 1 ), + "Keystroke Page Down moves date to next month" + ); + that.element.calendar( "destroy" ); + step8(); + }, 50 ); + } + + function step8() { + that.element.calendar( { value: testHelper.createDate( 2014, 1 - 1, 1 ) } ); + + testHelper.focusGrid( that.element ) + .simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN, altKey: true } ); + setTimeout( function() { + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + assert.dateEqual( + that.element.calendar( "valueAsDate" ), + testHelper.createDate( 2015, 1 - 1, 1 ), + "Keystroke Page Down + ALT moves date to next year" + ); + that.element.calendar( "destroy" ); + step9(); + }, 50 ); + } + + // Check for moving to short months + function step9() { + that.element.calendar( { value: testHelper.createDate( 2014, 3 - 1, 31 ) } ); + + testHelper.focusGrid( that.element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ); + setTimeout( function() { + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + assert.dateEqual( + that.element.calendar( "valueAsDate" ), + testHelper.createDate( 2014, 2 - 1, 28 ), + "Keystroke Page Up and short months" + ); + that.element.calendar( "destroy" ); + step10(); + }, 50 ); + } + + function step10() { + that.element.calendar( { value: testHelper.createDate( 2016, 1 - 1, 30 ) } ); + + testHelper.focusGrid( that.element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); + setTimeout( function() { + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + assert.dateEqual( + that.element.calendar( "valueAsDate" ), + testHelper.createDate( 2016, 2 - 1, 29 ), + "Keystroke Page Down and leap years" + ); + ready(); + }, 50 ); + } + + step1(); +} ); + +QUnit.test( "mouse", function( assert ) { + assert.expect( 6 ); + + var ready = assert.async(), + that = this, + date = testHelper.createDate(); + + function step1() { + $( "tbody button:contains(10)", that.element ).simulate( "mousedown" ); + date.setDate( 10 ); + assert.dateEqual( + that.element.calendar( "valueAsDate" ), + date, + "Mouse click" + ); + + that.element.calendar( "option", "value", testHelper.createDate( 2008, 2 - 1, 4 ) ); + $( ".ui-calendar-calendar tbody button:contains(12)", that.element ).simulate( "mousedown" ); + assert.dateEqual( + that.element.calendar( "valueAsDate" ), + testHelper.createDate( 2008, 2 - 1, 12 ), + "Mouse click - preset" + ); + + // Previous/next + that.element.calendar( "option", "value", testHelper.createDate( 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" ), + testHelper.createDate( 2008, 1 - 1, 16 ), + "Mouse click - previous" + ); + + that.element.calendar( "option", "value", testHelper.createDate( 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" ), + testHelper.createDate( 2008, 3 - 1, 18 ), + "Mouse click - next" + ); + + step2(); + } + + // Previous/next with minimum/maximum + function step2() { + that.element.calendar( "destroy" ); + that.element.calendar( { + value: testHelper.createDate( 2008, 3 - 1, 4 ), + min: testHelper.createDate( 2008, 2 - 1, 2 ), + max: testHelper.createDate( 2008, 2 - 1, 26 ) + } ); + + $( ".ui-calendar-prev", that.element ).simulate( "click" ); + $( "tbody button:contains(16)", that.element ).simulate( "mousedown" ); + assert.dateEqual( + that.element.calendar( "valueAsDate" ), + testHelper.createDate( 2008, 2 - 1, 16 ), + "Mouse click - previous + min/max" + ); + step3(); + } + + function step3() { + that.element.calendar( "destroy" ); + that.element.calendar( { + value: testHelper.createDate( 2008, 1 - 1, 4 ), + min: testHelper.createDate( 2008, 2 - 1, 2 ), + max: testHelper.createDate( 2008, 2 - 1, 26 ) + } ); + + $( ".ui-calendar-next", that.element ).simulate( "click" ); + $( "tbody button:contains(18)", that.element ).simulate( "mousedown" ); + assert.dateEqual( + that.element.calendar( "valueAsDate" ), + testHelper.createDate( 2008, 2 - 1, 18 ), + "Mouse click - next + min/max" + ); + ready(); + } + + step1(); +} ); + +QUnit.test( "ARIA", function( assert ) { + assert.expect( 15 ); + + var id = this.element.attr( "id" ), + headerId = id + "-title", + monthLabelId = id + "-month-label", + table = this.element.find( "table" ); + + assert.equal( this.element.attr( "role" ), "region", "Role attribute" ); + assert.equal( this.element.attr( "aria-labelledby" ), headerId, + "ARIA label attribute" ); + + assert.equal( this.element.find( "#" + headerId ).attr( "role" ), "header", + "Header role attribute" ); + assert.equal( this.element.find( "#" + monthLabelId ).attr( "role" ), "alert", + "Header month label role attribute" ); + + assert.equal( table.attr( "role" ), "grid", "Table role attribute" ); + assert.equal( table.attr( "aria-readonly" ), "true", + "Table ARIA readonly attribute" ); + assert.equal( table.attr( "aria-labelledby" ), monthLabelId, + "Table ARIA labelledby attribute" ); + assert.equal( table.attr( "tabindex" ), 0, "Table tabindex attribute" ); + + assert.equal( table.children( "thead" ).attr( "role" ), "presentation", + "Table head role attribute" ); + assert.equal( table.find( "thead tr" ).attr( "role" ), "row", + "Table head row role attribute" ); + assert.equal( table.find( "thead th" ).first().attr( "role" ), "columnheader", + "Table head cell role attribute" ); + + assert.equal( table.children( "tbody" ).attr( "role" ), "presentation", + "Table body role attribute" ); + assert.equal( table.find( "tbody tr" ).attr( "role" ), "row", + "Table body row role attribute" ); + assert.equal( table.find( "tbody td" ).first().attr( "role" ), "gridcell", + "Table body cell role attribute" ); + assert.equal( table.find( "tbody td" ).first().attr( "aria-describedby" ), + monthLabelId, "Table body cell ARIA describedby attribute" ); +} ); + +} ); diff --git a/tests/unit/calendar/events.js b/tests/unit/calendar/events.js new file mode 100644 index 00000000000..7148ff343a9 --- /dev/null +++ b/tests/unit/calendar/events.js @@ -0,0 +1,123 @@ +define( [ + "qunit", + "jquery", + "./helper", + "ui/widgets/calendar" +], function( QUnit, $, testHelper ) { + +QUnit.module( "calendar: events", { + beforeEach: function() { + this.element = $( "#calendar" ).calendar(); + } +} ); + +QUnit.test( "change", function( assert ) { + assert.expect( 8 ); + + var shouldFire, eventType; + + this.element.calendar( { + change: function( event, ui ) { + assert.ok( shouldFire, "change event fired" ); + assert.equal( + event.type, + "calendarchange", + "change event" + ); + assert.equal( + event.originalEvent.type, + eventType, + "change originalEvent on calendar button " + eventType + ); + assert.equal( $.type( ui.value ), "date", "value is a date object" ); + } + } ); + + 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 ); +} ); + +QUnit.test( "select", function( assert ) { + assert.expect( 8 ); + + var ready = assert.async(), + that = this, + message, eventType; + + this.element.calendar( { + select: function( event, ui ) { + assert.ok( true, "select event fired " + message ); + assert.equal( + event.type, + "calendarselect", + "select event " + message + ); + assert.equal( + event.originalEvent.type, + eventType, + "select originalEvent " + message + ); + assert.equal( $.type( ui.value ), "date", "value is a date object" ); + } + } ); + + 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( ready, 50 ); + } + + step1(); +} ); + +QUnit.test( "refresh", function( assert ) { + assert.expect( 2 ); + + var shouldFire; + + this.element.calendar( { + refresh: function() { + assert.ok( shouldFire, "refresh event fired" ); + } + } ); + + shouldFire = true; + this.element.find( "button.ui-calendar-next" ).simulate( "click" ); + + shouldFire = false; + this.element.find( "table button:eq(1)" ).simulate( "click" ); + + testHelper.focusGrid( this.element ).simulate( "keydown", { keyCode: $.ui.keyCode.END } ); + shouldFire = true; + testHelper.focusGrid( this.element ).simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); +} ); + +} ); diff --git a/tests/unit/calendar/helper.js b/tests/unit/calendar/helper.js new file mode 100644 index 00000000000..e1575e71bc1 --- /dev/null +++ b/tests/unit/calendar/helper.js @@ -0,0 +1,27 @@ +define( [ + "jquery", + "lib/helper" +], function( $, helper ) { + +return $.extend( helper, { + createDate: function( year, month, day ) { + if ( arguments.length === 1 ) { + return new Date( year ); + } + + if ( arguments.length === 3 ) { + return new Date( year, month, day ); + } + + return new Date(); + }, + focusGrid: function( element ) { + element.find( ":tabbable" ).last().simulate( "focus" ); + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB } ); + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB } ); + + return $( document.activeElement ); + } +} ); + +} ); diff --git a/tests/unit/calendar/methods.js b/tests/unit/calendar/methods.js new file mode 100644 index 00000000000..c0948244057 --- /dev/null +++ b/tests/unit/calendar/methods.js @@ -0,0 +1,147 @@ +define( [ + "qunit", + "jquery", + "./helper", + "ui/widgets/calendar" +], function( QUnit, $, testHelper ) { + +QUnit.module( "calendar: methods", { + beforeEach: function() { + this.element = $( "#calendar" ).calendar(); + this.widget = this.element.calendar( "widget" ); + }, + afterEach: function() { + this.element.calendar( "destroy" ); + } +} ); + +QUnit.test( "destroy", function( assert ) { + assert.expect( 1 ); + + var div = $( "
    " ).appendTo( "#qunit-fixture" ); + + assert.domEqual( div, function() { + div.calendar().calendar( "destroy" ); + } ); +} ); + +QUnit.test( "enable / disable", function( assert ) { + assert.expect( 8 ); + + this.element.calendar( "disable" ); + assert.ok( this.element.calendar( "option", "disabled" ), "disabled option is set" ); + assert.ok( this.element.hasClass( "ui-calendar-disabled" ), "has disabled widget class name" ); + assert.ok( this.element.hasClass( "ui-state-disabled" ), "has disabled state class name" ); + assert.equal( this.element.attr( "aria-disabled" ), "true", "has ARIA disabled" ); + + this.element.calendar( "enable" ); + assert.ok( !this.element.calendar( "option", "disabled" ), "enabled after enable() call" ); + assert.ok( !this.element.hasClass( "ui-calendar-disabled" ), "no longer has disabled widget class name" ); + assert.ok( !this.element.hasClass( "ui-state-disabled" ), "no longer has disabled state class name" ); + assert.equal( this.element.attr( "aria-disabled" ), "false", "no longer has ARIA disabled" ); +} ); + +QUnit.test( "widget", function( assert ) { + assert.expect( 1 ); + + assert.strictEqual( this.widget[ 0 ], this.element[ 0 ] ); +} ); + +QUnit.test( "value", function( assert ) { + assert.expect( 3 ); + + this.element.calendar( "value", "1/1/14" ); + assert.ok( this.element.find( "button[data-ui-calendar-timestamp]:first" ) + .hasClass( "ui-state-active" ), + "first day marked as selected" + ); + assert.equal( this.element.calendar( "value" ), "1/1/14", "getter" ); + + this.element.calendar( "value", "abc" ); + assert.equal( this.element.calendar( "value" ), null, "Setting invalid values." ); +} ); + +QUnit.test( "valueAsDate", function( assert ) { + assert.expect( 11 ); + + var minDate, maxDate, dateAndTimeToSet, dateAndTimeClone, + date1 = testHelper.createDate( 2008, 6 - 1, 4 ), + date2; + + this.element.calendar( "valueAsDate", testHelper.createDate( 2014, 0, 1 ) ); + assert.ok( this.element.find( "button[data-ui-calendar-timestamp]:first" ) + .hasClass( "ui-state-active" ), + "First day marked as selected" + ); + assert.dateEqual( this.element.calendar( "valueAsDate" ), testHelper.createDate( 2014, 0, 1 ), "Getter" ); + + this.element.calendar( "destroy" ); + this.element.calendar(); + assert.equal( this.element.calendar( "valueAsDate" ), null, "Set date - default" ); + + this.element.calendar( "valueAsDate", date1 ); + assert.dateEqual( this.element.calendar( "valueAsDate" ), date1, "Set date - 2008-06-04" ); + + // With minimum / maximum + date1 = testHelper.createDate( 2008, 1 - 1, 4 ); + date2 = testHelper.createDate( 2008, 6 - 1, 4 ); + minDate = testHelper.createDate( 2008, 2 - 1, 29 ); + maxDate = testHelper.createDate( 2008, 3 - 1, 28 ); + + this.element + .calendar( "option", { min: minDate } ) + .calendar( "valueAsDate", date2 ); + assert.dateEqual( + this.element.calendar( "valueAsDate" ), + date2, "Set date min/max - value > min" + ); + + this.element.calendar( "valueAsDate", date1 ); + assert.equal( + this.element.calendar( "valueAsDate" ), + null, + "Set date min/max - value < min" + ); + + this.element + .calendar( "option", { max: maxDate, min: null } ) + .calendar( "valueAsDate", date1 ); + assert.dateEqual( + this.element.calendar( "valueAsDate" ), + date1, + "Set date min/max - value < max" + ); + + this.element.calendar( "valueAsDate", date2 ); + assert.equal( + this.element.calendar( "valueAsDate" ), + null, + "Set date min/max - value > max" + ); + + this.element + .calendar( "option", { min: minDate } ) + .calendar( "valueAsDate", date1 ); + assert.equal( + this.element.calendar( "valueAsDate" ), + null, + "Set date min/max - value < min" + ); + + this.element.calendar( "valueAsDate", date2 ); + assert.equal( + this.element.calendar( "valueAsDate" ), + null, "Set date min/max - value > max" + ); + + dateAndTimeToSet = testHelper.createDate( 2008, 3 - 1, 28, 1, 11, 0 ); + dateAndTimeClone = testHelper.createDate( 2008, 3 - 1, 28, 1, 11, 0 ); + this.element.calendar( "valueAsDate", dateAndTimeToSet ); + assert.equal( + dateAndTimeToSet.getTime(), + dateAndTimeClone.getTime(), + "Date object passed should not be changed by valueAsDate" + ); +} ); + +} ); diff --git a/tests/unit/calendar/options.js b/tests/unit/calendar/options.js new file mode 100644 index 00000000000..6c813eb22b1 --- /dev/null +++ b/tests/unit/calendar/options.js @@ -0,0 +1,336 @@ +define( [ + "qunit", + "jquery", + "./helper", + "ui/widgets/calendar" +], function( QUnit, $, testHelper ) { + +QUnit.module( "calendar: options", { + beforeEach: function() { + this.element = $( "#calendar" ).calendar(); + this.widget = this.element.calendar( "widget" ); + }, + afterEach: function() { + this.element.calendar( "destroy" ); + } +} ); + +QUnit.test( "buttons", function( assert ) { + assert.expect( 21 ); + + var button, i, newButtons, + that = this, + buttons = { + "Ok": function( event ) { + assert.ok( true, "button click fires callback" ); + assert.equal( this, that.element[ 0 ], "context of callback" ); + assert.equal( event.target, button[ 0 ], "event target" ); + }, + "Cancel": function( event ) { + assert.ok( true, "button click fires callback" ); + assert.equal( this, that.element[ 0 ], "context of callback" ); + assert.equal( event.target, button[ 1 ], "event target" ); + } + }; + + this.element.calendar( { buttons: buttons } ); + button = this.widget.find( ".ui-calendar-buttonpane button" ); + assert.equal( button.length, 2, "number of buttons" ); + + i = 0; + $.each( buttons, function( key ) { + assert.equal( button.eq( i ).text(), key, "text of button " + ( i + 1 ) ); + i++; + } ); + + assert.ok( button.parent().hasClass( "ui-calendar-buttonset" ), "buttons in container" ); + assert.ok( + this.element.calendar( "widget" ).hasClass( "ui-calendar-buttons" ), + "calendar wrapper adds class about having buttons" + ); + + button.trigger( "click" ); + + newButtons = { + "Close": function( event ) { + assert.ok( true, "button click fires callback" ); + assert.equal( this, that.element[ 0 ], "context of callback" ); + assert.equal( event.target, button[ 0 ], "event target" ); + } + }; + + assert.deepEqual( + this.element.calendar( "option", "buttons" ), + buttons, + ".calendar('option', 'buttons') getter" + ); + this.element.calendar( "option", "buttons", newButtons ); + assert.deepEqual( + this.element.calendar( "option", "buttons" ), + newButtons, + ".calendar('option', 'buttons', ...) setter" + ); + + button = this.element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" ); + assert.equal( button.length, 1, "number of buttons after setter" ); + button.trigger( "click" ); + + i = 0; + $.each( newButtons, function( key ) { + assert.equal( button.eq( i ).text(), key, "text of button " + ( i + 1 ) ); + i += 1; + } ); + + this.element.calendar( "option", "buttons", null ); + button = this.widget.find( ".ui-calendar-buttonpane button" ); + assert.equal( button.length, 0, "all buttons have been removed" ); + assert.equal( this.element.find( ".ui-calendar-buttonset" ).length, 0, "buttonset has been removed" ); + assert.equal( this.element.hasClass( "ui-calendar-buttons" ), false, "calendar element removes class about having buttons" ); +} ); + +QUnit.test( "buttons - advanced", function( assert ) { + assert.expect( 7 ); + + var that = this, + buttons; + + this.element.calendar( { + buttons: [ { + text: "a button", + "class": "additional-class", + id: "my-button-id", + click: function() { + assert.equal( this, that.element[ 0 ], "correct context" ); + }, + icon: "ui-icon-cancel", + showLabel: false + } ] + } ); + + buttons = this.widget.find( ".ui-calendar-buttonpane button" ); + assert.equal( buttons.length, 1, "correct number of buttons" ); + assert.equal( buttons.attr( "id" ), "my-button-id", "correct id" ); + assert.equal( $.trim( buttons.text() ), "a button", "correct label" ); + assert.ok( buttons.hasClass( "additional-class" ), "additional classes added" ); + assert.equal( buttons.button( "option", "icon" ), "ui-icon-cancel" ); + assert.equal( buttons.button( "option", "showLabel" ), false ); + buttons.click(); +} ); + +QUnit.test( "dateFormat", function( assert ) { + assert.expect( 2 ); + + this.element.calendar( "value", "1/1/14" ); + + this.widget.find( "td[id]:first button" ).trigger( "mousedown" ); + assert.equal( this.element.calendar( "value" ), "1/1/14", "default formatting" ); + + this.element.calendar( "option", "dateFormat", { date: "full" } ); + assert.equal( this.element.calendar( "value" ), "Wednesday, January 1, 2014", "updated formatting" ); +} ); + +QUnit.test( "eachDay", function( assert ) { + assert.expect( 5 ); + + var timestamp, + firstCell = this.widget.find( "td[id]:first" ); + + assert.equal( firstCell.find( "button" ).length, 1, "days are selectable by default" ); + timestamp = parseInt( firstCell.find( "button" ).attr( "data-ui-calendar-timestamp" ), 10 ); + assert.equal( testHelper.createDate( timestamp ).getDate(), 1, "first available day is the 1st by default" ); + + // Do not render the 1st of the month + this.element.calendar( "option", "eachDay", function( day ) { + if ( day.date === 1 ) { + day.render = false; + } + } ); + firstCell = this.widget.find( "td[id]:first" ); + timestamp = parseInt( firstCell.find( "button" ).attr( "data-ui-calendar-timestamp" ), 10 ); + assert.equal( testHelper.createDate( timestamp ).getDate(), 2, "first available day is the 2nd" ); + + // Display the 1st of the month but make it not selectable. + this.element.calendar( "option", "eachDay", function( day ) { + if ( day.date === 1 ) { + day.selectable = false; + } + } ); + firstCell = this.widget.find( "td[id]:first" ); + assert.ok( firstCell.find( "button" ).prop( "disabled" ), "the 1st is not selectable" ); + + this.element.calendar( "option", "eachDay", function( day ) { + if ( day.date === 1 ) { + day.extraClasses = "ui-custom"; + } + } ); + assert.ok( this.widget.find( "td[id]:first button" ).hasClass( "ui-custom" ), "extraClasses applied" ); +} ); + +QUnit.test( "showWeek", function( assert ) { + assert.expect( 7 ); + + assert.equal( this.widget.find( "thead th" ).length, 7, "just 7 days, no column cell" ); + assert.equal( this.widget.find( ".ui-calendar-week-col" ).length, 0, + "no week column cells present" ); + this.element.calendar( "destroy" ); + + this.element.calendar( { showWeek: true } ); + assert.equal( this.widget.find( "thead th" ).length, 8, "7 days + a column cell" ); + assert.ok( this.widget.find( "thead th:first" ).is( ".ui-calendar-week-col" ), + "first cell should have ui-datepicker-week-col class name" ); + assert.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(); + assert.equal( this.widget.find( "thead th" ).length, 7, "no week column" ); + this.element.calendar( "option", "showWeek", true ); + assert.equal( this.widget.find( "thead th" ).length, 8, "supports changing option after init" ); +} ); + +QUnit.test( "min / max", function( assert ) { + assert.expect( 19 ); + + // With existing date + var prevButton = this.widget.find( ".ui-calendar-prev" ), + nextButton = this.widget.find( ".ui-calendar-next" ), + minDate = testHelper.createDate( 2008, 2 - 1, 29 ), + maxDate = testHelper.createDate( 2008, 12 - 1, 7 ); + + this.element + .calendar( "option", { min: minDate } ) + .calendar( "value", "6/4/08" ); + assert.dateEqual( this.element.calendar( "valueAsDate" ), testHelper.createDate( 2008, 6 - 1, 4 ), "Min/max - value > min" ); + + this.element + .calendar( "option", { min: minDate } ) + .calendar( "value", "1/4/08" ); + assert.equal( this.element.calendar( "valueAsDate" ), null, "Min/max - value < min" ); + + this.element + .calendar( "option", { min: null } ) + .calendar( "value", "6/4/08" ) + .calendar( "option", { max: maxDate } ); + assert.dateEqual( this.element.calendar( "valueAsDate" ), testHelper.createDate( 2008, 6 - 1, 4 ), "Min/max - value < max" ); + + this.element + .calendar( "option", { max: maxDate } ) + .calendar( "value", "1/4/09" ); + assert.equal( this.element.calendar( "valueAsDate" ), null, "Min/max - setDate > max" ); + + this.element + .calendar( "option", { min: minDate, max: maxDate } ) + .calendar( "value", "1/4/08" ); + assert.equal( this.element.calendar( "valueAsDate" ), null, "Min/max - value < min" ); + + this.element + .calendar( "option", { min: minDate, max: maxDate } ) + .calendar( "value", "6/4/08" ); + assert.dateEqual( this.element.calendar( "valueAsDate" ), testHelper.createDate( 2008, 6 - 1, 4 ), "Min/max - value > min, < max" ); + + this.element + .calendar( "option", { min: minDate, max: maxDate } ) + .calendar( "value", "1/4/09" ); + assert.equal( this.element.calendar( "valueAsDate" ), null, "Min/max - value > max" ); + + this.element.calendar( "option", { min: minDate } ); + this.element.calendar( "option", { min: "invalid" } ); + assert.equal( this.element.calendar( "option", "min" ), null, "Min/max - invalid" ); + + this.element.calendar( "option", { min: maxDate } ); + this.element.calendar( "option", { max: null } ); + assert.equal( this.element.calendar( "option", "max" ), null, "Min/max - null" ); + + this.element + .calendar( "option", { min: minDate, max: maxDate } ) + .calendar( "value", "3/4/08" ); + assert.ok( !prevButton.hasClass( "ui-state-disabled" ), "Prev button enabled" ); + prevButton.simulate( "click" ); + assert.ok( prevButton.hasClass( "ui-state-disabled" ), "Prev button disabled" ); + + this.element.calendar( "value", "11/4/08" ); + assert.ok( !nextButton.hasClass( "ui-state-disabled" ), "Next button enabled" ); + nextButton.simulate( "click" ); + assert.ok( nextButton.hasClass( "ui-state-disabled" ), "Next button disabled" ); + + this.element + .calendar( "option", { max: null } ) + .calendar( "value", "1/4/09" ) + .calendar( "option", { min: minDate, max: maxDate } ); + assert.ok( nextButton.hasClass( "ui-state-disabled" ), "Other year above max: Next button disabled" ); + prevButton.simulate( "click" ); + assert.ok( nextButton.hasClass( "ui-state-disabled" ), "Other year above max: Next button disabled after click" ); + prevButton.simulate( "click" ); + assert.ok( !nextButton.hasClass( "ui-state-disabled" ), "Other year above max: Next button enabled after click" ); + + this.element + .calendar( "option", { min: null } ) + .calendar( "value", "1/4/08" ) + .calendar( "option", { min: minDate, max: maxDate } ); + assert.ok( prevButton.hasClass( "ui-state-disabled" ), "Other year below min: Prev button disabled" ); + nextButton.simulate( "click" ); + assert.ok( prevButton.hasClass( "ui-state-disabled" ), "Other year below min: Prev button disabled after click" ); + nextButton.simulate( "click" ); + assert.ok( !prevButton.hasClass( "ui-state-disabled" ), "Other year below min: Prev button enabled after click" ); +} ); + +QUnit.test( "numberOfMonths", function( assert ) { + assert.expect( 6 ); + + var date = testHelper.createDate( 2015, 8 - 1, 1 ); + + this.element.calendar( "option", { + numberOfMonths: 3, + value: date + } ); + + assert.equal( this.widget.find( ".ui-calendar-group" ).length, 3, "3 calendar grids" ); + assert.equal( + this.widget.find( "tbody:first td[id]:first" ).attr( "id" ), + "calendar-2015-7-1", + "Correct id set for first day of first grid" + ); + assert.equal( + 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 + this.widget.find( "tbody:last td[id]:last button" ).trigger( "mousedown" ); + assert.equal( this.widget.find( "thead:last th:last" ).text(), "Sa", + "After mousedown last month: Last day is Saturday" + ); + + this.widget.find( "button.ui-calendar-prev" ).simulate( "click" ); + assert.equal( this.widget.find( ".ui-calendar-month:first" ).text(), "May", + "After move to previous month: First month is May" + ); + + this.widget.find( "tbody:last td[id]:last button" ).trigger( "mousedown" ); + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ); + assert.equal( this.widget.find( ".ui-calendar-month:last" ).text(), "October", + "After move to next month: Last month is October" + ); +} ); + +QUnit.test( "value", function( assert ) { + assert.expect( 4 ); + + var date = testHelper.createDate( 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( + testHelper.createDate( this.widget.find( "table button.ui-state-active" ).data( "ui-calendar-timestamp" ) ), + testHelper.createDate( 1463972400000 ), + "Active button timestamp" + ); + + this.element.calendar( "option", "value", "invalid" ); + assert.equal( this.element.calendar( "option", "value" ), null, "Value after invalid parameter" ); +} ); + +} ); diff --git a/tests/unit/date/all.html b/tests/unit/date/all.html new file mode 100644 index 00000000000..5248d7ace6a --- /dev/null +++ b/tests/unit/date/all.html @@ -0,0 +1,26 @@ + + + + + jQuery UI Date Test Suite + + + + + + + + + + + + + +
    +
    + +
    + + \ No newline at end of file diff --git a/tests/unit/date/core.js b/tests/unit/date/core.js new file mode 100644 index 00000000000..e52ab183cbb --- /dev/null +++ b/tests/unit/date/core.js @@ -0,0 +1,174 @@ +define( [ + "qunit", + "jquery", + "./helper", + "ui/date" +], function( QUnit, $, testHelper ) { + +QUnit.module( "date: core" ); + +var attributes = testHelper.getAttributes( "en" ); + +QUnit.test( "Instantiation", function( assert ) { + assert.expect( 2 ); + assert.ok( new $.ui.date( null, attributes ) instanceof $.ui.date, "constructor function" ); + assert.ok( $.ui.date( null, attributes ) instanceof $.ui.date, "instantiation without new" ); +} ); + +QUnit.test( "Check Sets and Gets", 6, function( assert ) { +var date = $.ui.date( null, attributes ); + assert.equal( date.setFullDate( 2012, 9, 15 ).year(), 2012, "Set full date and retrieve year" ); + assert.equal( date.month(), 9, "Set full date and retrieve month" ); + assert.equal( date.day(), 15, "Set full date and retrieve day" ); + + assert.equal( date.setTimestamp( 1490912843735 ).year(), 2017, "Set timestamp and retrieve year" ); + assert.equal( date.month(), 2, "Set timestamp and retrieve month" ); + assert.equal( date.day(), 31, "Set timestamp and retrieve day" ); +} ); + +QUnit.test( "Date Adjustments - Normal Use Cases", 10, function( assert ) { + var date = $.ui.date( null, attributes ); + + // Use October 15, 2012 + date.setFullDate( 2012, 9, 15 ); + assert.equal( date.adjust( "D", 1 ).day(), 16, "Add 1 day" ); + assert.equal( date.adjust( "D", -1 ).day(), 15, "Subtract 1 day" ); + assert.equal( date.adjust( "M", 1 ).month(), 10, "Add 1 month" ); + assert.equal( date.adjust( "M", -1 ).month(), 9, "Subtract 1 month" ); + assert.equal( date.adjust( "Y", 1 ).year(), 2013, "Add 1 year" ); + assert.equal( date.adjust( "Y", -1 ).year(), 2012, "Subtract 1 year" ); + + // Check changing one value impact another. Ex: Day impacts month + // Use April 30th 2012 + date.setFullDate( 2012, 3, 30 ); + assert.equal( date.adjust( "D", 1 ).month(), 4, "Add 1 day to change month from April to May" ); + assert.equal( date.adjust( "D", -1 ).month(), 3, "Subtract 1 day to change month from May to April" ); + + // Use December 31st 2012 + date.setFullDate( 2012, 11, 31 ); + assert.equal( date.adjust( "D", 1 ).year(), 2013, "Add 1 day to change year from 2012 to 2013" ); + assert.equal( date.adjust( "D", -1 ).year(), 2012, + "Subtract 1 day to change month from 2013 to 2012" ); +} ); + +QUnit.test( "Date Adjustments - Month Overflow Edge Cases", 2, function( assert ) { + var date = $.ui.date( null, attributes ); + + // Use May 31 2012 + date.setFullDate( 2012, 4, 31 ); + assert.equal( date.adjust( "M", 1 ).day(), 30, + "Add 1 month from May to June sets days to 30, last day in June (prevent Overflow)" ); + assert.equal( date.adjust( "M", -1 ).day(), 30, + "Subtract 1 month from June to May sets days to 30 in May" ); +} ); + +QUnit.test( "Date Adjustments - Leap Year Edge Cases", 1, function( assert ) { + var date = $.ui.date( null, attributes ); + + // Use February 29 2012 a Leap year + date.setFullDate( 2012, 1, 29 ); + assert.equal( date.adjust( "Y", 1 ).day(), 28, + "Feb 29 2012, add a year to convert to Feb 28, 2013" ); +} ); + +QUnit.test( "List days of Week", 2, function( assert ) { + var date = $.ui.date( null, attributes ), + offset0 = [ + { "fullname": "Sunday", "shortname": "Su" }, + { "fullname": "Monday", "shortname": "Mo" }, + { "fullname": "Tuesday", "shortname": "Tu" }, + { "fullname": "Wednesday", "shortname": "We" }, + { "fullname": "Thursday", "shortname": "Th" }, + { "fullname": "Friday", "shortname": "Fr" }, + { "fullname": "Saturday", "shortname": "Sa" } + ], + offset1 = [ + { "fullname": "Montag", "shortname": "Mo." }, + { "fullname": "Dienstag", "shortname": "Di." }, + { "fullname": "Mittwoch", "shortname": "Mi." }, + { "fullname": "Donnerstag", "shortname": "Do." }, + { "fullname": "Freitag", "shortname": "Fr." }, + { "fullname": "Samstag", "shortname": "Sa." }, + { "fullname": "Sonntag", "shortname": "So." } + ]; + + assert.deepEqual( date.weekdays(), offset0, "Get weekdays with start of day on 0 (English)" ); + date = $.ui.date( null, testHelper.getAttributes( "de" ) ); + assert.deepEqual( date.weekdays(), offset1, "Get weekdays with start of day on 1 (Germany)" ); +} ); + +QUnit.test( "Days in Month", 3, function( assert ) { + var date = $.ui.date( null, attributes ); + date.setFullDate( 2012, 1, 1 ); + assert.equal( date.daysInMonth(), 29, "Leap Year implicit check for 29 days" ); + assert.equal( date.daysInMonth( 2012, 1 ), 29, "Leap Year explicit check for 29 days" ); + assert.equal( date.daysInMonth( 2011, 3 ), 30, "April has 30 days" ); +} ); + +QUnit.test( "Month Name", 2, function( assert ) { + var date = $.ui.date( null, attributes ); + assert.equal( date.setFullDate( 2012, 3, 1 ).monthName(), "April", "Month name return April (English)" ); + date = $.ui.date( null, testHelper.getAttributes( "de" ) ); + assert.equal( date.setFullDate( 2012, 2, 1 ).monthName(), "März", "Month name return March (German)" ); +} ); + +QUnit.test( "Clone", 2, function( assert ) { + var date = $.ui.date( null, attributes ), + date2 = date.clone(); + assert.ok( date2, "Created cloned object" ); + assert.notEqual( date.adjust( "Y", 1 ).year(), date2.year(), "Object manipulated independently" ); +} ); + +QUnit.test( "Days", 1, function( assert ) { + var date = $.ui.date( null, attributes ); + date.eachDay = function( day ) { + if ( day.lead && day.date > 20 ) { + day.selectable = false; + day.render = true; + day.title = "These are the days of last month"; + day.extraClasses = "ui-state-disabled"; + } + if ( day.lead && day.date < 3 ) { + day.selectable = true; + day.render = true; + day.extraClasses = "ui-state-disabled"; + } + if ( day.date === 1 ) { + day.extraClasses = "ui-state-error"; + day.title = "Something bad explaining the error highlight"; + } + if ( day.today ) { + day.title = "A good day!"; + } + }; + assert.ok( date.days(), "Date days() returns" ); +} ); + +QUnit.test( "Months", 5, function( assert ) { + var date = $.ui.date( new Date( 2015, 11 - 1, 15 ), attributes ), + currentMonth = date.months( 1 )[ 0 ], + nextMonth = date.months( 1 )[ 1 ]; + + assert.ok( currentMonth.first, "Current month marked as first" ); + assert.ok( !nextMonth.first, "Next month not marked as first" ); + assert.ok( nextMonth.last, "Next month marked as last" ); + + assert.equal( currentMonth.month(), 10, "Current month index is November" ); + assert.equal( nextMonth.month(), 11, "Next month index is December" ); +} ); + +QUnit.test( "Equal", 4, function( assert ) { + var date = $.ui.date( null, attributes ); + date.setFullDate( 2012, 9, 16 ); + assert.ok( date.equal( new Date( 2012, 9, 16 ) ), "Does date equal provide date" ); + assert.ok( !date.equal( new Date( 2011, 9, 16 ) ), "Does date year not equal provide date" ); + assert.ok( !date.equal( new Date( 2012, 8, 16 ) ), "Does date month not equal provide date" ); + assert.ok( !date.equal( new Date( 2012, 9, 15 ) ), "Does date day not equal provide date" ); +} ); + +QUnit.test( "Date", 1, function( assert ) { + var date = $.ui.date( null, attributes ); + assert.ok( date.date() instanceof Date, "Date returned" ); +} ); + +} ); diff --git a/tests/unit/date/date.html b/tests/unit/date/date.html new file mode 100644 index 00000000000..3c11f519b83 --- /dev/null +++ b/tests/unit/date/date.html @@ -0,0 +1,16 @@ + + + + + jQuery UI Date Test Suite + + + + + + + +
    +
    + + diff --git a/tests/unit/date/helper.js b/tests/unit/date/helper.js new file mode 100644 index 00000000000..2f6f51fd95a --- /dev/null +++ b/tests/unit/date/helper.js @@ -0,0 +1,31 @@ +define( [ + "jquery", + "globalize", + "lib/helper", + "globalize/date" +], function( $, Globalize, helper ) { + +return $.extend( helper, { + getAttributes: function( locale ) { + var globalize = new Globalize( locale ), + weekdayShortFormatter = globalize.dateFormatter( { raw: "EEEEEE" } ), + weekdayNarrowFormatter = globalize.dateFormatter( { raw: "EEEEE" } ), + firstDayRaw = globalize.dateFormatter( { raw: "c" } )( new Date( 1970, 0, 3 ) ); + + return { + firstDay: ( 7 - globalize.parseNumber( firstDayRaw ) ), + formatWeekdayShort: function( date ) { + + // Return the short weekday if its length is < 3. Otherwise, its narrow form. + var shortWeekday = weekdayShortFormatter( date ); + + return shortWeekday.length > 3 ? weekdayNarrowFormatter( date ) : shortWeekday; + }, + formatWeekdayFull: globalize.dateFormatter( { raw: "EEEE" } ), + formatMonth: globalize.dateFormatter( { raw: "MMMM" } ), + formatWeekOfYear: globalize.dateFormatter( { raw: "w" } ) + }; + } +} ); + +} ); diff --git a/tests/unit/datepicker/common.js b/tests/unit/datepicker/common.js index 1eecc85cb50..6b0b0487dca 100644 --- a/tests/unit/datepicker/common.js +++ b/tests/unit/datepicker/common.js @@ -1,7 +1,54 @@ -/* -TestHelpers.commonWidgetTests( "datepicker", { +define( [ + "lib/common", + "ui/widgets/datepicker", + "globalize-locales" +], function( common ) { + +common.testWidget( "datepicker", { defaults: { - disabled: false + appendTo: null, + buttons: [], + classes: { + "ui-calendar": "ui-corner-all", + "ui-calendar-header-first": "ui-corner-left", + "ui-calendar-header-last": "ui-corner-right", + "ui-calendar-prev": "ui-corner-all", + "ui-calendar-next": "ui-corner-all" + }, + disabled: false, + dateFormat: { date: "short" }, + eachDay: $.noop, + icons: { + prevButton: "ui-icon-circle-triangle-w", + nextButton: "ui-icon-circle-triangle-e" + }, + labels: { + "datePickerRole": "date picker", + "nextText": "Next", + "prevText": "Prev", + "weekHeader": "Wk" + }, + locale: "en", + max: null, + min: null, + numberOfMonths: 1, + position: { + my: "left top", + at: "left bottom" + }, + show: true, + showWeek: false, + hide: true, + + // callbacks + beforeOpen: null, + change: null, + close: null, + create: null, + open: null, + refresh: null, + select: null } -}); -*/ +} ); + +} ); diff --git a/tests/unit/datepicker/core.js b/tests/unit/datepicker/core.js index 943a188b879..ebbfa060994 100644 --- a/tests/unit/datepicker/core.js +++ b/tests/unit/datepicker/core.js @@ -1,545 +1,185 @@ define( [ "qunit", "jquery", - "lib/common", - "./helper", - "ui/widgets/datepicker", - "ui/i18n/datepicker-he" -], function( QUnit, $, common, testHelper ) { + "../calendar/helper", + "ui/widgets/datepicker" +], function( QUnit, $, testHelper ) { QUnit.module( "datepicker: core", { beforeEach: function() { - $( "body" ).trigger( "focus" ); + this.element = $( "#datepicker" ).datepicker( { show: false, hide: false } ); + this.widget = this.element.datepicker( "widget" ); + }, + afterEach: function() { + this.element.datepicker( "destroy" ).val( "" ); } } ); -common.testJshint( "widgets/datepicker" ); +QUnit.test( "input's value determines starting date", function( assert ) { + assert.expect( 3 ); -QUnit.test( "initialization - Reinitialization after body had been emptied.", function( assert ) { - assert.expect( 1 ); - var bodyContent = $( "body" ).children(), inp = $( "#inp" ); - $( "#inp" ).datepicker(); - $( "body" ).empty().append( inp ); - $( "#inp" ).datepicker(); - assert.ok( $( "#" + $.datepicker._mainDivId ).length === 1, "Datepicker container added" ); - $( "body" ).empty().append( bodyContent ); // Returning to initial state for later tests -} ); + this.element = $( "" ).appendTo( "#qunit-fixture" ); + this.element.val( "1/1/14" ).datepicker(); + this.widget = this.element.datepicker( "widget" ); -QUnit.test( "widget method - empty collection", function( assert ) { - assert.expect( 1 ); - $( "#nonExist" ).datepicker(); // Should create nothing - assert.ok( !$( "#ui-datepicker-div" ).length, "Non init on empty collection" ); -} ); + this.element.datepicker( "open" ); -QUnit.test( "widget method", function( assert ) { - assert.expect( 1 ); - var actual = $( "#inp" ).datepicker().datepicker( "widget" )[ 0 ]; - assert.deepEqual( $( "body > #ui-datepicker-div:last-child" )[ 0 ], actual ); + assert.equal( this.widget.find( ".ui-calendar-month" ).html(), "January", "correct month displayed" ); + assert.equal( this.widget.find( ".ui-calendar-year" ).html(), "2014", "correct year displayed" ); + assert.equal( this.widget.find( ".ui-state-active" ).html(), "1", "correct day highlighted" ); } ); -QUnit.test( "baseStructure", function( assert ) { +QUnit.test( "base structure", function( assert ) { var ready = assert.async(); - assert.expect( 58 ); - var header, title, table, thead, week, panel, inl, child, - inp = testHelper.initNewInput(), - dp = $( "#ui-datepicker-div" ); - - function step1() { - testHelper.onFocus( inp, function() { - assert.ok( dp.is( ":visible" ), "Structure - datepicker visible" ); - assert.ok( !dp.is( ".ui-datepicker-rtl" ), "Structure - not right-to-left" ); - assert.ok( !dp.is( ".ui-datepicker-multi" ), "Structure - not multi-month" ); - assert.equal( dp.children().length, 2, "Structure - child count" ); - - header = dp.children( ":first" ); - assert.ok( header.is( "div.ui-datepicker-header" ), "Structure - header division" ); - assert.equal( header.children().length, 3, "Structure - header child count" ); - assert.ok( header.children( ":first" ).is( "a.ui-datepicker-prev" ) && header.children( ":first" ).html() !== "", "Structure - prev link" ); - assert.ok( header.children( ":eq(1)" ).is( "a.ui-datepicker-next" ) && header.children( ":eq(1)" ).html() !== "", "Structure - next link" ); - - title = header.children( ":last" ); - assert.ok( title.is( "div.ui-datepicker-title" ) && title.html() !== "", "Structure - title division" ); - assert.equal( title.children().length, 2, "Structure - title child count" ); - assert.ok( title.children( ":first" ).is( "span.ui-datepicker-month" ) && title.children( ":first" ).text() !== "", "Structure - month text" ); - assert.ok( title.children( ":last" ).is( "span.ui-datepicker-year" ) && title.children( ":last" ).text() !== "", "Structure - year text" ); - - table = dp.children( ":eq(1)" ); - assert.ok( table.is( "table.ui-datepicker-calendar" ), "Structure - month table" ); - assert.ok( table.children( ":first" ).is( "thead" ), "Structure - month table thead" ); - - thead = table.children( ":first" ).children( ":first" ); - assert.ok( thead.is( "tr" ), "Structure - month table title row" ); - assert.equal( thead.find( "th" ).length, 7, "Structure - month table title cells" ); - assert.ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure - month table body" ); - assert.ok( table.children( ":eq(1)" ).children( "tr" ).length >= 4, "Structure - month table week count" ); - - week = table.children( ":eq(1)" ).children( ":first" ); - assert.ok( week.is( "tr" ), "Structure - month table week row" ); - assert.equal( week.children().length, 7, "Structure - week child count" ); - assert.ok( week.children( ":first" ).is( "td.ui-datepicker-week-end" ), "Structure - month table first day cell" ); - assert.ok( week.children( ":last" ).is( "td.ui-datepicker-week-end" ), "Structure - month table second day cell" ); - - inp.datepicker( "hide" ).datepicker( "destroy" ); - step2(); - } ); - } - - function step2() { - - // Editable month/year and button panel - inp = testHelper.initNewInput( { - changeMonth: true, - changeYear: true, - showButtonPanel: true - } ); - testHelper.onFocus( inp, function() { - title = dp.find( "div.ui-datepicker-title" ); - assert.ok( title.children( ":first" ).is( "select.ui-datepicker-month" ), "Structure - month selector" ); - assert.ok( title.children( ":last" ).is( "select.ui-datepicker-year" ), "Structure - year selector" ); - - panel = dp.children( ":last" ); - assert.ok( panel.is( "div.ui-datepicker-buttonpane" ), "Structure - button panel division" ); - assert.equal( panel.children().length, 2, "Structure - button panel child count" ); - assert.ok( panel.children( ":first" ).is( "button.ui-datepicker-current" ), "Structure - today button" ); - assert.ok( panel.children( ":last" ).is( "button.ui-datepicker-close" ), "Structure - close button" ); - - inp.datepicker( "hide" ).datepicker( "destroy" ); - step3(); - } ); - } - - function step3() { - - // Multi-month 2 - inp = testHelper.initNewInput( { numberOfMonths: 2 } ); - testHelper.onFocus( inp, function() { - assert.ok( dp.is( ".ui-datepicker-multi" ), "Structure multi [2] - multi-month" ); - assert.equal( dp.children().length, 3, "Structure multi [2] - child count" ); - - child = dp.children( ":first" ); - assert.ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2] - first month division" ); - - child = dp.children( ":eq(1)" ); - assert.ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2] - second month division" ); - - child = dp.children( ":eq(2)" ); - assert.ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2] - row break" ); - assert.ok( dp.is( ".ui-datepicker-multi-2" ), "Structure multi [2] - multi-2" ); - - inp.datepicker( "hide" ).datepicker( "destroy" ); - step4(); - } ); - } - - function step4() { - - // Multi-month 3 - inp = testHelper.initNewInput( { numberOfMonths: 3 } ); - testHelper.onFocus( inp, function() { - assert.ok( dp.is( ".ui-datepicker-multi-3" ), "Structure multi [3] - multi-3" ); - assert.ok( !dp.is( ".ui-datepicker-multi-2" ), "Structure multi [3] - Trac #6704" ); - - inp.datepicker( "hide" ).datepicker( "destroy" ); - step5(); - } ); - } - - function step5() { - - // Multi-month [2, 2] - inp = testHelper.initNewInput( { numberOfMonths: [ 2, 2 ] } ); - testHelper.onFocus( inp, function() { - assert.ok( dp.is( ".ui-datepicker-multi" ), "Structure multi - multi-month" ); - assert.equal( dp.children().length, 6, "Structure multi [2,2] - child count" ); - - child = dp.children( ":first" ); - assert.ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2,2] - first month division" ); - - child = dp.children( ":eq(1)" ); - assert.ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2,2] - second month division" ); - - child = dp.children( ":eq(2)" ); - assert.ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2,2] - row break" ); - - child = dp.children( ":eq(3)" ); - assert.ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2,2] - third month division" ); - - child = dp.children( ":eq(4)" ); - assert.ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2,2] - fourth month division" ); - - child = dp.children( ":eq(5)" ); - assert.ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2,2] - row break" ); + assert.expect( 5 ); - inp.datepicker( "hide" ).datepicker( "destroy" ); + var that = this; - // Inline - inl = testHelper.init( "#inl" ); - dp = inl.children(); + this.element.focus(); - assert.ok( dp.is( ".ui-datepicker-inline" ), "Structure inline - main div" ); - assert.ok( !dp.is( ".ui-datepicker-rtl" ), "Structure inline - not right-to-left" ); - assert.ok( !dp.is( ".ui-datepicker-multi" ), "Structure inline - not multi-month" ); - assert.equal( dp.children().length, 2, "Structure inline - child count" ); + setTimeout( function() { + assert.ok( that.widget.is( ":visible" ), "Datepicker visible" ); + assert.equal( that.widget.children().length, 3, "Child count" ); + assert.ok( that.widget.is( ".ui-calendar" ), "Class ui-calendar" ); + assert.ok( that.widget.is( ".ui-datepicker" ), "Class ui-datepicker" ); + assert.ok( that.widget.is( ".ui-front" ), "Class ui-front" ); - header = dp.children( ":first" ); - assert.ok( header.is( "div.ui-datepicker-header" ), "Structure inline - header division" ); - assert.equal( header.children().length, 3, "Structure inline - header child count" ); - - table = dp.children( ":eq(1)" ); - assert.ok( table.is( "table.ui-datepicker-calendar" ), "Structure inline - month table" ); - assert.ok( table.children( ":first" ).is( "thead" ), "Structure inline - month table thead" ); - assert.ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure inline - month table body" ); - - inl.datepicker( "destroy" ); - - // Inline multi-month - inl = testHelper.init( "#inl", { numberOfMonths: 2 } ); - dp = inl.children(); - - assert.ok( dp.is( ".ui-datepicker-inline" ) && dp.is( ".ui-datepicker-multi" ), "Structure inline multi - main div" ); - assert.equal( dp.children().length, 3, "Structure inline multi - child count" ); - - child = dp.children( ":first" ); - assert.ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure inline multi - first month division" ); + that.element.datepicker( "close" ); + ready(); + }, 50 ); +} ); - child = dp.children( ":eq(1)" ); - assert.ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure inline multi - second month division" ); +QUnit.test( "Keyboard handling: focus", function( assert ) { + var ready = assert.async(); + assert.expect( 2 ); - child = dp.children( ":eq(2)" ); - assert.ok( child.is( "div.ui-datepicker-row-break" ), "Structure inline multi - row break" ); + var that = this; - inl.datepicker( "destroy" ); - ready(); - } ); - } + assert.ok( !this.widget.is( ":visible" ), "datepicker closed" ); - step1(); + this.element.focus(); + setTimeout( function() { + assert.ok( that.widget.is( ":visible" ), "Datepicker opens when receiving focus" ); + ready(); + }, 100 ); } ); -QUnit.test( "customStructure", function( assert ) { +QUnit.test( "Keyboard handling: keystroke up", function( assert ) { var ready = assert.async(); - assert.expect( 20 ); - var header, panel, title, thead, - inp = testHelper.initNewInput( $.datepicker.regional.he ), - dp = $( "#ui-datepicker-div" ); - - function step1() { - inp.datepicker( "option", "showButtonPanel", true ); - - testHelper.onFocus( inp, function() { - assert.ok( dp.is( ".ui-datepicker-rtl" ), "Structure RTL - right-to-left" ); - - header = dp.children( ":first" ); - assert.ok( header.is( "div.ui-datepicker-header" ), "Structure RTL - header division" ); - assert.equal( header.children().length, 3, "Structure RTL - header child count" ); - assert.ok( header.children( ":first" ).is( "a.ui-datepicker-next" ), "Structure RTL - prev link" ); - assert.ok( header.children( ":eq(1)" ).is( "a.ui-datepicker-prev" ), "Structure RTL - next link" ); - - panel = dp.children( ":last" ); - assert.ok( panel.is( "div.ui-datepicker-buttonpane" ), "Structure RTL - button division" ); - assert.equal( panel.children().length, 2, "Structure RTL - button panel child count" ); - assert.ok( panel.children( ":first" ).is( "button.ui-datepicker-close" ), "Structure RTL - close button" ); - assert.ok( panel.children( ":last" ).is( "button.ui-datepicker-current" ), "Structure RTL - today button" ); - - inp.datepicker( "hide" ).datepicker( "destroy" ); - step2(); - } ); - } + assert.expect( 2 ); - // Hide prev/next - function step2() { - inp = testHelper.initNewInput( { - hideIfNoPrevNext: true, - minDate: new Date( 2008, 2 - 1, 4 ), - maxDate: new Date( 2008, 2 - 1, 14 ) - } ); - inp.val( "02/10/2008" ); - - testHelper.onFocus( inp, function() { - header = dp.children( ":first" ); - assert.ok( header.is( "div.ui-datepicker-header" ), "Structure hide prev/next - header division" ); - assert.equal( header.children().length, 1, "Structure hide prev/next - links child count" ); - assert.ok( header.children( ":first" ).is( "div.ui-datepicker-title" ), "Structure hide prev/next - title division" ); - - inp.datepicker( "hide" ).datepicker( "destroy" ); - step3(); - } ); - } + var that = this; - // Changeable Month with read-only year - function step3() { - inp = testHelper.initNewInput( { changeMonth: true } ); + assert.ok( !this.widget.is( ":visible" ), "datepicker closed" ); - testHelper.onFocus( inp, function() { - title = dp.children( ":first" ).children( ":last" ); - assert.equal( title.children().length, 2, "Structure changeable month - title child count" ); - assert.ok( title.children( ":first" ).is( "select.ui-datepicker-month" ), "Structure changeable month - month selector" ); - assert.ok( title.children( ":last" ).is( "span.ui-datepicker-year" ), "Structure changeable month - read-only year" ); + this.element.simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); + setTimeout( function() { + assert.ok( that.widget.is( ":visible" ), "Keystroke up opens datepicker" ); + ready(); + }, 100 ); +} ); - inp.datepicker( "hide" ).datepicker( "destroy" ); - step4(); - } ); - } +QUnit.test( "Keyboard handling: input", function( assert ) { + assert.expect( 6 ); - // Changeable year with read-only month - function step4() { - inp = testHelper.initNewInput( { changeYear: true } ); + var that = this, + instance = that.element.datepicker( "instance" ); - testHelper.onFocus( inp, function() { - title = dp.children( ":first" ).children( ":last" ); - assert.equal( title.children().length, 2, "Structure changeable year - title child count" ); - assert.ok( title.children( ":first" ).is( "span.ui-datepicker-month" ), "Structure changeable year - read-only month" ); - assert.ok( title.children( ":last" ).is( "select.ui-datepicker-year" ), "Structure changeable year - year selector" ); + // 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" ), testHelper.createDate( 2014, 0, 1 ), + "Keystroke enter - preset" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); - step5(); - } ); - } + that.element + .val( "" ) + .datepicker( "open" ); + assert.ok( instance.isOpen, "datepicker is open before escape" ); - // Read-only first day of week - function step5() { - inp = testHelper.initNewInput( { changeFirstDay: false } ); + that.element.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + assert.ok( !instance.isOpen, "escape closes the datepicker" ); - testHelper.onFocus( inp, function() { - thead = dp.find( ".ui-datepicker-calendar thead tr" ); - assert.equal( thead.children().length, 7, "Structure read-only first day - thead child count" ); - assert.equal( thead.find( "a" ).length, 0, "Structure read-only first day - thead links count" ); + that.element + .val( "1/1/14" ) + .datepicker( "open" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + assert.dateEqual( that.element.datepicker( "valueAsDate" ), testHelper.createDate( 2014, 0, 1 ), + "Keystroke esc - preset" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); - ready(); - } ); - } + 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" ), testHelper.createDate( 2014, 0, 1 ), + "Keystroke esc - abandoned" ); - // TODO: figure out why this setTimeout is needed in IE, - // it only is necessary when the previous baseStructure tests runs first - // Support: IE - setTimeout( step1 ); + that.element + .val( "1/2/14" ) + .simulate( "keyup" ); + assert.dateEqual( that.element.datepicker( "valueAsDate" ), testHelper.createDate( 2014, 0, 2 ), + "Picker updated as user types into input" ); } ); -QUnit.test( "keystrokes", function( assert ) { - assert.expect( 26 ); - var inp = testHelper.init( "#inp" ), - date = new Date(); - inp.val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke enter" ); - inp.val( "02/04/2008" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), - "Keystroke enter - preset" ); - inp.val( "02/04/2008" ).datepicker( "show" ). - simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke ctrl+home" ); - inp.val( "02/04/2008" ).datepicker( "show" ). - simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END } ); - assert.ok( inp.datepicker( "getDate" ) == null, "Keystroke ctrl+end" ); - inp.val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - assert.ok( inp.datepicker( "getDate" ) == null, "Keystroke esc" ); - inp.val( "02/04/2008" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), - "Keystroke esc - preset" ); - inp.val( "02/04/2008" ).datepicker( "show" ). - simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), - "Keystroke esc - abandoned" ); +QUnit.test( "ARIA", function( assert ) { + assert.expect( 4 ); + + var widget = this.element.datepicker( "widget" ), + id = widget.attr( "id" ); - // Moving by day or week - inp.val( "" ).datepicker( "show" ). - simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.LEFT } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date.setDate( date.getDate() - 1 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke ctrl+left" ); - inp.val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date.setDate( date.getDate() + 1 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke left" ); - inp.val( "" ).datepicker( "show" ). - simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.RIGHT } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date.setDate( date.getDate() + 1 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke ctrl+right" ); - inp.val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date.setDate( date.getDate() - 1 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke right" ); - inp.val( "" ).datepicker( "show" ). - simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.UP } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date.setDate( date.getDate() - 7 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke ctrl+up" ); - inp.val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.UP } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date.setDate( date.getDate() + 7 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke up" ); - inp.val( "" ).datepicker( "show" ). - simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.DOWN } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date.setDate( date.getDate() + 7 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke ctrl+down" ); - inp.val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date.setDate( date.getDate() - 7 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Keystroke down" ); - - // Moving by month or year - inp.val( "02/04/2008" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 1 - 1, 4 ), - "Keystroke pgup" ); - inp.val( "02/04/2008" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 3 - 1, 4 ), - "Keystroke pgdn" ); - inp.val( "02/04/2008" ).datepicker( "show" ). - simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2007, 2 - 1, 4 ), - "Keystroke ctrl+pgup" ); - inp.val( "02/04/2008" ).datepicker( "show" ). - simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2009, 2 - 1, 4 ), - "Keystroke ctrl+pgdn" ); - - // Check for moving to short months - inp.val( "03/31/2008" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 29 ), - "Keystroke pgup - Feb" ); - inp.val( "01/30/2008" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 29 ), - "Keystroke pgdn - Feb" ); - inp.val( "02/29/2008" ).datepicker( "show" ). - simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2007, 2 - 1, 28 ), - "Keystroke ctrl+pgup - Feb" ); - inp.val( "02/29/2008" ).datepicker( "show" ). - simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2009, 2 - 1, 28 ), - "Keystroke ctrl+pgdn - Feb" ); - - // Goto current - inp.datepicker( "option", { gotoCurrent: true } ). - datepicker( "hide" ).val( "02/04/2008" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ). - simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), - "Keystroke ctrl+home" ); - - // Change steps - inp.datepicker( "option", { stepMonths: 2, gotoCurrent: false } ). - datepicker( "hide" ).val( "02/04/2008" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2007, 12 - 1, 4 ), - "Keystroke pgup step 2" ); - inp.val( "02/04/2008" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 4 - 1, 4 ), - "Keystroke pgdn step 2" ); + assert.equal( this.element.attr( "aria-haspopup" ), "true", + "Input aria-haspopup attribute" ); + assert.equal( this.element.attr( "aria-owns" ), id, "ARIA owns attribute" ); + + assert.equal( widget.attr( "aria-hidden" ), "true", + "Widget ARIA hidden attribute" ); + assert.equal( widget.attr( "aria-expanded" ), "false", + "Widget ARIA expanded attribute" ); } ); QUnit.test( "mouse", function( assert ) { - assert.expect( 15 ); - var inl, - inp = testHelper.init( "#inp" ), - dp = $( "#ui-datepicker-div" ), - date = new Date(); - inp.val( "" ).datepicker( "show" ); - $( ".ui-datepicker-calendar tbody a:contains(10)", dp ).simulate( "click", {} ); - date.setDate( 10 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Mouse click" ); - inp.val( "02/04/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar tbody a:contains(12)", dp ).simulate( "click", {} ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 12 ), - "Mouse click - preset" ); - inp.val( "02/04/2008" ).datepicker( "show" ); - inp.val( "" ).datepicker( "show" ); - $( "button.ui-datepicker-close", dp ).simulate( "click", {} ); - assert.ok( inp.datepicker( "getDate" ) == null, "Mouse click - close" ); - inp.val( "02/04/2008" ).datepicker( "show" ); - $( "button.ui-datepicker-close", dp ).simulate( "click", {} ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), - "Mouse click - close + preset" ); - inp.val( "02/04/2008" ).datepicker( "show" ); - $( "a.ui-datepicker-prev", dp ).simulate( "click", {} ); - $( "button.ui-datepicker-close", dp ).simulate( "click", {} ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 4 ), - "Mouse click - abandoned" ); - - // Current/previous/next - inp.val( "02/04/2008" ).datepicker( "option", { showButtonPanel: true } ).datepicker( "show" ); - $( ".ui-datepicker-current", dp ).simulate( "click", {} ); - $( ".ui-datepicker-calendar tbody a:contains(14)", dp ).simulate( "click", {} ); - date.setDate( 14 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Mouse click - current" ); - inp.val( "02/04/2008" ).datepicker( "show" ); - $( ".ui-datepicker-prev", dp ).simulate( "click" ); - $( ".ui-datepicker-calendar tbody a:contains(16)", dp ).simulate( "click" ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 1 - 1, 16 ), - "Mouse click - previous" ); - inp.val( "02/04/2008" ).datepicker( "show" ); - $( ".ui-datepicker-next", dp ).simulate( "click" ); - $( ".ui-datepicker-calendar tbody a:contains(18)", dp ).simulate( "click" ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 3 - 1, 18 ), - "Mouse click - next" ); - - // Previous/next with minimum/maximum - inp.datepicker( "option", { minDate: new Date( 2008, 2 - 1, 2 ), - maxDate: new Date( 2008, 2 - 1, 26 ) } ).val( "02/04/2008" ).datepicker( "show" ); - $( ".ui-datepicker-prev", dp ).simulate( "click" ); - $( ".ui-datepicker-calendar tbody a:contains(16)", dp ).simulate( "click" ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 16 ), - "Mouse click - previous + min/max" ); - inp.val( "02/04/2008" ).datepicker( "show" ); - $( ".ui-datepicker-next", dp ).simulate( "click" ); - $( ".ui-datepicker-calendar tbody a:contains(18)", dp ).simulate( "click" ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 2 - 1, 18 ), - "Mouse click - next + min/max" ); - - // Inline - inl = testHelper.init( "#inl" ); - dp = $( ".ui-datepicker-inline", inl ); - date = new Date(); - inl.datepicker( "setDate", date ); - $( ".ui-datepicker-calendar tbody a:contains(10)", dp ).simulate( "click", {} ); - date.setDate( 10 ); - testHelper.equalsDate( assert, inl.datepicker( "getDate" ), date, "Mouse click inline" ); - inl.datepicker( "option", { showButtonPanel: true } ).datepicker( "setDate", new Date( 2008, 2 - 1, 4 ) ); - $( ".ui-datepicker-calendar tbody a:contains(12)", dp ).simulate( "click", {} ); - testHelper.equalsDate( assert, inl.datepicker( "getDate" ), new Date( 2008, 2 - 1, 12 ), "Mouse click inline - preset" ); - inl.datepicker( "option", { showButtonPanel: true } ); - $( ".ui-datepicker-current", dp ).simulate( "click", {} ); - $( ".ui-datepicker-calendar tbody a:contains(14)", dp ).simulate( "click", {} ); - date.setDate( 14 ); - testHelper.equalsDate( assert, inl.datepicker( "getDate" ), date, "Mouse click inline - current" ); - inl.datepicker( "setDate", new Date( 2008, 2 - 1, 4 ) ); - $( ".ui-datepicker-prev", dp ).simulate( "click" ); - $( ".ui-datepicker-calendar tbody a:contains(16)", dp ).simulate( "click" ); - testHelper.equalsDate( assert, inl.datepicker( "getDate" ), new Date( 2008, 1 - 1, 16 ), - "Mouse click inline - previous" ); - inl.datepicker( "setDate", new Date( 2008, 2 - 1, 4 ) ); - $( ".ui-datepicker-next", dp ).simulate( "click" ); - $( ".ui-datepicker-calendar tbody a:contains(18)", dp ).simulate( "click" ); - testHelper.equalsDate( assert, inl.datepicker( "getDate" ), new Date( 2008, 3 - 1, 18 ), - "Mouse click inline - next" ); + var ready = assert.async(); + assert.expect( 4 ); + + var that = this; + + this.element.datepicker( "open" ); + + setTimeout( function() { + 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" ), + testHelper.createDate( 2008, 4 - 1, 12 ), + "Mouse click - preset" + ); + + that.element.val( "" ).datepicker( "refresh" ); + that.element.simulate( "click" ); + assert.strictEqual( that.element.datepicker( "valueAsDate" ), null, "Mouse click - close" ); + + that.element.val( "4/4/08" ).datepicker( "refresh" ).datepicker( "open" ); + that.element.simulate( "click" ); + assert.dateEqual( + that.element.datepicker( "valueAsDate" ), + testHelper.createDate( 2008, 4 - 1, 4 ), + "Mouse click - close + preset" + ); + + 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" ), + testHelper.createDate( 2008, 4 - 1, 4 ), + "Mouse click - abandoned" + ); + + ready(); + }, 100 ); } ); } ); diff --git a/tests/unit/datepicker/datepicker.html b/tests/unit/datepicker/datepicker.html index 26d8de3e0f8..ae93487009f 100644 --- a/tests/unit/datepicker/datepicker.html +++ b/tests/unit/datepicker/datepicker.html @@ -5,7 +5,7 @@ jQuery UI Datepicker Test Suite - + @@ -13,8 +13,7 @@
    -
    -

    +
    diff --git a/tests/unit/datepicker/events.js b/tests/unit/datepicker/events.js index 941822ef886..5a923d252fe 100644 --- a/tests/unit/datepicker/events.js +++ b/tests/unit/datepicker/events.js @@ -1,163 +1,201 @@ define( [ "qunit", "jquery", - "./helper", "ui/widgets/datepicker" -], function( QUnit, $, testHelper ) { - -QUnit.module( "datepicker: events" ); - -var selectedThis = null, -selectedDate = null, -selectedInst = null; - -function callback( date, inst ) { - selectedThis = this; - selectedDate = date; - selectedInst = inst; -} - -function callback2( year, month, inst ) { - selectedThis = this; - selectedDate = year + "/" + month; - selectedInst = inst; -} - -QUnit.test( "events", function( assert ) { - assert.expect( 26 ); - var dateStr, newMonthYear, inp2, - inp = testHelper.init( "#inp", { onSelect: callback } ), - date = new Date(); - - // OnSelect - inp.val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - assert.equal( selectedThis, inp[ 0 ], "Callback selected this" ); - assert.equal( selectedInst, $.data( inp[ 0 ], testHelper.PROP_NAME ), "Callback selected inst" ); - assert.equal( selectedDate, $.datepicker.formatDate( "mm/dd/yy", date ), - "Callback selected date" ); - inp.val( "" ).datepicker( "show" ). - simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.DOWN } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date.setDate( date.getDate() + 7 ); - assert.equal( selectedDate, $.datepicker.formatDate( "mm/dd/yy", date ), - "Callback selected date - ctrl+down" ); - inp.val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - assert.equal( selectedDate, $.datepicker.formatDate( "mm/dd/yy", date ), - "Callback selected date - esc" ); - dateStr = "02/04/2008"; - inp.val( dateStr ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - assert.equal( dateStr, selectedDate, - "onSelect is called after enter keydown" ); - - // OnChangeMonthYear - inp.datepicker( "option", { onChangeMonthYear: callback2, onSelect: null } ). - val( "" ).datepicker( "show" ); - newMonthYear = function( date ) { - return date.getFullYear() + "/" + ( date.getMonth() + 1 ); - }; - date = new Date(); - date.setDate( 1 ); - inp.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ); - date.setMonth( date.getMonth() - 1 ); - assert.equal( selectedThis, inp[ 0 ], "Callback change month/year this" ); - assert.equal( selectedInst, $.data( inp[ 0 ], testHelper.PROP_NAME ), "Callback change month/year inst" ); - assert.equal( selectedDate, newMonthYear( date ), - "Callback change month/year date - pgup" ); - inp.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); - date.setMonth( date.getMonth() + 1 ); - assert.equal( selectedDate, newMonthYear( date ), - "Callback change month/year date - pgdn" ); - inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ); - date.setFullYear( date.getFullYear() - 1 ); - assert.equal( selectedDate, newMonthYear( date ), - "Callback change month/year date - ctrl+pgup" ); - inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME } ); - date.setFullYear( date.getFullYear() + 1 ); - assert.equal( selectedDate, newMonthYear( date ), - "Callback change month/year date - ctrl+home" ); - inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ); - date.setFullYear( date.getFullYear() + 1 ); - assert.equal( selectedDate, newMonthYear( date ), - "Callback change month/year date - ctrl+pgdn" ); - inp.datepicker( "setDate", new Date( 2007, 1 - 1, 26 ) ); - assert.equal( selectedDate, "2007/1", "Callback change month/year date - setDate" ); - selectedDate = null; - inp.datepicker( "setDate", new Date( 2007, 1 - 1, 12 ) ); - assert.ok( selectedDate == null, "Callback change month/year date - setDate no change" ); - - // OnChangeMonthYear step by 2 - inp.datepicker( "option", { stepMonths: 2 } ). - datepicker( "hide" ).val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } ); - date.setMonth( date.getMonth() - 14 ); - assert.equal( selectedDate, newMonthYear( date ), - "Callback change month/year by 2 date - pgup" ); - inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ); - date.setMonth( date.getMonth() - 12 ); - assert.equal( selectedDate, newMonthYear( date ), - "Callback change month/year by 2 date - ctrl+pgup" ); - inp.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); - date.setMonth( date.getMonth() + 2 ); - assert.equal( selectedDate, newMonthYear( date ), - "Callback change month/year by 2 date - pgdn" ); - inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ); - date.setMonth( date.getMonth() + 12 ); - assert.equal( selectedDate, newMonthYear( date ), - "Callback change month/year by 2 date - ctrl+pgdn" ); - - // OnClose - inp.datepicker( "option", { onClose: callback, onChangeMonthYear: null, stepMonths: 1 } ). - val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - assert.equal( selectedThis, inp[ 0 ], "Callback close this" ); - assert.equal( selectedInst, $.data( inp[ 0 ], testHelper.PROP_NAME ), "Callback close inst" ); - assert.equal( selectedDate, "", "Callback close date - esc" ); - inp.val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - assert.equal( selectedDate, $.datepicker.formatDate( "mm/dd/yy", new Date() ), - "Callback close date - enter" ); - inp.val( "02/04/2008" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - assert.equal( selectedDate, "02/04/2008", "Callback close date - preset" ); - inp.val( "02/04/2008" ).datepicker( "show" ). - simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END } ); - assert.equal( selectedDate, "", "Callback close date - ctrl+end" ); - - inp2 = testHelper.init( "#inp2" ); - inp2.datepicker().datepicker( "option", { onClose: callback } ).datepicker( "show" ); - inp.datepicker( "show" ); - assert.equal( selectedThis, inp2[ 0 ], "Callback close this" ); +], function( QUnit, $ ) { + +QUnit.module( "datepicker: events", { + beforeEach: function() { + this.element = $( "#datepicker" ).datepicker( { show: false, hide: false } ); + this.widget = this.element.datepicker( "widget" ); + }, + afterEach: function() { + this.element.datepicker( "destroy" ).val( "" ); + } } ); -QUnit.test( "beforeShowDay-getDate", function( assert ) { +QUnit.test( "beforeOpen", function( assert ) { assert.expect( 3 ); - var inp = testHelper.init( "#inp", { beforeShowDay: function() { inp.datepicker( "getDate" ); return [ true, "" ]; } } ), - dp = $( "#ui-datepicker-div" ); - inp.val( "01/01/2010" ).datepicker( "show" ); - - // Contains non-breaking space - assert.equal( $( "div.ui-datepicker-title" ).text(), - - // Support: IE <9, jQuery <1.8 - // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways - $( "January 2010" ).text(), "Initial month" ); - $( "a.ui-datepicker-next", dp ).trigger( "click" ); - $( "a.ui-datepicker-next", dp ).trigger( "click" ); - - // Contains non-breaking space - assert.equal( $( "div.ui-datepicker-title" ).text(), - $( "March 2010" ).text(), "After next clicks" ); - inp.datepicker( "hide" ).datepicker( "show" ); - $( "a.ui-datepicker-prev", dp ).trigger( "click" ); - $( "a.ui-datepicker-prev", dp ).trigger( "click" ); - - // Contains non-breaking space - assert.equal( $( "div.ui-datepicker-title" ).text(), - $( "November 2009" ).text(), "After prev clicks" ); - inp.datepicker( "hide" ); + + var that = this; + + this.element.datepicker( { + beforeOpen: function() { + assert.ok( true, "beforeOpen event fired before open" ); + assert.ok( that.element.datepicker( "widget" ).is( ":hidden" ), "calendar hidden on beforeOpen" ); + }, + open: function() { + assert.ok( that.element.datepicker( "widget" ).is( ":visible" ), "calendar open on open" ); + } + } ); + + this.element + .datepicker( "open" ) + .datepicker( "close" ) + .datepicker( "option", { + beforeOpen: function() { + return false; + }, + open: function() { + assert.ok( false, "calendar should not open when openBefore is canceled" ); + } + } ) + .datepicker( "open" ); +} ); + +QUnit.test( "change", function( assert ) { + assert.expect( 6 ); + + var shouldFire; + + this.element.datepicker( { + change: function( event, ui ) { + assert.ok( shouldFire, "change event fired" ); + assert.equal( + event.type, + "datepickerchange", + "change event" + ); + assert.equal( $.type( ui.value ), "date", "value is a date object" ); + } + } ); + + 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" ); +} ); + +QUnit.test( "close", function( assert ) { + assert.expect( 4 ); + + var shouldFire; + + this.element.datepicker( { + close: function() { + assert.ok( shouldFire, "close event fired" ); + } + } ); + + shouldFire = false; + this.element.datepicker( "open" ); + shouldFire = true; + this.element.datepicker( "close" ); + + shouldFire = false; + this.element.datepicker( "open" ); + shouldFire = true; + $( "body" ).trigger( "mousedown" ); + + shouldFire = false; + this.element.datepicker( "open" ); + shouldFire = true; + this.element.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + + shouldFire = false; + this.element.datepicker( "open" ); + shouldFire = true; + this.widget.find( "tbody tr:first button:first" ).simulate( "mousedown" ); +} ); + +QUnit.test( "open", function( assert ) { + assert.expect( 2 ); + + var that = this; + + this.element.datepicker( { + open: function() { + assert.ok( true, "open event fired on open" ); + assert.ok( that.widget.is( ":visible" ), "calendar open on open" ); + } + } ); + + this.element.datepicker( "open" ); +} ); + +QUnit.test( "select", function( assert ) { + var ready = assert.async(); + assert.expect( 6 ); + + var message = "", + that = this; + + this.element.datepicker( { + select: function( event, ui ) { + assert.ok( true, "select event fired " + message ); + assert.equal( + event.originalEvent.type, + "calendarselect", + "select originalEvent " + message + ); + assert.equal( $.type( ui.value ), "date", "value is a date object" ); + } + } ); + + function step1() { + message = "on calendar cell click"; + that.element + .simulate( "focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + setTimeout( function() { + that.widget.find( "tbody tr:first button:first" ).simulate( "mousedown" ); + that.element.datepicker( "close" ); + step2(); + }, 100 ); + } + + function step2() { + message = "on calendar cell enter"; + 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 } ); + that.element.datepicker( "close" ); + step3(); + }, 100 ); + } + + function step3() { + message = "on calendar escape (not expected)"; + that.element + .simulate( "focus" ) + .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + setTimeout( function() { + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + that.element.datepicker( "close" ); + ready(); + }, 100 ); + } + + step1(); +} ); + +QUnit.test( "refresh", function( assert ) { + assert.expect( 1 ); + + var shouldFire; + + this.element.calendar( { + refresh: function() { + assert.ok( shouldFire, "refresh event fired" ); + } + } ); + + shouldFire = true; + this.element.find( "button.ui-calendar-next" ).simulate( "click" ); + + shouldFire = false; + this.element.find( "table button:eq(1)" ).simulate( "click" ); } ); } ); diff --git a/tests/unit/datepicker/helper.js b/tests/unit/datepicker/helper.js deleted file mode 100644 index 7fd149bf156..00000000000 --- a/tests/unit/datepicker/helper.js +++ /dev/null @@ -1,39 +0,0 @@ -define( [ - "qunit", - "jquery", - "lib/helper", - "ui/widgets/datepicker" -], function( QUnit, $, 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( assert, d1, d2, message ) { - if ( !d1 || !d2 ) { - assert.ok( false, message + " - missing date" ); - return; - } - d1 = new Date( d1.getFullYear(), d1.getMonth(), d1.getDate() ); - d2 = new Date( d2.getFullYear(), d2.getMonth(), d2.getDate() ); - assert.equal( d1.toString(), d2.toString(), message ); - }, - - init: function( id, options ) { - $.datepicker.setDefaults( $.datepicker.regional[ "" ] ); - return $( id ).datepicker( $.extend( { showAnim: "" }, options || {} ) ); - }, - - initNewInput: function( options ) { - var id = $( "" ).appendTo( "#qunit-fixture" ); - return this.init( id, options ); - }, - - PROP_NAME: "datepicker" -} ); - -} ); diff --git a/tests/unit/datepicker/methods.js b/tests/unit/datepicker/methods.js index 4fc0c84ec74..7061a23c35d 100644 --- a/tests/unit/datepicker/methods.js +++ b/tests/unit/datepicker/methods.js @@ -1,134 +1,116 @@ define( [ "qunit", "jquery", - "./helper", + "../calendar/helper", "ui/widgets/datepicker" ], function( QUnit, $, testHelper ) { -QUnit.module( "datepicker: methods" ); +QUnit.module( "datepicker: methods", { + beforeEach: function() { + this.element = $( "#datepicker" ).datepicker( { show: false, hide: false } ); + this.widget = this.element.datepicker( "widget" ); + }, + afterEach: function() { + this.element.datepicker( "destroy" ).val( "" ); + } +} ); QUnit.test( "destroy", function( assert ) { - assert.expect( 33 ); - var inl, - inp = testHelper.init( "#inp" ); - assert.ok( inp.is( ".hasDatepicker" ), "Default - marker class set" ); - assert.ok( $.data( inp[ 0 ], testHelper.PROP_NAME ), "Default - instance present" ); - assert.ok( inp.next().is( "#alt" ), "Default - button absent" ); - inp.datepicker( "destroy" ); - inp = $( "#inp" ); - assert.ok( !inp.is( ".hasDatepicker" ), "Default - marker class cleared" ); - assert.ok( !$.data( inp[ 0 ], testHelper.PROP_NAME ), "Default - instance absent" ); - assert.ok( inp.next().is( "#alt" ), "Default - button absent" ); - - // With button - inp = testHelper.init( "#inp", { showOn: "both" } ); - assert.ok( inp.is( ".hasDatepicker" ), "Button - marker class set" ); - assert.ok( $.data( inp[ 0 ], testHelper.PROP_NAME ), "Button - instance present" ); - assert.ok( inp.next().text() === "...", "Button - button added" ); - inp.datepicker( "destroy" ); - inp = $( "#inp" ); - assert.ok( !inp.is( ".hasDatepicker" ), "Button - marker class cleared" ); - assert.ok( !$.data( inp[ 0 ], testHelper.PROP_NAME ), "Button - instance absent" ); - assert.ok( inp.next().is( "#alt" ), "Button - button removed" ); - - // With append text - inp = testHelper.init( "#inp", { appendText: "Testing" } ); - assert.ok( inp.is( ".hasDatepicker" ), "Append - marker class set" ); - assert.ok( $.data( inp[ 0 ], testHelper.PROP_NAME ), "Append - instance present" ); - assert.ok( inp.next().text() === "Testing", "Append - append text added" ); - inp.datepicker( "destroy" ); - inp = $( "#inp" ); - assert.ok( !inp.is( ".hasDatepicker" ), "Append - marker class cleared" ); - assert.ok( !$.data( inp[ 0 ], testHelper.PROP_NAME ), "Append - instance absent" ); - assert.ok( inp.next().is( "#alt" ), "Append - append text removed" ); - - // With both - inp = testHelper.init( "#inp", { showOn: "both", buttonImageOnly: true, - buttonImage: "images/calendar.gif", appendText: "Testing" } ); - assert.ok( inp.is( ".hasDatepicker" ), "Both - marker class set" ); - assert.ok( $.data( inp[ 0 ], testHelper.PROP_NAME ), "Both - instance present" ); - assert.ok( inp.next()[ 0 ].nodeName.toLowerCase() === "img", "Both - button added" ); - assert.ok( inp.next().next().text() === "Testing", "Both - append text added" ); - inp.datepicker( "destroy" ); - inp = $( "#inp" ); - assert.ok( !inp.is( ".hasDatepicker" ), "Both - marker class cleared" ); - assert.ok( !$.data( inp[ 0 ], testHelper.PROP_NAME ), "Both - instance absent" ); - assert.ok( inp.next().is( "#alt" ), "Both - button and append text absent" ); - - // Inline - inl = testHelper.init( "#inl" ); - assert.ok( inl.is( ".hasDatepicker" ), "Inline - marker class set" ); - assert.ok( inl.html() !== "", "Inline - datepicker present" ); - assert.ok( $.data( inl[ 0 ], testHelper.PROP_NAME ), "Inline - instance present" ); - assert.ok( inl.next().length === 0 || inl.next().is( "p" ), "Inline - button absent" ); - inl.datepicker( "destroy" ); - inl = $( "#inl" ); - assert.ok( !inl.is( ".hasDatepicker" ), "Inline - marker class cleared" ); - assert.ok( inl.html() === "", "Inline - datepicker absent" ); - assert.ok( !$.data( inl[ 0 ], testHelper.PROP_NAME ), "Inline - instance absent" ); - assert.ok( inl.next().length === 0 || inl.next().is( "p" ), "Inline - button absent" ); + assert.expect( 3 ); + + var input = $( "" ).appendTo( "#qunit-fixture" ); + + assert.domEqual( input, function() { + input.datepicker(); + assert.ok( input.attr( "aria-owns" ), "aria-owns attribute added" ); + assert.ok( input.attr( "aria-haspopup" ), "aria-haspopup attribute added" ); + input.datepicker( "destroy" ); + } ); +} ); + +QUnit.test( "enable / disable", function( assert ) { + assert.expect( 10 ); + + this.element.datepicker( "disable" ); + assert.ok( this.element.datepicker( "option", "disabled" ), "disabled option is set" ); + assert.ok( this.widget.hasClass( "ui-datepicker-disabled" ), "has disabled widget class name" ); + assert.ok( this.element.hasClass( "ui-state-disabled" ), "has disabled state class name" ); + assert.equal( this.element.attr( "aria-disabled" ), "true", "has ARIA disabled" ); + assert.equal( this.element.attr( "disabled" ), "disabled", "input disabled" ); + + this.element.datepicker( "enable" ); + assert.ok( !this.element.datepicker( "option", "disabled" ), "enabled after enable() call" ); + assert.ok( !this.widget.hasClass( "ui-datepicker-disabled" ), "no longer has disabled widget class name" ); + assert.ok( !this.element.hasClass( "ui-state-disabled" ), "no longer has disabled state class name" ); + assert.equal( this.element.attr( "aria-disabled" ), "false", "no longer has ARIA disabled" ); + assert.equal( this.element.attr( "disabled" ), undefined, "input no longer disabled" ); } ); -QUnit.test( "enableDisable", function( assert ) { - assert.expect( 33 ); - var inl, dp, - inp = testHelper.init( "#inp" ); - assert.ok( !inp.datepicker( "isDisabled" ), "Enable/disable - initially marked as enabled" ); - assert.ok( !inp[ 0 ].disabled, "Enable/disable - field initially enabled" ); - inp.datepicker( "disable" ); - assert.ok( inp.datepicker( "isDisabled" ), "Enable/disable - now marked as disabled" ); - assert.ok( inp[ 0 ].disabled, "Enable/disable - field now disabled" ); - inp.datepicker( "enable" ); - assert.ok( !inp.datepicker( "isDisabled" ), "Enable/disable - now marked as enabled" ); - assert.ok( !inp[ 0 ].disabled, "Enable/disable - field now enabled" ); - inp.datepicker( "destroy" ); - - // With a button - inp = testHelper.init( "#inp", { showOn: "button" } ); - assert.ok( !inp.datepicker( "isDisabled" ), "Enable/disable button - initially marked as enabled" ); - assert.ok( !inp[ 0 ].disabled, "Enable/disable button - field initially enabled" ); - assert.ok( !inp.next( "button" )[ 0 ].disabled, "Enable/disable button - button initially enabled" ); - inp.datepicker( "disable" ); - assert.ok( inp.datepicker( "isDisabled" ), "Enable/disable button - now marked as disabled" ); - assert.ok( inp[ 0 ].disabled, "Enable/disable button - field now disabled" ); - assert.ok( inp.next( "button" )[ 0 ].disabled, "Enable/disable button - button now disabled" ); - inp.datepicker( "enable" ); - assert.ok( !inp.datepicker( "isDisabled" ), "Enable/disable button - now marked as enabled" ); - assert.ok( !inp[ 0 ].disabled, "Enable/disable button - field now enabled" ); - assert.ok( !inp.next( "button" )[ 0 ].disabled, "Enable/disable button - button now enabled" ); - inp.datepicker( "destroy" ); - - // With an image button - inp = testHelper.init( "#inp", { showOn: "button", buttonImageOnly: true, - buttonImage: "images/calendar.gif" } ); - assert.ok( !inp.datepicker( "isDisabled" ), "Enable/disable image - initially marked as enabled" ); - assert.ok( !inp[ 0 ].disabled, "Enable/disable image - field initially enabled" ); - assert.ok( parseFloat( inp.next( "img" ).css( "opacity" ) ) === 1, "Enable/disable image - image initially enabled" ); - inp.datepicker( "disable" ); - assert.ok( inp.datepicker( "isDisabled" ), "Enable/disable image - now marked as disabled" ); - assert.ok( inp[ 0 ].disabled, "Enable/disable image - field now disabled" ); - assert.ok( parseFloat( inp.next( "img" ).css( "opacity" ) ) !== 1, "Enable/disable image - image now disabled" ); - inp.datepicker( "enable" ); - assert.ok( !inp.datepicker( "isDisabled" ), "Enable/disable image - now marked as enabled" ); - assert.ok( !inp[ 0 ].disabled, "Enable/disable image - field now enabled" ); - assert.ok( parseFloat( inp.next( "img" ).css( "opacity" ) ) === 1, "Enable/disable image - image now enabled" ); - inp.datepicker( "destroy" ); - - // Inline - inl = testHelper.init( "#inl", { changeYear: true } ); - dp = $( ".ui-datepicker-inline", inl ); - assert.ok( !inl.datepicker( "isDisabled" ), "Enable/disable inline - initially marked as enabled" ); - assert.ok( !dp.children().is( ".ui-state-disabled" ), "Enable/disable inline - not visually disabled initially" ); - assert.ok( !dp.find( "select" ).prop( "disabled" ), "Enable/disable inline - form element enabled initially" ); - inl.datepicker( "disable" ); - assert.ok( inl.datepicker( "isDisabled" ), "Enable/disable inline - now marked as disabled" ); - assert.ok( dp.children().is( ".ui-state-disabled" ), "Enable/disable inline - visually disabled" ); - assert.ok( dp.find( "select" ).prop( "disabled" ), "Enable/disable inline - form element disabled" ); - inl.datepicker( "enable" ); - assert.ok( !inl.datepicker( "isDisabled" ), "Enable/disable inline - now marked as enabled" ); - assert.ok( !dp.children().is( ".ui-state-disabled" ), "Enable/disable inline - not visiually disabled" ); - assert.ok( !dp.find( "select" ).prop( "disabled" ), "Enable/disable inline - form element enabled" ); - inl.datepicker( "destroy" ); +QUnit.test( "widget", function( assert ) { + assert.expect( 1 ); + + assert.deepEqual( $( "body > .ui-front" )[ 0 ], this.widget[ 0 ] ); + this.widget.remove(); +} ); + +QUnit.test( "open / close", function( assert ) { + assert.expect( 7 ); + + assert.ok( this.widget.is( ":hidden" ), "calendar hidden on init" ); + + this.element.datepicker( "open" ); + assert.ok( this.widget.is( ":visible" ), "open: calendar visible" ); + assert.equal( this.widget.attr( "aria-hidden" ), "false", "open: calendar aria-hidden" ); + assert.equal( this.widget.attr( "aria-expanded" ), "true", "close: calendar aria-expanded" ); + + this.element.datepicker( "close" ); + assert.ok( !this.widget.is( ":visible" ), "close: calendar hidden" ); + assert.equal( this.widget.attr( "aria-hidden" ), "true", "close: calendar aria-hidden" ); + assert.equal( this.widget.attr( "aria-expanded" ), "false", "close: calendar aria-expanded" ); +} ); + +QUnit.test( "value", function( assert ) { + assert.expect( 4 ); + + this.element.datepicker( "value", "1/1/14" ); + assert.equal( this.element.val(), "1/1/14", "input's value set" ); + + this.element.datepicker( "open" ); + assert.ok( + this.widget.find( "button[data-ui-calendar-timestamp]" ).eq( 0 ).hasClass( "ui-state-active" ), + "first day marked as selected" + ); + assert.equal( this.element.datepicker( "value" ), "1/1/14", "getter" ); + + this.element.val( "abc" ); + assert.strictEqual( this.element.datepicker( "value" ), null, "Invalid values should return null." ); +} ); + +QUnit.test( "valueAsDate", function( assert ) { + assert.expect( 5 ); + + assert.strictEqual( this.element.datepicker( "valueAsDate" ), null, "Default" ); + + this.element.datepicker( "valueAsDate", testHelper.createDate( 2014, 0, 1 ) ); + assert.equal( this.element.val(), "1/1/14", "Input's value set" ); + assert.ok( + this.widget.find( "button[data-ui-calendar-timestamp]" ).eq( 0 ).hasClass( "ui-state-active" ), + "First day marked as selected" + ); + assert.dateEqual( this.element.datepicker( "valueAsDate" ), testHelper.createDate( 2014, 0, 1 ), "Getter" ); + + this.element.val( "a/b/c" ); + assert.equal( this.element.datepicker( "valueAsDate" ), null, "Invalid dates return null" ); +} ); + +QUnit.test( "isValid", function( assert ) { + assert.expect( 2 ); + + this.element.val( "1/1/14" ); + assert.ok( this.element.datepicker( "isValid" ) ); + + this.element.val( "1/1/abc" ); + assert.ok( !this.element.datepicker( "isValid" ) ); } ); } ); diff --git a/tests/unit/datepicker/options.js b/tests/unit/datepicker/options.js index 821852ed4a7..f895f85bf1f 100644 --- a/tests/unit/datepicker/options.js +++ b/tests/unit/datepicker/options.js @@ -1,1154 +1,193 @@ define( [ "qunit", "jquery", - "./helper", - "ui/widgets/datepicker", - "ui/i18n/datepicker-fr", - "ui/i18n/datepicker-he", - "ui/i18n/datepicker-zh-CN", - "ui/ie" + "../calendar/helper", + "ui/widgets/datepicker" ], function( QUnit, $, testHelper ) { -QUnit.module( "datepicker: options" ); - -QUnit.test( "setDefaults", function( assert ) { - assert.expect( 3 ); - testHelper.init( "#inp" ); - assert.equal( $.datepicker._defaults.showOn, "focus", "Initial showOn" ); - $.datepicker.setDefaults( { showOn: "button" } ); - assert.equal( $.datepicker._defaults.showOn, "button", "Change default showOn" ); - $.datepicker.setDefaults( { showOn: "focus" } ); - assert.equal( $.datepicker._defaults.showOn, "focus", "Restore showOn" ); -} ); - -QUnit.test( "option", function( assert ) { - assert.expect( 17 ); - var inp = testHelper.init( "#inp" ), - inst = $.data( inp[ 0 ], testHelper.PROP_NAME ); - - // Set option - assert.equal( inst.settings.showOn, null, "Initial setting showOn" ); - assert.equal( $.datepicker._get( inst, "showOn" ), "focus", "Initial instance showOn" ); - assert.equal( $.datepicker._defaults.showOn, "focus", "Initial default showOn" ); - inp.datepicker( "option", "showOn", "button" ); - assert.equal( inst.settings.showOn, "button", "Change setting showOn" ); - assert.equal( $.datepicker._get( inst, "showOn" ), "button", "Change instance showOn" ); - assert.equal( $.datepicker._defaults.showOn, "focus", "Retain default showOn" ); - inp.datepicker( "option", { showOn: "both" } ); - assert.equal( inst.settings.showOn, "both", "Change setting showOn" ); - assert.equal( $.datepicker._get( inst, "showOn" ), "both", "Change instance showOn" ); - assert.equal( $.datepicker._defaults.showOn, "focus", "Retain default showOn" ); - inp.datepicker( "option", "showOn", undefined ); - assert.equal( inst.settings.showOn, null, "Clear setting showOn" ); - assert.equal( $.datepicker._get( inst, "showOn" ), "focus", "Restore instance showOn" ); - assert.equal( $.datepicker._defaults.showOn, "focus", "Retain default showOn" ); - - // Get option - inp = testHelper.init( "#inp" ); - assert.equal( inp.datepicker( "option", "showOn" ), "focus", "Initial setting showOn" ); - inp.datepicker( "option", "showOn", "button" ); - assert.equal( inp.datepicker( "option", "showOn" ), "button", "Change instance showOn" ); - inp.datepicker( "option", "showOn", undefined ); - assert.equal( inp.datepicker( "option", "showOn" ), "focus", "Reset instance showOn" ); - assert.deepEqual( inp.datepicker( "option", "all" ), { showAnim: "" }, "Get instance settings" ); - assert.deepEqual( inp.datepicker( "option", "defaults" ), $.datepicker._defaults, - "Get default settings" ); -} ); - -QUnit.test( "disabled", function( assert ) { - assert.expect( 8 ); - var inp = testHelper.init( "#inp" ); - assert.ok( !inp.datepicker( "isDisabled" ), "Initially marked as enabled" ); - assert.ok( !inp[ 0 ].disabled, "Field initially enabled" ); - inp.datepicker( "option", "disabled", true ); - assert.ok( inp.datepicker( "isDisabled" ), "Marked as disabled" ); - assert.ok( inp[ 0 ].disabled, "Field now disabled" ); - inp.datepicker( "option", "disabled", false ); - assert.ok( !inp.datepicker( "isDisabled" ), "Marked as enabled" ); - assert.ok( !inp[ 0 ].disabled, "Field now enabled" ); - inp.datepicker( "destroy" ); - - inp = testHelper.init( "#inp", { disabled: true } ); - assert.ok( inp.datepicker( "isDisabled" ), "Initially marked as disabled" ); - assert.ok( inp[ 0 ].disabled, "Field initially disabled" ); -} ); - -QUnit.test( "change", function( assert ) { - assert.expect( 12 ); - var inp = testHelper.init( "#inp" ), - inst = $.data( inp[ 0 ], testHelper.PROP_NAME ); - assert.equal( inst.settings.showOn, null, "Initial setting showOn" ); - assert.equal( $.datepicker._get( inst, "showOn" ), "focus", "Initial instance showOn" ); - assert.equal( $.datepicker._defaults.showOn, "focus", "Initial default showOn" ); - inp.datepicker( "change", "showOn", "button" ); - assert.equal( inst.settings.showOn, "button", "Change setting showOn" ); - assert.equal( $.datepicker._get( inst, "showOn" ), "button", "Change instance showOn" ); - assert.equal( $.datepicker._defaults.showOn, "focus", "Retain default showOn" ); - inp.datepicker( "change", { showOn: "both" } ); - assert.equal( inst.settings.showOn, "both", "Change setting showOn" ); - assert.equal( $.datepicker._get( inst, "showOn" ), "both", "Change instance showOn" ); - assert.equal( $.datepicker._defaults.showOn, "focus", "Retain default showOn" ); - inp.datepicker( "change", "showOn", undefined ); - assert.equal( inst.settings.showOn, null, "Clear setting showOn" ); - assert.equal( $.datepicker._get( inst, "showOn" ), "focus", "Restore instance showOn" ); - assert.equal( $.datepicker._defaults.showOn, "focus", "Retain default showOn" ); -} ); - -( function() { - var url = window.location.search; - url = decodeURIComponent( url.slice( url.indexOf( "swarmURL=" ) + 9 ) ); - - // TODO: This test occassionally fails in IE in TestSwarm - if ( $.ui.ie && url && url.indexOf( "http" ) === 0 ) { - return; +QUnit.module( "datepicker: options", { + beforeEach: function() { + this.element = $( "#datepicker" ).datepicker( { show: false, hide: false } ); + this.widget = this.element.datepicker( "widget" ); + }, + afterEach: function() { + this.element.datepicker( "destroy" ).val( "" ); } +} ); - QUnit.test( "invocation", function( assert ) { - var ready = assert.async(); - var button, image, - isOldIE = $.ui.ie && ( !document.documentMode || document.documentMode < 9 ), - body = $( "body" ); - - assert.expect( isOldIE ? 25 : 29 ); - - function step0() { - var inp = testHelper.initNewInput(), - dp = $( "#ui-datepicker-div" ); - - button = inp.siblings( "button" ); - assert.ok( button.length === 0, "Focus - button absent" ); - image = inp.siblings( "img" ); - assert.ok( image.length === 0, "Focus - image absent" ); - - testHelper.onFocus( inp, function() { - assert.ok( dp.is( ":visible" ), "Focus - rendered on focus" ); - inp.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - assert.ok( !dp.is( ":visible" ), "Focus - hidden on exit" ); - step1(); - } ); - } - - function step1() { +QUnit.test( "appendTo", function( assert ) { + assert.expect( 6 ); - var inp = testHelper.initNewInput(), - dp = $( "#ui-datepicker-div" ); + var container = this.widget.parent()[ 0 ], + detached = $( "
    " ); - testHelper.onFocus( inp, function() { - assert.ok( dp.is( ":visible" ), "Focus - rendered on focus" ); - body.simulate( "mousedown", {} ); - assert.ok( !dp.is( ":visible" ), "Focus - hidden on external click" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); + assert.equal( container, document.body, "defaults to body" ); + this.element.datepicker( "destroy" ); - step2(); - } ); - } + this.element.datepicker( { appendTo: "#qunit-fixture" } ); + container = this.element.datepicker( "widget" ).parent()[ 0 ]; + assert.equal( container, $( "#qunit-fixture" )[ 0 ], "child of specified element" ); + this.element.datepicker( "destroy" ); - function step2() { - var inp = testHelper.initNewInput( { - showOn: "button", - buttonText: "Popup" - } ), - dp = $( "#ui-datepicker-div" ); + this.element.datepicker( { appendTo: "#does-not-exist" } ); + container = this.element.datepicker( "widget" ).parent()[ 0 ]; + assert.equal( container, document.body, "set to body if element does not exist" ); + this.element.datepicker( "destroy" ); - assert.ok( !dp.is( ":visible" ), "Button - initially hidden" ); - button = inp.siblings( "button" ); - image = inp.siblings( "img" ); - assert.ok( button.length === 1, "Button - button present" ); - assert.ok( image.length === 0, "Button - image absent" ); - assert.equal( button.text(), "Popup", "Button - button text" ); + this.element.datepicker() + .datepicker( "option", "appendTo", "#qunit-fixture" ); + container = this.element.datepicker( "widget" ).parent()[ 0 ]; + assert.equal( container, $( "#qunit-fixture" )[ 0 ], "modified after init" ); + this.element.datepicker( "destroy" ); - testHelper.onFocus( inp, function() { - assert.ok( !dp.is( ":visible" ), "Button - not rendered on focus" ); - button.trigger( "click" ); - assert.ok( dp.is( ":visible" ), "Button - rendered on button click" ); - button.trigger( "click" ); - assert.ok( !dp.is( ":visible" ), "Button - hidden on second button click" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); + this.element.datepicker( { appendTo: detached } ); + container = this.element.datepicker( "widget" ).parent()[ 0 ]; + assert.equal( container, detached[ 0 ], "detached jQuery object" ); + this.element.datepicker( "destroy" ); - step3(); - } ); - } - - function step3() { - var inp = testHelper.initNewInput( { - showOn: "button", - buttonImageOnly: true, - buttonImage: "images/calendar.gif", - buttonText: "Cal" - } ), - dp = $( "#ui-datepicker-div" ); - - assert.ok( !dp.is( ":visible" ), "Image button - initially hidden" ); - button = inp.siblings( "button" ); - assert.ok( button.length === 0, "Image button - button absent" ); - image = inp.siblings( "img" ); - assert.ok( image.length === 1, "Image button - image present" ); - assert.ok( /images\/calendar\.gif$/.test( image.attr( "src" ) ), "Image button - image source" ); - assert.equal( image.attr( "title" ), "Cal", "Image button - image text" ); + this.element.datepicker( { appendTo: detached[ 0 ] } ); + container = this.element.datepicker( "widget" ).parent()[ 0 ]; + assert.equal( container, detached[ 0 ], "detached DOM element" ); +} ); - testHelper.onFocus( inp, function() { - assert.ok( !dp.is( ":visible" ), "Image button - not rendered on focus" ); - image.trigger( "click" ); - assert.ok( dp.is( ":visible" ), "Image button - rendered on image click" ); - image.trigger( "click" ); - assert.ok( !dp.is( ":visible" ), "Image button - hidden on second image click" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); +QUnit.test( "min / max", function( assert ) { + assert.expect( 10 ); - step4(); - } ); + var min, max; + + this.element.datepicker( "option", { min: "10/20/08", max: "10/25/08" } ); + assert.dateEqual( this.element.datepicker( "option", "min" ), testHelper.createDate( 2008, 10 - 1, 20 ), "Set min option as string" ); + assert.dateEqual( this.element.datepicker( "option", "max" ), testHelper.createDate( 2008, 10 - 1, 25 ), "Set max option as string" ); + + min = testHelper.createDate( 2009, 10 - 1, 20 ); + max = testHelper.createDate( 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" ), testHelper.createDate( 2010, 10 - 1, 20 ), "Set min option as attribute" ); + assert.dateEqual( this.element.datepicker( "option", "max" ), testHelper.createDate( 2010, 10 - 1, 25 ), "Set max option as attribute" ); + + min = testHelper.createDate( 2011, 10 - 1, 20 ); + max = testHelper.createDate( 2011, 10 - 1, 25 ); + this.element + .datepicker( "destroy" ) + .datepicker( { min: min, max: max } ); + assert.dateEqual( this.element.datepicker( "option", "min" ), testHelper.createDate( 2011, 10 - 1, 20 ), "Set min option as date object on init" ); + assert.dateEqual( this.element.datepicker( "option", "max" ), testHelper.createDate( 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" ), testHelper.createDate( 2012, 10 - 1, 20 ), "Set min option as string on init" ); + assert.dateEqual( this.element.datepicker( "option", "max" ), testHelper.createDate( 2012, 10 - 1, 25 ), "Set max option as string on init" ); + +} ); + +QUnit.test( "Pass-through options", function( assert ) { + assert.expect( 11 ); + + var options = { + buttons: { "Test": $.noop }, + dateFormat: { date: "full" }, + disabled: true, + eachDay: function( day ) { day; }, + locale: "de", + max: testHelper.createDate( 2000, 0, 1 ), + min: testHelper.createDate( 2000, 0, 2 ), + numberOfMonths: 3, + showWeek: true + }, + input = $( "" ).val( "1/1/14" ).appendTo( "#qunit-fixture" ).datepicker(), + instance = input.datepicker( "instance" ); + + $.each( options, function( key, value ) { + input.datepicker( "option", key, value ); + + assert.deepEqual( + instance.calendar.calendar( "option", key ), + value, + "option " + key + ": correct value" + ); + + if ( key === "dateFormat" ) { + assert.equal( input.val(), "Wednesday, January 1, 2014", "option " + key + ": updated format" ); } - function step4() { - var inp = testHelper.initNewInput( { - showOn: "both", - buttonImage: "images/calendar.gif" - } ), - dp = $( "#ui-datepicker-div" ); - - assert.ok( !dp.is( ":visible" ), "Both - initially hidden" ); - button = inp.siblings( "button" ); - assert.ok( button.length === 1, "Both - button present" ); - image = inp.siblings( "img" ); - assert.ok( image.length === 0, "Both - image absent" ); - image = button.children( "img" ); - assert.ok( image.length === 1, "Both - button image present" ); - - // TODO: This test occasionally fails to focus in IE8 in BrowserStack - if ( !isOldIE ) { - testHelper.onFocus( inp, function() { - assert.ok( dp.is( ":visible" ), "Both - rendered on focus" ); - body.simulate( "mousedown", {} ); - assert.ok( !dp.is( ":visible" ), "Both - hidden on external click" ); - button.trigger( "click" ); - assert.ok( dp.is( ":visible" ), "Both - rendered on button click" ); - button.trigger( "click" ); - assert.ok( !dp.is( ":visible" ), "Both - hidden on second button click" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); - - ready(); - } ); - } else { - ready(); - } + if ( key === "locale" ) { + assert.equal( input.val(), "Mittwoch, 1. Januar 2014", "option " + key + ": updated locale" ); } - - step0(); } ); -} )(); - -QUnit.test( "otherMonths", function( assert ) { - assert.expect( 8 ); - var inp = testHelper.init( "#inp" ), - pop = $( "#ui-datepicker-div" ); - inp.val( "06/01/2009" ).datepicker( "show" ); - assert.equal( pop.find( "tbody" ).text(), - - // Support: IE <9, jQuery <1.8 - // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways - $( "\u00a0123456789101112131415161718192021222324252627282930\u00a0\u00a0\u00a0\u00a0" ).text(), - "Other months - none" ); - assert.ok( pop.find( "td:last *" ).length === 0, "Other months - no content" ); - inp.datepicker( "hide" ).datepicker( "option", "showOtherMonths", true ).datepicker( "show" ); - assert.equal( pop.find( "tbody" ).text(), "311234567891011121314151617181920212223242526272829301234", - "Other months - show" ); - assert.ok( pop.find( "td:last span" ).length === 1, "Other months - span content" ); - inp.datepicker( "hide" ).datepicker( "option", "selectOtherMonths", true ).datepicker( "show" ); - assert.equal( pop.find( "tbody" ).text(), "311234567891011121314151617181920212223242526272829301234", - "Other months - select" ); - assert.ok( pop.find( "td:last a" ).length === 1, "Other months - link content" ); - inp.datepicker( "hide" ).datepicker( "option", "showOtherMonths", false ).datepicker( "show" ); - assert.equal( pop.find( "tbody" ).text(), - - // Support: IE <9, jQuery <1.8 - // In IE7/8 with jQuery <1.8, encoded spaces behave in strange ways - $( "\u00a0123456789101112131415161718192021222324252627282930\u00a0\u00a0\u00a0\u00a0" ).text(), - "Other months - none" ); - assert.ok( pop.find( "td:last *" ).length === 0, "Other months - no content" ); -} ); - -QUnit.test( "defaultDate", function( assert ) { - assert.expect( 16 ); - var inp = testHelper.init( "#inp" ), - date = new Date(); - inp.val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date null" ); - - // Numeric values - inp.datepicker( "option", { defaultDate: -2 } ). - datepicker( "hide" ).val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date.setDate( date.getDate() - 2 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date -2" ); - - date = new Date(); - inp.datepicker( "option", { defaultDate: 3 } ). - datepicker( "hide" ).val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date.setDate( date.getDate() + 3 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date 3" ); - - date = new Date(); - inp.datepicker( "option", { defaultDate: 1 / "a" } ). - datepicker( "hide" ).val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date NaN" ); - - // String offset values - inp.datepicker( "option", { defaultDate: "-1d" } ). - datepicker( "hide" ).val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date.setDate( date.getDate() - 1 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date -1d" ); - inp.datepicker( "option", { defaultDate: "+3D" } ). - datepicker( "hide" ).val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date.setDate( date.getDate() + 4 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date +3D" ); - inp.datepicker( "option", { defaultDate: " -2 w " } ). - datepicker( "hide" ).val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date(); - date.setDate( date.getDate() - 14 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date -2 w" ); - inp.datepicker( "option", { defaultDate: "+1 W" } ). - datepicker( "hide" ).val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date.setDate( date.getDate() + 21 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date +1 W" ); - inp.datepicker( "option", { defaultDate: " -1 m " } ). - datepicker( "hide" ).val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = testHelper.addMonths( new Date(), -1 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date -1 m" ); - inp.datepicker( "option", { defaultDate: "+2M" } ). - datepicker( "hide" ).val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = testHelper.addMonths( new Date(), 2 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date +2M" ); - inp.datepicker( "option", { defaultDate: "-2y" } ). - datepicker( "hide" ).val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date(); - date.setFullYear( date.getFullYear() - 2 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date -2y" ); - inp.datepicker( "option", { defaultDate: "+1 Y " } ). - datepicker( "hide" ).val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date.setFullYear( date.getFullYear() + 3 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date +1 Y" ); - inp.datepicker( "option", { defaultDate: "+1M +10d" } ). - datepicker( "hide" ).val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = testHelper.addMonths( new Date(), 1 ); - date.setDate( date.getDate() + 10 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date +1M +10d" ); - - // String date values - inp.datepicker( "option", { defaultDate: "07/04/2007" } ). - datepicker( "hide" ).val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2007, 7 - 1, 4 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date 07/04/2007" ); - inp.datepicker( "option", { dateFormat: "yy-mm-dd", defaultDate: "2007-04-02" } ). - datepicker( "hide" ).val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date( 2007, 4 - 1, 2 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date 2007-04-02" ); - - // Date value - date = new Date( 2007, 1 - 1, 26 ); - inp.datepicker( "option", { dateFormat: "mm/dd/yy", defaultDate: date } ). - datepicker( "hide" ).val( "" ).datepicker( "show" ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, "Default date 01/26/2007" ); -} ); - -QUnit.test( "miscellaneous", function( assert ) { - assert.expect( 19 ); - var curYear, longNames, shortNames, date, - dp = $( "#ui-datepicker-div" ), - inp = testHelper.init( "#inp" ); - - // Year range - function genRange( start, offset ) { - var i = start, - range = ""; - for ( ; i < start + offset; i++ ) { - range += i; - } - return range; - } - curYear = new Date().getFullYear(); - inp.val( "02/04/2008" ).datepicker( "show" ); - assert.equal( dp.find( ".ui-datepicker-year" ).text(), "2008", "Year range - read-only default" ); - inp.datepicker( "hide" ).datepicker( "option", { changeYear: true } ).datepicker( "show" ); - assert.equal( dp.find( ".ui-datepicker-year" ).text(), genRange( 2008 - 10, 21 ), "Year range - changeable default" ); - inp.datepicker( "hide" ).datepicker( "option", { yearRange: "c-6:c+2", changeYear: true } ).datepicker( "show" ); - assert.equal( dp.find( ".ui-datepicker-year" ).text(), genRange( 2008 - 6, 9 ), "Year range - c-6:c+2" ); - inp.datepicker( "hide" ).datepicker( "option", { yearRange: "2000:2010", changeYear: true } ).datepicker( "show" ); - assert.equal( dp.find( ".ui-datepicker-year" ).text(), genRange( 2000, 11 ), "Year range - 2000:2010" ); - inp.datepicker( "hide" ).datepicker( "option", { yearRange: "-5:+3", changeYear: true } ).datepicker( "show" ); - assert.equal( dp.find( ".ui-datepicker-year" ).text(), genRange( curYear - 5, 9 ), "Year range - -5:+3" ); - inp.datepicker( "hide" ).datepicker( "option", { yearRange: "2000:-5", changeYear: true } ).datepicker( "show" ); - assert.equal( dp.find( ".ui-datepicker-year" ).text(), genRange( 2000, curYear - 2004 ), "Year range - 2000:-5" ); - inp.datepicker( "hide" ).datepicker( "option", { yearRange: "", changeYear: true } ).datepicker( "show" ); - assert.equal( dp.find( ".ui-datepicker-year" ).text(), genRange( curYear, 1 ), "Year range - -6:+2" ); - - // Navigation as date format - inp.datepicker( "option", { showButtonPanel: true } ); - assert.equal( dp.find( ".ui-datepicker-prev" ).text(), "Prev", "Navigation prev - default" ); - assert.equal( dp.find( ".ui-datepicker-current" ).text(), "Today", "Navigation current - default" ); - assert.equal( dp.find( ".ui-datepicker-next" ).text(), "Next", "Navigation next - default" ); - inp.datepicker( "hide" ).datepicker( "option", { navigationAsDateFormat: true, prevText: "< M", currentText: "MM", nextText: "M >" } ). - val( "02/04/2008" ).datepicker( "show" ); - longNames = $.datepicker.regional[ "" ].monthNames; - shortNames = $.datepicker.regional[ "" ].monthNamesShort; - date = new Date(); - assert.equal( dp.find( ".ui-datepicker-prev" ).text(), "< " + shortNames[ 0 ], "Navigation prev - as date format" ); - assert.equal( dp.find( ".ui-datepicker-current" ).text(), - longNames[ date.getMonth() ], "Navigation current - as date format" ); - assert.equal( dp.find( ".ui-datepicker-next" ).text(), - shortNames[ 2 ] + " >", "Navigation next - as date format" ); - inp.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ); - assert.equal( dp.find( ".ui-datepicker-prev" ).text(), - "< " + shortNames[ 1 ], "Navigation prev - as date format + pgdn" ); - assert.equal( dp.find( ".ui-datepicker-current" ).text(), - longNames[ date.getMonth() ], "Navigation current - as date format + pgdn" ); - assert.equal( dp.find( ".ui-datepicker-next" ).text(), - shortNames[ 3 ] + " >", "Navigation next - as date format + pgdn" ); - inp.datepicker( "hide" ).datepicker( "option", { gotoCurrent: true } ). - val( "02/04/2008" ).datepicker( "show" ); - assert.equal( dp.find( ".ui-datepicker-prev" ).text(), - "< " + shortNames[ 0 ], "Navigation prev - as date format + goto current" ); - assert.equal( dp.find( ".ui-datepicker-current" ).text(), - longNames[ 1 ], "Navigation current - as date format + goto current" ); - assert.equal( dp.find( ".ui-datepicker-next" ).text(), - shortNames[ 2 ] + " >", "Navigation next - as date format + goto current" ); } ); -QUnit.test( "minMax", function( assert ) { - assert.expect( 23 ); - var date, - inp = testHelper.init( "#inp" ), - dp = $( "#ui-datepicker-div" ), - lastYear = new Date( 2007, 6 - 1, 4 ), - nextYear = new Date( 2009, 6 - 1, 4 ), - minDate = new Date( 2008, 2 - 1, 29 ), - maxDate = new Date( 2008, 12 - 1, 7 ); - inp.val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), lastYear, - "Min/max - null, null - ctrl+pgup" ); - inp.val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), nextYear, - "Min/max - null, null - ctrl+pgdn" ); - inp.datepicker( "option", { minDate: minDate } ). - datepicker( "hide" ).val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), minDate, - "Min/max - 02/29/2008, null - ctrl+pgup" ); - inp.val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), nextYear, - "Min/max - 02/29/2008, null - ctrl+pgdn" ); - inp.datepicker( "option", { maxDate: maxDate } ). - datepicker( "hide" ).val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), minDate, - "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgup" ); - inp.val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), maxDate, - "Min/max - 02/29/2008, 12/07/2008 - ctrl+pgdn" ); - inp.datepicker( "option", { minDate: null } ). - datepicker( "hide" ).val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), lastYear, - "Min/max - null, 12/07/2008 - ctrl+pgup" ); - inp.val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), maxDate, - "Min/max - null, 12/07/2008 - ctrl+pgdn" ); - - // Relative dates - date = new Date(); - date.setDate( date.getDate() - 7 ); - inp.datepicker( "option", { minDate: "-1w", maxDate: "+1 M +10 D " } ). - datepicker( "hide" ).val( "" ).datepicker( "show" ); - inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, - "Min/max - -1w, +1 M +10 D - ctrl+pgup" ); - date = testHelper.addMonths( new Date(), 1 ); - date.setDate( date.getDate() + 10 ); - inp.val( "" ).datepicker( "show" ); - inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_DOWN } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date, - "Min/max - -1w, +1 M +10 D - ctrl+pgdn" ); - - // With existing date - inp = testHelper.init( "#inp" ); - inp.val( "06/04/2008" ).datepicker( "option", { minDate: minDate } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - setDate > min" ); - inp.datepicker( "option", { minDate: null } ).val( "01/04/2008" ).datepicker( "option", { minDate: minDate } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), minDate, "Min/max - setDate < min" ); - inp.datepicker( "option", { minDate: null } ).val( "06/04/2008" ).datepicker( "option", { maxDate: maxDate } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - setDate < max" ); - inp.datepicker( "option", { maxDate: null } ).val( "01/04/2009" ).datepicker( "option", { maxDate: maxDate } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), maxDate, "Min/max - setDate > max" ); - inp.datepicker( "option", { maxDate: null } ).val( "01/04/2008" ).datepicker( "option", { minDate: minDate, maxDate: maxDate } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), minDate, "Min/max - setDate < min" ); - inp.datepicker( "option", { maxDate: null } ).val( "06/04/2008" ).datepicker( "option", { minDate: minDate, maxDate: maxDate } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - setDate > min, < max" ); - inp.datepicker( "option", { maxDate: null } ).val( "01/04/2009" ).datepicker( "option", { minDate: minDate, maxDate: maxDate } ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), maxDate, "Min/max - setDate > max" ); - - inp.datepicker( "option", { yearRange: "-0:+1" } ).val( "01/01/" + new Date().getFullYear() ); - assert.ok( dp.find( ".ui-datepicker-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - previous button disabled at 1/1/minYear" ); - inp.datepicker( "setDate", "12/30/" + new Date().getFullYear() ); - assert.ok( dp.find( ".ui-datepicker-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - next button disabled at 12/30/maxYear" ); - - inp.val( "" ).datepicker( "option", { - minDate: new Date( 1900, 0, 1 ), - maxDate: "-7Y", - yearRange: "1900:-7" - } ); - assert.ok( dp.find( ".ui-datepicker-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - relative - next button disabled" ); - assert.ok( !dp.find( ".ui-datepicker-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - relative - prev button enabled" ); +QUnit.test( "position", function( assert ) { + var ready = assert.async(); + assert.expect( 3 ); - inp.val( "" ).datepicker( "option", { - minDate: new Date( 1900, 0, 1 ), - maxDate: "1/25/2007", - yearRange: "1900:2007" + var input = $( "" ).datepicker().appendTo( "body" ).css( { + position: "absolute", + top: 0, + left: 0 + } ), + container = input.datepicker( "widget" ); + + input.datepicker( "open" ); + setTimeout( function() { + assert.close( input.offset().left, container.offset().left, 1, "left sides line up by default" ); + assert.close( container.offset().top, input.offset().top + input.outerHeight(), 1, + "datepicker directly under input by default" ); + + // Change the position option using option() + input.datepicker( "option", "position", { + my: "left top", + at: "right bottom" + } ); + assert.close( container.offset().left, input.offset().left + input.outerWidth(), 1, + "datepicker on right hand side of input after position change" ); + + input.remove(); + ready(); } ); - assert.ok( dp.find( ".ui-datepicker-next" ).hasClass( "ui-state-disabled" ), "Year Range Test - absolute - next button disabled" ); - assert.ok( !dp.find( ".ui-datepicker-prev" ).hasClass( "ui-state-disabled" ), "Year Range Test - absolute - prev button enabled" ); -} ); - -QUnit.test( "setDate", function( assert ) { - assert.expect( 24 ); - var inl, alt, minDate, maxDate, dateAndTimeToSet, dateAndTimeClone, - inp = testHelper.init( "#inp" ), - date1 = new Date( 2008, 6 - 1, 4 ), - date2 = new Date(); - assert.ok( inp.datepicker( "getDate" ) == null, "Set date - default" ); - inp.datepicker( "setDate", date1 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date1, "Set date - 2008-06-04" ); - date1 = new Date(); - date1.setDate( date1.getDate() + 7 ); - inp.datepicker( "setDate", +7 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date1, "Set date - +7" ); - date2.setFullYear( date2.getFullYear() + 2 ); - inp.datepicker( "setDate", "+2y" ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date2, "Set date - +2y" ); - inp.datepicker( "setDate", date1, date2 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date1, "Set date - two dates" ); - inp.datepicker( "setDate" ); - assert.ok( inp.datepicker( "getDate" ) == null, "Set date - null" ); - - // Relative to current date - date1 = new Date(); - date1.setDate( date1.getDate() + 7 ); - inp.datepicker( "setDate", "c +7" ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date1, "Set date - c +7" ); - date1.setDate( date1.getDate() + 7 ); - inp.datepicker( "setDate", "c+7" ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date1, "Set date - c+7" ); - date1.setDate( date1.getDate() - 21 ); - inp.datepicker( "setDate", "c -3 w" ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date1, "Set date - c -3 w" ); - - // Inline - inl = testHelper.init( "#inl" ); - date1 = new Date( 2008, 6 - 1, 4 ); - date2 = new Date(); - testHelper.equalsDate( assert, inl.datepicker( "getDate" ), date2, "Set date inline - default" ); - inl.datepicker( "setDate", date1 ); - testHelper.equalsDate( assert, inl.datepicker( "getDate" ), date1, "Set date inline - 2008-06-04" ); - date1 = new Date(); - date1.setDate( date1.getDate() + 7 ); - inl.datepicker( "setDate", +7 ); - testHelper.equalsDate( assert, inl.datepicker( "getDate" ), date1, "Set date inline - +7" ); - date2.setFullYear( date2.getFullYear() + 2 ); - inl.datepicker( "setDate", "+2y" ); - testHelper.equalsDate( assert, inl.datepicker( "getDate" ), date2, "Set date inline - +2y" ); - inl.datepicker( "setDate", date1, date2 ); - testHelper.equalsDate( assert, inl.datepicker( "getDate" ), date1, "Set date inline - two dates" ); - inl.datepicker( "setDate" ); - assert.ok( inl.datepicker( "getDate" ) == null, "Set date inline - null" ); - - // Alternate field - alt = $( "#alt" ); - inp.datepicker( "option", { altField: "#alt", altFormat: "yy-mm-dd" } ); - date1 = new Date( 2008, 6 - 1, 4 ); - inp.datepicker( "setDate", date1 ); - assert.equal( inp.val(), "06/04/2008", "Set date alternate - 06/04/2008" ); - assert.equal( alt.val(), "2008-06-04", "Set date alternate - 2008-06-04" ); - - // With minimum/maximum - inp = testHelper.init( "#inp" ); - 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 ); - inp.val( "" ).datepicker( "option", { minDate: minDate } ).datepicker( "setDate", date2 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date2, "Set date min/max - setDate > min" ); - inp.datepicker( "setDate", date1 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), minDate, "Set date min/max - setDate < min" ); - inp.val( "" ).datepicker( "option", { maxDate: maxDate, minDate: null } ).datepicker( "setDate", date1 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), date1, "Set date min/max - setDate < max" ); - inp.datepicker( "setDate", date2 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), maxDate, "Set date min/max - setDate > max" ); - inp.val( "" ).datepicker( "option", { minDate: minDate } ).datepicker( "setDate", date1 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), minDate, "Set date min/max - setDate < min" ); - inp.datepicker( "setDate", date2 ); - testHelper.equalsDate( assert, inp.datepicker( "getDate" ), maxDate, "Set date min/max - setDate > max" ); - dateAndTimeToSet = new Date( 2008, 3 - 1, 28, 1, 11, 0 ); - dateAndTimeClone = new Date( 2008, 3 - 1, 28, 1, 11, 0 ); - inp.datepicker( "setDate", dateAndTimeToSet ); - assert.equal( dateAndTimeToSet.getTime(), dateAndTimeClone.getTime(), "Date object passed should not be changed by setDate" ); } ); -QUnit.test( "altField", function( assert ) { - assert.expect( 10 ); - var inp = testHelper.init( "#inp" ), - alt = $( "#alt" ); - - // No alternate field set - alt.val( "" ); - inp.val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - assert.equal( inp.val(), "06/04/2008", "Alt field - dp - enter" ); - assert.equal( alt.val(), "", "Alt field - alt not set" ); - - // Alternate field set - alt.val( "" ); - inp.datepicker( "option", { altField: "#alt", altFormat: "yy-mm-dd" } ). - val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - assert.equal( inp.val(), "06/04/2008", "Alt field - dp - enter" ); - assert.equal( alt.val(), "2008-06-04", "Alt field - alt - enter" ); - - // Move from initial date - alt.val( "" ); - inp.val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - assert.equal( inp.val(), "07/04/2008", "Alt field - dp - pgdn" ); - assert.equal( alt.val(), "2008-07-04", "Alt field - alt - pgdn" ); - - // Alternate field set - closed - alt.val( "" ); - inp.val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } ). - simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); - assert.equal( inp.val(), "06/04/2008", "Alt field - dp - pgdn/esc" ); - assert.equal( alt.val(), "", "Alt field - alt - pgdn/esc" ); - - // Clear date and alternate - alt.val( "" ); - inp.val( "06/04/2008" ).datepicker( "show" ); - inp.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END } ); - assert.equal( inp.val(), "", "Alt field - dp - ctrl+end" ); - assert.equal( alt.val(), "", "Alt field - alt - ctrl+end" ); -} ); - -QUnit.test( "autoSize", function( assert ) { - assert.expect( 15 ); - var inp = testHelper.init( "#inp" ); - assert.equal( inp.prop( "size" ), 20, "Auto size - default" ); - inp.datepicker( "option", "autoSize", true ); - assert.equal( inp.prop( "size" ), 10, "Auto size - mm/dd/yy" ); - inp.datepicker( "option", "dateFormat", "m/d/yy" ); - assert.equal( inp.prop( "size" ), 10, "Auto size - m/d/yy" ); - inp.datepicker( "option", "dateFormat", "D M d yy" ); - assert.equal( inp.prop( "size" ), 15, "Auto size - D M d yy" ); - inp.datepicker( "option", "dateFormat", "DD, MM dd, yy" ); - assert.equal( inp.prop( "size" ), 29, "Auto size - DD, MM dd, yy" ); - - // French - inp.datepicker( "option", $.extend( { autoSize: false }, $.datepicker.regional.fr ) ); - assert.equal( inp.prop( "size" ), 29, "Auto size - fr - default" ); - inp.datepicker( "option", "autoSize", true ); - assert.equal( inp.prop( "size" ), 10, "Auto size - fr - dd/mm/yy" ); - inp.datepicker( "option", "dateFormat", "m/d/yy" ); - assert.equal( inp.prop( "size" ), 10, "Auto size - fr - m/d/yy" ); - inp.datepicker( "option", "dateFormat", "D M d yy" ); - assert.equal( inp.prop( "size" ), 18, "Auto size - fr - D M d yy" ); - inp.datepicker( "option", "dateFormat", "DD, MM dd, yy" ); - assert.equal( inp.prop( "size" ), 28, "Auto size - fr - DD, MM dd, yy" ); - - // Hebrew - inp.datepicker( "option", $.extend( { autoSize: false }, $.datepicker.regional.he ) ); - assert.equal( inp.prop( "size" ), 28, "Auto size - he - default" ); - inp.datepicker( "option", "autoSize", true ); - assert.equal( inp.prop( "size" ), 10, "Auto size - he - dd/mm/yy" ); - inp.datepicker( "option", "dateFormat", "m/d/yy" ); - assert.equal( inp.prop( "size" ), 10, "Auto size - he - m/d/yy" ); - inp.datepicker( "option", "dateFormat", "D M d yy" ); - assert.equal( inp.prop( "size" ), 16, "Auto size - he - D M d yy" ); - inp.datepicker( "option", "dateFormat", "DD, MM dd, yy" ); - assert.equal( inp.prop( "size" ), 23, "Auto size - he - DD, MM dd, yy" ); -} ); - -QUnit.test( "daylightSaving", function( assert ) { - assert.expect( 25 ); - var inp = testHelper.init( "#inp" ), - dp = $( "#ui-datepicker-div" ); - assert.ok( true, "Daylight saving - " + new Date() ); - - // Australia, Sydney - AM change, southern hemisphere - inp.val( "04/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(6) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "04/05/2008", "Daylight saving - Australia 04/05/2008" ); - inp.val( "04/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(7) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "04/06/2008", "Daylight saving - Australia 04/06/2008" ); - inp.val( "04/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(8) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "04/07/2008", "Daylight saving - Australia 04/07/2008" ); - inp.val( "10/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(6) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "10/04/2008", "Daylight saving - Australia 10/04/2008" ); - inp.val( "10/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(7) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "10/05/2008", "Daylight saving - Australia 10/05/2008" ); - inp.val( "10/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(8) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "10/06/2008", "Daylight saving - Australia 10/06/2008" ); - - // Brasil, Brasilia - midnight change, southern hemisphere - inp.val( "02/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(20) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "02/16/2008", "Daylight saving - Brasil 02/16/2008" ); - inp.val( "02/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(21) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "02/17/2008", "Daylight saving - Brasil 02/17/2008" ); - inp.val( "02/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(22) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "02/18/2008", "Daylight saving - Brasil 02/18/2008" ); - inp.val( "10/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(13) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "10/11/2008", "Daylight saving - Brasil 10/11/2008" ); - inp.val( "10/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(14) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "10/12/2008", "Daylight saving - Brasil 10/12/2008" ); - inp.val( "10/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(15) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "10/13/2008", "Daylight saving - Brasil 10/13/2008" ); - - // Lebanon, Beirut - midnight change, northern hemisphere - inp.val( "03/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(34) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "03/29/2008", "Daylight saving - Lebanon 03/29/2008" ); - inp.val( "03/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(35) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "03/30/2008", "Daylight saving - Lebanon 03/30/2008" ); - inp.val( "03/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(36) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "03/31/2008", "Daylight saving - Lebanon 03/31/2008" ); - inp.val( "10/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(27) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "10/25/2008", "Daylight saving - Lebanon 10/25/2008" ); - inp.val( "10/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(28) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "10/26/2008", "Daylight saving - Lebanon 10/26/2008" ); - inp.val( "10/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(29) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "10/27/2008", "Daylight saving - Lebanon 10/27/2008" ); - - // US, Eastern - AM change, northern hemisphere - inp.val( "03/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(13) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "03/08/2008", "Daylight saving - US 03/08/2008" ); - inp.val( "03/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(14) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "03/09/2008", "Daylight saving - US 03/09/2008" ); - inp.val( "03/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(15) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "03/10/2008", "Daylight saving - US 03/10/2008" ); - inp.val( "11/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(6) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "11/01/2008", "Daylight saving - US 11/01/2008" ); - inp.val( "11/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(7) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "11/02/2008", "Daylight saving - US 11/02/2008" ); - inp.val( "11/01/2008" ).datepicker( "show" ); - $( ".ui-datepicker-calendar td:eq(8) a", dp ).simulate( "click" ); - assert.equal( inp.val(), "11/03/2008", "Daylight saving - US 11/03/2008" ); -} ); - -var beforeShowThis = null, - beforeShowInput = null, - beforeShowInst = null, - beforeShowDayThis = null, - beforeShowDayOK = true; - -function beforeAll( input, inst ) { - beforeShowThis = this; - beforeShowInput = input; - beforeShowInst = inst; - return { currentText: "Current" }; -} - -function beforeDay( date ) { - beforeShowDayThis = this; - beforeShowDayOK &= ( date > new Date( 2008, 1 - 1, 26 ) && - date < new Date( 2008, 3 - 1, 6 ) ); - return [ ( date.getDate() % 2 === 0 ), ( date.getDate() % 10 === 0 ? "day10" : "" ), - ( date.getDate() % 3 === 0 ? "Divisble by 3" : "" ) ]; -} - -QUnit.test( "callbacks", function( assert ) { - assert.expect( 13 ); - - // Before show - var dp, day20, day21, - inp = testHelper.init( "#inp", { beforeShow: beforeAll } ), - inst = $.data( inp[ 0 ], "datepicker" ); - assert.equal( $.datepicker._get( inst, "currentText" ), "Today", "Before show - initial" ); - inp.val( "02/04/2008" ).datepicker( "show" ); - assert.equal( $.datepicker._get( inst, "currentText" ), "Current", "Before show - changed" ); - assert.ok( beforeShowThis.id === inp[ 0 ].id, "Before show - this OK" ); - assert.ok( beforeShowInput.id === inp[ 0 ].id, "Before show - input OK" ); - assert.deepEqual( beforeShowInst, inst, "Before show - inst OK" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); - - // Before show day - inp = testHelper.init( "#inp", { beforeShowDay: beforeDay } ); - dp = $( "#ui-datepicker-div" ); - inp.val( "02/04/2008" ).datepicker( "show" ); - assert.ok( beforeShowDayThis.id === inp[ 0 ].id, "Before show day - this OK" ); - assert.ok( beforeShowDayOK, "Before show day - dates OK" ); - day20 = dp.find( ".ui-datepicker-calendar td:contains('20')" ); - day21 = dp.find( ".ui-datepicker-calendar td:contains('21')" ); - assert.ok( !day20.is( ".ui-datepicker-unselectable" ), "Before show day - unselectable 20" ); - assert.ok( day21.is( ".ui-datepicker-unselectable" ), "Before show day - unselectable 21" ); - assert.ok( day20.is( ".day10" ), "Before show day - CSS 20" ); - assert.ok( !day21.is( ".day10" ), "Before show day - CSS 21" ); - assert.ok( !day20.attr( "title" ), "Before show day - title 20" ); - assert.ok( day21.attr( "title" ) === "Divisble by 3", "Before show day - title 21" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); -} ); - -QUnit.test( "beforeShowDay - tooltips with quotes", function( assert ) { +QUnit.test( "Stop datepicker from appearing with beforeOpen event handler - nothing", function( assert ) { assert.expect( 1 ); - var inp, dp; - inp = testHelper.init( "#inp", { - beforeShowDay: function() { - return [ true, "", "'" ]; - } - } ); - dp = $( "#ui-datepicker-div" ); - inp.datepicker( "show" ); - assert.equal( dp.find( ".ui-datepicker-calendar td:contains('9')" ).attr( "title" ), "'" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); -} ); - -QUnit.test( "localisation", function( assert ) { - assert.expect( 24 ); - var dp, month, day, date, - inp = testHelper.init( "#inp", $.datepicker.regional.fr ); - inp.datepicker( "option", { dateFormat: "DD, d MM yy", showButtonPanel:true, changeMonth:true, changeYear:true } ).val( "" ).datepicker( "show" ); - dp = $( "#ui-datepicker-div" ); - assert.equal( $( ".ui-datepicker-close", dp ).text(), "Fermer", "Localisation - close" ); - $( ".ui-datepicker-close", dp ).simulate( "mouseover" ); - assert.equal( $( ".ui-datepicker-prev", dp ).text(), "Précédent", "Localisation - previous" ); - assert.equal( $( ".ui-datepicker-current", dp ).text(), "Aujourd'hui", "Localisation - current" ); - assert.equal( $( ".ui-datepicker-next", dp ).text(), "Suivant", "Localisation - next" ); - month = 0; - $( ".ui-datepicker-month option", dp ).each( function() { - assert.equal( $( this ).text(), $.datepicker.regional.fr.monthNamesShort[ month ], - "Localisation - month " + month ); - month++; - } ); - day = 1; - $( ".ui-datepicker-calendar th", dp ).each( function() { - assert.equal( $( this ).text(), $.datepicker.regional.fr.dayNamesMin[ day ], - "Localisation - day " + day ); - day = ( day + 1 ) % 7; + this.element.datepicker( { + beforeOpen: function() {} } ); - inp.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - date = new Date(); - assert.equal( inp.val(), $.datepicker.regional.fr.dayNames[ date.getDay() ] + ", " + - date.getDate() + " " + $.datepicker.regional.fr.monthNames[ date.getMonth() ] + - " " + date.getFullYear(), "Localisation - formatting" ); -} ); - -QUnit.test( "noWeekends", function( assert ) { - assert.expect( 31 ); - var i, date; - for ( i = 1; i <= 31; i++ ) { - date = new Date( 2001, 1 - 1, i ); - assert.deepEqual( $.datepicker.noWeekends( date ), [ ( i + 1 ) % 7 >= 2, "" ], - "No weekends " + date ); - } -} ); - -QUnit.test( "iso8601Week", function( assert ) { - assert.expect( 12 ); - var date = new Date( 2000, 12 - 1, 31 ); - assert.equal( $.datepicker.iso8601Week( date ), 52, "ISO 8601 week " + date ); - date = new Date( 2001, 1 - 1, 1 ); - assert.equal( $.datepicker.iso8601Week( date ), 1, "ISO 8601 week " + date ); - date = new Date( 2001, 1 - 1, 7 ); - assert.equal( $.datepicker.iso8601Week( date ), 1, "ISO 8601 week " + date ); - date = new Date( 2001, 1 - 1, 8 ); - assert.equal( $.datepicker.iso8601Week( date ), 2, "ISO 8601 week " + date ); - date = new Date( 2003, 12 - 1, 28 ); - assert.equal( $.datepicker.iso8601Week( date ), 52, "ISO 8601 week " + date ); - date = new Date( 2003, 12 - 1, 29 ); - assert.equal( $.datepicker.iso8601Week( date ), 1, "ISO 8601 week " + date ); - date = new Date( 2004, 1 - 1, 4 ); - assert.equal( $.datepicker.iso8601Week( date ), 1, "ISO 8601 week " + date ); - date = new Date( 2004, 1 - 1, 5 ); - assert.equal( $.datepicker.iso8601Week( date ), 2, "ISO 8601 week " + date ); - date = new Date( 2009, 12 - 1, 28 ); - assert.equal( $.datepicker.iso8601Week( date ), 53, "ISO 8601 week " + date ); - date = new Date( 2010, 1 - 1, 3 ); - assert.equal( $.datepicker.iso8601Week( date ), 53, "ISO 8601 week " + date ); - date = new Date( 2010, 1 - 1, 4 ); - assert.equal( $.datepicker.iso8601Week( date ), 1, "ISO 8601 week " + date ); - date = new Date( 2010, 1 - 1, 10 ); - assert.equal( $.datepicker.iso8601Week( date ), 1, "ISO 8601 week " + date ); -} ); - -QUnit.test( "parseDate", function( assert ) { - assert.expect( 26 ); - testHelper.init( "#inp" ); - var currentYear, gmtDate, fr, settings, zh; - assert.ok( $.datepicker.parseDate( "d m y", "" ) == null, "Parse date empty" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "d m y", "3 2 01" ), - new Date( 2001, 2 - 1, 3 ), "Parse date d m y" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "dd mm yy", "03 02 2001" ), - new Date( 2001, 2 - 1, 3 ), "Parse date dd mm yy" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "d m y", "13 12 01" ), - new Date( 2001, 12 - 1, 13 ), "Parse date d m y" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "dd mm yy", "13 12 2001" ), - new Date( 2001, 12 - 1, 13 ), "Parse date dd mm yy" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "y-o", "01-34" ), - new Date( 2001, 2 - 1, 3 ), "Parse date y-o" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "yy-oo", "2001-347" ), - new Date( 2001, 12 - 1, 13 ), "Parse date yy-oo" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "oo yy", "348 2004" ), - new Date( 2004, 12 - 1, 13 ), "Parse date oo yy" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "D d M y", "Sat 3 Feb 01" ), - new Date( 2001, 2 - 1, 3 ), "Parse date D d M y" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "d MM DD yy", "3 February Saturday 2001" ), - new Date( 2001, 2 - 1, 3 ), "Parse date dd MM DD yy" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "DD, MM d, yy", "Saturday, February 3, 2001" ), - new Date( 2001, 2 - 1, 3 ), "Parse date DD, MM d, yy" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "'day' d 'of' MM (''DD''), yy", - "day 3 of February ('Saturday'), 2001" ), new Date( 2001, 2 - 1, 3 ), - "Parse date 'day' d 'of' MM (''DD''), yy" ); - currentYear = new Date().getFullYear(); - testHelper.equalsDate( assert, $.datepicker.parseDate( "y-m-d", ( currentYear - 2000 ) + "-02-03" ), - new Date( currentYear, 2 - 1, 3 ), "Parse date y-m-d - default cutuff" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "y-m-d", ( currentYear - 2000 + 10 ) + "-02-03" ), - new Date( currentYear + 10, 2 - 1, 3 ), "Parse date y-m-d - default cutuff" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "y-m-d", ( currentYear - 2000 + 11 ) + "-02-03" ), - new Date( currentYear - 89, 2 - 1, 3 ), "Parse date y-m-d - default cutuff" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "y-m-d", "80-02-03", { shortYearCutoff: 80 } ), - new Date( 2080, 2 - 1, 3 ), "Parse date y-m-d - cutoff 80" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "y-m-d", "81-02-03", { shortYearCutoff: 80 } ), - new Date( 1981, 2 - 1, 3 ), "Parse date y-m-d - cutoff 80" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "y-m-d", ( currentYear - 2000 + 60 ) + "-02-03", { shortYearCutoff: "+60" } ), - new Date( currentYear + 60, 2 - 1, 3 ), "Parse date y-m-d - cutoff +60" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "y-m-d", ( currentYear - 2000 + 61 ) + "-02-03", { shortYearCutoff: "+60" } ), - new Date( currentYear - 39, 2 - 1, 3 ), "Parse date y-m-d - cutoff +60" ); - gmtDate = new Date( 2001, 2 - 1, 3 ); - gmtDate.setMinutes( gmtDate.getMinutes() - gmtDate.getTimezoneOffset() ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "@", "981158400000" ), gmtDate, "Parse date @" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "!", "631167552000000000" ), gmtDate, "Parse date !" ); - - fr = $.datepicker.regional.fr; - settings = { dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, - monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames }; - testHelper.equalsDate( assert, $.datepicker.parseDate( "D d M y", "Lun. 9 avr. 01", settings ), - new Date( 2001, 4 - 1, 9 ), "Parse date D M y with settings" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "d MM DD yy", "9 Avril Lundi 2001", settings ), - new Date( 2001, 4 - 1, 9 ), "Parse date d MM DD yy with settings" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "DD, MM d, yy", "Lundi, Avril 9, 2001", settings ), - new Date( 2001, 4 - 1, 9 ), "Parse date DD, MM d, yy with settings" ); - testHelper.equalsDate( assert, $.datepicker.parseDate( "'jour' d 'de' MM (''DD''), yy", "jour 9 de Avril ('Lundi'), 2001", settings ), - new Date( 2001, 4 - 1, 9 ), "Parse date 'jour' d 'de' MM (''DD''), yy with settings" ); - - zh = $.datepicker.regional[ "zh-CN" ]; - testHelper.equalsDate( assert, $.datepicker.parseDate( "yy M d", "2011 十一月 22", zh ), - new Date( 2011, 11 - 1, 22 ), "Parse date yy M d with zh-CN" ); -} ); - -QUnit.test( "parseDateErrors", function( assert ) { - assert.expect( 18 ); - testHelper.init( "#inp" ); - var fr, settings; - function expectError( expr, value, error ) { - try { - expr(); - assert.ok( false, "Parsed error " + value ); - } - catch ( e ) { - assert.equal( e, error, "Parsed error " + value ); - } - } - expectError( function() { $.datepicker.parseDate( null, "Sat 2 01" ); }, - "Sat 2 01", "Invalid arguments" ); - expectError( function() { $.datepicker.parseDate( "d m y", null ); }, - "null", "Invalid arguments" ); - expectError( function() { $.datepicker.parseDate( "d m y", "Sat 2 01" ); }, - "Sat 2 01 - d m y", "Missing number at position 0" ); - expectError( function() { $.datepicker.parseDate( "dd mm yy", "Sat 2 01" ); }, - "Sat 2 01 - dd mm yy", "Missing number at position 0" ); - expectError( function() { $.datepicker.parseDate( "d m y", "3 Feb 01" ); }, - "3 Feb 01 - d m y", "Missing number at position 2" ); - expectError( function() { $.datepicker.parseDate( "dd mm yy", "3 Feb 01" ); }, - "3 Feb 01 - dd mm yy", "Missing number at position 2" ); - expectError( function() { $.datepicker.parseDate( "mm dd yy", "2 1 01" ); }, - "2 1 01 - dd mm yy", "Missing number at position 4" ); - expectError( function() { $.datepicker.parseDate( "d m y", "3 2 AD01" ); }, - "3 2 AD01 - d m y", "Missing number at position 4" ); - expectError( function() { $.datepicker.parseDate( "d m yy", "3 2 AD01" ); }, - "3 2 AD01 - dd mm yy", "Missing number at position 4" ); - expectError( function() { $.datepicker.parseDate( "y-o", "01-D01" ); }, - "2001-D01 - y-o", "Missing number at position 3" ); - expectError( function() { $.datepicker.parseDate( "yy-oo", "2001-D01" ); }, - "2001-D01 - yy-oo", "Missing number at position 5" ); - expectError( function() { $.datepicker.parseDate( "D d M y", "D7 3 Feb 01" ); }, - "D7 3 Feb 01 - D d M y", "Unknown name at position 0" ); - expectError( function() { $.datepicker.parseDate( "D d M y", "Sat 3 M2 01" ); }, - "Sat 3 M2 01 - D d M y", "Unknown name at position 6" ); - expectError( function() { $.datepicker.parseDate( "DD, MM d, yy", "Saturday- Feb 3, 2001" ); }, - "Saturday- Feb 3, 2001 - DD, MM d, yy", "Unexpected literal at position 8" ); - expectError( function() { $.datepicker.parseDate( "'day' d 'of' MM (''DD''), yy", - "day 3 of February (\"Saturday\"), 2001" ); }, - "day 3 of Mon2 ('Day7'), 2001", "Unexpected literal at position 19" ); - expectError( function() { $.datepicker.parseDate( "d m y", "29 2 01" ); }, - "29 2 01 - d m y", "Invalid date" ); - fr = $.datepicker.regional.fr; - settings = { dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, - monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames }; - expectError( function() { $.datepicker.parseDate( "D d M y", "Mon 9 Avr 01", settings ); }, - "Mon 9 Avr 01 - D d M y", "Unknown name at position 0" ); - expectError( function() { $.datepicker.parseDate( "D d M y", "Lun. 9 Apr 01", settings ); }, - "Lun. 9 Apr 01 - D d M y", "Unknown name at position 7" ); -} ); -QUnit.test( "Ticket #7244: date parser does not fail when too many numbers are passed into the date function", function( assert ) { - assert.expect( 4 ); - var date; - try { - date = $.datepicker.parseDate( "dd/mm/yy", "18/04/19881" ); - assert.ok( false, "Did not properly detect an invalid date" ); - }catch ( e ) { - assert.ok( "invalid date detected" ); - } - - try { - date = $.datepicker.parseDate( "dd/mm/yy", "18/04/1988 @ 2:43 pm" ); - assert.equal( date.getDate(), 18 ); - assert.equal( date.getMonth(), 3 ); - assert.equal( date.getFullYear(), 1988 ); - } catch ( e ) { - assert.ok( false, "Did not properly parse date with extra text separated by whitespace" ); - } -} ); - -QUnit.test( "formatDate", function( assert ) { - assert.expect( 16 ); - testHelper.init( "#inp" ); - var gmtDate, fr, settings; - assert.equal( $.datepicker.formatDate( "d m y", new Date( 2001, 2 - 1, 3 ) ), - "3 2 01", "Format date d m y" ); - assert.equal( $.datepicker.formatDate( "dd mm yy", new Date( 2001, 2 - 1, 3 ) ), - "03 02 2001", "Format date dd mm yy" ); - assert.equal( $.datepicker.formatDate( "d m y", new Date( 2001, 12 - 1, 13 ) ), - "13 12 01", "Format date d m y" ); - assert.equal( $.datepicker.formatDate( "dd mm yy", new Date( 2001, 12 - 1, 13 ) ), - "13 12 2001", "Format date dd mm yy" ); - assert.equal( $.datepicker.formatDate( "yy-o", new Date( 2001, 2 - 1, 3 ) ), - "2001-34", "Format date yy-o" ); - assert.equal( $.datepicker.formatDate( "yy-oo", new Date( 2001, 2 - 1, 3 ) ), - "2001-034", "Format date yy-oo" ); - assert.equal( $.datepicker.formatDate( "D M y", new Date( 2001, 2 - 1, 3 ) ), - "Sat Feb 01", "Format date D M y" ); - assert.equal( $.datepicker.formatDate( "DD MM yy", new Date( 2001, 2 - 1, 3 ) ), - "Saturday February 2001", "Format date DD MM yy" ); - assert.equal( $.datepicker.formatDate( "DD, MM d, yy", new Date( 2001, 2 - 1, 3 ) ), - "Saturday, February 3, 2001", "Format date DD, MM d, yy" ); - assert.equal( $.datepicker.formatDate( "'day' d 'of' MM (''DD''), yy", - new Date( 2001, 2 - 1, 3 ) ), "day 3 of February ('Saturday'), 2001", - "Format date 'day' d 'of' MM ('DD'), yy" ); - gmtDate = new Date( 2001, 2 - 1, 3 ); - gmtDate.setMinutes( gmtDate.getMinutes() - gmtDate.getTimezoneOffset() ); - assert.equal( $.datepicker.formatDate( "@", gmtDate ), "981158400000", "Format date @" ); - assert.equal( $.datepicker.formatDate( "!", gmtDate ), "631167552000000000", "Format date !" ); - fr = $.datepicker.regional.fr; - settings = { dayNamesShort: fr.dayNamesShort, dayNames: fr.dayNames, - monthNamesShort: fr.monthNamesShort, monthNames: fr.monthNames }; - assert.equal( $.datepicker.formatDate( "D M y", new Date( 2001, 4 - 1, 9 ), settings ), - "lun. avr. 01", "Format date D M y with settings" ); - assert.equal( $.datepicker.formatDate( "DD MM yy", new Date( 2001, 4 - 1, 9 ), settings ), - "lundi avril 2001", "Format date DD MM yy with settings" ); - assert.equal( $.datepicker.formatDate( "DD, MM d, yy", new Date( 2001, 4 - 1, 9 ), settings ), - "lundi, avril 9, 2001", "Format date DD, MM d, yy with settings" ); - assert.equal( $.datepicker.formatDate( "'jour' d 'de' MM (''DD''), yy", - new Date( 2001, 4 - 1, 9 ), settings ), "jour 9 de avril ('lundi'), 2001", - "Format date 'jour' d 'de' MM (''DD''), yy with settings" ); + this.element.datepicker( "open" ); + assert.ok( this.element.datepicker( "widget" ).is( ":visible" ), "beforeOpen returns nothing" ); } ); -// TODO: Fix this test so it isn't mysteriously flaky in Browserstack on certain OS/Browser combos -// test("Ticket 6827: formatDate day of year calculation is wrong during day lights savings time", function(){ -// expect( 1 ); -// var time = $.datepicker.formatDate("oo", new Date("2010/03/30 12:00:00 CDT")); -// equal(time, "089"); -// }); - -QUnit.test( "Ticket 7602: Stop datepicker from appearing with beforeShow event handler", function( assert ) { - assert.expect( 3 ); - - var inp, dp; - - inp = testHelper.init( "#inp", { - beforeShow: function() { - } - } ); - dp = $( "#ui-datepicker-div" ); - inp.datepicker( "show" ); - assert.equal( dp.css( "display" ), "block", "beforeShow returns nothing" ); - inp.datepicker( "hide" ).datepicker( "destroy" ); +QUnit.test( "Stop datepicker from appearing with beforeOpen event handler - true", function( assert ) { + assert.expect( 1 ); - inp = testHelper.init( "#inp", { - beforeShow: function() { + this.element.datepicker( { + beforeOpen: function() { return true; } } ); - dp = $( "#ui-datepicker-div" ); - inp.datepicker( "show" ); - assert.equal( dp.css( "display" ), "block", "beforeShow returns true" ); - inp.datepicker( "hide" ); - inp.datepicker( "destroy" ); + this.element.datepicker( "open" ); + assert.ok( this.element.datepicker( "widget" ).is( ":visible" ), "beforeOpen returns true" ); +} ); + +QUnit.test( "Stop datepicker from appearing with beforeOpen event handler - false", function( assert ) { + assert.expect( 1 ); - inp = testHelper.init( "#inp", { - beforeShow: function() { + this.element.datepicker( { + beforeOpen: function() { return false; } } ); - dp = $( "#ui-datepicker-div" ); - inp.datepicker( "show" ); - assert.equal( dp.css( "display" ), "none", "beforeShow returns false" ); - inp.datepicker( "destroy" ); + this.element.datepicker( "open" ); + assert.ok( !this.element.datepicker( "widget" ).is( ":visible" ), "beforeOpen returns false" ); } ); } ); diff --git a/tests/unit/index.html b/tests/unit/index.html index 091e39c4185..9f793141ed2 100644 --- a/tests/unit/index.html +++ b/tests/unit/index.html @@ -39,6 +39,7 @@

    Widgets