basenode_test.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. // Copyright 2009 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.tree.BaseNodeTest');
  15. goog.setTestOnly('goog.ui.tree.BaseNodeTest');
  16. goog.require('goog.a11y.aria');
  17. goog.require('goog.dom');
  18. goog.require('goog.dom.TagName');
  19. goog.require('goog.dom.classlist');
  20. goog.require('goog.html.testing');
  21. goog.require('goog.testing.jsunit');
  22. goog.require('goog.ui.Component');
  23. goog.require('goog.ui.tree.BaseNode');
  24. goog.require('goog.ui.tree.TreeControl');
  25. goog.require('goog.ui.tree.TreeNode');
  26. function testAdd() {
  27. var node1 = new goog.ui.tree.TreeNode('node1');
  28. var node2 = new goog.ui.tree.TreeNode('node2');
  29. var node3 = new goog.ui.tree.TreeNode('node3');
  30. var node4 = new goog.ui.tree.TreeNode('node4');
  31. assertEquals('node2 added', node2, node1.add(node2));
  32. assertEquals('node3 added', node3, node1.add(node3));
  33. assertEquals('node4 added', node4, node1.add(node4, node3));
  34. assertEquals('node1 has 3 children', 3, node1.getChildCount());
  35. assertEquals('first child', node2, node1.getChildAt(0));
  36. assertEquals('second child', node4, node1.getChildAt(1));
  37. assertEquals('third child', node3, node1.getChildAt(2));
  38. assertNull('node1 has no parent', node1.getParent());
  39. assertEquals('the parent of node2 is node1', node1, node2.getParent());
  40. assertEquals('node4 moved under node2', node4, node2.add(node4));
  41. assertEquals('node1 has 2 children', 2, node1.getChildCount());
  42. assertEquals('node2 has 1 child', 1, node2.getChildCount());
  43. assertEquals('the child of node2 is node4', node4, node2.getChildAt(0));
  44. assertEquals('the parent of node4 is node2', node2, node4.getParent());
  45. }
  46. function testAriaExpandedFalseSetByDefaultOnParentAfterAddChild() {
  47. var tree = new goog.ui.tree.TreeControl('root');
  48. var node1 = new goog.ui.tree.TreeNode('node1');
  49. var nodeA = new goog.ui.tree.TreeNode('nodeA');
  50. tree.render(goog.dom.createDom(goog.dom.TagName.DIV));
  51. tree.addChild(node1);
  52. assertFalse(
  53. 'node1 should not have aria-expanded state',
  54. goog.a11y.aria.hasState(node1.getElement(), 'expanded'));
  55. node1.add(nodeA);
  56. assertEquals(
  57. 'node1 should have aria-expanded state', 'false',
  58. goog.a11y.aria.getState(node1.getElement(), 'expanded'));
  59. }
  60. function testAriaExpandedSetProperlyAfterSetExpandedCalledOnLeafNode() {
  61. var tree = new goog.ui.tree.TreeControl('root');
  62. var node1 = new goog.ui.tree.TreeNode('node1');
  63. var nodeA = new goog.ui.tree.TreeNode('nodeA');
  64. tree.render(goog.dom.createDom(goog.dom.TagName.DIV));
  65. tree.addChild(node1);
  66. assertFalse(
  67. 'node1 should not have aria-expanded state',
  68. goog.a11y.aria.hasState(node1.getElement(), 'expanded'));
  69. node1.setExpanded(true);
  70. node1.add(nodeA);
  71. assertEquals(
  72. 'node1 should have aria-expanded=true', 'true',
  73. goog.a11y.aria.getState(node1.getElement(), 'expanded'));
  74. }
  75. function testExpandIconAfterAddChild() {
  76. var tree = new goog.ui.tree.TreeControl('root');
  77. var node1 = new goog.ui.tree.TreeNode('node1');
  78. var node2 = new goog.ui.tree.TreeNode('node2');
  79. tree.render(goog.dom.createDom(goog.dom.TagName.DIV));
  80. tree.addChild(node1);
  81. node1.addChild(node2);
  82. assertTrue(
  83. 'expand icon of node1 changed to L+',
  84. goog.dom.classlist.contains(
  85. node1.getExpandIconElement(), 'goog-tree-expand-icon-lplus'));
  86. node1.removeChild(node2);
  87. assertFalse(
  88. 'expand icon of node1 changed back to L',
  89. goog.dom.classlist.contains(
  90. node1.getExpandIconElement(), 'goog-tree-expand-icon-lplus'));
  91. }
  92. function testExpandEvents() {
  93. var n = new goog.ui.tree.BaseNode('');
  94. n.getTree = function() {};
  95. var expanded = false;
  96. n.setExpanded(expanded);
  97. assertEquals(expanded, n.getExpanded());
  98. var callCount = 0;
  99. n.addEventListener(
  100. goog.ui.tree.BaseNode.EventType.BEFORE_EXPAND, function(e) {
  101. assertEquals(expanded, n.getExpanded());
  102. callCount++;
  103. });
  104. n.addEventListener(goog.ui.tree.BaseNode.EventType.EXPAND, function(e) {
  105. assertEquals(!expanded, n.getExpanded());
  106. callCount++;
  107. });
  108. n.setExpanded(!expanded);
  109. assertEquals(2, callCount);
  110. }
  111. function testExpandEvents2() {
  112. var n = new goog.ui.tree.BaseNode('');
  113. n.getTree = function() {};
  114. var expanded = true;
  115. n.setExpanded(expanded);
  116. assertEquals(expanded, n.getExpanded());
  117. var callCount = 0;
  118. n.addEventListener(
  119. goog.ui.tree.BaseNode.EventType.BEFORE_COLLAPSE, function(e) {
  120. assertEquals(expanded, n.getExpanded());
  121. callCount++;
  122. });
  123. n.addEventListener(goog.ui.tree.BaseNode.EventType.COLLAPSE, function(e) {
  124. assertEquals(!expanded, n.getExpanded());
  125. callCount++;
  126. });
  127. n.setExpanded(!expanded);
  128. assertEquals(2, callCount);
  129. }
  130. function testExpandEventsPreventDefault() {
  131. var n = new goog.ui.tree.BaseNode('');
  132. n.getTree = function() {};
  133. var expanded = true;
  134. n.setExpanded(expanded);
  135. assertEquals(expanded, n.getExpanded());
  136. var callCount = 0;
  137. n.addEventListener(
  138. goog.ui.tree.BaseNode.EventType.BEFORE_COLLAPSE, function(e) {
  139. assertEquals(expanded, n.getExpanded());
  140. e.preventDefault();
  141. callCount++;
  142. });
  143. n.addEventListener(goog.ui.tree.BaseNode.EventType.COLLAPSE, function(e) {
  144. fail('Should not fire COLLAPSE');
  145. });
  146. n.setExpanded(!expanded);
  147. assertEquals(1, callCount);
  148. }
  149. function testExpandEventsPreventDefault2() {
  150. var n = new goog.ui.tree.BaseNode('');
  151. n.getTree = function() {};
  152. var expanded = false;
  153. n.setExpanded(expanded);
  154. assertEquals(expanded, n.getExpanded());
  155. var callCount = 0;
  156. n.addEventListener(
  157. goog.ui.tree.BaseNode.EventType.BEFORE_EXPAND, function(e) {
  158. assertEquals(expanded, n.getExpanded());
  159. e.preventDefault();
  160. callCount++;
  161. });
  162. n.addEventListener(goog.ui.tree.BaseNode.EventType.EXPAND, function(e) {
  163. fail('Should not fire EXPAND');
  164. });
  165. n.setExpanded(!expanded);
  166. assertEquals(1, callCount);
  167. }
  168. function testRemoveChild() {
  169. var tree = new goog.ui.tree.TreeControl('root');
  170. var node1 = new goog.ui.tree.TreeNode('node1');
  171. var nodeA = new goog.ui.tree.TreeNode('nodeA');
  172. var nodeB = new goog.ui.tree.TreeNode('nodeB');
  173. tree.render(goog.dom.createDom(goog.dom.TagName.DIV));
  174. tree.addChild(node1);
  175. node1.add(nodeA);
  176. node1.add(nodeB);
  177. node1.removeChild(nodeA);
  178. assertFalse(
  179. 'nodeA should be removed from tree of node1', node1.contains(nodeA));
  180. assertTrue(
  181. 'node1 still has children; node1 should still have aria-expanded state',
  182. goog.a11y.aria.hasState(node1.getElement(), 'expanded'));
  183. }
  184. function testRemoveLastChildRemovesAriaExpandedState() {
  185. var tree = new goog.ui.tree.TreeControl('root');
  186. var node1 = new goog.ui.tree.TreeNode('node1');
  187. var node2 = new goog.ui.tree.TreeNode('node2');
  188. tree.render(goog.dom.createDom(goog.dom.TagName.DIV));
  189. tree.addChild(node1);
  190. node1.add(node2);
  191. node1.removeChild(node2);
  192. assertFalse(
  193. 'node1 has no more children; node1 should not have aria-expanded state',
  194. goog.a11y.aria.hasState(node1.getElement(), 'expanded'));
  195. }
  196. function testGetNextShownNode() {
  197. var tree = new goog.ui.tree.TreeControl('tree');
  198. assertNull('next node for unpopulated tree', tree.getNextShownNode());
  199. var node1 = new goog.ui.tree.TreeNode('node1');
  200. var node2 = new goog.ui.tree.TreeNode('node2');
  201. var node3 = new goog.ui.tree.TreeNode('node3');
  202. node1.add(node2);
  203. node1.add(node3);
  204. assertNull('next node for unexpanded node1', node1.getNextShownNode());
  205. node1.expand();
  206. assertEquals('next node for expanded node1', node2, node1.getNextShownNode());
  207. assertEquals('next node for node2', node3, node2.getNextShownNode());
  208. assertNull('next node for node3', node3.getNextShownNode());
  209. tree.add(node1);
  210. assertEquals('next node for populated tree', node1, tree.getNextShownNode());
  211. assertNull('next node for node3 inside the tree', node3.getNextShownNode());
  212. var component = new goog.ui.Component();
  213. component.addChild(tree);
  214. assertNull(
  215. 'next node for node3 inside the tree if the tree has parent',
  216. node3.getNextShownNode());
  217. }
  218. function testGetPreviousShownNode() {
  219. var tree = new goog.ui.tree.TreeControl('tree');
  220. assertNull('next node for unpopulated tree', tree.getPreviousShownNode());
  221. var node1 = new goog.ui.tree.TreeNode('node1');
  222. var node2 = new goog.ui.tree.TreeNode('node2');
  223. var node3 = new goog.ui.tree.TreeNode('node3');
  224. tree.add(node1);
  225. node1.add(node2);
  226. tree.add(node3);
  227. assertEquals(
  228. 'prev node for node3 when node1 is unexpanded', node1,
  229. node3.getPreviousShownNode());
  230. node1.expand();
  231. assertEquals(
  232. 'prev node for node3 when node1 is expanded', node2,
  233. node3.getPreviousShownNode());
  234. assertEquals(
  235. 'prev node for node2 when node1 is expanded', node1,
  236. node2.getPreviousShownNode());
  237. assertEquals(
  238. 'prev node for node1 when root is shown', tree,
  239. node1.getPreviousShownNode());
  240. tree.setShowRootNode(false);
  241. assertNull(
  242. 'next node for node1 when root is not shown',
  243. node1.getPreviousShownNode());
  244. var component = new goog.ui.Component();
  245. component.addChild(tree);
  246. assertNull(
  247. 'prev node for root if the tree has parent', tree.getPreviousShownNode());
  248. }
  249. function testInvisibleNodesInUnrenderedTree() {
  250. var tree = new goog.ui.tree.TreeControl('tree');
  251. var a = new goog.ui.tree.TreeNode('a');
  252. var b = new goog.ui.tree.TreeNode('b');
  253. tree.add(a);
  254. a.add(b);
  255. tree.render();
  256. var textContent =
  257. tree.getElement().textContent || tree.getElement().innerText;
  258. assertContains('Node should be rendered.', 'tree', textContent);
  259. assertContains('Node should be rendered.', 'a', textContent);
  260. assertNotContains(
  261. 'Unexpanded node child should not be rendered.', 'b', textContent);
  262. a.expand();
  263. var textContent =
  264. tree.getElement().textContent || tree.getElement().innerText;
  265. assertContains('Node should be rendered.', 'tree', textContent);
  266. assertContains('Node should be rendered.', 'a', textContent);
  267. assertContains('Expanded node child should be rendered.', 'b', textContent);
  268. tree.dispose();
  269. }
  270. function testInvisibleNodesInRenderedTree() {
  271. var tree = new goog.ui.tree.TreeControl('tree');
  272. tree.render();
  273. var a = new goog.ui.tree.TreeNode('a');
  274. var b = new goog.ui.tree.TreeNode('b');
  275. tree.add(a);
  276. a.add(b);
  277. var textContent =
  278. tree.getElement().textContent || tree.getElement().innerText;
  279. assertContains('Node should be rendered.', 'tree', textContent);
  280. assertContains('Node should be rendered.', 'a', textContent);
  281. assertNotContains(
  282. 'Unexpanded node child should not be rendered.', 'b', textContent);
  283. a.expand();
  284. var textContent =
  285. tree.getElement().textContent || tree.getElement().innerText;
  286. assertContains('Node should be rendered.', 'tree', textContent);
  287. assertContains('Node should be rendered.', 'a', textContent);
  288. assertContains('Expanded node child should be rendered.', 'b', textContent);
  289. tree.dispose();
  290. }
  291. function testConstructor() {
  292. var tree = new goog.ui.tree.TreeControl('tree');
  293. assertEquals('tree', tree.getHtml());
  294. tree = new goog.ui.tree.TreeControl(
  295. goog.html.testing.newSafeHtmlForTest('tree'));
  296. assertEquals('tree', tree.getHtml());
  297. }
  298. function testConstructor_allowsPlainText() {
  299. var tree = new goog.ui.tree.TreeControl('tree <3');
  300. assertEquals('tree &lt;3', tree.getHtml());
  301. }
  302. function testSetSafeHtml() {
  303. var tree = new goog.ui.tree.TreeControl('');
  304. tree.setSafeHtml(goog.html.testing.newSafeHtmlForTest('<b>tree</b>'));
  305. assertEquals('<b>tree</b>', tree.getHtml());
  306. }