ac_test.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. // Copyright 2007 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. goog.provide('goog.ui.acTest');
  15. goog.setTestOnly('goog.ui.acTest');
  16. goog.require('goog.array');
  17. goog.require('goog.asserts');
  18. goog.require('goog.dom');
  19. goog.require('goog.dom.NodeType');
  20. goog.require('goog.dom.classlist');
  21. goog.require('goog.dom.selection');
  22. goog.require('goog.events');
  23. goog.require('goog.events.BrowserEvent');
  24. goog.require('goog.events.Event');
  25. goog.require('goog.events.EventType');
  26. goog.require('goog.events.KeyCodes');
  27. goog.require('goog.style');
  28. goog.require('goog.testing.MockClock');
  29. goog.require('goog.testing.jsunit');
  30. goog.require('goog.ui.ac');
  31. goog.require('goog.userAgent');
  32. var autocomplete;
  33. var data = ['ab', 'aab', 'aaab'];
  34. var input;
  35. var mockClock;
  36. function setUpPage() {
  37. goog.ui.ac.createSimpleAutoComplete(
  38. data, goog.dom.getElement('user'), true, false);
  39. }
  40. function setUp() {
  41. mockClock = new goog.testing.MockClock(true);
  42. input = goog.dom.getElement('input');
  43. input.value = '';
  44. autocomplete = goog.ui.ac.createSimpleAutoComplete(data, input, true, false);
  45. }
  46. function tearDown() {
  47. autocomplete.dispose();
  48. mockClock.dispose();
  49. }
  50. //=========================================================================
  51. // Utility methods
  52. /**
  53. * Fire listeners of a given type that are listening to the event's
  54. * currentTarget.
  55. *
  56. * @param {goog.events.BrowserEvent} event
  57. */
  58. function simulateEvent(event) {
  59. goog.events.fireListeners(event.currentTarget, event.type, true, event);
  60. goog.events.fireListeners(event.currentTarget, event.type, false, event);
  61. }
  62. /**
  63. * Fire all key event listeners that are listening to the input element.
  64. *
  65. * @param {number} keyCode The key code.
  66. */
  67. function simulateAllKeyEventsOnInput(keyCode) {
  68. var eventTypes = [
  69. goog.events.EventType.KEYDOWN, goog.events.EventType.KEYPRESS,
  70. goog.events.EventType.KEYUP
  71. ];
  72. goog.array.forEach(eventTypes, function(type) {
  73. var event = new goog.events.Event(type, input);
  74. event.keyCode = keyCode;
  75. simulateEvent(new goog.events.BrowserEvent(event, input));
  76. });
  77. }
  78. /**
  79. * @param {string} text
  80. * @return {Node} Node whose inner text maches the given text.
  81. */
  82. function findNodeByInnerText(text) {
  83. return goog.dom.findNode(document.body, function(node) {
  84. try {
  85. var display = goog.userAgent.IE ?
  86. goog.style.getCascadedStyle(node, 'display') :
  87. goog.style.getComputedStyle(node, 'display');
  88. return goog.dom.getRawTextContent(node) == text && 'none' != display &&
  89. node.nodeType == goog.dom.NodeType.ELEMENT;
  90. } catch (e) {
  91. return false;
  92. }
  93. });
  94. }
  95. //=========================================================================
  96. // Tests
  97. /**
  98. * Ensure that the display of the autocompleter works.
  99. */
  100. function testBasicDisplay() {
  101. simulateAllKeyEventsOnInput(goog.events.KeyCodes.DOWN);
  102. input.value = 'a';
  103. simulateAllKeyEventsOnInput(goog.events.KeyCodes.A);
  104. mockClock.tick(500);
  105. var nodes = [
  106. findNodeByInnerText(data[0]), findNodeByInnerText(data[1]),
  107. findNodeByInnerText(data[2])
  108. ];
  109. assert(!!nodes[0]);
  110. assert(!!nodes[1]);
  111. assert(!!nodes[2]);
  112. assert(goog.style.isUnselectable(nodes[0]));
  113. assert(goog.style.isUnselectable(nodes[1]));
  114. assert(goog.style.isUnselectable(nodes[2]));
  115. input.value = 'aa';
  116. simulateAllKeyEventsOnInput(goog.events.KeyCodes.A);
  117. mockClock.tick(500);
  118. assertFalse(!!findNodeByInnerText(data[0]));
  119. assert(!!findNodeByInnerText(data[1]));
  120. assert(!!findNodeByInnerText(data[2]));
  121. }
  122. /**
  123. * Ensure that key navigation with multiple inputs work
  124. */
  125. function testKeyNavigation() {
  126. simulateAllKeyEventsOnInput(goog.events.KeyCodes.DOWN);
  127. input.value = 'c, a';
  128. goog.dom.selection.setCursorPosition(input, 'c, a'.length);
  129. simulateAllKeyEventsOnInput(goog.events.KeyCodes.A);
  130. mockClock.tick(500);
  131. assert(document.body.innerHTML, !!findNodeByInnerText(data[1]));
  132. assert(!!findNodeByInnerText(data[2]));
  133. var selected = goog.asserts.assertElement(findNodeByInnerText(data[0]));
  134. assertTrue(
  135. 'Should have new standard active class',
  136. goog.dom.classlist.contains(selected, 'ac-active'));
  137. assertTrue(
  138. 'Should have legacy active class',
  139. goog.dom.classlist.contains(selected, 'active'));
  140. simulateAllKeyEventsOnInput(goog.events.KeyCodes.DOWN);
  141. assertFalse(
  142. goog.dom.classlist.contains(
  143. goog.asserts.assertElement(findNodeByInnerText(data[0])),
  144. 'ac-active'));
  145. assert(
  146. goog.dom.classlist.contains(
  147. goog.asserts.assertElement(findNodeByInnerText(data[1])),
  148. 'ac-active'));
  149. simulateAllKeyEventsOnInput(goog.events.KeyCodes.ENTER);
  150. assertEquals('c, aab, ', input.value);
  151. }
  152. /**
  153. * Ensure that mouse navigation with multiple inputs works.
  154. */
  155. function testMouseNavigation() {
  156. simulateAllKeyEventsOnInput(goog.events.KeyCodes.DOWN);
  157. input.value = 'c, a';
  158. goog.dom.selection.setCursorPosition(input, 'c, a'.length);
  159. simulateAllKeyEventsOnInput(goog.events.KeyCodes.A);
  160. mockClock.tick(500);
  161. var secondOption = goog.asserts.assertElement(findNodeByInnerText(data[1]));
  162. var parent = secondOption.parentNode;
  163. assertFalse(goog.dom.classlist.contains(secondOption, 'ac-active'));
  164. var mouseOver =
  165. new goog.events.Event(goog.events.EventType.MOUSEOVER, secondOption);
  166. simulateEvent(new goog.events.BrowserEvent(mouseOver, parent));
  167. assert(goog.dom.classlist.contains(secondOption, 'ac-active'));
  168. var mouseDown =
  169. new goog.events.Event(goog.events.EventType.MOUSEDOWN, secondOption);
  170. simulateEvent(new goog.events.BrowserEvent(mouseDown, parent));
  171. var mouseClick =
  172. new goog.events.Event(goog.events.EventType.CLICK, secondOption);
  173. simulateEvent(new goog.events.BrowserEvent(mouseClick, parent));
  174. assertEquals('c, aab, ', input.value);
  175. }