inputhandler_test.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  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.ac.InputHandlerTest');
  15. goog.setTestOnly('goog.ui.ac.InputHandlerTest');
  16. goog.require('goog.a11y.aria');
  17. goog.require('goog.a11y.aria.Role');
  18. goog.require('goog.a11y.aria.State');
  19. goog.require('goog.dom');
  20. goog.require('goog.dom.TagName');
  21. goog.require('goog.dom.selection');
  22. goog.require('goog.events.BrowserEvent');
  23. goog.require('goog.events.Event');
  24. goog.require('goog.events.EventTarget');
  25. goog.require('goog.events.KeyCodes');
  26. goog.require('goog.functions');
  27. goog.require('goog.object');
  28. goog.require('goog.testing.MockClock');
  29. goog.require('goog.testing.jsunit');
  30. goog.require('goog.ui.ac.InputHandler');
  31. goog.require('goog.userAgent');
  32. /**
  33. * Mock out the input element.
  34. * @constructor
  35. */
  36. function MockElement() {
  37. goog.events.EventTarget.call(this);
  38. this.setAttributeNS = function() {};
  39. this.setAttribute = function(key, value) { this[key] = value; };
  40. this.focus = function() {};
  41. this.blur = function() {};
  42. this.ownerDocument = document;
  43. this.selectionStart = 0;
  44. }
  45. goog.inherits(MockElement, goog.events.EventTarget);
  46. /**
  47. * @constructor
  48. */
  49. function MockAutoCompleter() {
  50. this.setToken = null;
  51. this.setTokenWasCalled = false;
  52. this.selectHilitedWasCalled = false;
  53. this.dismissWasCalled = false;
  54. this.getTarget = function() { return mockElement };
  55. this.setTarget = function() {};
  56. this.setToken = function(token) {
  57. this.setTokenWasCalled = true;
  58. this.setToken = token;
  59. };
  60. this.selectHilited = function() {
  61. this.selectHilitedWasCalled = true;
  62. return true; // Success.
  63. };
  64. this.cancelDelayedDismiss = function() {};
  65. this.dismissOnDelay = function() {};
  66. this.dismiss = function() { this.dismissWasCalled = true; };
  67. this.isOpen = goog.functions.TRUE;
  68. }
  69. /**
  70. * MockInputHandler simulates key events for testing the IME behavior of
  71. * InputHandler.
  72. * @constructor
  73. */
  74. function MockInputHandler() {
  75. goog.ui.ac.InputHandler.call(this);
  76. this.ac_ = new MockAutoCompleter();
  77. this.cursorPosition_ = 0;
  78. this.attachInput(mockElement);
  79. }
  80. goog.inherits(MockInputHandler, goog.ui.ac.InputHandler);
  81. /** Checks for updates to the text area, should not happen during IME. */
  82. MockInputHandler.prototype.update = function() {
  83. this.updates++;
  84. };
  85. /** Simulates key events. */
  86. MockInputHandler.prototype.fireKeyEvents = function(
  87. keyCode, down, press, up, opt_properties) {
  88. if (down) this.fireEvent('keydown', keyCode, opt_properties);
  89. if (press) this.fireEvent('keypress', keyCode, opt_properties);
  90. if (up) this.fireEvent('keyup', keyCode, opt_properties);
  91. };
  92. /** Simulates an event. */
  93. MockInputHandler.prototype.fireEvent = function(type, keyCode, opt_properties) {
  94. var e = {};
  95. e.type = type;
  96. e.keyCode = keyCode;
  97. e.preventDefault = function() {};
  98. if (!goog.userAgent.IE) {
  99. e.which = type == 'keydown' ? keyCode : 0;
  100. }
  101. if (opt_properties) {
  102. goog.object.extend(e, opt_properties);
  103. }
  104. e = new goog.events.BrowserEvent(e);
  105. mockElement.dispatchEvent(e);
  106. };
  107. MockInputHandler.prototype.setCursorPosition = function(cursorPosition) {
  108. this.cursorPosition_ = cursorPosition;
  109. };
  110. MockInputHandler.prototype.getCursorPosition = function() {
  111. return this.cursorPosition_;
  112. };
  113. // Variables used by all test
  114. var mh = null;
  115. var oldMac, oldWin, oldLinux, oldIe, oldFf, oldWebkit, oldVersion;
  116. var oldUsesKeyDown;
  117. var mockElement;
  118. var mockClock;
  119. function setUp() {
  120. oldMac = goog.userAgent.MAC;
  121. oldWin = goog.userAgent.WINDOWS;
  122. oldLinux = goog.userAgent.LINUX;
  123. oldIe = goog.userAgent.IE;
  124. oldFf = goog.userAgent.GECKO;
  125. oldWebkit = goog.userAgent.WEBKIT;
  126. oldVersion = goog.userAgent.VERSION;
  127. oldUsesKeyDown = goog.events.KeyHandler.USES_KEYDOWN_;
  128. mockClock = new goog.testing.MockClock(true);
  129. mockElement = new MockElement;
  130. mh = new MockInputHandler;
  131. }
  132. function tearDown() {
  133. goog.userAgent.MAC = oldMac;
  134. goog.userAgent.WINDOWS = oldWin;
  135. goog.userAgent.LINUX = oldLinux;
  136. goog.userAgent.IE = oldIe;
  137. goog.userAgent.GECKO = oldFf;
  138. goog.userAgent.WEBKIT = oldWebkit;
  139. goog.userAgent.VERSION = oldVersion;
  140. goog.events.KeyHandler.USES_KEYDOWN_ = oldUsesKeyDown;
  141. mockClock.dispose();
  142. mockElement.dispose();
  143. }
  144. /** Used to simulate behavior of Windows/Firefox3 */
  145. function simulateWinFirefox3() {
  146. goog.userAgent.MAC = false;
  147. goog.userAgent.WINDOWS = true;
  148. goog.userAgent.LINUX = false;
  149. goog.userAgent.IE = false;
  150. goog.userAgent.EDGE = false;
  151. goog.userAgent.EDGE_OR_IE = false;
  152. goog.userAgent.GECKO = true;
  153. goog.userAgent.WEBKIT = false;
  154. goog.events.KeyHandler.USES_KEYDOWN_ = false;
  155. }
  156. /** Used to simulate behavior of Windows/InternetExplorer7 */
  157. function simulateWinIe7() {
  158. goog.userAgent.MAC = false;
  159. goog.userAgent.WINDOWS = true;
  160. goog.userAgent.LINUX = false;
  161. goog.userAgent.IE = true;
  162. goog.userAgent.EDGE = false;
  163. goog.userAgent.EDGE_OR_IE = true;
  164. goog.userAgent.DOCUMENT_MODE = 7;
  165. goog.userAgent.GECKO = false;
  166. goog.userAgent.WEBKIT = false;
  167. goog.events.KeyHandler.USES_KEYDOWN_ = true;
  168. }
  169. /** Used to simulate behavior of Windows/Chrome */
  170. function simulateWinChrome() {
  171. goog.userAgent.MAC = false;
  172. goog.userAgent.WINDOWS = true;
  173. goog.userAgent.LINUX = false;
  174. goog.userAgent.IE = false;
  175. goog.userAgent.EDGE = false;
  176. goog.userAgent.EDGE_OR_IE = false;
  177. goog.userAgent.GECKO = false;
  178. goog.userAgent.WEBKIT = true;
  179. goog.userAgent.VERSION = '525';
  180. goog.events.KeyHandler.USES_KEYDOWN_ = true;
  181. }
  182. /** Used to simulate behavior of Mac/Firefox3 */
  183. function simulateMacFirefox3() {
  184. goog.userAgent.MAC = true;
  185. goog.userAgent.WINDOWS = false;
  186. goog.userAgent.LINUX = false;
  187. goog.userAgent.IE = false;
  188. goog.userAgent.EDGE = false;
  189. goog.userAgent.EDGE_OR_IE = false;
  190. goog.userAgent.GECKO = true;
  191. goog.userAgent.WEBKIT = false;
  192. goog.events.KeyHandler.USES_KEYDOWN_ = true;
  193. }
  194. /** Used to simulate behavior of Mac/Safari3 */
  195. function simulateMacSafari3() {
  196. goog.userAgent.MAC = true;
  197. goog.userAgent.WINDOWS = false;
  198. goog.userAgent.LINUX = false;
  199. goog.userAgent.IE = false;
  200. goog.userAgent.EDGE = false;
  201. goog.userAgent.EDGE_OR_IE = false;
  202. goog.userAgent.GECKO = false;
  203. goog.userAgent.WEBKIT = true;
  204. goog.userAgent.VERSION = '525';
  205. goog.events.KeyHandler.USES_KEYDOWN_ = true;
  206. }
  207. /** Used to simulate behavior of Linux/Firefox3 */
  208. function simulateLinuxFirefox3() {
  209. goog.userAgent.MAC = false;
  210. goog.userAgent.WINDOWS = false;
  211. goog.userAgent.LINUX = true;
  212. goog.userAgent.IE = false;
  213. goog.userAgent.EDGE = false;
  214. goog.userAgent.EDGE_OR_IE = false;
  215. goog.userAgent.GECKO = true;
  216. goog.userAgent.WEBKIT = false;
  217. goog.events.KeyHandler.USES_KEYDOWN_ = true;
  218. }
  219. /** Test the normal, non-IME case */
  220. function testRegularKey() {
  221. // Each key fires down, press, and up in that order, and each should
  222. // trigger an autocomplete update
  223. assertFalse('IME should not be triggered', mh.waitingForIme_);
  224. mh.fireKeyEvents(goog.events.KeyCodes.K, true, true, true);
  225. assertFalse('IME should not be triggered by K', mh.waitingForIme_);
  226. mh.fireKeyEvents(goog.events.KeyCodes.A, true, true, true);
  227. assertFalse('IME should not be triggered by A', mh.waitingForIme_);
  228. }
  229. /**
  230. * This test simulates the key inputs generated by pressing
  231. * '<ime_on>a<enter>i<ime_off>u' using the Japanese IME
  232. * on Windows/Firefox3.
  233. */
  234. function testImeWinFirefox3() {
  235. simulateWinFirefox3();
  236. mh.fireEvent('focus', '');
  237. assertFalse('IME should not be triggered', mh.waitingForIme_);
  238. // ime_on
  239. // a
  240. mh.fireKeyEvents(goog.events.KeyCodes.WIN_IME, true, true, false);
  241. // Event is not generated for key code a.
  242. assertTrue('IME should be triggered', mh.waitingForIme_);
  243. // enter
  244. mh.fireKeyEvents(goog.events.KeyCodes.ENTER, false, false, true);
  245. assertFalse('IME should not be triggered', mh.waitingForIme_);
  246. // i
  247. mh.fireKeyEvents(goog.events.KeyCodes.WIN_IME, true, true, false);
  248. // Event is not generated for key code i.
  249. assertTrue('IME should be triggered', mh.waitingForIme_);
  250. // ime_off
  251. // u
  252. mh.fireKeyEvents(goog.events.KeyCodes.U, true, true, true);
  253. assertFalse('IME should not be triggered', mh.waitingForIme_);
  254. mh.fireEvent('blur', '');
  255. }
  256. /**
  257. * This test simulates the key inputs generated by pressing
  258. * '<ime_on>a<enter>i<ime_off>u' using the Japanese IME
  259. * on Windows/InternetExplorer7.
  260. */
  261. function testImeWinIe7() {
  262. simulateWinIe7();
  263. mh.fireEvent('focus', '');
  264. assertFalse('IME should not be triggered', mh.waitingForIme_);
  265. // ime_on
  266. // a
  267. mh.fireKeyEvents(goog.events.KeyCodes.WIN_IME, true, false, false);
  268. mh.fireKeyEvents(goog.events.KeyCodes.A, false, false, true);
  269. assertTrue('IME should be triggered', mh.waitingForIme_);
  270. // enter
  271. mh.fireKeyEvents(goog.events.KeyCodes.WIN_IME, true, false, false);
  272. mh.fireKeyEvents(goog.events.KeyCodes.ENTER, false, false, true);
  273. assertFalse('IME should not be triggered', mh.waitingForIme_);
  274. // i
  275. mh.fireKeyEvents(goog.events.KeyCodes.WIN_IME, true, false, false);
  276. mh.fireKeyEvents(goog.events.KeyCodes.I, false, false, true);
  277. assertTrue('IME should be triggered', mh.waitingForIme_);
  278. // ime_off
  279. // u
  280. mh.fireKeyEvents(goog.events.KeyCodes.U, true, true, true);
  281. assertFalse('IME should not be triggered', mh.waitingForIme_);
  282. mh.fireEvent('blur', '');
  283. }
  284. /**
  285. * This test simulates the key inputs generated by pressing
  286. * '<ime_on>a<enter>i<ime_off>u' using the Japanese IME
  287. * on Windows/Chrome.
  288. */
  289. function testImeWinChrome() {
  290. simulateWinChrome();
  291. mh.fireEvent('focus', '');
  292. assertFalse('IME should not be triggered', mh.waitingForIme_);
  293. // ime_on
  294. // a
  295. mh.fireKeyEvents(goog.events.KeyCodes.WIN_IME, true, false, false);
  296. mh.fireKeyEvents(goog.events.KeyCodes.A, false, false, true);
  297. assertTrue('IME should be triggered', mh.waitingForIme_);
  298. // enter
  299. mh.fireKeyEvents(goog.events.KeyCodes.WIN_IME, true, false, false);
  300. mh.fireKeyEvents(goog.events.KeyCodes.ENTER, false, false, true);
  301. assertFalse('IME should not be triggered', mh.waitingForIme_);
  302. // i
  303. mh.fireKeyEvents(goog.events.KeyCodes.WIN_IME, true, false, false);
  304. mh.fireKeyEvents(goog.events.KeyCodes.I, false, false, true);
  305. assertTrue('IME should be triggered', mh.waitingForIme_);
  306. // ime_off
  307. // u
  308. mh.fireKeyEvents(goog.events.KeyCodes.U, true, true, true);
  309. assertFalse('IME should not be triggered', mh.waitingForIme_);
  310. mh.fireEvent('blur', '');
  311. }
  312. /**
  313. * This test simulates the key inputs generated by pressing
  314. * '<ime_on>a<enter>i<ime_off>u' using the Japanese IME
  315. * on Mac/Firefox3.
  316. */
  317. function testImeMacFirefox3() {
  318. // TODO(user): Currently our code cannot distinguish preedit characters
  319. // from normal ones for Mac/Firefox3.
  320. // Enable this test after we fix it.
  321. simulateMacFirefox3();
  322. mh.fireEvent('focus', '');
  323. assertFalse('IME should not be triggered', mh.waitingForIme_);
  324. // ime_on
  325. // a
  326. mh.fireKeyEvents(goog.events.KeyCodes.WIN_IME, true, true, false);
  327. assertTrue('IME should be triggered', mh.waitingForIme_);
  328. mh.fireKeyEvents(goog.events.KeyCodes.A, true, false, true);
  329. assertTrue('IME should be triggered', mh.waitingForIme_);
  330. // enter
  331. mh.fireKeyEvents(goog.events.KeyCodes.ENTER, true, true, true);
  332. assertFalse('IME should not be triggered', mh.waitingForIme_);
  333. // i
  334. mh.fireKeyEvents(goog.events.KeyCodes.WIN_IME, true, true, false);
  335. mh.fireKeyEvents(goog.events.KeyCodes.I, true, false, true);
  336. assertTrue('IME should be triggered', mh.waitingForIme_);
  337. // ime_off
  338. // u
  339. mh.fireKeyEvents(goog.events.KeyCodes.U, true, true, true);
  340. assertFalse('IME should not be triggered', mh.waitingForIme_);
  341. mh.fireEvent('blur', '');
  342. }
  343. /**
  344. * This test simulates the key inputs generated by pressing
  345. * '<ime_on>a<enter>i<ime_off>u' using the Japanese IME
  346. * on Mac/Safari3.
  347. */
  348. function testImeMacSafari3() {
  349. simulateMacSafari3();
  350. mh.fireEvent('focus', '');
  351. assertFalse('IME should not be triggered', mh.waitingForIme_);
  352. // ime_on
  353. // a
  354. mh.fireKeyEvents(goog.events.KeyCodes.WIN_IME, true, false, false);
  355. mh.fireKeyEvents(goog.events.KeyCodes.A, false, false, true);
  356. assertTrue('IME should be triggered', mh.waitingForIme_);
  357. // enter
  358. mh.fireKeyEvents(goog.events.KeyCodes.WIN_IME, true, false, false);
  359. mh.fireKeyEvents(goog.events.KeyCodes.ENTER, false, false, true);
  360. assertFalse('IME should not be triggered', mh.waitingForIme_);
  361. // i
  362. mh.fireKeyEvents(goog.events.KeyCodes.WIN_IME, true, false, false);
  363. mh.fireKeyEvents(goog.events.KeyCodes.I, false, false, true);
  364. assertTrue('IME should be triggered', mh.waitingForIme_);
  365. // ime_off
  366. // u
  367. mh.fireKeyEvents(goog.events.KeyCodes.U, true, true, true);
  368. assertFalse('IME should not be triggered', mh.waitingForIme_);
  369. mh.fireEvent('blur', '');
  370. }
  371. /**
  372. * This test simulates the key inputs generated by pressing
  373. * '<ime_on>a<enter>i<ime_off>u' using the Japanese IME
  374. * on Linux/Firefox3.
  375. */
  376. function testImeLinuxFirefox3() {
  377. // TODO(user): Currently our code cannot distinguish preedit characters
  378. // from normal ones for Linux/Firefox3.
  379. // Enable this test after we fix it.
  380. simulateLinuxFirefox3();
  381. mh.fireEvent('focus', '');
  382. assertFalse('IME should not be triggered', mh.waitingForIme_);
  383. // ime_on
  384. mh.fireKeyEvents(goog.events.KeyCodes.WIN_IME, true, true, false);
  385. // a
  386. mh.fireKeyEvents(goog.events.KeyCodes.A, true, false, true);
  387. assertTrue('IME should be triggered', mh.waitingForIme_);
  388. // enter
  389. mh.fireKeyEvents(goog.events.KeyCodes.ENTER, true, true, true);
  390. assertFalse('IME should not be triggered', mh.waitingForIme_);
  391. // i
  392. mh.fireKeyEvents(goog.events.KeyCodes.WIN_IME, true, true, false);
  393. mh.fireKeyEvents(goog.events.KeyCodes.I, true, false, true);
  394. assertTrue('IME should be triggered', mh.waitingForIme_);
  395. // ime_off
  396. // u
  397. mh.fireKeyEvents(goog.events.KeyCodes.U, true, true, true);
  398. assertFalse('IME should not be triggered', mh.waitingForIme_);
  399. mh.fireEvent('blur', '');
  400. }
  401. /**
  402. * Check attaching to an EventTarget instead of an element.
  403. */
  404. function testAttachEventTarget() {
  405. var target = new goog.events.EventTarget();
  406. assertNull(mh.activeElement_);
  407. mh.attachInput(target);
  408. assertNull(mh.activeElement_);
  409. mockElement.dispatchEvent(new goog.events.Event('focus', mockElement));
  410. assertEquals(mockElement, mh.activeElement_);
  411. mh.detachInput(target);
  412. }
  413. /**
  414. * Make sure that the active element handling works.
  415. */
  416. function testActiveElement() {
  417. assertNull(mh.activeElement_);
  418. mockElement.dispatchEvent('keydown');
  419. assertEquals(mockElement, mh.activeElement_);
  420. mockElement.dispatchEvent('blur');
  421. assertNull(mh.activeElement_);
  422. mockElement.dispatchEvent('focus');
  423. assertEquals(mockElement, mh.activeElement_);
  424. mh.detachInput(mockElement);
  425. assertNull(mh.activeElement_);
  426. }
  427. /**
  428. * We can attach an EventTarget that isn't an element.
  429. */
  430. function testAttachEventTarget() {
  431. var target = new goog.events.EventTarget();
  432. assertNull(mh.activeElement_);
  433. mh.attachInput(target);
  434. assertNull(mh.activeElement_);
  435. target.dispatchEvent(new goog.events.Event('focus', mockElement));
  436. assertEquals(mockElement, mh.activeElement_);
  437. mh.detachInput(target);
  438. }
  439. /**
  440. * Make sure an already-focused element becomes active immediately.
  441. */
  442. function testActiveElementAlreadyFocused() {
  443. var element = document.getElementById('textInput');
  444. element.style.display = '';
  445. element.focus();
  446. assertNull(mh.activeElement_);
  447. mh.attachInput(element);
  448. assertEquals(element, mh.activeElement_);
  449. mh.detachInput(element);
  450. element.style.display = 'none';
  451. }
  452. function testUpdateDoesNotTriggerSetTokenForSelectRow() {
  453. var ih = new goog.ui.ac.InputHandler();
  454. // Set up our input handler with the necessary mocks
  455. var mockAutoCompleter = new MockAutoCompleter();
  456. ih.ac_ = mockAutoCompleter;
  457. ih.activeElement_ = mockElement;
  458. var row = {};
  459. ih.selectRow(row, false);
  460. ih.update();
  461. assertFalse(
  462. 'update should not call setToken on selectRow',
  463. mockAutoCompleter.setTokenWasCalled);
  464. ih.update();
  465. assertFalse(
  466. 'update should not call setToken on selectRow',
  467. mockAutoCompleter.setTokenWasCalled);
  468. }
  469. function testSetTokenText() {
  470. var ih = new MockInputHandler();
  471. // Set up our input handler with the necessary mocks
  472. var mockAutoCompleter = new MockAutoCompleter();
  473. ih.ac_ = mockAutoCompleter;
  474. ih.activeElement_ = mockElement;
  475. mockElement.value = 'bob, wal, joey';
  476. ih.setCursorPosition(8);
  477. ih.setTokenText('waldo', true /* multi-row */);
  478. assertEquals('bob, waldo, joey', mockElement.value);
  479. }
  480. function testSetTokenTextLeftHandSideOfToken() {
  481. var ih = new MockInputHandler();
  482. ih.setSeparators(' ');
  483. ih.setWhitespaceWrapEntries(false);
  484. // Set up our input handler with the necessary mocks
  485. var mockAutoCompleter = new MockAutoCompleter();
  486. ih.ac_ = mockAutoCompleter;
  487. ih.activeElement_ = mockElement;
  488. mockElement.value = 'foo bar';
  489. // Sets cursor position right before 'bar'
  490. ih.setCursorPosition(4);
  491. ih.setTokenText('bar', true /* multi-row */);
  492. assertEquals('foo bar ', mockElement.value);
  493. }
  494. function testEmptyTokenWithSeparator() {
  495. var ih = new goog.ui.ac.InputHandler();
  496. var mockAutoCompleter = new MockAutoCompleter();
  497. ih.ac_ = mockAutoCompleter;
  498. ih.activeElement_ = mockElement;
  499. mockElement.value = ', ,';
  500. // Sets cursor position before the second comma
  501. goog.dom.selection.setStart(mockElement, 2);
  502. ih.update();
  503. assertTrue(
  504. 'update should call setToken on selectRow',
  505. mockAutoCompleter.setTokenWasCalled);
  506. assertEquals(
  507. 'update should be called with empty string', '',
  508. mockAutoCompleter.setToken);
  509. }
  510. function testNonEmptyTokenWithSeparator() {
  511. var ih = new goog.ui.ac.InputHandler();
  512. var mockAutoCompleter = new MockAutoCompleter();
  513. ih.ac_ = mockAutoCompleter;
  514. ih.activeElement_ = mockElement;
  515. mockElement.value = ', joe ,';
  516. // Sets cursor position before the second comma
  517. goog.dom.selection.setStart(mockElement, 5);
  518. ih.update();
  519. assertTrue(
  520. 'update should call setToken on selectRow',
  521. mockAutoCompleter.setTokenWasCalled);
  522. assertEquals(
  523. 'update should be called with expected string', 'joe',
  524. mockAutoCompleter.setToken);
  525. }
  526. function testGetThrottleTime() {
  527. var ih = new goog.ui.ac.InputHandler();
  528. ih.setThrottleTime(999);
  529. assertEquals('throttle time set+get', 999, ih.getThrottleTime());
  530. }
  531. function testGetUpdateDuringTyping() {
  532. var ih = new goog.ui.ac.InputHandler();
  533. ih.setUpdateDuringTyping(false);
  534. assertFalse('update during typing set+get', ih.getUpdateDuringTyping());
  535. }
  536. function testEnterToSelect() {
  537. mh.fireEvent('focus', '');
  538. mh.fireKeyEvents(goog.events.KeyCodes.ENTER, true, true, true);
  539. assertTrue('Should hilite', mh.ac_.selectHilitedWasCalled);
  540. assertFalse('Should NOT be dismissed', mh.ac_.dismissWasCalled);
  541. }
  542. function testEnterDoesNotSelectWhenClosed() {
  543. mh.fireEvent('focus', '');
  544. mh.ac_.isOpen = goog.functions.FALSE;
  545. mh.fireKeyEvents(goog.events.KeyCodes.ENTER, true, true, true);
  546. assertFalse('Should NOT hilite', mh.ac_.selectHilitedWasCalled);
  547. assertTrue('Should be dismissed', mh.ac_.dismissWasCalled);
  548. }
  549. function testTabToSelect() {
  550. mh.fireEvent('focus', '');
  551. mh.fireKeyEvents(goog.events.KeyCodes.TAB, true, true, true);
  552. assertTrue('Should hilite', mh.ac_.selectHilitedWasCalled);
  553. assertFalse('Should NOT be dismissed', mh.ac_.dismissWasCalled);
  554. }
  555. function testTabDoesNotSelectWhenClosed() {
  556. mh.fireEvent('focus', '');
  557. mh.ac_.isOpen = goog.functions.FALSE;
  558. mh.fireKeyEvents(goog.events.KeyCodes.TAB, true, true, true);
  559. assertFalse('Should NOT hilite', mh.ac_.selectHilitedWasCalled);
  560. assertTrue('Should be dismissed', mh.ac_.dismissWasCalled);
  561. }
  562. function testShiftTabDoesNotSelect() {
  563. mh.fireEvent('focus', '');
  564. mh.ac_.isOpen = goog.functions.TRUE;
  565. mh.fireKeyEvents(
  566. goog.events.KeyCodes.TAB, true, true, true, {shiftKey: true});
  567. assertFalse('Should NOT hilite', mh.ac_.selectHilitedWasCalled);
  568. assertTrue('Should be dismissed', mh.ac_.dismissWasCalled);
  569. }
  570. function testEmptySeparatorUsesDefaults() {
  571. var inputHandler = new goog.ui.ac.InputHandler('');
  572. assertFalse(inputHandler.separatorCheck_.test(''));
  573. assertFalse(inputHandler.separatorCheck_.test('x'));
  574. assertTrue(inputHandler.separatorCheck_.test(','));
  575. }
  576. function testMultipleSeparatorUsesEmptyDefaults() {
  577. var inputHandler = new goog.ui.ac.InputHandler(',\n', null, true);
  578. inputHandler.setWhitespaceWrapEntries(false);
  579. inputHandler.setSeparators(',\n', '');
  580. // Set up our input handler with the necessary mocks
  581. var mockAutoCompleter = new MockAutoCompleter();
  582. inputHandler.ac_ = mockAutoCompleter;
  583. inputHandler.activeElement_ = mockElement;
  584. mockElement.value = 'bob,wal';
  585. inputHandler.setCursorPosition(8);
  586. inputHandler.setTokenText('waldo', true /* multi-row */);
  587. assertEquals('bob,waldo', mockElement.value);
  588. }
  589. function testAriaTags() {
  590. var target = goog.dom.createDom(goog.dom.TagName.DIV);
  591. mh.attachInput(target);
  592. assertEquals(goog.a11y.aria.Role.COMBOBOX, goog.a11y.aria.getRole(target));
  593. assertEquals(
  594. 'list',
  595. goog.a11y.aria.getState(target, goog.a11y.aria.State.AUTOCOMPLETE));
  596. mh.detachInput(target);
  597. assertNull(goog.a11y.aria.getRole(target));
  598. assertEquals(
  599. '', goog.a11y.aria.getState(target, goog.a11y.aria.State.AUTOCOMPLETE));
  600. }