map_test.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. // Copyright 2012 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.labs.structs.MapTest');
  15. goog.setTestOnly('goog.labs.structs.MapTest');
  16. goog.require('goog.labs.structs.Map');
  17. goog.require('goog.testing.PropertyReplacer');
  18. goog.require('goog.testing.jsunit');
  19. var map;
  20. var stubs;
  21. function setUpPage() {
  22. stubs = new goog.testing.PropertyReplacer();
  23. }
  24. function setUp() {
  25. map = new goog.labs.structs.Map();
  26. }
  27. function testSet() {
  28. var key = 'test';
  29. var value = 'value';
  30. map.set(key, value);
  31. assertEquals(value, map.get(key));
  32. }
  33. function testSetsWithSameKey() {
  34. var key = 'test';
  35. var value = 'value';
  36. var value2 = 'value2';
  37. map.set(key, value);
  38. map.set(key, value2);
  39. assertEquals(value2, map.get(key));
  40. }
  41. function testSetWithUndefinedValue() {
  42. var key = 'test';
  43. map.set(key, undefined);
  44. assertUndefined(map.get(key));
  45. }
  46. function testSetWithUnderUnderProtoUnderUnder() {
  47. var key = '__proto__';
  48. var value = 'value';
  49. var value2 = 'value2';
  50. map.set(key, value);
  51. assertEquals(value, map.get(key));
  52. map.set(key, value2);
  53. assertEquals(value2, map.get(key));
  54. }
  55. function testSetWithBuiltInPropertyShadows() {
  56. var key = 'toString';
  57. var value = 'value';
  58. var key2 = 'hasOwnProperty';
  59. var value2 = 'value2';
  60. map.set(key, value);
  61. map.set(key2, value2);
  62. assertEquals(value, map.get(key));
  63. assertEquals(value2, map.get(key2));
  64. map.set(key, value2);
  65. map.set(key2, value);
  66. assertEquals(value2, map.get(key));
  67. assertEquals(value, map.get(key2));
  68. }
  69. function testGetBeforeSetOfUnderUnderProtoUnderUnder() {
  70. assertUndefined(map.get('__proto__'));
  71. }
  72. function testContainsKey() {
  73. assertFalse(map.containsKey('key'));
  74. assertFalse(map.containsKey('__proto__'));
  75. assertFalse(map.containsKey('toString'));
  76. assertFalse(map.containsKey('hasOwnProperty'));
  77. assertFalse(map.containsKey('key2'));
  78. assertFalse(map.containsKey('key3'));
  79. assertFalse(map.containsKey('key4'));
  80. map.set('key', 'v');
  81. map.set('__proto__', 'v');
  82. map.set('toString', 'v');
  83. map.set('hasOwnProperty', 'v');
  84. map.set('key2', undefined);
  85. map.set('key3', null);
  86. map.set('key4', '');
  87. assertTrue(map.containsKey('key'));
  88. assertTrue(map.containsKey('__proto__'));
  89. assertTrue(map.containsKey('toString'));
  90. assertTrue(map.containsKey('hasOwnProperty'));
  91. assertTrue(map.containsKey('key2'));
  92. assertTrue(map.containsKey('key3'));
  93. assertTrue(map.containsKey('key4'));
  94. }
  95. function testContainsValueWithShadowKeys() {
  96. assertFalse(map.containsValue('v2'));
  97. assertFalse(map.containsValue('v3'));
  98. assertFalse(map.containsValue('v4'));
  99. map.set('__proto__', 'v2');
  100. map.set('toString', 'v3');
  101. map.set('hasOwnProperty', 'v4');
  102. assertTrue(map.containsValue('v2'));
  103. assertTrue(map.containsValue('v3'));
  104. assertTrue(map.containsValue('v4'));
  105. assertFalse(map.containsValue(Object.prototype.toString));
  106. assertFalse(map.containsValue(Object.prototype.hasOwnProperty));
  107. }
  108. function testContainsValueWithNullAndUndefined() {
  109. assertFalse(map.containsValue(undefined));
  110. assertFalse(map.containsValue(null));
  111. map.set('key2', undefined);
  112. map.set('key3', null);
  113. assertTrue(map.containsValue(undefined));
  114. assertTrue(map.containsValue(null));
  115. }
  116. function testContainsValueWithNumber() {
  117. assertFalse(map.containsValue(-1));
  118. assertFalse(map.containsValue(0));
  119. assertFalse(map.containsValue(1));
  120. map.set('key', -1);
  121. map.set('key2', 0);
  122. map.set('key3', 1);
  123. assertTrue(map.containsValue(-1));
  124. assertTrue(map.containsValue(0));
  125. assertTrue(map.containsValue(1));
  126. }
  127. function testContainsValueWithNaN() {
  128. assertFalse(map.containsValue(NaN));
  129. map.set('key', NaN);
  130. assertTrue(map.containsValue(NaN));
  131. }
  132. function testContainsValueWithNegativeZero() {
  133. assertFalse(map.containsValue(-0));
  134. map.set('key', -0);
  135. assertTrue(map.containsValue(-0));
  136. assertFalse(map.containsValue(0));
  137. map.set('key', 0);
  138. assertFalse(map.containsValue(-0));
  139. assertTrue(map.containsValue(0));
  140. }
  141. function testContainsValueWithStrings() {
  142. assertFalse(map.containsValue(''));
  143. assertFalse(map.containsValue('v'));
  144. map.set('key', '');
  145. map.set('key2', 'v');
  146. assertTrue(map.containsValue(''));
  147. assertTrue(map.containsValue('v'));
  148. }
  149. function testRemove() {
  150. map.set('key', 'v');
  151. map.set('__proto__', 'v2');
  152. map.set('toString', 'v3');
  153. map.set('hasOwnProperty', 'v4');
  154. map.set('key2', undefined);
  155. map.set('key3', null);
  156. map.set('key4', '');
  157. assertFalse(map.remove('key do not exist'));
  158. assertTrue(map.remove('key'));
  159. assertFalse(map.containsKey('key'));
  160. assertFalse(map.remove('key'));
  161. assertTrue(map.remove('__proto__'));
  162. assertFalse(map.containsKey('__proto__'));
  163. assertFalse(map.remove('__proto__'));
  164. assertTrue(map.remove('toString'));
  165. assertFalse(map.containsKey('toString'));
  166. assertFalse(map.remove('toString'));
  167. assertTrue(map.remove('hasOwnProperty'));
  168. assertFalse(map.containsKey('hasOwnProperty'));
  169. assertFalse(map.remove('hasOwnProperty'));
  170. assertTrue(map.remove('key2'));
  171. assertFalse(map.containsKey('key2'));
  172. assertFalse(map.remove('key2'));
  173. assertTrue(map.remove('key3'));
  174. assertFalse(map.containsKey('key3'));
  175. assertFalse(map.remove('key3'));
  176. assertTrue('', map.remove('key4'));
  177. assertFalse(map.containsKey('key4'));
  178. assertFalse(map.remove('key4'));
  179. }
  180. function testGetCountAndIsEmpty() {
  181. assertEquals(0, map.getCount());
  182. assertTrue(map.isEmpty());
  183. map.set('key', 'v');
  184. assertEquals(1, map.getCount());
  185. map.set('__proto__', 'v2');
  186. assertEquals(2, map.getCount());
  187. map.set('toString', 'v3');
  188. assertEquals(3, map.getCount());
  189. map.set('hasOwnProperty', 'v4');
  190. assertEquals(4, map.getCount());
  191. map.set('key', 'a');
  192. assertEquals(4, map.getCount());
  193. map.set('__proto__', 'a2');
  194. assertEquals(4, map.getCount());
  195. map.set('toString', 'a3');
  196. assertEquals(4, map.getCount());
  197. map.set('hasOwnProperty', 'a4');
  198. assertEquals(4, map.getCount());
  199. map.remove('key');
  200. assertEquals(3, map.getCount());
  201. map.remove('__proto__');
  202. assertEquals(2, map.getCount());
  203. map.remove('toString');
  204. assertEquals(1, map.getCount());
  205. map.remove('hasOwnProperty');
  206. assertEquals(0, map.getCount());
  207. }
  208. function testClear() {
  209. map.set('key', 'v');
  210. map.set('__proto__', 'v');
  211. map.set('toString', 'v');
  212. map.set('hasOwnProperty', 'v');
  213. map.set('key2', undefined);
  214. map.set('key3', null);
  215. map.set('key4', '');
  216. map.clear();
  217. assertFalse(map.containsKey('key'));
  218. assertFalse(map.containsKey('__proto__'));
  219. assertFalse(map.containsKey('toString'));
  220. assertFalse(map.containsKey('hasOwnProperty'));
  221. assertFalse(map.containsKey('key2'));
  222. assertFalse(map.containsKey('key3'));
  223. assertFalse(map.containsKey('key4'));
  224. }
  225. function testGetEntries() {
  226. map.set('key', 'v');
  227. map.set('__proto__', 'v');
  228. map.set('toString', 'v');
  229. map.set('hasOwnProperty', 'v');
  230. map.set('key2', undefined);
  231. map.set('key3', null);
  232. map.set('key4', '');
  233. var entries = map.getEntries();
  234. assertEquals(7, entries.length);
  235. assertContainsEntry(['key', 'v'], entries);
  236. assertContainsEntry(['__proto__', 'v'], entries);
  237. assertContainsEntry(['toString', 'v'], entries);
  238. assertContainsEntry(['hasOwnProperty', 'v'], entries);
  239. assertContainsEntry(['key2', undefined], entries);
  240. assertContainsEntry(['key3', null], entries);
  241. assertContainsEntry(['key4', ''], entries);
  242. }
  243. function testGetKeys() {
  244. map.set('key', 'v');
  245. map.set('__proto__', 'v');
  246. map.set('toString', 'v');
  247. map.set('hasOwnProperty', 'v');
  248. map.set('key2', undefined);
  249. map.set('key3', null);
  250. map.set('k4', '');
  251. var values = map.getKeys();
  252. assertSameElements(
  253. ['key', '__proto__', 'toString', 'hasOwnProperty', 'key2', 'key3', 'k4'],
  254. values);
  255. }
  256. function testGetValues() {
  257. map.set('key', 'v');
  258. map.set('__proto__', 'v');
  259. map.set('toString', 'v');
  260. map.set('hasOwnProperty', 'v');
  261. map.set('key2', undefined);
  262. map.set('key3', null);
  263. map.set('key4', '');
  264. var values = map.getValues();
  265. assertSameElements(['v', 'v', 'v', 'v', undefined, null, ''], values);
  266. }
  267. function testAddAllToEmptyMap() {
  268. map.set('key', 'v');
  269. map.set('key2', 'v2');
  270. map.set('key3', 'v3');
  271. map.set('key4', 'v4');
  272. var map2 = new goog.labs.structs.Map();
  273. map2.addAll(map);
  274. assertEquals(4, map2.getCount());
  275. assertEquals('v', map2.get('key'));
  276. assertEquals('v2', map2.get('key2'));
  277. assertEquals('v3', map2.get('key3'));
  278. assertEquals('v4', map2.get('key4'));
  279. }
  280. function testAddAllToNonEmptyMap() {
  281. map.set('key', 'v');
  282. map.set('key2', 'v2');
  283. map.set('key3', 'v3');
  284. map.set('key4', 'v4');
  285. var map2 = new goog.labs.structs.Map();
  286. map2.set('key0', 'o');
  287. map2.set('key', 'o');
  288. map2.set('key2', 'o2');
  289. map2.set('key3', 'o3');
  290. map2.addAll(map);
  291. assertEquals(5, map2.getCount());
  292. assertEquals('o', map2.get('key0'));
  293. assertEquals('v', map2.get('key'));
  294. assertEquals('v2', map2.get('key2'));
  295. assertEquals('v3', map2.get('key3'));
  296. assertEquals('v4', map2.get('key4'));
  297. }
  298. function testClone() {
  299. map.set('key', 'v');
  300. map.set('key2', 'v2');
  301. map.set('key3', 'v3');
  302. map.set('key4', 'v4');
  303. var map2 = map.clone();
  304. assertEquals(4, map2.getCount());
  305. assertEquals('v', map2.get('key'));
  306. assertEquals('v2', map2.get('key2'));
  307. assertEquals('v3', map2.get('key3'));
  308. assertEquals('v4', map2.get('key4'));
  309. }
  310. function testMapWithModifiedObjectPrototype() {
  311. stubs.set(Object.prototype, 'toString', function() {});
  312. stubs.set(Object.prototype, 'foo', function() {});
  313. stubs.set(Object.prototype, 'field', 100);
  314. stubs.set(Object.prototype, 'fooKey', function() {});
  315. map = new goog.labs.structs.Map();
  316. map.set('key', 'v');
  317. map.set('key2', 'v2');
  318. map.set('fooKey', 'v3');
  319. assertTrue(map.containsKey('key'));
  320. assertTrue(map.containsKey('key2'));
  321. assertTrue(map.containsKey('fooKey'));
  322. assertFalse(map.containsKey('toString'));
  323. assertFalse(map.containsKey('foo'));
  324. assertFalse(map.containsKey('field'));
  325. assertTrue(map.containsValue('v'));
  326. assertTrue(map.containsValue('v2'));
  327. assertTrue(map.containsValue('v3'));
  328. assertFalse(map.containsValue(100));
  329. var entries = map.getEntries();
  330. assertEquals(3, entries.length);
  331. assertContainsEntry(['key', 'v'], entries);
  332. assertContainsEntry(['key2', 'v2'], entries);
  333. assertContainsEntry(['fooKey', 'v3'], entries);
  334. }
  335. function assertContainsEntry(entry, entryList) {
  336. for (var i = 0; i < entryList.length; ++i) {
  337. if (entry[0] == entryList[i][0] && entry[1] === entryList[i][1]) {
  338. return;
  339. }
  340. }
  341. fail('Did not find entry: ' + entry + ' in: ' + entryList);
  342. }