fast_progressive_emojipicker_test.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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.emoji.FastProgressiveEmojiPickerTest');
  15. goog.setTestOnly('goog.ui.emoji.FastProgressiveEmojiPickerTest');
  16. goog.require('goog.Promise');
  17. goog.require('goog.dom.classlist');
  18. goog.require('goog.events');
  19. goog.require('goog.events.EventType');
  20. goog.require('goog.net.EventType');
  21. goog.require('goog.style');
  22. goog.require('goog.testing.jsunit');
  23. goog.require('goog.ui.emoji.Emoji');
  24. goog.require('goog.ui.emoji.EmojiPicker');
  25. goog.require('goog.ui.emoji.SpriteInfo');
  26. var images;
  27. var picker;
  28. var palette;
  29. var sprite = '../../demos/emoji/sprite.png';
  30. var sprite2 = '../../demos/emoji/sprite2.png';
  31. /**
  32. * Creates a SpriteInfo object with the specified properties. If the image is
  33. * sprited via CSS, then only the first parameter needs a value. If the image
  34. * is sprited via metadata, then the first parameter should be left null.
  35. *
  36. * @param {?string} cssClass CSS class to properly display the sprited image.
  37. * @param {string=} opt_url Url of the sprite image.
  38. * @param {number=} opt_width Width of the image being sprited.
  39. * @param {number=} opt_height Height of the image being sprited.
  40. * @param {number=} opt_xOffset Positive x offset of the image being sprited
  41. * within the sprite.
  42. * @param {number=} opt_yOffset Positive y offset of the image being sprited
  43. * within the sprite.
  44. * @param {boolean=} opt_animated Whether the sprite info is for an animated
  45. * emoji.
  46. */
  47. function si(
  48. cssClass, opt_url, opt_width, opt_height, opt_xOffset, opt_yOffset,
  49. opt_animated) {
  50. return new goog.ui.emoji.SpriteInfo(
  51. cssClass, opt_url, opt_width, opt_height, opt_xOffset, opt_yOffset,
  52. opt_animated);
  53. }
  54. // This group contains a mix of sprited emoji via css, sprited emoji via
  55. // metadata, and non-sprited emoji.
  56. var spritedEmoji2 = [
  57. 'Emoji 1',
  58. [
  59. ['../../demos/emoji/200.gif', 'std.200', si('SPRITE_200')],
  60. ['../../demos/emoji/201.gif', 'std.201', si('SPRITE_201')],
  61. ['../../demos/emoji/202.gif', 'std.202', si('SPRITE_202')],
  62. ['../../demos/emoji/203.gif', 'std.203', si('SPRITE_203')],
  63. ['../../demos/emoji/204.gif', 'std.204', si('SPRITE_204')],
  64. ['../../demos/emoji/205.gif', 'std.205', si('SPRITE_205')],
  65. ['../../demos/emoji/206.gif', 'std.206', si('SPRITE_206')],
  66. ['../../demos/emoji/2BC.gif', 'std.2BC', si('SPRITE_2BC')],
  67. ['../../demos/emoji/2BD.gif', 'std.2BD', si('SPRITE_2BD')],
  68. ['../../demos/emoji/2BE.gif', 'std.2BE', si(null, sprite, 18, 18, 36, 54)],
  69. ['../../demos/emoji/2BF.gif', 'std.2BF', si(null, sprite, 18, 18, 0, 126)],
  70. ['../../demos/emoji/2C0.gif', 'std.2C0', si(null, sprite, 18, 18, 18, 305)],
  71. ['../../demos/emoji/2C1.gif', 'std.2C1', si(null, sprite, 18, 18, 0, 287)],
  72. ['../../demos/emoji/2C2.gif', 'std.2C2', si(null, sprite, 18, 18, 18, 126)],
  73. ['../../demos/emoji/2C3.gif', 'std.2C3', si(null, sprite, 18, 18, 36, 234)],
  74. ['../../demos/emoji/2C4.gif', 'std.2C4', si(null, sprite, 18, 18, 36, 72)],
  75. ['../../demos/emoji/2C5.gif', 'std.2C5', si(null, sprite, 18, 18, 54, 54)],
  76. ['../../demos/emoji/2C6.gif', 'std.2C6'],
  77. ['../../demos/emoji/2C7.gif', 'std.2C7'],
  78. ['../../demos/emoji/2C8.gif', 'std.2C8'],
  79. ['../../demos/emoji/2C9.gif', 'std.2C9'],
  80. [
  81. '../../demos/emoji/2CA.gif', 'std.2CA',
  82. si(null, sprite2, 18, 20, 36, 72, 1)
  83. ],
  84. [
  85. '../../demos/emoji/2E3.gif', 'std.2E3', si(null, sprite2, 18, 18, 0, 0, 1)
  86. ],
  87. [
  88. '../../demos/emoji/2EF.gif', 'std.2EF',
  89. si(null, sprite2, 18, 20, 0, 300, 1)
  90. ],
  91. [
  92. '../../demos/emoji/2F1.gif', 'std.2F1',
  93. si(null, sprite2, 18, 18, 0, 320, 1)
  94. ]
  95. ]
  96. ];
  97. /**
  98. * Returns true if the two paths end with the same file.
  99. *
  100. * E.g., ('../../cool.gif', 'file:///home/usr/somewhere/cool.gif') --> true
  101. *
  102. * @param {string} path1 First url
  103. * @param {string} path2 Second url
  104. */
  105. function checkPathsEndWithSameFile(path1, path2) {
  106. var pieces1 = path1.split('/');
  107. var file1 = pieces1[pieces1.length - 1];
  108. var pieces2 = path2.split('/');
  109. var file2 = pieces2[pieces2.length - 1];
  110. return file1 == file2;
  111. }
  112. /**
  113. * Checks and verifies the structure of a progressive fast-loading picker
  114. * after the animated emoji have loaded.
  115. */
  116. function testStructure() {
  117. var emoji = spritedEmoji2;
  118. for (var i = 0; i < emoji[1].length; i++) {
  119. palette.setSelectedIndex(i);
  120. var emojiInfo = emoji[1][i];
  121. var cell = palette.getSelectedItem();
  122. var id = cell.getAttribute(goog.ui.emoji.Emoji.ATTRIBUTE);
  123. var inner = /** @type {Element} */ (cell.firstChild);
  124. // Check that the cell is a div wrapped around something else, and that the
  125. // outer div contains the goomoji attribute
  126. assertEquals(
  127. 'The palette item should be a div wrapped around something',
  128. cell.tagName, 'DIV');
  129. assertNotNull('The outer div is not wrapped around another element', inner);
  130. assertEquals(
  131. 'The palette item should have the goomoji attribute',
  132. cell.getAttribute(goog.ui.emoji.Emoji.ATTRIBUTE), emojiInfo[1]);
  133. assertEquals(
  134. 'The palette item should have the data-goomoji attribute',
  135. cell.getAttribute(goog.ui.emoji.Emoji.DATA_ATTRIBUTE), emojiInfo[1]);
  136. // Now check the contents of the cells
  137. var url = emojiInfo[0]; // url of the animated emoji
  138. var spriteInfo = emojiInfo[2];
  139. if (spriteInfo) {
  140. if (spriteInfo.isAnimated()) {
  141. var testImg = images[id];
  142. var img = inner.firstChild;
  143. checkPathsEndWithSameFile(img.src, url);
  144. assertEquals(testImg.width, img.width);
  145. assertEquals(testImg.height, img.height);
  146. assertEquals(
  147. '0', goog.style.getStyle(img, 'left')
  148. .replace(/px/g, '')
  149. .replace(/pt/g, ''));
  150. assertEquals(
  151. '0', goog.style.getStyle(img, 'top')
  152. .replace(/px/g, '')
  153. .replace(/pt/g, ''));
  154. } else {
  155. var cssClass = spriteInfo.getCssClass();
  156. if (cssClass) {
  157. assertEquals('DIV', inner.tagName);
  158. assertTrue(
  159. 'Sprite should have its CSS class set',
  160. goog.dom.classlist.contains(inner, cssClass));
  161. } else {
  162. // There's an inner div wrapping an img tag
  163. assertEquals('DIV', inner.tagName);
  164. var img = inner.firstChild;
  165. assertNotNull('Div should be wrapping something', img);
  166. assertEquals('IMG', img.tagName);
  167. checkPathsEndWithSameFile(img.src, spriteInfo.getUrl());
  168. assertEquals(
  169. spriteInfo.getWidthCssValue(),
  170. goog.style.getStyle(inner, 'width'));
  171. assertEquals(
  172. spriteInfo.getHeightCssValue(),
  173. goog.style.getStyle(inner, 'height'));
  174. assertEquals(
  175. spriteInfo.getXOffsetCssValue().replace(/px/, '').replace(
  176. /pt/, ''),
  177. goog.style.getStyle(img, 'left')
  178. .replace(/px/, '')
  179. .replace(/pt/, ''));
  180. assertEquals(
  181. spriteInfo.getYOffsetCssValue().replace(/px/, '').replace(
  182. /pt/, ''),
  183. goog.style.getStyle(img, 'top')
  184. .replace(/px/, '')
  185. .replace(/pt/, ''));
  186. }
  187. }
  188. } else {
  189. // A non-sprited emoji is just an img
  190. assertEquals(inner.tagName, 'IMG');
  191. checkPathsEndWithSameFile(inner.src, emojiInfo[0]);
  192. }
  193. }
  194. }
  195. function setUp() {
  196. var defaultImg = '../../demos/emoji/none.gif';
  197. picker = new goog.ui.emoji.EmojiPicker(defaultImg);
  198. picker.setDelayedLoad(false);
  199. picker.setManualLoadOfAnimatedEmoji(true);
  200. picker.setProgressiveRender(true);
  201. picker.addEmojiGroup(spritedEmoji2[0], spritedEmoji2[1]);
  202. picker.render();
  203. palette = picker.getPage(0);
  204. var imageLoader = palette.getImageLoader();
  205. images = {};
  206. return new goog.Promise(function(resolve, reject) {
  207. goog.events.listen(imageLoader, goog.net.EventType.COMPLETE, resolve);
  208. goog.events.listen(imageLoader, goog.events.EventType.LOAD, function(e) {
  209. var image = e.target;
  210. images[image.id] = image;
  211. });
  212. // Now we load the animated emoji and check the structure again. The
  213. // animated emoji will be different.
  214. picker.manuallyLoadAnimatedEmoji();
  215. });
  216. }
  217. function tearDown() {
  218. picker.dispose();
  219. }