| // 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.FilteredMenuTest'); |
| goog.setTestOnly('goog.ui.FilteredMenuTest'); |
| |
| goog.require('goog.a11y.aria'); |
| goog.require('goog.a11y.aria.AutoCompleteValues'); |
| goog.require('goog.a11y.aria.State'); |
| goog.require('goog.dom'); |
| goog.require('goog.events'); |
| goog.require('goog.events.EventType'); |
| goog.require('goog.events.KeyCodes'); |
| goog.require('goog.math.Rect'); |
| goog.require('goog.style'); |
| goog.require('goog.testing.events'); |
| goog.require('goog.testing.jsunit'); |
| goog.require('goog.ui.FilteredMenu'); |
| goog.require('goog.ui.MenuItem'); |
| |
| var sandbox; |
| |
| function setUp() { |
| sandbox = goog.dom.getElement('sandbox'); |
| } |
| |
| |
| function tearDown() { |
| sandbox.innerHTML = ''; |
| } |
| |
| |
| function testRender() { |
| menu = new goog.ui.FilteredMenu(); |
| menu.addItem(new goog.ui.MenuItem('Menu Item 1')); |
| menu.addItem(new goog.ui.MenuItem('Menu Item 2')); |
| menu.render(sandbox); |
| |
| assertEquals('Menu should contain two items.', 2, menu.getChildCount()); |
| assertEquals('Caption of first menu item should match supplied value.', |
| 'Menu Item 1', |
| menu.getItemAt(0).getCaption()); |
| assertEquals('Caption of second menu item should match supplied value.', |
| 'Menu Item 2', |
| menu.getItemAt(1).getCaption()); |
| assertTrue('Caption of first item should be in document.', |
| sandbox.innerHTML.indexOf('Menu Item 1') != -1); |
| assertTrue('Caption of second item should be in document.', |
| sandbox.innerHTML.indexOf('Menu Item 2') != -1); |
| |
| menu.dispose(); |
| } |
| |
| |
| function testDecorate() { |
| menu = new goog.ui.FilteredMenu(); |
| menu.decorate(goog.dom.getElement('testmenu')); |
| |
| assertEquals('Menu should contain four items.', 4, menu.getChildCount()); |
| assertEquals('Caption of menu item should match decorated element', |
| 'Apple', |
| menu.getItemAt(0).getCaption()); |
| assertEquals('Accelerator of menu item should match accelerator element', |
| 'A', |
| menu.getItemAt(0).getAccelerator()); |
| assertEquals('Caption of menu item should match decorated element', |
| 'Lemon', |
| menu.getItemAt(1).getCaption()); |
| assertEquals('Caption of menu item should match decorated element', |
| 'Orange', |
| menu.getItemAt(2).getCaption()); |
| assertEquals('Caption of menu item should match decorated element', |
| 'Strawberry', |
| menu.getItemAt(3).getCaption()); |
| |
| menu.dispose(); |
| } |
| |
| |
| function testFilter() { |
| menu = new goog.ui.FilteredMenu(); |
| menu.addItem(new goog.ui.MenuItem('Family')); |
| menu.addItem(new goog.ui.MenuItem('Friends')); |
| menu.addItem(new goog.ui.MenuItem('Photos')); |
| menu.addItem(new goog.ui.MenuItem([ |
| goog.dom.createTextNode('Work'), |
| goog.dom.createDom('span', goog.ui.MenuItem.ACCELERATOR_CLASS, 'W') |
| ])); |
| |
| menu.render(sandbox); |
| |
| // Check menu items. |
| assertEquals('Family should be the first label in the move to menu', |
| 'Family', menu.getChildAt(0).getCaption()); |
| assertEquals('Friends should be the second label in the move to menu', |
| 'Friends', menu.getChildAt(1).getCaption()); |
| assertEquals('Photos should be the third label in the move to menu', |
| 'Photos', menu.getChildAt(2).getCaption()); |
| assertEquals('Work should be the fourth label in the move to menu', |
| 'Work', menu.getChildAt(3).getCaption()); |
| |
| // Filter menu. |
| menu.setFilter('W'); |
| assertFalse('Family should not be visible when the menu is filtered', |
| menu.getChildAt(0).isVisible()); |
| assertFalse('Friends should not be visible when the menu is filtered', |
| menu.getChildAt(1).isVisible()); |
| assertFalse('Photos should not be visible when the menu is filtered', |
| menu.getChildAt(2).isVisible()); |
| assertTrue('Work should be visible when the menu is filtered', |
| menu.getChildAt(3).isVisible()); |
| // Check accelerator. |
| assertEquals('The accelerator for Work should be present', |
| 'W', menu.getChildAt(3).getAccelerator()); |
| |
| menu.setFilter('W,'); |
| for (var i = 0; i < menu.getChildCount(); i++) { |
| assertFalse('W, should not match anything with allowMultiple set to false', |
| menu.getChildAt(i).isVisible()); |
| } |
| |
| // Clear filter. |
| menu.setFilter(''); |
| for (var i = 0; i < menu.getChildCount(); i++) { |
| assertTrue('All items should be visible', menu.getChildAt(i).isVisible()); |
| } |
| |
| menu.dispose(); |
| } |
| |
| |
| function testFilterAllowMultiple() { |
| menu = new goog.ui.FilteredMenu(); |
| menu.setAllowMultiple(true); |
| menu.addItem(new goog.ui.MenuItem('Family')); |
| menu.addItem(new goog.ui.MenuItem('Friends')); |
| menu.addItem(new goog.ui.MenuItem('Photos')); |
| menu.addItem(new goog.ui.MenuItem('Work')); |
| |
| menu.render(sandbox); |
| |
| // Filter menu. |
| menu.setFilter('W,'); |
| for (var i = 0; i < menu.getChildCount(); i++) { |
| assertTrue('W, should show all items with allowMultiple set to true', |
| menu.getChildAt(i).isVisible()); |
| } |
| |
| // Filter second label. |
| menu.setFilter('Work,P'); |
| assertFalse('Family should not be visible when the menu is filtered', |
| menu.getChildAt(0).isVisible()); |
| assertFalse('Friends should not be visible when the menu is filtered', |
| menu.getChildAt(1).isVisible()); |
| assertTrue('Photos should be visible when the menu is filtered', |
| menu.getChildAt(2).isVisible()); |
| assertFalse('Work should not be visible when the menu is filtered', |
| menu.getChildAt(3).isVisible()); |
| |
| // Clear filter. |
| menu.setFilter(''); |
| for (var i = 0; i < menu.getChildCount(); i++) { |
| assertTrue('All items should be visible', menu.getChildAt(i).isVisible()); |
| } |
| |
| menu.dispose(); |
| } |
| |
| |
| function testFilterWordBoundary() { |
| menu = new goog.ui.FilteredMenu(); |
| menu.addItem(new goog.ui.MenuItem('Vacation Photos')); |
| menu.addItem(new goog.ui.MenuItem('Work')); |
| menu.addItem(new goog.ui.MenuItem('Receipts & Invoices')); |
| menu.addItem(new goog.ui.MenuItem('Invitations')); |
| menu.addItem(new goog.ui.MenuItem('3.Family')); |
| menu.addItem(new goog.ui.MenuItem('No:Farm')); |
| menu.addItem(new goog.ui.MenuItem('Syd/Family')); |
| |
| menu.render(sandbox); |
| |
| // Filter menu. |
| menu.setFilter('Photos'); |
| assertTrue('Vacation Photos should be visible when the menu is filtered', |
| menu.getChildAt(0).isVisible()); |
| assertFalse('Work should not be visible when the menu is filtered', |
| menu.getChildAt(1).isVisible()); |
| assertFalse('Receipts & Invoices should not be visible when the menu is ' + |
| 'filtered', |
| menu.getChildAt(2).isVisible()); |
| assertFalse('Invitations should not be visible when the menu is filtered', |
| menu.getChildAt(3).isVisible()); |
| |
| menu.setFilter('I'); |
| assertFalse('Vacation Photos should not be visible when the menu is filtered', |
| menu.getChildAt(0).isVisible()); |
| assertFalse('Work should not be visible when the menu is filtered', |
| menu.getChildAt(1).isVisible()); |
| assertTrue('Receipts & Invoices should be visible when the menu is filtered', |
| menu.getChildAt(2).isVisible()); |
| assertTrue('Invitations should be visible when the menu is filtered', |
| menu.getChildAt(3).isVisible()); |
| |
| menu.setFilter('Fa'); |
| assertTrue('3.Family should be visible when the menu is filtered', |
| menu.getChildAt(4).isVisible()); |
| assertTrue('No:Farm should be visible when the menu is filtered', |
| menu.getChildAt(5).isVisible()); |
| assertTrue('Syd/Family should be visible when the menu is filtered', |
| menu.getChildAt(6).isVisible()); |
| |
| menu.dispose(); |
| } |
| |
| |
| function testScrollIntoView() { |
| menu = new goog.ui.FilteredMenu(); |
| menu.addItem(new goog.ui.MenuItem('Family')); |
| menu.addItem(new goog.ui.MenuItem('Friends')); |
| menu.addItem(new goog.ui.MenuItem('Photos')); |
| menu.addItem(new goog.ui.MenuItem('Work')); |
| menu.render(sandbox); |
| |
| menu.setHighlightedIndex(0); |
| assertTrue('Highlighted item should be visible', isHighlightedVisible(menu)); |
| menu.setHighlightedIndex(1); |
| assertTrue('Highlighted item should be visible', isHighlightedVisible(menu)); |
| menu.setHighlightedIndex(2); |
| assertTrue('Highlighted item should be visible', isHighlightedVisible(menu)); |
| menu.setHighlightedIndex(3); |
| assertTrue('Highlighted item should be visible', isHighlightedVisible(menu)); |
| menu.setHighlightedIndex(0); |
| assertTrue('Highlighted item should be visible', isHighlightedVisible(menu)); |
| |
| menu.dispose(); |
| } |
| |
| function testEscapeKeyHandling() { |
| menu = new goog.ui.FilteredMenu(); |
| menu.addItem(new goog.ui.MenuItem('Family')); |
| menu.addItem(new goog.ui.MenuItem('Friends')); |
| menu.render(sandbox); |
| |
| var gotKeyCode = false; |
| var wrapper = document.getElementById('wrapper'); |
| goog.events.listenOnce(wrapper, goog.events.EventType.KEYPRESS, function(e) { |
| gotKeyCode = true; |
| }); |
| goog.testing.events.fireKeySequence(menu.getFilterInputElement(), |
| goog.events.KeyCodes.ESC); |
| assertFalse('ESC key should not propagate out to parent', gotKeyCode); |
| } |
| |
| |
| function testAriaRoles() { |
| menu = new goog.ui.FilteredMenu(); |
| menu.addItem(new goog.ui.MenuItem('Item 1')); |
| menu.render(sandbox); |
| |
| var input = menu.getFilterInputElement(); |
| assertEquals(goog.a11y.aria.AutoCompleteValues.LIST, |
| goog.a11y.aria.getState(input, goog.a11y.aria.State.AUTOCOMPLETE)); |
| assertEquals(menu.getContentElement().id, |
| goog.a11y.aria.getState(input, goog.a11y.aria.State.OWNS)); |
| assertEquals('true', |
| goog.a11y.aria.getState(input, goog.a11y.aria.State.EXPANDED)); |
| } |
| |
| |
| function testInputActiveDecendant() { |
| menu = new goog.ui.FilteredMenu(); |
| var menuItem1 = new goog.ui.MenuItem('Item 1'); |
| var menuItem2 = new goog.ui.MenuItem('Item 2'); |
| menu.addItem(menuItem1); |
| menu.addItem(menuItem2); |
| menu.render(sandbox); |
| |
| assertNull(goog.a11y.aria.getActiveDescendant(menu.getFilterInputElement())); |
| menu.setHighlightedIndex(0); |
| assertEquals(menuItem1.getElementStrict(), |
| goog.a11y.aria.getActiveDescendant(menu.getFilterInputElement())); |
| menu.setHighlightedIndex(1); |
| assertEquals(menuItem2.getElementStrict(), |
| goog.a11y.aria.getActiveDescendant(menu.getFilterInputElement())); |
| } |
| |
| |
| function isHighlightedVisible(menu) { |
| var contRect = goog.style.getBounds(menu.getContentElement()); |
| // Expands the containing rectangle by 1px on top and bottom. The test |
| // sometime fails with 1px out of bound on FF6/Linux. This is not |
| // consistently reproducible. |
| contRect = new goog.math.Rect( |
| contRect.left, contRect.top - 1, contRect.width, contRect.height + 2); |
| var itemRect = goog.style.getBounds(menu.getHighlighted().getElement()); |
| return contRect.contains(itemRect); |
| } |