linkedmap_test.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. // Copyright 2006 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.LinkedMapTest');
  15. goog.setTestOnly('goog.structs.LinkedMapTest');
  16. goog.require('goog.structs.LinkedMap');
  17. goog.require('goog.testing.jsunit');
  18. goog.require('goog.testing.recordFunction');
  19. function fillLinkedMap(m) {
  20. m.set('a', 0);
  21. m.set('b', 1);
  22. m.set('c', 2);
  23. m.set('d', 3);
  24. }
  25. var someObj = {};
  26. function testLinkedMap() {
  27. var m = new goog.structs.LinkedMap();
  28. fillLinkedMap(m);
  29. assertArrayEquals(['a', 'b', 'c', 'd'], m.getKeys());
  30. assertArrayEquals([0, 1, 2, 3], m.getValues());
  31. }
  32. function testMaxSizeLinkedMap() {
  33. var m = new goog.structs.LinkedMap(3);
  34. fillLinkedMap(m);
  35. assertArrayEquals(['b', 'c', 'd'], m.getKeys());
  36. assertArrayEquals([1, 2, 3], m.getValues());
  37. }
  38. function testLruLinkedMap() {
  39. var m = new goog.structs.LinkedMap(undefined, true);
  40. fillLinkedMap(m);
  41. assertArrayEquals(['d', 'c', 'b', 'a'], m.getKeys());
  42. assertArrayEquals([3, 2, 1, 0], m.getValues());
  43. m.get('a');
  44. assertArrayEquals(['a', 'd', 'c', 'b'], m.getKeys());
  45. assertArrayEquals([0, 3, 2, 1], m.getValues());
  46. m.set('b', 4);
  47. assertArrayEquals(['b', 'a', 'd', 'c'], m.getKeys());
  48. assertArrayEquals([4, 0, 3, 2], m.getValues());
  49. }
  50. function testMaxSizeLruLinkedMap() {
  51. var m = new goog.structs.LinkedMap(3, true);
  52. fillLinkedMap(m);
  53. assertArrayEquals(['d', 'c', 'b'], m.getKeys());
  54. assertArrayEquals([3, 2, 1], m.getValues());
  55. m.get('c');
  56. assertArrayEquals(['c', 'd', 'b'], m.getKeys());
  57. assertArrayEquals([2, 3, 1], m.getValues());
  58. m.set('d', 4);
  59. assertArrayEquals(['d', 'c', 'b'], m.getKeys());
  60. assertArrayEquals([4, 2, 1], m.getValues());
  61. }
  62. function testMaxSizeLruLinkedMapWithEvictionCallback() {
  63. var cb = goog.testing.recordFunction();
  64. var m = new goog.structs.LinkedMap(4, true, cb);
  65. fillLinkedMap(m);
  66. assertEquals(0, cb.getCallCount()); // But cache is full.
  67. assertArrayEquals(['d', 'c', 'b', 'a'], m.getKeys());
  68. m.set('d', 'exists');
  69. assertEquals(0, cb.getCallCount());
  70. m.set('extra1', 'val1');
  71. assertEquals(1, cb.getCallCount());
  72. assertArrayEquals(['a', 0], cb.getLastCall().getArguments());
  73. m.set('extra2', 'val2');
  74. assertEquals(2, cb.getCallCount());
  75. assertArrayEquals(['b', 1], cb.getLastCall().getArguments());
  76. m.set('extra2', 'val2_2');
  77. assertEquals(2, cb.getCallCount());
  78. }
  79. function testGetCount() {
  80. var m = new goog.structs.LinkedMap();
  81. assertEquals(0, m.getCount());
  82. m.set('a', 0);
  83. assertEquals(1, m.getCount());
  84. m.set('a', 1);
  85. assertEquals(1, m.getCount());
  86. m.set('b', 2);
  87. assertEquals(2, m.getCount());
  88. m.remove('a');
  89. assertEquals(1, m.getCount());
  90. }
  91. function testIsEmpty() {
  92. var m = new goog.structs.LinkedMap();
  93. assertTrue(m.isEmpty());
  94. m.set('a', 0);
  95. assertFalse(m.isEmpty());
  96. m.remove('a');
  97. assertTrue(m.isEmpty());
  98. }
  99. function testSetMaxCount() {
  100. var m = new goog.structs.LinkedMap(3);
  101. fillLinkedMap(m);
  102. assertEquals(3, m.getCount());
  103. m.setMaxCount(5);
  104. m.set('e', 5);
  105. m.set('f', 6);
  106. m.set('g', 7);
  107. assertEquals(5, m.getCount());
  108. m.setMaxCount(4);
  109. assertEquals(4, m.getCount());
  110. m.setMaxCount(0);
  111. m.set('h', 8);
  112. m.set('i', 9);
  113. m.set('j', 10);
  114. assertEquals(7, m.getCount());
  115. }
  116. function testClear() {
  117. var m = new goog.structs.LinkedMap();
  118. fillLinkedMap(m);
  119. m.clear();
  120. assertTrue(m.isEmpty());
  121. }
  122. function testForEach() {
  123. var m = new goog.structs.LinkedMap();
  124. fillLinkedMap(m);
  125. m.forEach(function(val, key, linkedMap) {
  126. linkedMap.set(key, val * 2);
  127. assertEquals('forEach should run in provided context.', someObj, this);
  128. }, someObj);
  129. assertArrayEquals(['a', 'b', 'c', 'd'], m.getKeys());
  130. assertArrayEquals([0, 2, 4, 6], m.getValues());
  131. }
  132. function testMap() {
  133. var m = new goog.structs.LinkedMap();
  134. fillLinkedMap(m);
  135. var result = m.map(function(val, key, linkedMap) {
  136. assertEquals('The LinkedMap object should get passed in', m, linkedMap);
  137. assertEquals('map should run in provided context', someObj, this);
  138. return key + val;
  139. }, someObj);
  140. assertArrayEquals(['a0', 'b1', 'c2', 'd3'], result);
  141. }
  142. function testSome() {
  143. var m = new goog.structs.LinkedMap();
  144. fillLinkedMap(m);
  145. var result = m.some(function(val, key, linkedMap) {
  146. assertEquals('The LinkedMap object should get passed in', m, linkedMap);
  147. assertEquals('map should run in provided context', someObj, this);
  148. return val > 2;
  149. }, someObj);
  150. assertTrue(result);
  151. assertFalse(m.some(function(val) { return val > 3 }));
  152. assertTrue(m.some(function(val, key) { return key == 'c'; }));
  153. assertFalse(m.some(function(val, key) { return key == 'e'; }));
  154. }
  155. function testEvery() {
  156. var m = new goog.structs.LinkedMap();
  157. fillLinkedMap(m);
  158. var result = m.every(function(val, key, linkedMap) {
  159. assertEquals('The LinkedMap object should get passed in', m, linkedMap);
  160. assertEquals('map should run in provided context', someObj, this);
  161. return val < 5;
  162. }, someObj);
  163. assertTrue(result);
  164. assertFalse(m.every(function(val) { return val < 2 }));
  165. assertTrue(m.every(function(val, key) { return key.length == 1; }));
  166. assertFalse(m.every(function(val, key) { return key == 'b'; }));
  167. }
  168. function testPeek() {
  169. var m = new goog.structs.LinkedMap();
  170. assertEquals(undefined, m.peek());
  171. assertEquals(undefined, m.peekLast());
  172. fillLinkedMap(m);
  173. assertEquals(0, m.peek());
  174. m.remove('a');
  175. assertEquals(1, m.peek());
  176. assertEquals(3, m.peekLast());
  177. assertEquals(3, m.peekValue('d'));
  178. assertEquals(1, m.peek());
  179. m.remove('d');
  180. assertEquals(2, m.peekLast());
  181. }
  182. function testPop() {
  183. var m = new goog.structs.LinkedMap();
  184. assertEquals(undefined, m.shift());
  185. assertEquals(undefined, m.pop());
  186. fillLinkedMap(m);
  187. assertEquals(4, m.getCount());
  188. assertEquals(0, m.shift());
  189. assertEquals(1, m.peek());
  190. assertEquals(3, m.pop());
  191. assertEquals(2, m.peekLast());
  192. assertEquals(2, m.getCount());
  193. }
  194. function testContains() {
  195. var m = new goog.structs.LinkedMap();
  196. fillLinkedMap(m);
  197. assertTrue(m.contains(2));
  198. assertFalse(m.contains(4));
  199. }
  200. function testContainsKey() {
  201. var m = new goog.structs.LinkedMap();
  202. fillLinkedMap(m);
  203. assertTrue(m.containsKey('b'));
  204. assertFalse(m.containsKey('elephant'));
  205. assertFalse(m.containsKey('undefined'));
  206. }
  207. function testRemoveNodeCalls() {
  208. var m = new goog.structs.LinkedMap(1);
  209. m.removeNode = goog.testing.recordFunction(m.removeNode);
  210. m.set('1', 1);
  211. assertEquals(
  212. 'removeNode not called after adding an element', 0,
  213. m.removeNode.getCallCount());
  214. m.set('1', 2);
  215. assertEquals(
  216. 'removeNode not called after updating an element', 0,
  217. m.removeNode.getCallCount());
  218. m.set('2', 2);
  219. assertEquals(
  220. 'removeNode called after adding an overflowing element', 1,
  221. m.removeNode.getCallCount());
  222. m.remove('3');
  223. assertEquals(
  224. 'removeNode not called after removing a non-existing element', 1,
  225. m.removeNode.getCallCount());
  226. m.remove('2');
  227. assertEquals(
  228. 'removeNode called after removing an existing element', 2,
  229. m.removeNode.getCallCount());
  230. m.set('1', 1);
  231. m.clear();
  232. assertEquals(
  233. 'removeNode called after clearing the map', 3,
  234. m.removeNode.getCallCount());
  235. m.clear();
  236. assertEquals(
  237. 'removeNode not called after clearing an empty map', 3,
  238. m.removeNode.getCallCount());
  239. m.set('1', 1);
  240. m.pop();
  241. assertEquals(
  242. 'removeNode called after calling pop', 4, m.removeNode.getCallCount());
  243. m.pop();
  244. assertEquals(
  245. 'removeNode not called after calling pop on an empty map', 4,
  246. m.removeNode.getCallCount());
  247. m.set('1', 1);
  248. m.shift();
  249. assertEquals(
  250. 'removeNode called after calling shift', 5, m.removeNode.getCallCount());
  251. m.shift();
  252. assertEquals(
  253. 'removeNode not called after calling shift on an empty map', 5,
  254. m.removeNode.getCallCount());
  255. m.setMaxCount(2);
  256. m.set('1', 1);
  257. m.set('2', 2);
  258. assertEquals(
  259. 'removeNode not called after increasing the maximum map size', 5,
  260. m.removeNode.getCallCount());
  261. m.setMaxCount(1);
  262. assertEquals(
  263. 'removeNode called after decreasing the maximum map size', 6,
  264. m.removeNode.getCallCount());
  265. }