quadtree_test.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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.structs.QuadTreeTest');
  15. goog.setTestOnly('goog.structs.QuadTreeTest');
  16. goog.require('goog.structs');
  17. goog.require('goog.structs.QuadTree');
  18. goog.require('goog.testing.jsunit');
  19. function getTree() {
  20. var qt = new goog.structs.QuadTree(0, 0, 100, 100);
  21. qt.set(5, 20, 'Foo');
  22. qt.set(50, 32, 'Bar');
  23. qt.set(47, 96, 'Baz');
  24. qt.set(50, 50, 'Bing');
  25. qt.set(12, 0, 'Bong');
  26. return qt;
  27. }
  28. function testGetCount() {
  29. var qt = getTree();
  30. assertEquals('Count should be 5', 5, qt.getCount());
  31. qt.remove(50, 32);
  32. assertEquals('Count should be 4', 4, qt.getCount());
  33. }
  34. function testGetKeys() {
  35. var keys = getTree().getKeys();
  36. var keyString = keys.sort().join(' ');
  37. var expected = '(12, 0) (47, 96) (5, 20) (50, 32) (50, 50)';
  38. assertEquals('Sorted keys should be ' + expected, expected, keyString);
  39. }
  40. function testGetValues() {
  41. var values = getTree().getValues();
  42. var valueString = values.sort().join(',');
  43. assertEquals(
  44. 'Sorted values should be Bar,Baz,Bing,Bong,Foo', 'Bar,Baz,Bing,Bong,Foo',
  45. valueString);
  46. }
  47. function testContains() {
  48. var qt = getTree();
  49. assertTrue('Should contain (5, 20)', qt.contains(5, 20));
  50. assertFalse('Should not contain (13, 13)', qt.contains(13, 13));
  51. }
  52. function testClear() {
  53. var qt = getTree();
  54. qt.clear();
  55. assertTrue('Tree should be empty', qt.isEmpty());
  56. assertFalse('Tree should not contain (5, 20)', qt.contains(5, 20));
  57. }
  58. function testConstructor() {
  59. var qt = new goog.structs.QuadTree(-10, -5, 6, 12);
  60. var root = qt.getRootNode();
  61. assertEquals('X of root should be -10', -10, root.x);
  62. assertEquals('Y of root should be -5', -5, root.y);
  63. assertEquals('Width of root should be 16', 16, root.w);
  64. assertEquals('Height of root should be 17', 17, root.h);
  65. assertTrue('Tree should be empty', qt.isEmpty());
  66. }
  67. function testClone() {
  68. var qt = getTree().clone();
  69. assertFalse('Clone should not be empty', qt.isEmpty());
  70. assertTrue('Should contain (47, 96)', qt.contains(47, 96));
  71. }
  72. function testRemove() {
  73. var qt = getTree();
  74. assertEquals('(5, 20) should be removed', 'Foo', qt.remove(5, 20));
  75. assertEquals('(5, 20) should be removed', 'Bar', qt.remove(50, 32));
  76. assertEquals('(5, 20) should be removed', 'Baz', qt.remove(47, 96));
  77. assertEquals('(5, 20) should be removed', 'Bing', qt.remove(50, 50));
  78. assertEquals('(5, 20) should be removed', 'Bong', qt.remove(12, 0));
  79. assertNull('(6, 6) wasn\'t there to remove', qt.remove(6, 6));
  80. assertTrue('Tree should be empty', qt.isEmpty());
  81. assertTreesChildrenAreNull(qt);
  82. }
  83. function testIsEmpty() {
  84. var qt = getTree();
  85. qt.clear();
  86. assertTrue(qt.isEmpty());
  87. assertEquals(
  88. 'Root should be empty node', goog.structs.QuadTree.NodeType.EMPTY,
  89. qt.getRootNode().nodeType);
  90. assertTreesChildrenAreNull(qt);
  91. }
  92. function testForEach() {
  93. var qt = getTree();
  94. var s = '';
  95. goog.structs.forEach(qt, function(val, key, qt2) {
  96. assertNotUndefined(key);
  97. assertEquals(qt, qt2);
  98. s += key.x + ',' + key.y + '=' + val + ' ';
  99. });
  100. assertEquals('50,32=Bar 50,50=Bing 47,96=Baz 5,20=Foo 12,0=Bong ', s);
  101. }
  102. function testBalancing() {
  103. var qt = new goog.structs.QuadTree(0, 0, 100, 100);
  104. var root = qt.getRootNode();
  105. // Add a point to the NW quadrant.
  106. qt.set(25, 25, 'first');
  107. assertEquals(
  108. 'Root should be a leaf node.', goog.structs.QuadTree.NodeType.LEAF,
  109. root.nodeType);
  110. assertTreesChildrenAreNull(qt);
  111. assertEquals('first', root.point.value);
  112. // Add another point in the NW quadrant
  113. qt.set(25, 30, 'second');
  114. assertEquals(
  115. 'Root should now be a pointer.', goog.structs.QuadTree.NodeType.POINTER,
  116. root.nodeType);
  117. assertNotNull('NE should be not be null', root.ne);
  118. assertNotNull('NW should be not be null', root.nw);
  119. assertNotNull('SE should be not be null', root.se);
  120. assertNotNull('SW should be not be null', root.sw);
  121. assertNull(root.point);
  122. // Delete the second point.
  123. qt.remove(25, 30);
  124. assertEquals(
  125. 'Root should have been rebalanced and be a leaf node.',
  126. goog.structs.QuadTree.NodeType.LEAF, root.nodeType);
  127. assertTreesChildrenAreNull(qt);
  128. assertEquals('first', root.point.value);
  129. }
  130. function testTreeBounds() {
  131. var qt = getTree();
  132. assertFails(qt, qt.set, [-10, -10, 1]);
  133. assertFails(qt, qt.set, [-10, 10, 2]);
  134. assertFails(qt, qt.set, [10, -10, 3]);
  135. assertFails(qt, qt.set, [-10, 110, 4]);
  136. assertFails(qt, qt.set, [10, 130, 5]);
  137. assertFails(qt, qt.set, [110, -10, 6]);
  138. assertFails(qt, qt.set, [150, 14, 7]);
  139. }
  140. // Helper functions
  141. function assertFails(context, fn, args) {
  142. assertThrows(
  143. 'Exception expected from ' + fn.toString() + ' with arguments ' + args,
  144. function() { fn.apply(context, args); });
  145. }
  146. function assertTreesChildrenAreNull(qt) {
  147. var root = qt.getRootNode();
  148. assertNull('NE should be null', root.ne);
  149. assertNull('NW should be null', root.nw);
  150. assertNull('SE should be null', root.se);
  151. assertNull('SW should be null', root.sw);
  152. }