textarea_test.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. // Copyright 2010 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.TextareaTest');
  15. goog.setTestOnly('goog.ui.TextareaTest');
  16. goog.require('goog.dom');
  17. goog.require('goog.dom.classlist');
  18. goog.require('goog.events');
  19. goog.require('goog.style');
  20. goog.require('goog.testing.ExpectedFailures');
  21. goog.require('goog.testing.events.EventObserver');
  22. goog.require('goog.testing.jsunit');
  23. goog.require('goog.ui.Textarea');
  24. goog.require('goog.ui.TextareaRenderer');
  25. goog.require('goog.userAgent');
  26. goog.require('goog.userAgent.product');
  27. var sandbox;
  28. var textarea;
  29. var demoTextareaElement;
  30. var expectedFailures;
  31. function setUp() {
  32. sandbox = goog.dom.getElement('sandbox');
  33. textarea = new goog.ui.Textarea();
  34. demoTextareaElement = goog.dom.getElement('demo-textarea');
  35. expectedFailures = new goog.testing.ExpectedFailures();
  36. }
  37. function tearDown() {
  38. expectedFailures.handleTearDown();
  39. textarea.dispose();
  40. goog.dom.removeChildren(sandbox);
  41. }
  42. /**
  43. * @return {boolean} Whether we're on Mac Safari 3.x.
  44. */
  45. function isMacSafari3() {
  46. return goog.userAgent.WEBKIT && goog.userAgent.MAC &&
  47. !goog.userAgent.isVersionOrHigher('527');
  48. }
  49. /**
  50. * @return {boolean} Whether we're on Linux Firefox 3.6.3.
  51. */
  52. function isLinuxFirefox() {
  53. return goog.userAgent.product.FIREFOX && goog.userAgent.LINUX;
  54. }
  55. /**
  56. * @return {boolean} Whether we're on Firefox 3.0.
  57. */
  58. function isFirefox3() {
  59. return goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher('1.9.1');
  60. }
  61. function testConstructor() {
  62. assertNotNull('Textarea must not be null', textarea);
  63. assertEquals(
  64. 'Renderer must default to expected value',
  65. goog.ui.TextareaRenderer.getInstance(), textarea.getRenderer());
  66. var fakeDomHelper = {'getDocument': function() { return true; }};
  67. var testTextarea = new goog.ui.Textarea(
  68. 'Hello', goog.ui.TextareaRenderer.getInstance(), fakeDomHelper);
  69. assertEquals(
  70. 'Content must have expected content', 'Hello', testTextarea.getContent());
  71. assertEquals(
  72. 'Renderer must have expected value',
  73. goog.ui.TextareaRenderer.getInstance(), testTextarea.getRenderer());
  74. assertEquals(
  75. 'DOM helper must have expected value', fakeDomHelper,
  76. testTextarea.getDomHelper());
  77. testTextarea.dispose();
  78. }
  79. function testConstructorWithDecorator() {
  80. var decoratedTextarea = new goog.ui.Textarea();
  81. decoratedTextarea.decorate(demoTextareaElement);
  82. assertEquals(
  83. 'Textarea should have current content after decoration', 'Foo',
  84. decoratedTextarea.getContent());
  85. var initialHeight = decoratedTextarea.getHeight_();
  86. var initialOffsetHeight = decoratedTextarea.getElement().offsetHeight;
  87. // focus() will trigger the grow/shrink flow.
  88. decoratedTextarea.getElement().focus();
  89. assertEquals(
  90. 'Height should not have changed without content change', initialHeight,
  91. decoratedTextarea.getHeight_());
  92. assertEquals(
  93. 'offsetHeight should not have changed without content ' +
  94. 'change',
  95. initialOffsetHeight, decoratedTextarea.getElement().offsetHeight);
  96. decoratedTextarea.dispose();
  97. }
  98. function testGetSetContent() {
  99. textarea.render(sandbox);
  100. assertEquals(
  101. 'Textarea\'s content must default to an empty string', '',
  102. textarea.getContent());
  103. textarea.setContent(17);
  104. assertEquals(
  105. 'Textarea element must have expected content', '17',
  106. textarea.getElement().value);
  107. textarea.setContent('foo');
  108. assertEquals(
  109. 'Textarea element must have updated content', 'foo',
  110. textarea.getElement().value);
  111. }
  112. function testGetSetValue() {
  113. textarea.render(sandbox);
  114. assertEquals(
  115. 'Textarea\'s content must default to an empty string', '',
  116. textarea.getValue());
  117. textarea.setValue(17);
  118. assertEquals(
  119. 'Textarea element must have expected content', '17', textarea.getValue());
  120. textarea.setValue('17');
  121. assertEquals(
  122. 'Textarea element must have expected content', '17', textarea.getValue());
  123. }
  124. function testBasicTextareaBehavior() {
  125. var observer = new goog.testing.events.EventObserver();
  126. goog.events.listen(textarea, goog.ui.Textarea.EventType.RESIZE, observer);
  127. textarea.render(sandbox);
  128. var el = textarea.getElement();
  129. var heightBefore = textarea.getHeight_();
  130. assertTrue(
  131. 'One resize event should be fired during render',
  132. observer.getEvents().length == 1);
  133. textarea.setContent(
  134. 'Lorem ipsum dolor sit amet, consectetuer ' +
  135. 'elit. Aenean sollicitudin ultrices urna. Proin vehicula mauris ac ' +
  136. 'est. Ut scelerisque, risus ut facilisis dictum, est massa lacinia ' +
  137. 'lorem, in fermentum purus ligula quis nunc.');
  138. var heightAfter = textarea.getHeight_();
  139. assertTrue(
  140. 'With this much content, height should have grown.',
  141. heightAfter > heightBefore);
  142. assertTrue(
  143. 'With a height change, a resize event should have fired.',
  144. observer.getEvents().length == 2);
  145. textarea.setContent('');
  146. heightAfter = textarea.getHeight_();
  147. assertTrue(
  148. 'Textarea should shrink with no content.', heightAfter <= heightBefore);
  149. assertTrue(
  150. 'With a height change, a resize event should have fired.',
  151. observer.getEvents().length == 3);
  152. goog.events.unlisten(textarea, goog.ui.Textarea.EventType.RESIZE, observer);
  153. }
  154. function testMinHeight() {
  155. textarea.render(sandbox);
  156. textarea.setMinHeight(50);
  157. assertEquals(
  158. 'offsetHeight should be 50 initially', 50,
  159. textarea.getElement().offsetHeight);
  160. textarea.setContent(
  161. 'Lorem ipsum dolor sit amet, consectetuer ' +
  162. 'elit. Aenean sollicitudin ultrices urna. Proin vehicula mauris ac ' +
  163. 'est. Ut scelerisque, risus ut facilisis dictum, est massa lacinia ' +
  164. 'lorem, in fermentum purus ligula quis nunc.');
  165. assertTrue('getHeight_() should be > 50', textarea.getHeight_() > 50);
  166. textarea.setContent('');
  167. assertEquals(
  168. 'With no content, offsetHeight should go back to 50, ' +
  169. 'the minHeight.',
  170. 50, textarea.getElement().offsetHeight);
  171. expectedFailures.expectFailureFor(isMacSafari3());
  172. try {
  173. textarea.setMinHeight(0);
  174. assertTrue(
  175. 'After setting minHeight to 0, offsetHeight should ' +
  176. 'now be < 50, but it is ' + textarea.getElement().offsetHeight,
  177. textarea.getElement().offsetHeight < 50);
  178. } catch (e) {
  179. expectedFailures.handleException(e);
  180. }
  181. }
  182. function testMouseUpListener() {
  183. textarea.render(sandbox);
  184. textarea.setMinHeight(100);
  185. textarea.setMaxHeight(200);
  186. textarea.mouseUpListener_({});
  187. assertEquals(
  188. 'After a mouseup which is not a resize, minHeight should ' +
  189. 'still be 100',
  190. 100, textarea.minHeight_);
  191. // We need to test how CSS drop shadows effect this too.
  192. goog.dom.classlist.add(textarea.getElement(), 'drop-shadowed');
  193. textarea.mouseUpListener_({});
  194. assertEquals(
  195. 'After a mouseup which is not a resize, minHeight should ' +
  196. 'still be 100 even with a shadow',
  197. 100, textarea.minHeight_);
  198. }
  199. function testMaxHeight() {
  200. textarea.render(sandbox);
  201. textarea.setMaxHeight(50);
  202. assertTrue(
  203. 'Initial offsetHeight should be less than 50',
  204. textarea.getElement().offsetHeight < 50);
  205. var newContent = 'Lorem ipsum dolor sit amet, consectetuer adipiscing ' +
  206. 'elit. Aenean sollicitudin ultrices urna. Proin vehicula mauris ac ' +
  207. 'est. Ut scelerisque, risus ut facilisis dictum, est massa lacinia ' +
  208. 'lorem, in fermentum purus ligula quis nunc.';
  209. textarea.setContent(newContent);
  210. assertTrue(
  211. 'With lots of content, getHeight_() should be > 50',
  212. textarea.getHeight_() > 50);
  213. assertEquals(
  214. 'Even with lots of content, offsetHeight should be 50 ' +
  215. 'with maxHeight set',
  216. 50, textarea.getElement().offsetHeight);
  217. textarea.setMaxHeight(0);
  218. assertTrue(
  219. 'After setting maxHeight to 0, offsetHeight should now ' +
  220. 'be > 50',
  221. textarea.getElement().offsetHeight > 50);
  222. }
  223. function testMaxHeight_canShrink() {
  224. textarea.render(sandbox);
  225. textarea.setMaxHeight(50);
  226. assertTrue(
  227. 'Initial offsetHeight should be less than 50',
  228. textarea.getElement().offsetHeight < 50);
  229. var newContent = 'Lorem ipsum dolor sit amet, consectetuer adipiscing ' +
  230. 'elit. Aenean sollicitudin ultrices urna. Proin vehicula mauris ac ' +
  231. 'est. Ut scelerisque, risus ut facilisis dictum, est massa lacinia ' +
  232. 'lorem, in fermentum purus ligula quis nunc.';
  233. textarea.setContent(newContent);
  234. assertEquals(
  235. 'Even with lots of content, offsetHeight should be 50 ' +
  236. 'with maxHeight set',
  237. 50, textarea.getElement().offsetHeight);
  238. textarea.setContent('');
  239. assertTrue(
  240. 'With no content, offsetHeight should be back to < 50',
  241. textarea.getElement().offsetHeight < 50);
  242. }
  243. function testSetPlaceholder() {
  244. textarea.setPlaceholder('Some default text here.');
  245. textarea.setPlaceholder('new default text...');
  246. textarea.render(sandbox);
  247. if (textarea.supportsNativePlaceholder_()) {
  248. assertEquals('new default text...', textarea.getElement().placeholder);
  249. }
  250. assertEquals('', textarea.getValue());
  251. textarea.setValue('some value');
  252. assertEquals('some value', textarea.getValue());
  253. // ensure setting a new placeholder doesn't replace the value.
  254. textarea.setPlaceholder('some new placeholder');
  255. assertEquals('some value', textarea.getValue());
  256. }
  257. function testSetPlaceholderForInitialContent() {
  258. var testTextarea = new goog.ui.Textarea('initial content');
  259. testTextarea.render(sandbox);
  260. assertEquals('initial content', testTextarea.getValue());
  261. testTextarea.setPlaceholder('new default text...');
  262. assertEquals('initial content', testTextarea.getValue());
  263. testTextarea.setValue('new content');
  264. assertEquals('new content', testTextarea.getValue());
  265. testTextarea.setValue('');
  266. assertEquals('', testTextarea.getValue());
  267. if (!testTextarea.supportsNativePlaceholder_()) {
  268. // Pretend we leave the textarea. When that happens, the
  269. // placeholder text should appear.
  270. assertEquals('', testTextarea.getElement().value);
  271. testTextarea.blur_();
  272. assertEquals('new default text...', testTextarea.getElement().value);
  273. }
  274. }
  275. function testMinAndMaxHeight() {
  276. textarea.render(sandbox);
  277. textarea.setMinHeight(50);
  278. textarea.setMaxHeight(150);
  279. assertEquals(
  280. 'offsetHeight should be 50 initially', 50,
  281. textarea.getElement().offsetHeight);
  282. textarea.setContent(
  283. 'Lorem ipsum dolor sit amet, consectetuer ' +
  284. 'elit. Aenean sollicitudin ultrices urna. Proin vehicula mauris ac ' +
  285. 'est. Ut scelerisque, risus ut facilisis dictum, est massa lacinia ' +
  286. 'lorem, in fermentum purus ligula quis nunc.');
  287. var height = textarea.getHeight_();
  288. // For some reason Mac Safari 3 has 136 and Linux FF has 146 here.
  289. expectedFailures.expectFailureFor(isMacSafari3() || isLinuxFirefox());
  290. try {
  291. assertTrue(
  292. 'With lots of content, getHeight_() should be > 150 ' +
  293. '(it is ' + height + ')',
  294. height > 150);
  295. assertEquals(
  296. 'Even with lots of content, offsetHeight should be 150 ' +
  297. 'with maxHeight set',
  298. 150, textarea.getElement().offsetHeight);
  299. textarea.setMaxHeight(0);
  300. assertTrue(
  301. 'After setting maxHeight to 0, offsetHeight should now ' +
  302. 'be > 150 (it is ' + textarea.getElement().offsetHeight + ')',
  303. textarea.getElement().offsetHeight > 150);
  304. textarea.setContent('');
  305. textarea.setMinHeight(0);
  306. assertTrue(
  307. 'After setting minHeight to 0, with no contents, ' +
  308. 'offsetHeight should now be < 50',
  309. textarea.getElement().offsetHeight < 50);
  310. } catch (e) {
  311. expectedFailures.handleException(e);
  312. }
  313. }
  314. function testSetValueWhenInvisible() {
  315. textarea.render(sandbox);
  316. var content = 'Lorem ipsum dolor sit amet, consectetuer ' +
  317. 'elit. Aenean sollicitudin ultrices urna. Proin vehicula mauris ac ' +
  318. 'est. Ut scelerisque, risus ut facilisis dictum, est massa lacinia ' +
  319. 'lorem, in fermentum purus ligula quis nunc.';
  320. textarea.setValue(content);
  321. var height = textarea.getHeight_();
  322. var elementHeight = goog.style.getStyle(textarea.getElement(), 'height');
  323. assertEquals(height + 'px', elementHeight);
  324. // Hide the element, height_ should be invalidate when setValue().
  325. goog.style.setElementShown(textarea.getElement(), false);
  326. textarea.setValue(content);
  327. // Show the element again.
  328. goog.style.setElementShown(textarea.getElement(), true);
  329. textarea.setValue(content);
  330. height = textarea.getHeight_();
  331. elementHeight = goog.style.getStyle(textarea.getElement(), 'height');
  332. assertEquals(height + 'px', elementHeight);
  333. }
  334. function testSetAriaLabel() {
  335. assertNull(
  336. 'Textarea must not have aria label by default', textarea.getAriaLabel());
  337. textarea.setAriaLabel('My textarea');
  338. textarea.render(sandbox);
  339. var element = textarea.getElementStrict();
  340. assertNotNull('Element must not be null', element);
  341. assertEquals(
  342. 'Item element must have expected aria-label', 'My textarea',
  343. element.getAttribute('aria-label'));
  344. textarea.setAriaLabel('My new textarea');
  345. assertEquals(
  346. 'Item element must have updated aria-label', 'My new textarea',
  347. element.getAttribute('aria-label'));
  348. }