// Copyright 2008 The Closure Library Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS-IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. goog.provide('goog.ui.DatePickerTest'); goog.setTestOnly('goog.ui.DatePickerTest'); goog.require('goog.a11y.aria'); goog.require('goog.a11y.aria.Role'); goog.require('goog.date.Date'); goog.require('goog.date.DateRange'); goog.require('goog.dom'); goog.require('goog.dom.TagName'); goog.require('goog.dom.classlist'); goog.require('goog.events'); goog.require('goog.events.KeyCodes'); goog.require('goog.i18n.DateTimeSymbols'); goog.require('goog.i18n.DateTimeSymbols_en_US'); goog.require('goog.i18n.DateTimeSymbols_zh_HK'); goog.require('goog.style'); goog.require('goog.testing.events'); goog.require('goog.testing.jsunit'); goog.require('goog.testing.recordFunction'); goog.require('goog.ui.DatePicker'); var picker; var $$ = goog.dom.getElementsByTagNameAndClass; var sandbox; function setUpPage() { sandbox = goog.dom.getElement('sandbox'); } function tearDown() { picker.dispose(); goog.dom.removeChildren(sandbox); } function testIsMonthOnLeft() { goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_en_US; picker = new goog.ui.DatePicker(); picker.create(sandbox); var head = $$('tr', 'goog-date-picker-head')[0]; var month = $$('button', 'goog-date-picker-month', head.firstChild)[0]; assertSameElements( 'Button element must have expected class names', ['goog-date-picker-btn', 'goog-date-picker-month'], goog.dom.classlist.get(month)); } function testIsYearOnLeft() { goog.i18n.DateTimeSymbols = goog.i18n.DateTimeSymbols_zh_HK; picker = new goog.ui.DatePicker(); picker.create(sandbox); var head = $$('tr', 'goog-date-picker-head')[0]; var year = $$('button', 'goog-date-picker-year', head.firstChild)[0]; assertSameElements( 'Button element must have expected class names', ['goog-date-picker-btn', 'goog-date-picker-year'], goog.dom.classlist.get(year)); } function testHidingOfTableFoot0() { picker = new goog.ui.DatePicker(); picker.setAllowNone(false); picker.setShowToday(false); picker.create(sandbox); var tFoot = $$('tfoot')[0]; assertFalse(goog.style.isElementShown(tFoot)); } function testHidingOfTableFoot1() { picker = new goog.ui.DatePicker(); picker.setAllowNone(false); picker.setShowToday(true); picker.create(sandbox); var tFoot = $$('tfoot')[0]; assertTrue(goog.style.isElementShown(tFoot)); } function testHidingOfTableFoot2() { picker = new goog.ui.DatePicker(); picker.setAllowNone(true); picker.setShowToday(false); picker.create(sandbox); var tFoot = $$('tfoot')[0]; assertTrue(goog.style.isElementShown(tFoot)); } function testHidingOfTableFoot3() { picker = new goog.ui.DatePicker(); picker.setAllowNone(true); picker.setShowToday(true); picker.create(sandbox); var tFoot = $$('tfoot')[0]; assertTrue(goog.style.isElementShown(tFoot)); } function testHidingOfTableFootAfterCreate0() { picker = new goog.ui.DatePicker(); picker.create(sandbox); picker.setAllowNone(false); picker.setShowToday(false); var tFoot = $$('tfoot')[0]; assertFalse(goog.style.isElementShown(tFoot)); } function testHidingOfTableFootAfterCreate1() { picker = new goog.ui.DatePicker(); picker.create(sandbox); picker.setAllowNone(false); picker.setShowToday(true); var tFoot = $$('tfoot')[0]; assertTrue(goog.style.isElementShown(tFoot)); } function testHidingOfTableFootAfterCreate2() { picker = new goog.ui.DatePicker(); picker.create(sandbox); picker.setAllowNone(true); picker.setShowToday(false); var tFoot = $$('tfoot')[0]; assertTrue(goog.style.isElementShown(tFoot)); } function testHidingOfTableFootAfterCreate3() { picker = new goog.ui.DatePicker(); picker.create(sandbox); picker.setAllowNone(true); picker.setShowToday(true); var tFoot = $$('tfoot')[0]; assertTrue(goog.style.isElementShown(tFoot)); } function testLongDateFormat() { picker = new goog.ui.DatePicker(); picker.create(sandbox); picker.setLongDateFormat(true); var dates = $$('td', 'goog-date-picker-date'); for (var i = 0; i < dates.length; i++) { assertEquals(2, goog.dom.getTextContent(dates[i]).length); } } function testGetActiveMonth() { picker = new goog.ui.DatePicker(new Date(2000, 5, 5)); var month = picker.getActiveMonth(); assertObjectEquals(new goog.date.Date(2000, 5, 1), month); month.setMonth(10); assertObjectEquals( 'modifying the returned object is safe', new goog.date.Date(2000, 5, 1), picker.getActiveMonth()); } function testGetActiveMonthBeforeYear100() { var date = new Date(23, 5, 5); // Above statement will create date with year 1923, need to set full year // explicitly. date.setFullYear(23); var expectedMonth = new goog.date.Date(23, 5, 1); expectedMonth.setFullYear(23); picker = new goog.ui.DatePicker(date); var month = picker.getActiveMonth(); assertObjectEquals(expectedMonth, month); month.setMonth(10); assertObjectEquals( 'modifying the returned object is safe', expectedMonth, picker.getActiveMonth()); } function testGetDate() { picker = new goog.ui.DatePicker(new Date(2000, 0, 1)); var date = picker.getDate(); assertObjectEquals(new goog.date.Date(2000, 0, 1), date); date.setMonth(1); assertObjectEquals( 'modifying the returned date is safe', new goog.date.Date(2000, 0, 1), picker.getDate()); picker.setDate(null); assertNull('no date is selected', picker.getDate()); } function testGetDateBeforeYear100() { var inputDate = new Date(23, 5, 5); // Above statement will create date with year 1923, need to set full year // explicitly. inputDate.setFullYear(23); picker = new goog.ui.DatePicker(inputDate); var date = picker.getDate(); var expectedDate = new goog.date.Date(23, 5, 5); expectedDate.setFullYear(23); assertObjectEquals(expectedDate, date); picker.setDate(inputDate); assertObjectEquals(expectedDate, picker.getDate()); var expectedMonth = new goog.date.Date(23, 5, 1); expectedMonth.setFullYear(23); assertObjectEquals(expectedMonth, picker.getActiveMonth()); } function testGridForDecember23() { // Initialize picker to December 23. var inputDate = new Date(23, 11, 5); // Above statement will create date with year 1923, need to set full year // explicitly. inputDate.setFullYear(23); picker = new goog.ui.DatePicker(inputDate); picker.create(sandbox); // Grid start with last days of November 23, shows December 23 and first days // of January 24. for (var i = 0; i < 6; i++) { for (var j = 0; j < 7; j++) { var date = picker.getDateAt(i, j); if (date.getMonth() == 0) { assertEquals(24, date.getFullYear()); } else { assertEquals(23, date.getFullYear()); } } } } function testGridForJanuary22() { // Initialize picker to January 22. var inputDate = new Date(22, 0, 5); // Above statement will create date with year 1922, need to set full year // explicitly. inputDate.setFullYear(22); picker = new goog.ui.DatePicker(inputDate); picker.create(sandbox); // Grid start with last days of December 21, shows January 22 and first days // of February 22. for (var i = 0; i < 6; i++) { for (var j = 0; j < 7; j++) { var date = picker.getDateAt(i, j); if (date.getMonth() == 11) { assertEquals(21, date.getFullYear()); } else { assertEquals(22, date.getFullYear()); } } } } function testGetDateAt() { picker = new goog.ui.DatePicker(); picker.create(sandbox); picker.setDate(new Date(2000, 5, 5)); var date = picker.getDateAt(0, 0); assertTrue(date.equals(picker.grid_[0][0])); date.setMonth(1); assertFalse(date.equals(picker.grid_[0][0])); } function testGetDateAt_NotInGrid() { picker = new goog.ui.DatePicker(); picker.create(sandbox); picker.setDate(new Date(2000, 5, 5)); var date = picker.getDateAt(-1, 0); assertNull(date); date = picker.getDateAt(0, -1); assertNull(date); } function testGetDateElementAt() { picker = new goog.ui.DatePicker(); picker.create(sandbox); picker.setDate(new Date(2000, 5, 5)); var element = picker.getDateElementAt(0, 0); assertEquals('td', element.tagName.toLowerCase()); assertObjectEquals(element, picker.elTable_[1][1]); } function testGetDateElementAt_NotInTable() { picker = new goog.ui.DatePicker(); picker.create(sandbox); picker.setDate(new Date(2000, 5, 5)); var element = picker.getDateElementAt(-1, 0); assertNull(element); element = picker.getDateElementAt(0, -1); assertNull(element); element = picker.getDateElementAt(picker.elTable_.length - 1, 0); assertNull(element); element = picker.getDateElementAt(0, picker.elTable_[0].length - 1); assertNull(element); } function testSetDate() { picker = new goog.ui.DatePicker(); picker.createDom(); picker.enterDocument(); var selectEvents = 0; var changeEvents = 0; var changeActiveMonthEvents = 0; goog.events.listen( picker, goog.ui.DatePicker.Events.SELECT, function() { selectEvents++; }); goog.events.listen( picker, goog.ui.DatePicker.Events.CHANGE, function() { changeEvents++; }); goog.events.listen( picker, goog.ui.DatePicker.Events.CHANGE_ACTIVE_MONTH, function() { changeActiveMonthEvents++; }); // Set date. picker.setDate(new Date(2010, 1, 26)); assertEquals('no select event dispatched', 1, selectEvents); assertEquals('no change event dispatched', 1, changeEvents); assertEquals( 'no change active month event dispatched', 1, changeActiveMonthEvents); assertTrue( 'date is set', new goog.date.Date(2010, 1, 26).equals(picker.getDate())); // Set date to same date. picker.setDate(new Date(2010, 1, 26)); assertEquals('1 select event dispatched', 2, selectEvents); assertEquals('no change event dispatched', 1, changeEvents); assertEquals( 'no change active month event dispatched', 1, changeActiveMonthEvents); // Set date to different date. picker.setDate(new Date(2010, 1, 27)); assertEquals('another select event dispatched', 3, selectEvents); assertEquals('1 change event dispatched', 2, changeEvents); assertEquals( '2 change active month events dispatched', 1, changeActiveMonthEvents); // Set date to a date in a different month. picker.setDate(new Date(2010, 2, 27)); assertEquals('another select event dispatched', 4, selectEvents); assertEquals('another change event dispatched', 3, changeEvents); assertEquals( '3 change active month event dispatched', 2, changeActiveMonthEvents); // Set date to none. picker.setDate(null); assertEquals('another select event dispatched', 5, selectEvents); assertEquals('another change event dispatched', 4, changeEvents); assertNull('date cleared', picker.getDate()); } function testChangeActiveMonth() { picker = new goog.ui.DatePicker(); var changeActiveMonthEvents = 0; goog.events.listen( picker, goog.ui.DatePicker.Events.CHANGE_ACTIVE_MONTH, function() { changeActiveMonthEvents++; }); // Set date. picker.setDate(new Date(2010, 1, 26)); assertEquals( 'no change active month event dispatched', 1, changeActiveMonthEvents); assertTrue( 'date is set', new goog.date.Date(2010, 1, 26).equals(picker.getDate())); // Change to next month. picker.nextMonth(); assertEquals( '1 change active month event dispatched', 2, changeActiveMonthEvents); assertTrue( 'date should still be the same', new goog.date.Date(2010, 1, 26).equals(picker.getDate())); // Change to next year. picker.nextYear(); assertEquals( '2 change active month events dispatched', 3, changeActiveMonthEvents); // Change to previous month. picker.previousMonth(); assertEquals( '3 change active month events dispatched', 4, changeActiveMonthEvents); // Change to previous year. picker.previousYear(); assertEquals( '4 change active month events dispatched', 5, changeActiveMonthEvents); } function testUserSelectableDates() { var dateRange = new goog.date.DateRange( new goog.date.Date(2010, 1, 25), new goog.date.Date(2010, 1, 27)); picker = new goog.ui.DatePicker(); picker.setUserSelectableDateRange(dateRange); assertFalse( 'should not be selectable date', picker.isUserSelectableDate_(new goog.date.Date(2010, 1, 24))); assertTrue( 'should be a selectable date', picker.isUserSelectableDate_(new goog.date.Date(2010, 1, 25))); assertTrue( 'should be a selectable date', picker.isUserSelectableDate_(new goog.date.Date(2010, 1, 26))); assertTrue( 'should be a selectable date', picker.isUserSelectableDate_(new goog.date.Date(2010, 1, 27))); assertFalse( 'should not be selectable date', picker.isUserSelectableDate_(new goog.date.Date(2010, 1, 28))); } function testGetUserSelectableDateRange() { picker = new goog.ui.DatePicker(); var dateRange = picker.getUserSelectableDateRange(); assertTrue( 'default date range is all time', goog.date.DateRange.equals(dateRange, goog.date.DateRange.allTime())); var newDateRange = new goog.date.DateRange( new goog.date.Date(2010, 1, 25), new goog.date.Date(2010, 1, 27)); picker.setUserSelectableDateRange(newDateRange); dateRange = picker.getUserSelectableDateRange(); assertTrue( 'should be equal to updated date range', goog.date.DateRange.equals(dateRange, newDateRange)); } function testUniqueCellIds() { picker = new goog.ui.DatePicker(); picker.render(); var cells = goog.dom.getElementsByTagNameAndClass( goog.dom.TagName.TD, undefined, picker.getElement()); var existingIds = {}; var numCells = cells.length; for (var i = 0; i < numCells; i++) { assertNotNull(cells[i]); if (goog.a11y.aria.getRole(cells[i]) == goog.a11y.aria.Role.GRIDCELL) { assertNonEmptyString('cell id is non empty', cells[i].id); assertUndefined('cell id is not unique', existingIds[cells[i].id]); existingIds[cells[i].id] = 1; } } } function testDecoratePreservesClasses() { picker = new goog.ui.DatePicker(); var div = goog.dom.createDom(goog.dom.TagName.DIV, 'existing-class'); picker.decorate(div); assertTrue(goog.dom.classlist.contains(div, picker.getBaseCssClass())); assertTrue(goog.dom.classlist.contains(div, 'existing-class')); } function testKeyboardNavigation() { picker = new goog.ui.DatePicker(); picker.render(goog.dom.getElement('sandbox')); var selectEvents = goog.testing.recordFunction(); var changeEvents = goog.testing.recordFunction(); goog.events.listen(picker, goog.ui.DatePicker.Events.SELECT, selectEvents); goog.events.listen(picker, goog.ui.DatePicker.Events.CHANGE, changeEvents); goog.testing.events.fireNonAsciiKeySequence( picker.getElement(), goog.events.KeyCodes.DOWN, goog.events.KeyCodes.DOWN); changeEvents.assertCallCount(1); selectEvents.assertCallCount(0); goog.testing.events.fireNonAsciiKeySequence( picker.getElement(), goog.events.KeyCodes.ENTER, goog.events.KeyCodes.ENTER); changeEvents.assertCallCount(1); selectEvents.assertCallCount(1); } function testDayGridHasNonEmptyAriaLabels() { picker = new goog.ui.DatePicker(new Date(2017, 8, 9)); picker.render(goog.dom.getElement('sandbox')); var cells = goog.dom.getElementsByTagNameAndClass( goog.dom.TagName.TD, undefined, picker.getElement()); var numCells = cells.length; for (var i = 0; i < numCells; i++) { assertNotNull(cells[i]); if (goog.a11y.aria.getRole(cells[i]) == goog.a11y.aria.Role.GRIDCELL) { assertNonEmptyString( 'Aria label in date cell should not be empty', goog.a11y.aria.getLabel(cells[i])); } } }