blob: a6e1967e28f6227be729f3de06900df64334b654 [file] [log] [blame]
// Copyright 2007 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.acTest');
goog.setTestOnly('goog.ui.acTest');
goog.require('goog.array');
goog.require('goog.asserts');
goog.require('goog.dom');
goog.require('goog.dom.NodeType');
goog.require('goog.dom.classlist');
goog.require('goog.dom.selection');
goog.require('goog.events');
goog.require('goog.events.BrowserEvent');
goog.require('goog.events.Event');
goog.require('goog.events.EventType');
goog.require('goog.events.KeyCodes');
goog.require('goog.style');
goog.require('goog.testing.MockClock');
goog.require('goog.testing.jsunit');
goog.require('goog.ui.ac');
goog.require('goog.userAgent');
var autocomplete;
var data = ['ab', 'aab', 'aaab'];
var input;
var mockClock;
function setUpPage() {
goog.ui.ac.createSimpleAutoComplete(data, goog.dom.getElement('user'), true,
false);
}
function setUp() {
mockClock = new goog.testing.MockClock(true);
input = goog.dom.getElement('input');
input.value = '';
autocomplete = goog.ui.ac.createSimpleAutoComplete(data, input, true, false);
}
function tearDown() {
autocomplete.dispose();
mockClock.dispose();
}
//=========================================================================
// Utility methods
/**
* Fire listeners of a given type that are listening to the event's
* currentTarget.
*
* @param {goog.events.BrowserEvent} event
*/
function simulateEvent(event) {
goog.events.fireListeners(
event.currentTarget, event.type, true, event);
goog.events.fireListeners(
event.currentTarget, event.type, false, event);
}
/**
* Fire all key event listeners that are listening to the input element.
*
* @param {number} keyCode The key code.
*/
function simulateAllKeyEventsOnInput(keyCode) {
var eventTypes = [
goog.events.EventType.KEYDOWN,
goog.events.EventType.KEYPRESS,
goog.events.EventType.KEYUP
];
goog.array.forEach(eventTypes,
function(type) {
var event = new goog.events.Event(type, input);
event.keyCode = keyCode;
simulateEvent(new goog.events.BrowserEvent(event, input));
});
}
/**
* @param {string} text
* @return {Node} Node whose inner text maches the given text.
*/
function findNodeByInnerText(text) {
return goog.dom.findNode(document.body, function(node) {
try {
var display = goog.userAgent.IE ?
goog.style.getCascadedStyle(node, 'display') :
goog.style.getComputedStyle(node, 'display');
return goog.dom.getRawTextContent(node) == text &&
'none' != display && node.nodeType == goog.dom.NodeType.ELEMENT;
} catch (e) {
return false;
}
});
}
//=========================================================================
// Tests
/**
* Ensure that the display of the autocompleter works.
*/
function testBasicDisplay() {
simulateAllKeyEventsOnInput(goog.events.KeyCodes.DOWN);
input.value = 'a';
simulateAllKeyEventsOnInput(goog.events.KeyCodes.A);
mockClock.tick(500);
var nodes = [
findNodeByInnerText(data[0]),
findNodeByInnerText(data[1]),
findNodeByInnerText(data[2])
];
assert(!!nodes[0]);
assert(!!nodes[1]);
assert(!!nodes[2]);
assert(goog.style.isUnselectable(nodes[0]));
assert(goog.style.isUnselectable(nodes[1]));
assert(goog.style.isUnselectable(nodes[2]));
input.value = 'aa';
simulateAllKeyEventsOnInput(goog.events.KeyCodes.A);
mockClock.tick(500);
assertFalse(!!findNodeByInnerText(data[0]));
assert(!!findNodeByInnerText(data[1]));
assert(!!findNodeByInnerText(data[2]));
}
/**
* Ensure that key navigation with multiple inputs work
*/
function testKeyNavigation() {
simulateAllKeyEventsOnInput(goog.events.KeyCodes.DOWN);
input.value = 'c, a';
goog.dom.selection.setCursorPosition(input, 'c, a'.length);
simulateAllKeyEventsOnInput(goog.events.KeyCodes.A);
mockClock.tick(500);
assert(document.body.innerHTML, !!findNodeByInnerText(data[1]));
assert(!!findNodeByInnerText(data[2]));
var selected = goog.asserts.assertElement(findNodeByInnerText(data[0]));
assertTrue('Should have new standard active class',
goog.dom.classlist.contains(selected, 'ac-active'));
assertTrue('Should have legacy active class',
goog.dom.classlist.contains(selected, 'active'));
simulateAllKeyEventsOnInput(goog.events.KeyCodes.DOWN);
assertFalse(goog.dom.classlist.contains(
goog.asserts.assertElement(findNodeByInnerText(data[0])), 'ac-active'));
assert(goog.dom.classlist.contains(
goog.asserts.assertElement(findNodeByInnerText(data[1])), 'ac-active'));
simulateAllKeyEventsOnInput(goog.events.KeyCodes.ENTER);
assertEquals('c, aab, ', input.value);
}
/**
* Ensure that mouse navigation with multiple inputs works.
*/
function testMouseNavigation() {
simulateAllKeyEventsOnInput(goog.events.KeyCodes.DOWN);
input.value = 'c, a';
goog.dom.selection.setCursorPosition(input, 'c, a'.length);
simulateAllKeyEventsOnInput(goog.events.KeyCodes.A);
mockClock.tick(500);
var secondOption = goog.asserts.assertElement(findNodeByInnerText(data[1]));
var parent = secondOption.parentNode;
assertFalse(goog.dom.classlist.contains(secondOption, 'ac-active'));
var mouseOver = new goog.events.Event(
goog.events.EventType.MOUSEOVER, secondOption);
simulateEvent(new goog.events.BrowserEvent(mouseOver, parent));
assert(goog.dom.classlist.contains(secondOption, 'ac-active'));
var mouseDown = new goog.events.Event(
goog.events.EventType.MOUSEDOWN, secondOption);
simulateEvent(new goog.events.BrowserEvent(mouseDown, parent));
var mouseClick = new goog.events.Event(
goog.events.EventType.CLICK, secondOption);
simulateEvent(new goog.events.BrowserEvent(mouseClick, parent));
assertEquals('c, aab, ', input.value);
}