combobox_test.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. // Copyright 2008 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.ComboBoxTest');
  15. goog.setTestOnly('goog.ui.ComboBoxTest');
  16. goog.require('goog.dom');
  17. goog.require('goog.dom.TagName');
  18. goog.require('goog.dom.classlist');
  19. goog.require('goog.events.KeyCodes');
  20. goog.require('goog.testing.MockClock');
  21. goog.require('goog.testing.events');
  22. goog.require('goog.testing.jsunit');
  23. goog.require('goog.ui.ComboBox');
  24. goog.require('goog.ui.ComboBoxItem');
  25. goog.require('goog.ui.Component');
  26. goog.require('goog.ui.ControlRenderer');
  27. goog.require('goog.ui.LabelInput');
  28. goog.require('goog.ui.Menu');
  29. goog.require('goog.ui.MenuItem');
  30. var comboBox;
  31. var input;
  32. function setUp() {
  33. goog.dom.removeChildren(goog.dom.getElement('combo'));
  34. comboBox = new goog.ui.ComboBox();
  35. comboBox.setDefaultText('Select a color...');
  36. comboBox.addItem(new goog.ui.ComboBoxItem('Red'));
  37. comboBox.addItem(new goog.ui.ComboBoxItem('Maroon'));
  38. comboBox.addItem(new goog.ui.ComboBoxItem('Gre<en'));
  39. comboBox.addItem(new goog.ui.ComboBoxItem('Blue'));
  40. comboBox.addItem(new goog.ui.ComboBoxItem('Royal Blue'));
  41. comboBox.addItem(new goog.ui.ComboBoxItem('Yellow'));
  42. comboBox.addItem(new goog.ui.ComboBoxItem('Magenta'));
  43. comboBox.addItem(new goog.ui.ComboBoxItem('Mouve'));
  44. comboBox.addItem(new goog.ui.ComboBoxItem('Grey'));
  45. comboBox.render(goog.dom.getElement('combo'));
  46. input = comboBox.getInputElement();
  47. }
  48. function tearDown() {
  49. comboBox.dispose();
  50. }
  51. function testInputElementAttributes() {
  52. var comboBox = new goog.ui.ComboBox();
  53. comboBox.setFieldName('a_form_field');
  54. comboBox.createDom();
  55. var inputElement = comboBox.getInputElement();
  56. assertEquals('text', inputElement.type);
  57. assertEquals('a_form_field', inputElement.name);
  58. assertEquals('off', inputElement.autocomplete);
  59. comboBox.dispose();
  60. }
  61. function testSetDefaultText() {
  62. assertEquals('Select a color...', comboBox.getDefaultText());
  63. comboBox.setDefaultText('new default text...');
  64. assertEquals('new default text...', comboBox.getDefaultText());
  65. assertEquals('new default text...', comboBox.labelInput_.getLabel());
  66. }
  67. function testGetMenu() {
  68. assertTrue(
  69. 'Menu should be instance of goog.ui.Menu',
  70. comboBox.getMenu() instanceof goog.ui.Menu);
  71. assertEquals(
  72. 'Menu should have correct number of children', 9,
  73. comboBox.getMenu().getChildCount());
  74. }
  75. function testMenuBeginsInvisible() {
  76. assertFalse('Menu should begin invisible', comboBox.getMenu().isVisible());
  77. }
  78. function testClickCausesPopup() {
  79. goog.testing.events.fireClickSequence(input);
  80. assertTrue(
  81. 'Menu becomes visible after click', comboBox.getMenu().isVisible());
  82. }
  83. function testUpKeyCausesPopup() {
  84. goog.testing.events.fireKeySequence(input, goog.events.KeyCodes.UP);
  85. assertTrue(
  86. 'Menu becomes visible after UP key', comboBox.getMenu().isVisible());
  87. }
  88. function testActionSelectsItem() {
  89. comboBox.getMenu().getItemAt(2).dispatchEvent(
  90. goog.ui.Component.EventType.ACTION);
  91. assertEquals('Gre<en', input.value);
  92. }
  93. function testActionSelectsItemWithModel() {
  94. var itemWithModel = new goog.ui.MenuItem('one', 1);
  95. comboBox.addItem(itemWithModel);
  96. itemWithModel.dispatchEvent(goog.ui.Component.EventType.ACTION);
  97. assertEquals('one', comboBox.getValue());
  98. }
  99. function testRedisplayMenuAfterBackspace() {
  100. input.value = 'mx';
  101. comboBox.onInputEvent_();
  102. input.value = 'm';
  103. comboBox.onInputEvent_();
  104. assertEquals(
  105. 'Three items should be displayed', 3,
  106. comboBox.getNumberOfVisibleItems_());
  107. }
  108. function testExternallyCreatedMenu() {
  109. var menu = new goog.ui.Menu();
  110. menu.decorate(goog.dom.getElement('menu'));
  111. assertTrue(
  112. 'Menu items should be instances of goog.ui.ComboBoxItem',
  113. menu.getChildAt(0) instanceof goog.ui.ComboBoxItem);
  114. comboBox = new goog.ui.ComboBox(null, menu);
  115. comboBox.render(goog.dom.getElement('combo'));
  116. input = goog.dom.getElementsByTagName(
  117. goog.dom.TagName.INPUT, comboBox.getElement())[0];
  118. menu.getItemAt(2).dispatchEvent(goog.ui.Component.EventType.ACTION);
  119. assertEquals('Blue', input.value);
  120. }
  121. function testRecomputeVisibleCountAfterChangingItems() {
  122. input.value = 'Black';
  123. comboBox.onInputEvent_();
  124. assertEquals(
  125. 'No items should be displayed', 0, comboBox.getNumberOfVisibleItems_());
  126. comboBox.addItem(new goog.ui.ComboBoxItem('Black'));
  127. assertEquals(
  128. 'One item should be displayed', 1, comboBox.getNumberOfVisibleItems_());
  129. input.value = 'Red';
  130. comboBox.onInputEvent_();
  131. assertEquals(
  132. 'One item should be displayed', 1, comboBox.getNumberOfVisibleItems_());
  133. comboBox.removeItemAt(0); // Red
  134. assertEquals(
  135. 'No items should be displayed', 0, comboBox.getNumberOfVisibleItems_());
  136. }
  137. function testSetEnabled() {
  138. // By default, everything should be enabled.
  139. assertFalse('Text input should initially not be disabled', input.disabled);
  140. assertFalse(
  141. 'Text input should initially not look disabled',
  142. goog.dom.classlist.contains(
  143. input,
  144. goog.getCssName(
  145. goog.ui.LabelInput.prototype.labelCssClassName, 'disabled')));
  146. assertFalse(
  147. 'Combo box should initially not look disabled',
  148. goog.dom.classlist.contains(
  149. comboBox.getElement(), goog.getCssName('goog-combobox-disabled')));
  150. goog.testing.events.fireClickSequence(comboBox.getElement());
  151. assertTrue(
  152. 'Menu initially becomes visible after click',
  153. comboBox.getMenu().isVisible());
  154. goog.testing.events.fireClickSequence(document);
  155. assertFalse(
  156. 'Menu initially becomes invisible after document click',
  157. comboBox.getMenu().isVisible());
  158. assertTrue(comboBox.isEnabled());
  159. comboBox.setEnabled(false);
  160. assertFalse(comboBox.isEnabled());
  161. assertTrue(
  162. 'Text input should be disabled after being disabled', input.disabled);
  163. assertTrue(
  164. 'Text input should appear disabled after being disabled',
  165. goog.dom.classlist.contains(
  166. input,
  167. goog.getCssName(
  168. goog.ui.LabelInput.prototype.labelCssClassName, 'disabled')));
  169. assertTrue(
  170. 'Combo box should appear disabled after being disabled',
  171. goog.dom.classlist.contains(
  172. comboBox.getElement(), goog.getCssName('goog-combobox-disabled')));
  173. goog.testing.events.fireClickSequence(comboBox.getElement());
  174. assertFalse(
  175. 'Menu should not become visible after click if disabled',
  176. comboBox.getMenu().isVisible());
  177. comboBox.setEnabled(true);
  178. assertTrue(comboBox.isEnabled());
  179. assertFalse(
  180. 'Text input should not be disabled after being re-enabled',
  181. input.disabled);
  182. assertFalse(
  183. 'Text input should not appear disabled after being re-enabled',
  184. goog.dom.classlist.contains(
  185. input,
  186. goog.getCssName(
  187. goog.ui.LabelInput.prototype.labelCssClassName, 'disabled')));
  188. assertFalse(
  189. 'Combo box should not appear disabled after being re-enabled',
  190. goog.dom.classlist.contains(
  191. comboBox.getElement(), goog.getCssName('goog-combobox-disabled')));
  192. goog.testing.events.fireClickSequence(comboBox.getElement());
  193. assertTrue(
  194. 'Menu becomes visible after click when re-enabled',
  195. comboBox.getMenu().isVisible());
  196. goog.testing.events.fireClickSequence(document);
  197. assertFalse(
  198. 'Menu becomes invisible after document click when re-enabled',
  199. comboBox.getMenu().isVisible());
  200. }
  201. function testSetFormatFromToken() {
  202. var item = new goog.ui.ComboBoxItem('ABc');
  203. item.setFormatFromToken('b');
  204. var div = goog.dom.createDom(goog.dom.TagName.DIV);
  205. new goog.ui.ControlRenderer().setContent(div, item.getContent());
  206. assertTrue(div.innerHTML == 'A<b>B</b>c' || div.innerHTML == 'A<B>B</B>c');
  207. }
  208. function testSetValue() {
  209. var clock = new goog.testing.MockClock(/* autoInstall */ true);
  210. // Get the input focus. Note that both calls are needed to correctly
  211. // simulate the focus (and setting document.activeElement) across all
  212. // browsers.
  213. input.focus();
  214. goog.testing.events.fireClickSequence(input);
  215. // Simulate text input.
  216. input.value = 'Black';
  217. comboBox.onInputEvent_();
  218. clock.tick();
  219. assertEquals(
  220. 'No items should be displayed', 0, comboBox.getNumberOfVisibleItems_());
  221. assertFalse('Menu should be invisible', comboBox.getMenu().isVisible());
  222. // Programmatic change with the input focus causes the menu visibility to
  223. // change if needed.
  224. comboBox.setValue('Blue');
  225. clock.tick();
  226. assertTrue('Menu should be visible1', comboBox.getMenu().isVisible());
  227. assertEquals(
  228. 'One item should be displayed', 1, comboBox.getNumberOfVisibleItems_());
  229. // Simulate user input to ensure all the items are invisible again, then
  230. // blur away.
  231. input.value = 'Black';
  232. comboBox.onInputEvent_();
  233. clock.tick();
  234. input.blur();
  235. document.body.focus();
  236. clock.tick(goog.ui.ComboBox.BLUR_DISMISS_TIMER_MS);
  237. assertEquals(
  238. 'No items should be displayed', 0, comboBox.getNumberOfVisibleItems_());
  239. assertFalse('Menu should be invisible', comboBox.getMenu().isVisible());
  240. // Programmatic change without the input focus does not pop up the menu,
  241. // but still updates the list of visible items within it.
  242. comboBox.setValue('Blue');
  243. clock.tick();
  244. assertFalse('Menu should be invisible', comboBox.getMenu().isVisible());
  245. assertEquals(
  246. 'Menu should contain one item', 1, comboBox.getNumberOfVisibleItems_());
  247. // Click on the combobox. The entire menu becomes visible, the last item
  248. // (programmatically) set is highlighted.
  249. goog.testing.events.fireClickSequence(comboBox.getElement());
  250. assertTrue('Menu should be visible2', comboBox.getMenu().isVisible());
  251. assertEquals(
  252. 'All items should be displayed', comboBox.getMenu().getItemCount(),
  253. comboBox.getNumberOfVisibleItems_());
  254. assertEquals(
  255. 'The last item set should be highlighted',
  256. /* Blue= */ 3, comboBox.getMenu().getHighlightedIndex());
  257. clock.uninstall();
  258. }