weakmap_functionality.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. // Functional WeakMap tests -- verifies the APIs work correctly
  6. // Note however this does not verify the GC semantics of WeakMap
  7. WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js");
  8. var tests = [
  9. {
  10. name: "WeakMap constructor called on undefined or WeakMap.prototype returns new WeakMap object (and throws on null, non-extensible object)",
  11. body: function () {
  12. // WeakMap is no longer allowed to be called as a function unless the object it is given
  13. // for its this argument already has the [[WeakMapData]] property on it.
  14. //
  15. // For IE11 we simply throw if WeakMap() is called as a function instead of in a new expression
  16. assert.throws(function () { WeakMap.call(undefined); }, TypeError, "WeakMap.call() throws TypeError given undefined");
  17. assert.throws(function () { WeakMap.call(null); }, TypeError, "WeakMap.call() throws TypeError given null");
  18. assert.throws(function () { WeakMap.call(WeakMap.prototype); }, TypeError, "WeakMap.call() throws TypeError given WeakMap.prototype");
  19. /*
  20. var weakmap1 = WeakMap.call(undefined);
  21. assert.isTrue(weakmap1 !== null && weakmap1 !== undefined && weakmap1 !== WeakMap.prototype, "WeakMap constructor creates new WeakMap object when this is undefined");
  22. var weakmap2 = WeakMap.call(WeakMap.prototype);
  23. assert.isTrue(weakmap2 !== null && weakmap2 !== undefined && weakmap2 !== WeakMap.prototype, "WeakMap constructor creates new WeakMap object when this is equal to WeakMap.prototype");
  24. var o = { };
  25. Object.preventExtensions(o);
  26. assert.throws(function () { WeakMap.call(null); }, TypeError, "WeakMap constructor throws on null");
  27. assert.throws(function () { WeakMap.call(o); }, TypeError, "WeakMap constructor throws on non-extensible object");
  28. */
  29. }
  30. },
  31. {
  32. name: "WeakMap constructor throws when called on already initialized WeakMap object",
  33. body: function () {
  34. var weakmap = new WeakMap();
  35. assert.throws(function () { WeakMap.call(weakmap); }, TypeError);
  36. // WeakMap is no longer allowed to be called as a function unless the object it is given
  37. // for its this argument already has the [[WeakMapData]] property on it.
  38. /*
  39. var obj = {};
  40. WeakMap.call(obj);
  41. assert.throws(function () { WeakMap.call(obj); }, TypeError);
  42. function MyWeakMap() {
  43. WeakMap.call(this);
  44. }
  45. MyWeakMap.prototype = new WeakMap();
  46. MyWeakMap.prototype.constructor = MyWeakMap;
  47. var myweakmap = new MyWeakMap();
  48. assert.throws(function () { WeakMap.call(myweakmap); }, TypeError);
  49. assert.throws(function () { MyWeakMap.call(myweakmap); }, TypeError);
  50. */
  51. }
  52. },
  53. {
  54. name: "WeakMap constructor populates the weakmap with key-values pairs from given optional iterable argument",
  55. body: function () {
  56. var keys = [ { }, { }, { }, { } ];
  57. var wm = new WeakMap([ [keys[0], 1], [keys[1], 2], [keys[2], 3] ]);
  58. assert.areEqual(1, wm.get(keys[0]), "wm has key keys[0] mapping to value 1");
  59. assert.areEqual(2, wm.get(keys[1]), "wm has key keys[1] mapping to value 2");
  60. assert.areEqual(3, wm.get(keys[2]), "wm has key keys[2] mapping to value 3");
  61. var customIterable = {
  62. [Symbol.iterator]: function () {
  63. var i = 0;
  64. return {
  65. next: function () {
  66. return {
  67. done: i > 3,
  68. value: [ keys[i], ++i * 2 ]
  69. };
  70. }
  71. };
  72. }
  73. };
  74. wm = new WeakMap(customIterable);
  75. assert.areEqual(2, wm.get(keys[0]), "wm has key keys[0] mapping to value 2");
  76. assert.areEqual(4, wm.get(keys[1]), "wm has key keys[1] mapping to value 4");
  77. assert.areEqual(6, wm.get(keys[2]), "wm has key keys[2] mapping to value 6");
  78. assert.areEqual(8, wm.get(keys[3]), "wm has key keys[3] mapping to value 8");
  79. }
  80. },
  81. {
  82. name : "WeakMap constructor caches next method from iterator",
  83. body: function () {
  84. const keys = [ { }, { }, { } ];
  85. let iterCount = 0;
  86. const iter = {
  87. [Symbol.iterator]() { return this; },
  88. next() {
  89. this.next = function (){ throw new Error ("Next should have been cached so this should not be called") };
  90. return {
  91. value : [keys[iterCount], iterCount],
  92. done : iterCount++ > 2
  93. }
  94. }
  95. }
  96. const wm = new WeakMap(iter);
  97. assert.areEqual(0, wm.get(keys[0]), "wm has key keys[0]");
  98. assert.areEqual(1, wm.get(keys[1]), "wm has key keys[1]");
  99. assert.areEqual(2, wm.get(keys[2]), "wm has key keys[2]");
  100. }
  101. },
  102. {
  103. name: "WeakMap constructor throws exceptions for non- and malformed iterable arguments",
  104. body: function () {
  105. var iterableNoIteratorMethod = { [Symbol.iterator]: 123 };
  106. var iterableBadIteratorMethod = { [Symbol.iterator]: function () { } };
  107. var iterableNoIteratorNextMethod = { [Symbol.iterator]: function () { return { }; } };
  108. var iterableBadIteratorNextMethod = { [Symbol.iterator]: function () { return { next: 123 }; } };
  109. var iterableNoIteratorResultObject = { [Symbol.iterator]: function () { return { next: function () { } }; } };
  110. assert.throws(function () { new WeakMap(123); }, TypeError, "new WeakMap() throws on non-object", "Function expected");
  111. assert.throws(function () { new WeakMap({ }); }, TypeError, "new WeakMap() throws on non-iterable object", "Function expected");
  112. assert.throws(function () { new WeakMap(iterableNoIteratorMethod); }, TypeError, "new WeakMap() throws on non-iterable object where @@iterator property is not a function", "Function expected");
  113. assert.throws(function () { new WeakMap(iterableBadIteratorMethod); }, TypeError, "new WeakMap() throws on non-iterable object where @@iterator function doesn't return an iterator", "Object expected");
  114. assert.throws(function () { new WeakMap(iterableNoIteratorNextMethod); }, TypeError, "new WeakMap() throws on iterable object where iterator object does not have next property", "Function expected");
  115. assert.throws(function () { new WeakMap(iterableBadIteratorNextMethod); }, TypeError, "new WeakMap() throws on iterable object where iterator object's next property is not a function", "Function expected");
  116. assert.throws(function () { new WeakMap(iterableNoIteratorResultObject); }, TypeError, "new WeakMap() throws on iterable object where iterator object's next method doesn't return an iterator result", "Object expected");
  117. }
  118. },
  119. {
  120. name: "APIs throw TypeError where specified",
  121. body: function () {
  122. function MyWeakMapImposter() { }
  123. MyWeakMapImposter.prototype = new WeakMap();
  124. MyWeakMapImposter.prototype.constructor = MyWeakMapImposter;
  125. var o = new MyWeakMapImposter();
  126. assert.throws(function () { o.delete(o); }, TypeError, "delete should throw if this doesn't have WeakMapData property");
  127. assert.throws(function () { o.get(o); }, TypeError, "get should throw if this doesn't have WeakMapData property");
  128. assert.throws(function () { o.has(o); }, TypeError, "has should throw if this doesn't have WeakMapData property");
  129. assert.throws(function () { o.set(o, o); }, TypeError, "set should throw if this doesn't have WeakMapData property");
  130. assert.throws(function () { WeakMap.prototype.delete.call(); }, TypeError, "delete should throw if called with no arguments");
  131. assert.throws(function () { WeakMap.prototype.get.call(); }, TypeError, "get should throw if called with no arguments");
  132. assert.throws(function () { WeakMap.prototype.has.call(); }, TypeError, "has should throw if called with no arguments");
  133. assert.throws(function () { WeakMap.prototype.set.call(); }, TypeError, "set should throw if called with no arguments");
  134. assert.throws(function () { WeakMap.prototype.delete.call(null, o); }, TypeError, "delete should throw if this is null");
  135. assert.throws(function () { WeakMap.prototype.get.call(null, o); }, TypeError, "get should throw if this is null");
  136. assert.throws(function () { WeakMap.prototype.has.call(null, o); }, TypeError, "has should throw if this is null");
  137. assert.throws(function () { WeakMap.prototype.set.call(null, o, o); }, TypeError, "set should throw if this is null");
  138. assert.throws(function () { WeakMap.prototype.delete.call(undefined, o); }, TypeError, "delete should throw if this is undefined");
  139. assert.throws(function () { WeakMap.prototype.get.call(undefined, o); }, TypeError, "get should throw if this is undefined");
  140. assert.throws(function () { WeakMap.prototype.has.call(undefined, o); }, TypeError, "has should throw if this is undefined");
  141. assert.throws(function () { WeakMap.prototype.set.call(undefined, o, o); }, TypeError, "set should throw if this is undefined");
  142. var weakmap = new WeakMap();
  143. assert.throws(function () { weakmap.set(null, o); }, TypeError, "set should throw if key is not an object, e.g. null");
  144. assert.throws(function () { weakmap.set(undefined, o); }, TypeError, "set should throw if key is not an object, e.g. undefined");
  145. assert.throws(function () { weakmap.set(true, o); }, TypeError, "set should throw if key is not an object, e.g. a boolean");
  146. assert.throws(function () { weakmap.set(10, o); }, TypeError, "set should throw if key is not an object, e.g. a number");
  147. assert.throws(function () { weakmap.set("hello", o); }, TypeError, "set should throw if key is not an object, e.g. a string");
  148. }
  149. },
  150. {
  151. name: "Non-object key argument silent fails delete, get, and has",
  152. body: function () {
  153. var weakmap = new WeakMap();
  154. assert.isTrue(weakmap.get(null) === undefined, "null is not an object and cannot be a key in a WeakMap; get returns undefined");
  155. assert.isTrue(weakmap.get(undefined) === undefined, "undefined is not an object and cannot be a key in a WeakMap; get returns undefined");
  156. assert.isTrue(weakmap.get(true) === undefined, "boolean is not an object and cannot be a key in a WeakMap; get returns undefined");
  157. assert.isTrue(weakmap.get(10) === undefined, "number is not an object and cannot be a key in a WeakMap; get returns undefined");
  158. assert.isTrue(weakmap.get("hello") === undefined, "string is not an object and cannot be a key in a WeakMap; get returns undefined");
  159. assert.isFalse(weakmap.has(null), "null is not an object and cannot be a key in a WeakMap; has returns false");
  160. assert.isFalse(weakmap.has(undefined), "undefined is not an object and cannot be a key in a WeakMap; has returns false");
  161. assert.isFalse(weakmap.has(true), "boolean is not an object and cannot be a key in a WeakMap; has returns false");
  162. assert.isFalse(weakmap.has(10), "number is not an object and cannot be a key in a WeakMap; has returns false");
  163. assert.isFalse(weakmap.has("hello"), "string is not an object and cannot be a key in a WeakMap; has returns false");
  164. assert.isFalse(weakmap.delete(null), "null is not an object and cannot be a key in a WeakMap; delete returns false");
  165. assert.isFalse(weakmap.delete(undefined), "undefined is not an object and cannot be a key in a WeakMap; delete returns false");
  166. assert.isFalse(weakmap.delete(true), "boolean is not an object and cannot be a key in a WeakMap; delete returns false");
  167. assert.isFalse(weakmap.delete(10), "number is not an object and cannot be a key in a WeakMap; delete returns false");
  168. assert.isFalse(weakmap.delete("hello"), "string is not an object and cannot be a key in a WeakMap; delete returns false");
  169. var booleanObject = new Boolean(true);
  170. var numberObject = new Number(10);
  171. var stringObject = new String("hello");
  172. weakmap.set(booleanObject, null);
  173. weakmap.set(numberObject, null);
  174. weakmap.set(stringObject, null);
  175. assert.isTrue(weakmap.get(true) === undefined, "boolean is not an object and cannot be a key in a WeakMap; get returns undefined");
  176. assert.isTrue(weakmap.get(10) === undefined, "number is not an object and cannot be a key in a WeakMap; get returns undefined");
  177. assert.isTrue(weakmap.get("hello") === undefined, "string is not an object and cannot be a key in a WeakMap; get returns undefined");
  178. assert.isFalse(weakmap.has(true), "boolean is not an object and cannot be a key in a WeakMap; has returns false");
  179. assert.isFalse(weakmap.has(10), "number is not an object and cannot be a key in a WeakMap; has returns false");
  180. assert.isFalse(weakmap.has("hello"), "string is not an object and cannot be a key in a WeakMap; has returns false");
  181. assert.isFalse(weakmap.delete(true), "boolean is not an object and cannot be a key in a WeakMap; delete returns false");
  182. assert.isFalse(weakmap.delete(10), "number is not an object and cannot be a key in a WeakMap; delete returns false");
  183. assert.isFalse(weakmap.delete("hello"), "string is not an object and cannot be a key in a WeakMap; delete returns false");
  184. }
  185. },
  186. {
  187. name: "Basic usage, delete, get, has, set",
  188. body: function () {
  189. var weakmap = new WeakMap();
  190. var o = { };
  191. var p = { };
  192. var q = { };
  193. weakmap.set(o, 10);
  194. weakmap.set(p, o);
  195. weakmap.set(q, q);
  196. assert.isTrue(weakmap.has(o), "Should contain key o");
  197. assert.isTrue(weakmap.has(p), "Should contain key p");
  198. assert.isTrue(weakmap.has(q), "Should contain key q");
  199. assert.isFalse(weakmap.has(weakmap), "Should not contain other keys, 'weakmap'");
  200. assert.isFalse(weakmap.has({ }), "Should not contain other keys, '{ }'");
  201. assert.isTrue(weakmap.get(o) === 10, "Should weakmap o to 10");
  202. assert.isTrue(weakmap.get(p) === o, "Should weakmap p to o");
  203. assert.isTrue(weakmap.get(q) === q, "Should weakmap q to q");
  204. assert.isTrue(weakmap.get(weakmap) === undefined, "Should return undefined for non-existant key, 'weakmap'");
  205. assert.isTrue(weakmap.get({ }) === undefined, "Should return undefined for non-existant key, '{ }'");
  206. assert.isTrue(weakmap.delete(p), "Should return true after deleting key p");
  207. assert.isTrue(weakmap.has(o), "Should still contain key o");
  208. assert.isFalse(weakmap.has(p), "Should no longer contain key p");
  209. assert.isTrue(weakmap.has(q), "Should still contain key q");
  210. assert.isFalse(weakmap.delete(p), "Should return false, p is no longer a key");
  211. assert.isTrue(weakmap.delete(o), "Should return true after deleting key o");
  212. assert.isTrue(weakmap.delete(q), "Should return true after deleting key q");
  213. assert.isFalse(weakmap.has(o), "Should no longer contain key o");
  214. assert.isFalse(weakmap.has(p), "Should still not contain key p");
  215. assert.isFalse(weakmap.has(q), "Should no longer contain key q");
  216. }
  217. },
  218. {
  219. name: "Not specifying arguments should default them to undefined",
  220. body: function () {
  221. var weakmap = new WeakMap();
  222. assert.isFalse(weakmap.has(), "Should return false for implicit undefined; has");
  223. assert.isTrue(weakmap.get() === undefined, "Should return undefined for implicit undefined; get");
  224. assert.isFalse(weakmap.delete(), "Should return false for implicit undefined; delete");
  225. assert.throws(function () { weakmap.set(); }, TypeError, "Should throw TypeError for implicit undefined; set");
  226. }
  227. },
  228. {
  229. name: "Extra arguments should be ignored",
  230. body: function () {
  231. var weakmap = new WeakMap();
  232. var o = { };
  233. var p = { };
  234. var q = { };
  235. assert.isFalse(weakmap.has(o, p, q), "Looks for o, ignores p and q, weak weakmap is empty and has should return false");
  236. assert.isTrue(weakmap.get(o, p, q) === undefined, "Looks for o, ignores p and q, weak weakmap is empty and get should return false");
  237. assert.isFalse(weakmap.delete(o, p, q), "Looks for o, ignores p and q, weak weakmap is empty and delete should return false");
  238. weakmap.set(o, p, q);
  239. assert.isTrue(weakmap.has(o), "Should contain o");
  240. assert.isFalse(weakmap.has(p), "Should not contain p");
  241. assert.isFalse(weakmap.has(q), "Should not contain q");
  242. assert.isTrue(weakmap.has(o, p, q), "Ignores p and q, does have o");
  243. assert.isTrue(weakmap.has(o, q, p), "Order of extra arguments has no affect, still has o");
  244. assert.isFalse(weakmap.has(p, o), "Ignores o, does not have p");
  245. assert.isTrue(weakmap.get(o) === p, "Should contain o and return p");
  246. assert.isTrue(weakmap.get(p) === undefined, "Should not contain p and return undefined");
  247. assert.isTrue(weakmap.get(q) === undefined, "Should not contain q and return undefined");
  248. assert.isTrue(weakmap.get(o, p, q) === p, "Ignores p and q, does have o, returns p");
  249. assert.isTrue(weakmap.get(o, q, p) === p, "Order of extra arguments has no affect, still has o, still returns p");
  250. assert.isTrue(weakmap.get(p, o) === undefined, "Ignores o, does not have p and returns undefined");
  251. assert.isFalse(weakmap.delete(p, o, q), "p is not found so should return false, ignores o and q");
  252. assert.isFalse(weakmap.delete(q, o), "q is not found so should return false, ignores o");
  253. assert.isTrue(weakmap.delete(o, p, q), "o is found and deleted, so should return true, ignores p and q");
  254. }
  255. },
  256. {
  257. name: "Delete should return true if item was in the WeakMap, false if not",
  258. body: function () {
  259. var weakmap = new WeakMap();
  260. var o = { };
  261. var p = { };
  262. weakmap.set(o, p);
  263. assert.isFalse(weakmap.delete(p), "p is not a key in the weakmap, delete should return false");
  264. assert.isTrue(weakmap.delete(o), "o is a key in the weakmap, delete should remove it and return true");
  265. assert.isFalse(weakmap.delete(o), "o is no longer a key in the weakmap, delete should now return false");
  266. }
  267. },
  268. {
  269. name: "Setting the same key twice is valid, and should modify the value",
  270. body: function () {
  271. var weakmap = new WeakMap();
  272. var o = { };
  273. var p = { };
  274. weakmap.set(o);
  275. weakmap.set(o);
  276. weakmap.set(p);
  277. weakmap.delete(o);
  278. weakmap.set(p);
  279. weakmap.set(o);
  280. weakmap.set(o);
  281. weakmap.delete(o);
  282. weakmap.delete(p);
  283. weakmap.set(o, 3);
  284. assert.isTrue(weakmap.get(o) === 3, "o maps to 3");
  285. weakmap.set(o, 4);
  286. assert.isTrue(weakmap.get(o) === 4, "o maps to 4");
  287. weakmap.set(p, 5);
  288. assert.isTrue(weakmap.get(o) === 4, "o still maps to 4");
  289. assert.isTrue(weakmap.get(p) === 5, "p maps to 5");
  290. weakmap.delete(o);
  291. assert.isTrue(weakmap.get(o) === undefined, "o is no longer in the weakmap");
  292. assert.isTrue(weakmap.get(p) === 5, "p still maps to 5");
  293. weakmap.set(p, 6);
  294. assert.isTrue(weakmap.get(p) === 6, "p maps to 6");
  295. }
  296. },
  297. {
  298. name: "set returns the weakmap instance itself",
  299. body: function () {
  300. var weakmap = new WeakMap();
  301. var o = { };
  302. assert.areEqual(weakmap, weakmap.set(o, o), "Setting new key should return WeakMap instance");
  303. assert.areEqual(weakmap, weakmap.set(o, o), "Setting existing key should return WeakMap instance");
  304. }
  305. },
  306. {
  307. name: "Adding and removing keys from one WeakMap shouldn't affect other WeakMaps",
  308. body: function () {
  309. var wm1 = new WeakMap();
  310. var wm2 = new WeakMap();
  311. var wm3 = new WeakMap();
  312. var o = { };
  313. var p = { };
  314. var q = { };
  315. wm1.set(o, o);
  316. wm1.set(p, q);
  317. wm2.set(q, o);
  318. assert.isTrue(wm1.has(o), "wm1 has o");
  319. assert.isFalse(wm2.has(o), "wm2 does not have o");
  320. assert.isFalse(wm3.has(o), "wm3 does not have o");
  321. assert.isTrue(wm1.get(o) === o, "wm1 has o map to o");
  322. assert.isTrue(wm2.get(o) === undefined, "wm2 does not have o and get returns undefined");
  323. assert.isTrue(wm3.get(o) === undefined, "wm3 does not have o and get returns undefined");
  324. assert.isTrue(wm1.has(p), "wm1 has p");
  325. assert.isTrue(wm2.has(q), "wm2 has q");
  326. assert.isFalse(wm1.has(q), "wm1 does not have q");
  327. assert.isFalse(wm2.has(p), "wm2 does not have p");
  328. assert.isFalse(wm3.has(p), "wm3 does not have p");
  329. assert.isFalse(wm3.has(q), "wm3 does not have q");
  330. assert.isTrue(wm1.get(p) === q, "wm1 has p map to q");
  331. assert.isTrue(wm2.get(q) === o, "wm2 has q map to o");
  332. assert.isTrue(wm1.get(q) === undefined, "wm1 does not have q and get returns undefined");
  333. assert.isTrue(wm2.get(p) === undefined, "wm2 does not have p and get returns undefined");
  334. assert.isTrue(wm3.get(p) === undefined, "wm3 does not have p and get returns undefined");
  335. assert.isTrue(wm3.get(q) === undefined, "wm3 does not have q and get returns undefined");
  336. wm3.set(p, o);
  337. wm3.set(q, p);
  338. assert.isTrue(wm3.has(p), "wm3 now has p");
  339. assert.isTrue(wm3.has(q), "wm3 now has q");
  340. assert.isTrue(wm1.has(p), "wm1 still has p");
  341. assert.isFalse(wm2.has(p), "wm2 still does not have p");
  342. assert.isFalse(wm1.has(q), "wm1 still does not have q");
  343. assert.isTrue(wm2.has(q), "wm2 still has q");
  344. assert.isTrue(wm1.delete(p), "p is removed from wm1");
  345. assert.isFalse(wm1.has(p), "wm1 no longer has p");
  346. assert.isTrue(wm3.has(p), "wm3 still has p");
  347. wm3.delete(p);
  348. wm3.delete(q);
  349. assert.isFalse(wm3.has(p), "wm3 no longer has p");
  350. assert.isFalse(wm3.has(q), "wm3 no longer has q");
  351. assert.isTrue(wm1.has(o), "wm1 still has o");
  352. assert.isTrue(wm2.has(q), "wm2 still has q");
  353. }
  354. },
  355. {
  356. name: "Number, Boolean, and String and other special objects should all as keys",
  357. body: function () {
  358. var weakmap = new WeakMap();
  359. var n = new Number(1);
  360. var b = new Boolean(2);
  361. var s = new String("Hi");
  362. var ab = new ArrayBuffer(32);
  363. weakmap.set(n, 1);
  364. weakmap.set(b, 2);
  365. weakmap.set(s, 3);
  366. weakmap.set(ab, 4);
  367. assert.isTrue(weakmap.has(n), "weakmap has key n which is a Number instance");
  368. assert.isTrue(weakmap.has(b), "weakmap has key b which is a Boolean instance");
  369. assert.isTrue(weakmap.has(s), "weakmap has key s which is a String instance");
  370. assert.isTrue(weakmap.has(ab), "weakmap has key ab which is an ArrayBuffer instance");
  371. assert.isTrue(weakmap.get(n) === 1, "weakmap has key n which is a Number instance and maps it to 1");
  372. assert.isTrue(weakmap.get(b) === 2, "weakmap has key b which is a Boolean instance and maps it to 2");
  373. assert.isTrue(weakmap.get(s) === 3, "weakmap has key s which is a String instance and maps it to 3");
  374. assert.isTrue(weakmap.get(ab) === 4, "weakmap has key ab which is an ArrayBuffer instance and maps it to 4");
  375. assert.isTrue(weakmap.delete(n), "Successfully delete key n which is a Number instance from weakmap");
  376. assert.isTrue(weakmap.delete(b), "Successfully delete key b which is a Boolean instance from weakmap");
  377. assert.isTrue(weakmap.delete(s), "Successfully delete key s which is a String instance from weakmap");
  378. assert.isTrue(weakmap.delete(ab), "Successfully delete key ab which is an ArrayBuffer instance from weakmap");
  379. assert.isFalse(weakmap.has(n), "weakmap no longer has key n");
  380. assert.isFalse(weakmap.has(b), "weakmap no longer has key b");
  381. assert.isFalse(weakmap.has(s), "weakmap no longer has key s");
  382. assert.isFalse(weakmap.has(ab), "weakmap no longer has key ab");
  383. }
  384. },
  385. {
  386. name: "WeakMap can add keys that are sealed and frozen (testworthy because WeakMap implementation sets internal property on key objects)",
  387. body: function () {
  388. var wm = new WeakMap();
  389. var sealedObj = Object.seal({ });
  390. var frozenObj = Object.freeze({ });
  391. wm.set(sealedObj, 1248);
  392. wm.set(frozenObj, 3927);
  393. assert.isTrue(wm.has(sealedObj), "WeakMap has sealed object as key");
  394. assert.isTrue(wm.has(frozenObj), "WeakMap has frozen object as key");
  395. assert.areEqual(1248, wm.get(sealedObj), "WeakMap maps sealed object key to corresponding mapped value");
  396. assert.areEqual(3927, wm.get(frozenObj), "WeakMap maps frozen object key to corresponding mapped value");
  397. var wm2 = new WeakMap();
  398. assert.isFalse(wm2.has(sealedObj), "Second WeakMap does not have sealed object key");
  399. assert.isFalse(wm2.has(frozenObj), "Second WeakMap does not have frozen object key");
  400. wm2.set(sealedObj, 42);
  401. wm2.set(frozenObj, 68);
  402. assert.isTrue(wm2.has(sealedObj), "Second WeakMap now has sealed object key");
  403. assert.isTrue(wm2.has(frozenObj), "Second WeakMap now has frozen object key");
  404. assert.isTrue(wm.has(sealedObj), "First WeakMap still has sealed object as key");
  405. assert.isTrue(wm.has(frozenObj), "First WeakMap still has frozen object as key");
  406. wm.delete(sealedObj);
  407. wm2.delete(frozenObj);
  408. assert.isTrue(wm2.has(sealedObj), "Second WeakMap still has sealed object key");
  409. assert.isFalse(wm2.has(frozenObj), "Second WeakMap no longer has frozen object key");
  410. assert.isFalse(wm.has(sealedObj), "First WeakMap no longer has sealed object as key");
  411. assert.isTrue(wm.has(frozenObj), "First WeakMap still has frozen object as key");
  412. }
  413. },
  414. {
  415. name: "WeakMap internal property data is not copied by Object.assign",
  416. body: function () {
  417. var key1 = {};
  418. var key2 = {};
  419. var map = new WeakMap();
  420. map.set(key1, 1);
  421. map.delete(Object.assign(key2, key1));
  422. assert.isFalse(map.has(key2));
  423. key1 = {};
  424. key2 = {};
  425. map = new WeakMap();
  426. map.set(key1, 1);
  427. key1.a = 1;
  428. map.delete(Object.assign(key2, key1));
  429. assert.isFalse(map.has(key2));
  430. }
  431. }
  432. ];
  433. testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });