blob: 1664a93bded19144733c7af0a6ea035020f3cd58 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// Copyright 2012 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
Ben Murdochda12d292016-06-02 14:46:10 +010028// Flags: --expose-gc --allow-natives-syntax
Ben Murdochb8a8cc12014-11-26 15:28:44 +000029
30
31function assertSize(expected, collection) {
32 if (collection instanceof Map || collection instanceof Set) {
33 assertEquals(expected, collection.size);
34 }
35}
36
37
38// Test valid getter and setter calls on Sets and WeakSets
39function TestValidSetCalls(m) {
40 assertDoesNotThrow(function () { m.add(new Object) });
41 assertDoesNotThrow(function () { m.has(new Object) });
42 assertDoesNotThrow(function () { m.delete(new Object) });
43}
44TestValidSetCalls(new Set);
45TestValidSetCalls(new WeakSet);
46
47
48// Test valid getter and setter calls on Maps and WeakMaps
49function TestValidMapCalls(m) {
50 assertDoesNotThrow(function () { m.get(new Object) });
51 assertDoesNotThrow(function () { m.set(new Object) });
52 assertDoesNotThrow(function () { m.has(new Object) });
53 assertDoesNotThrow(function () { m.delete(new Object) });
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000054 assertDoesNotThrow(function () { m.get(undefined) });
55 assertDoesNotThrow(function () { m.get(null) });
56 assertDoesNotThrow(function () { m.get(0) });
57 assertDoesNotThrow(function () { m.get('a-key') });
58 assertDoesNotThrow(function () { m.get(Symbol()) });
59 assertDoesNotThrow(function () { m.has(undefined) });
60 assertDoesNotThrow(function () { m.has(null) });
61 assertDoesNotThrow(function () { m.has(0) });
62 assertDoesNotThrow(function () { m.has('a-key') });
63 assertDoesNotThrow(function () { m.has(Symbol()) });
64 assertDoesNotThrow(function () { m.delete(undefined) });
65 assertDoesNotThrow(function () { m.delete(null) });
66 assertDoesNotThrow(function () { m.delete(0) });
67 assertDoesNotThrow(function () { m.delete('a-key') });
68 assertDoesNotThrow(function () { m.delete(Symbol()) });
Ben Murdochb8a8cc12014-11-26 15:28:44 +000069}
70TestValidMapCalls(new Map);
71TestValidMapCalls(new WeakMap);
72
73
74// Test invalid getter and setter calls for WeakMap only
75function TestInvalidCalls(m) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000076 assertThrows(function () { m.set(undefined, 0) }, TypeError);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000077 assertThrows(function () { m.set(null, 0) }, TypeError);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000078 assertThrows(function () { m.set(0, 0) }, TypeError);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000079 assertThrows(function () { m.set('a-key', 0) }, TypeError);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000080 assertThrows(function () { m.set(Symbol(), 0) }, TypeError);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000081}
82TestInvalidCalls(new WeakMap);
83
84
85// Test expected behavior for Sets and WeakSets
86function TestSet(set, key) {
87 assertFalse(set.has(key));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000088 assertFalse(set.delete(key));
89 if (typeof key === 'object' && !(set instanceof WeakSet)) {
90 assertSame(set, set.add(key));
91 assertTrue(set.has(key));
92 assertTrue(set.delete(key));
93 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000094 assertFalse(set.has(key));
95 assertFalse(set.delete(key));
96 assertFalse(set.has(key));
97}
98function TestSetBehavior(set) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000099 // Fill
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000100 for (var i = 0; i < 20; i++) {
101 TestSet(set, new Object);
102 TestSet(set, i);
103 TestSet(set, i / 100);
104 TestSet(set, 'key-' + i);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000105 TestSet(set, Symbol(i));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000106 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000107
108 var keys = [
109 -0, +0, 1, 1/3, 10, +Infinity, -Infinity, NaN, true, false, null, undefined,
110 'x', Symbol(), {}, function(){}
111 ];
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000112 for (var i = 0; i < keys.length; i++) {
113 TestSet(set, keys[i]);
114 }
115}
116TestSetBehavior(new Set);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000117TestSetBehavior(new WeakSet);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000118
119
120// Test expected mapping behavior for Maps and WeakMaps
121function TestMapping(map, key, value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000122 assertFalse(map.has(key));
123 assertSame(undefined, map.get(key));
124 assertFalse(map.delete(key));
125 if (typeof key === 'object' && !(map instanceof WeakMap)) {
126 assertSame(map, map.set(key, value));
127 assertSame(value, map.get(key));
128 assertTrue(map.has(key));
129 assertTrue(map.delete(key));
130 }
131 assertFalse(map.has(key));
132 assertSame(undefined, map.get(key));
133 assertFalse(map.delete(key));
134 assertFalse(map.has(key));
135 assertSame(undefined, map.get(key));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000136}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000137function TestMapBehavior(m) {
138 // Fill
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000139 TestMapping(m, new Object, 23);
140 TestMapping(m, new Object, 'the-value');
141 TestMapping(m, new Object, new Object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000142 for (var i = 0; i < 20; i++) {
143 TestMapping(m, i, new Object);
144 TestMapping(m, i / 10, new Object);
145 TestMapping(m, 'key-' + i, new Object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000146 TestMapping(m, Symbol(i), new Object);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000147 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000148
149 var keys = [
150 -0, +0, 1, 1/3, 10, +Infinity, -Infinity, NaN, true, false, null, undefined,
151 'x', Symbol(), {}, function(){}
152 ];
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000153 for (var i = 0; i < keys.length; i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000154 TestMapping(m, keys[i], 23);
155 TestMapping(m, keys[i], 'the-value');
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000156 TestMapping(m, keys[i], new Object);
157 }
158}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000159TestMapBehavior(new Map);
160TestMapBehavior(new WeakMap);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000161
162
163// Test expected querying behavior of Maps and WeakMaps
164function TestQuery(m) {
165 var key = new Object;
166 var values = [ 'x', 0, +Infinity, -Infinity, true, false, null, undefined ];
167 for (var i = 0; i < values.length; i++) {
168 TestMapping(m, key, values[i]);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000169 }
170}
171TestQuery(new Map);
172TestQuery(new WeakMap);
173
174
175// Test expected deletion behavior of Maps and WeakMaps
176function TestDelete(m) {
177 var key = new Object;
178 TestMapping(m, key, 'to-be-deleted');
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000179 assertFalse(m.delete(key));
180 assertFalse(m.delete(new Object));
181 assertSame(m.get(key), undefined);
182}
183TestDelete(new Map);
184TestDelete(new WeakMap);
185
186
187// Test GC of Maps and WeakMaps with entry
188function TestGC1(m) {
189 var key = new Object;
190 m.set(key, 'not-collected');
191 gc();
192 assertSame('not-collected', m.get(key));
193}
194TestGC1(new Map);
195TestGC1(new WeakMap);
196
197
198// Test GC of Maps and WeakMaps with chained entries
199function TestGC2(m) {
200 var head = new Object;
201 for (key = head, i = 0; i < 10; i++, key = m.get(key)) {
202 m.set(key, new Object);
203 }
204 gc();
205 var count = 0;
206 for (key = head; key != undefined; key = m.get(key)) {
207 count++;
208 }
209 assertEquals(11, count);
210}
211TestGC2(new Map);
212TestGC2(new WeakMap);
213
214
215// Test property attribute [[Enumerable]]
216function TestEnumerable(func) {
217 function props(x) {
218 var array = [];
219 for (var p in x) array.push(p);
220 return array.sort();
221 }
222 assertArrayEquals([], props(func));
223 assertArrayEquals([], props(func.prototype));
224 assertArrayEquals([], props(new func()));
225}
226TestEnumerable(Set);
227TestEnumerable(Map);
228TestEnumerable(WeakMap);
229TestEnumerable(WeakSet);
230
231
232// Test arbitrary properties on Maps and WeakMaps
233function TestArbitrary(m) {
234 function TestProperty(map, property, value) {
235 map[property] = value;
236 assertEquals(value, map[property]);
237 }
238 for (var i = 0; i < 20; i++) {
239 TestProperty(m, i, 'val' + i);
240 TestProperty(m, 'foo' + i, 'bar' + i);
241 }
242 TestMapping(m, new Object, 'foobar');
243}
244TestArbitrary(new Map);
245TestArbitrary(new WeakMap);
246
247
248// Test direct constructor call
249assertThrows(function() { Set(); }, TypeError);
250assertThrows(function() { Map(); }, TypeError);
251assertThrows(function() { WeakMap(); }, TypeError);
252assertThrows(function() { WeakSet(); }, TypeError);
253
254
255// Test whether NaN values as keys are treated correctly.
256var s = new Set;
257assertFalse(s.has(NaN));
258assertFalse(s.has(NaN + 1));
259assertFalse(s.has(23));
260s.add(NaN);
261assertTrue(s.has(NaN));
262assertTrue(s.has(NaN + 1));
263assertFalse(s.has(23));
264var m = new Map;
265assertFalse(m.has(NaN));
266assertFalse(m.has(NaN + 1));
267assertFalse(m.has(23));
268m.set(NaN, 'a-value');
269assertTrue(m.has(NaN));
270assertTrue(m.has(NaN + 1));
271assertFalse(m.has(23));
272
273
274// Test some common JavaScript idioms for Sets
275var s = new Set;
276assertTrue(s instanceof Set);
277assertTrue(Set.prototype.add instanceof Function)
278assertTrue(Set.prototype.has instanceof Function)
279assertTrue(Set.prototype.delete instanceof Function)
280assertTrue(Set.prototype.clear instanceof Function)
281
282
283// Test some common JavaScript idioms for Maps
284var m = new Map;
285assertTrue(m instanceof Map);
286assertTrue(Map.prototype.set instanceof Function)
287assertTrue(Map.prototype.get instanceof Function)
288assertTrue(Map.prototype.has instanceof Function)
289assertTrue(Map.prototype.delete instanceof Function)
290assertTrue(Map.prototype.clear instanceof Function)
291
292
293// Test some common JavaScript idioms for WeakMaps
294var m = new WeakMap;
295assertTrue(m instanceof WeakMap);
296assertTrue(WeakMap.prototype.set instanceof Function)
297assertTrue(WeakMap.prototype.get instanceof Function)
298assertTrue(WeakMap.prototype.has instanceof Function)
299assertTrue(WeakMap.prototype.delete instanceof Function)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000300
301
302// Test some common JavaScript idioms for WeakSets
303var s = new WeakSet;
304assertTrue(s instanceof WeakSet);
305assertTrue(WeakSet.prototype.add instanceof Function)
306assertTrue(WeakSet.prototype.has instanceof Function)
307assertTrue(WeakSet.prototype.delete instanceof Function)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000308
309
310// Test class of instance and prototype.
311assertEquals("Set", %_ClassOf(new Set))
312assertEquals("Object", %_ClassOf(Set.prototype))
313assertEquals("Map", %_ClassOf(new Map))
314assertEquals("Object", %_ClassOf(Map.prototype))
315assertEquals("WeakMap", %_ClassOf(new WeakMap))
316assertEquals("Object", %_ClassOf(WeakMap.prototype))
317assertEquals("WeakSet", %_ClassOf(new WeakSet))
318assertEquals("Object", %_ClassOf(WeakMap.prototype))
319
320
321// Test name of constructor.
322assertEquals("Set", Set.name);
323assertEquals("Map", Map.name);
324assertEquals("WeakMap", WeakMap.name);
325assertEquals("WeakSet", WeakSet.name);
326
327
328// Test prototype property of Set, Map, WeakMap and WeakSet.
329function TestPrototype(C) {
330 assertTrue(C.prototype instanceof Object);
331 assertEquals({
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400332 value: C.prototype,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000333 writable: false,
334 enumerable: false,
335 configurable: false
336 }, Object.getOwnPropertyDescriptor(C, "prototype"));
337}
338TestPrototype(Set);
339TestPrototype(Map);
340TestPrototype(WeakMap);
341TestPrototype(WeakSet);
342
343
344// Test constructor property of the Set, Map, WeakMap and WeakSet prototype.
345function TestConstructor(C) {
346 assertFalse(C === Object.prototype.constructor);
347 assertSame(C, C.prototype.constructor);
348 assertSame(C, (new C).__proto__.constructor);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000349 assertEquals(0, C.length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000350}
351TestConstructor(Set);
352TestConstructor(Map);
353TestConstructor(WeakMap);
354TestConstructor(WeakSet);
355
356
357// Test the Set, Map, WeakMap and WeakSet global properties themselves.
358function TestDescriptor(global, C) {
359 assertEquals({
360 value: C,
361 writable: true,
362 enumerable: false,
363 configurable: true
364 }, Object.getOwnPropertyDescriptor(global, C.name));
365}
366TestDescriptor(this, Set);
367TestDescriptor(this, Map);
368TestDescriptor(this, WeakMap);
369TestDescriptor(this, WeakSet);
370
371
372// Regression test for WeakMap prototype.
373assertTrue(WeakMap.prototype.constructor === WeakMap)
374assertTrue(Object.getPrototypeOf(WeakMap.prototype) === Object.prototype)
375
376
377// Regression test for issue 1617: The prototype of the WeakMap constructor
378// needs to be unique (i.e. different from the one of the Object constructor).
379assertFalse(WeakMap.prototype === Object.prototype);
380var o = Object.create({});
381assertFalse("get" in o);
382assertFalse("set" in o);
383assertEquals(undefined, o.get);
384assertEquals(undefined, o.set);
385var o = Object.create({}, { myValue: {
386 value: 10,
387 enumerable: false,
388 configurable: true,
389 writable: true
390}});
391assertEquals(10, o.myValue);
392
393
394// Regression test for issue 1884: Invoking any of the methods for Harmony
395// maps, sets, or weak maps, with a wrong type of receiver should be throwing
396// a proper TypeError.
397var alwaysBogus = [ undefined, null, true, "x", 23, {} ];
398var bogusReceiversTestSet = [
399 { proto: Set.prototype,
400 funcs: [ 'add', 'has', 'delete' ],
401 receivers: alwaysBogus.concat([ new Map, new WeakMap, new WeakSet ]),
402 },
403 { proto: Map.prototype,
404 funcs: [ 'get', 'set', 'has', 'delete' ],
405 receivers: alwaysBogus.concat([ new Set, new WeakMap, new WeakSet ]),
406 },
407 { proto: WeakMap.prototype,
408 funcs: [ 'get', 'set', 'has', 'delete' ],
409 receivers: alwaysBogus.concat([ new Set, new Map, new WeakSet ]),
410 },
411 { proto: WeakSet.prototype,
412 funcs: [ 'add', 'has', 'delete' ],
413 receivers: alwaysBogus.concat([ new Set, new Map, new WeakMap ]),
414 },
415];
416function TestBogusReceivers(testSet) {
417 for (var i = 0; i < testSet.length; i++) {
418 var proto = testSet[i].proto;
419 var funcs = testSet[i].funcs;
420 var receivers = testSet[i].receivers;
421 for (var j = 0; j < funcs.length; j++) {
422 var func = proto[funcs[j]];
423 for (var k = 0; k < receivers.length; k++) {
424 assertThrows(function () { func.call(receivers[k], {}) }, TypeError);
425 }
426 }
427 }
428}
429TestBogusReceivers(bogusReceiversTestSet);
430
431
432// Stress Test
433// There is a proposed stress-test available at the es-discuss mailing list
434// which cannot be reasonably automated. Check it out by hand if you like:
435// https://mail.mozilla.org/pipermail/es-discuss/2011-May/014096.html
436
437
438// Set and Map size getters
439var setSizeDescriptor = Object.getOwnPropertyDescriptor(Set.prototype, 'size');
440assertEquals(undefined, setSizeDescriptor.value);
441assertEquals(undefined, setSizeDescriptor.set);
442assertTrue(setSizeDescriptor.get instanceof Function);
443assertEquals(undefined, setSizeDescriptor.get.prototype);
444assertFalse(setSizeDescriptor.enumerable);
445assertTrue(setSizeDescriptor.configurable);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000446assertEquals('get size', setSizeDescriptor.get.name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000447
448var s = new Set();
449assertFalse(s.hasOwnProperty('size'));
450for (var i = 0; i < 10; i++) {
451 assertEquals(i, s.size);
452 s.add(i);
453}
454for (var i = 9; i >= 0; i--) {
455 s.delete(i);
456 assertEquals(i, s.size);
457}
458
459
460var mapSizeDescriptor = Object.getOwnPropertyDescriptor(Map.prototype, 'size');
461assertEquals(undefined, mapSizeDescriptor.value);
462assertEquals(undefined, mapSizeDescriptor.set);
463assertTrue(mapSizeDescriptor.get instanceof Function);
464assertEquals(undefined, mapSizeDescriptor.get.prototype);
465assertFalse(mapSizeDescriptor.enumerable);
466assertTrue(mapSizeDescriptor.configurable);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000467assertEquals('get size', mapSizeDescriptor.get.name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000468
469var m = new Map();
470assertFalse(m.hasOwnProperty('size'));
471for (var i = 0; i < 10; i++) {
472 assertEquals(i, m.size);
473 m.set(i, i);
474}
475for (var i = 9; i >= 0; i--) {
476 m.delete(i);
477 assertEquals(i, m.size);
478}
479
480
481// Test Set clear
482(function() {
483 var s = new Set();
484 s.add(42);
485 assertTrue(s.has(42));
486 assertEquals(1, s.size);
487 s.clear();
488 assertFalse(s.has(42));
489 assertEquals(0, s.size);
490})();
491
492
493// Test Map clear
494(function() {
495 var m = new Map();
496 m.set(42, true);
497 assertTrue(m.has(42));
498 assertEquals(1, m.size);
499 m.clear();
500 assertFalse(m.has(42));
501 assertEquals(0, m.size);
502})();
503
504
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000505(function TestMinusZeroSet() {
506 var s = new Set();
507 s.add(-0);
508 assertSame(0, s.values().next().value);
509 s.add(0);
510 assertEquals(1, s.size);
511 assertTrue(s.has(0));
512 assertTrue(s.has(-0));
513})();
514
515
516(function TestMinusZeroMap() {
517 var m = new Map();
518 m.set(-0, 'minus');
519 assertSame(0, m.keys().next().value);
520 m.set(0, 'plus');
521 assertEquals(1, m.size);
522 assertTrue(m.has(0));
523 assertTrue(m.has(-0));
524 assertEquals('plus', m.get(0));
525 assertEquals('plus', m.get(-0));
526})();
527
528
529(function TestSetForEachInvalidTypes() {
530 assertThrows(function() {
531 Set.prototype.set.forEach.call({});
532 }, TypeError);
533
534 var set = new Set();
535 assertThrows(function() {
536 set.forEach({});
537 }, TypeError);
538})();
539
540
541(function TestSetForEach() {
542 var set = new Set();
543 set.add('a');
544 set.add('b');
545 set.add('c');
546
547 var buffer = '';
548 var receiver = {};
549 set.forEach(function(v, k, s) {
550 assertSame(v, k);
551 assertSame(set, s);
552 assertSame(this, receiver);
553 buffer += v;
554 if (v === 'a') {
555 set.delete('b');
556 set.add('d');
557 set.add('e');
558 set.add('f');
559 } else if (v === 'c') {
560 set.add('b');
561 set.delete('e');
562 }
563 }, receiver);
564
565 assertEquals('acdfb', buffer);
566})();
567
568
569(function TestSetForEachAddAtEnd() {
570 var set = new Set();
571 set.add('a');
572 set.add('b');
573
574 var buffer = '';
575 set.forEach(function(v) {
576 buffer += v;
577 if (v === 'b') {
578 set.add('c');
579 }
580 });
581
582 assertEquals('abc', buffer);
583})();
584
585
586(function TestSetForEachDeleteNext() {
587 var set = new Set();
588 set.add('a');
589 set.add('b');
590 set.add('c');
591
592 var buffer = '';
593 set.forEach(function(v) {
594 buffer += v;
595 if (v === 'b') {
596 set.delete('c');
597 }
598 });
599
600 assertEquals('ab', buffer);
601})();
602
603
604(function TestSetForEachDeleteVisitedAndAddAgain() {
605 var set = new Set();
606 set.add('a');
607 set.add('b');
608 set.add('c');
609
610 var buffer = '';
611 set.forEach(function(v) {
612 buffer += v;
613 if (v === 'b') {
614 set.delete('a');
615 } else if (v === 'c') {
616 set.add('a');
617 }
618 });
619
620 assertEquals('abca', buffer);
621})();
622
623
624(function TestSetForEachClear() {
625 var set = new Set();
626 set.add('a');
627 set.add('b');
628 set.add('c');
629
630 var buffer = '';
631 set.forEach(function(v) {
632 buffer += v;
633 if (v === 'a') {
634 set.clear();
635 set.add('d');
636 set.add('e');
637 }
638 });
639
640 assertEquals('ade', buffer);
641})();
642
643
644(function TestSetForEachNested() {
645 var set = new Set();
646 set.add('a');
647 set.add('b');
648 set.add('c');
649
650 var buffer = '';
651 set.forEach(function(v) {
652 buffer += v;
653 set.forEach(function(v) {
654 buffer += v;
655 if (v === 'a') {
656 set.delete('b');
657 }
658 });
659 });
660
661 assertEquals('aaccac', buffer);
662})();
663
664
665(function TestSetForEachEarlyExit() {
666 var set = new Set();
667 set.add('a');
668 set.add('b');
669 set.add('c');
670
671 var buffer = '';
672 var ex = {};
673 try {
674 set.forEach(function(v) {
675 buffer += v;
676 throw ex;
677 });
678 } catch (e) {
679 assertEquals(ex, e);
680 }
681 assertEquals('a', buffer);
682})();
683
684
685(function TestSetForEachGC() {
686 var set = new Set();
687 for (var i = 0; i < 100; i++) {
688 set.add(i);
689 }
690
691 var accumulated = 0;
692 set.forEach(function(v) {
693 accumulated += v;
694 if (v % 10 === 0) {
695 gc();
696 }
697 });
698 assertEquals(4950, accumulated);
699})();
700
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400701
702(function TestSetForEachReceiverAsObject() {
703 var set = new Set(["1", "2"]);
704
705 // Create a new object in each function call when receiver is a
706 // primitive value. See ECMA-262, Annex C.
707 var a = [];
708 set.forEach(function() { a.push(this) }, "");
709 assertTrue(a[0] !== a[1]);
710
711 // Do not create a new object otherwise.
712 a = [];
713 set.forEach(function() { a.push(this); }, {});
714 assertEquals(a[0], a[1]);
715})();
716
717
718(function TestSetForEachReceiverAsObjectInStrictMode() {
719 var set = new Set(["1", "2"]);
720
721 // In strict mode primitive values should not be coerced to an object.
722 var a = [];
723 set.forEach(function() { 'use strict'; a.push(this); }, "");
724 assertTrue(a[0] === "" && a[0] === a[1]);
725})();
726
727
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000728(function TestMapForEachInvalidTypes() {
729 assertThrows(function() {
730 Map.prototype.map.forEach.call({});
731 }, TypeError);
732
733 var map = new Map();
734 assertThrows(function() {
735 map.forEach({});
736 }, TypeError);
737})();
738
739
740(function TestMapForEach() {
741 var map = new Map();
742 map.set(0, 'a');
743 map.set(1, 'b');
744 map.set(2, 'c');
745
746 var buffer = [];
747 var receiver = {};
748 map.forEach(function(v, k, m) {
749 assertEquals(map, m);
750 assertEquals(this, receiver);
751 buffer.push(k, v);
752 if (k === 0) {
753 map.delete(1);
754 map.set(3, 'd');
755 map.set(4, 'e');
756 map.set(5, 'f');
757 } else if (k === 2) {
758 map.set(1, 'B');
759 map.delete(4);
760 }
761 }, receiver);
762
763 assertArrayEquals([0, 'a', 2, 'c', 3, 'd', 5, 'f', 1, 'B'], buffer);
764})();
765
766
767(function TestMapForEachAddAtEnd() {
768 var map = new Map();
769 map.set(0, 'a');
770 map.set(1, 'b');
771
772 var buffer = [];
773 map.forEach(function(v, k) {
774 buffer.push(k, v);
775 if (k === 1) {
776 map.set(2, 'c');
777 }
778 });
779
780 assertArrayEquals([0, 'a', 1, 'b', 2, 'c'], buffer);
781})();
782
783
784(function TestMapForEachDeleteNext() {
785 var map = new Map();
786 map.set(0, 'a');
787 map.set(1, 'b');
788 map.set(2, 'c');
789
790 var buffer = [];
791 map.forEach(function(v, k) {
792 buffer.push(k, v);
793 if (k === 1) {
794 map.delete(2);
795 }
796 });
797
798 assertArrayEquals([0, 'a', 1, 'b'], buffer);
799})();
800
801
802(function TestSetForEachDeleteVisitedAndAddAgain() {
803 var map = new Map();
804 map.set(0, 'a');
805 map.set(1, 'b');
806 map.set(2, 'c');
807
808 var buffer = [];
809 map.forEach(function(v, k) {
810 buffer.push(k, v);
811 if (k === 1) {
812 map.delete(0);
813 } else if (k === 2) {
814 map.set(0, 'a');
815 }
816 });
817
818 assertArrayEquals([0, 'a', 1, 'b', 2, 'c', 0, 'a'], buffer);
819})();
820
821
822(function TestMapForEachClear() {
823 var map = new Map();
824 map.set(0, 'a');
825 map.set(1, 'b');
826 map.set(2, 'c');
827
828 var buffer = [];
829 map.forEach(function(v, k) {
830 buffer.push(k, v);
831 if (k === 0) {
832 map.clear();
833 map.set(3, 'd');
834 map.set(4, 'e');
835 }
836 });
837
838 assertArrayEquals([0, 'a', 3, 'd', 4, 'e'], buffer);
839})();
840
841
842(function TestMapForEachNested() {
843 var map = new Map();
844 map.set(0, 'a');
845 map.set(1, 'b');
846 map.set(2, 'c');
847
848 var buffer = [];
849 map.forEach(function(v, k) {
850 buffer.push(k, v);
851 map.forEach(function(v, k) {
852 buffer.push(k, v);
853 if (k === 0) {
854 map.delete(1);
855 }
856 });
857 });
858
859 assertArrayEquals([0, 'a', 0, 'a', 2, 'c', 2, 'c', 0, 'a', 2, 'c'], buffer);
860})();
861
862
863(function TestMapForEachEarlyExit() {
864 var map = new Map();
865 map.set(0, 'a');
866 map.set(1, 'b');
867 map.set(2, 'c');
868
869 var buffer = [];
870 var ex = {};
871 try {
872 map.forEach(function(v, k) {
873 buffer.push(k, v);
874 throw ex;
875 });
876 } catch (e) {
877 assertEquals(ex, e);
878 }
879 assertArrayEquals([0, 'a'], buffer);
880})();
881
882
883(function TestMapForEachGC() {
884 var map = new Map();
885 for (var i = 0; i < 100; i++) {
886 map.set(i, i);
887 }
888
889 var accumulated = 0;
890 map.forEach(function(v) {
891 accumulated += v;
892 if (v % 10 === 0) {
893 gc();
894 }
895 });
896 assertEquals(4950, accumulated);
897})();
898
899
900(function TestMapForEachAllRemovedTransition() {
901 var map = new Map;
902 map.set(0, 0);
903
904 var buffer = [];
905 map.forEach(function(v) {
906 buffer.push(v);
907 if (v === 0) {
908 for (var i = 1; i < 4; i++) {
909 map.set(i, i);
910 }
911 }
912
913 if (v === 3) {
914 for (var i = 0; i < 4; i++) {
915 map.delete(i);
916 }
917 for (var i = 4; i < 8; i++) {
918 map.set(i, i);
919 }
920 }
921 });
922
923 assertArrayEquals([0, 1, 2, 3, 4, 5, 6, 7], buffer);
924})();
925
926
927(function TestMapForEachClearTransition() {
928 var map = new Map;
929 map.set(0, 0);
930
931 var i = 0;
932 var buffer = [];
933 map.forEach(function(v) {
934 buffer.push(v);
935 if (++i < 5) {
936 for (var j = 0; j < 5; j++) {
937 map.clear();
938 map.set(i, i);
939 }
940 }
941 });
942
943 assertArrayEquals([0, 1, 2, 3, 4], buffer);
944})();
945
946
947(function TestMapForEachNestedNonTrivialTransition() {
948 var map = new Map;
949 map.set(0, 0);
950 map.set(1, 1);
951 map.set(2, 2);
952 map.set(3, 3);
953 map.delete(0);
954
955 var i = 0;
956 var buffer = [];
957 map.forEach(function(v) {
958 if (++i > 10) return;
959
960 buffer.push(v);
961
962 if (v == 3) {
963 map.delete(1);
964 for (var j = 4; j < 10; j++) {
965 map.set(j, j);
966 }
967 for (var j = 4; j < 10; j += 2) {
968 map.delete(j);
969 }
970 map.delete(2);
971
972 for (var j = 10; j < 20; j++) {
973 map.set(j, j);
974 }
975 for (var j = 10; j < 20; j += 2) {
976 map.delete(j);
977 }
978
979 map.delete(3);
980 }
981 });
982
983 assertArrayEquals([1, 2, 3, 5, 7, 9, 11, 13, 15, 17], buffer);
984})();
985
986
987(function TestMapForEachAllRemovedTransitionNoClear() {
988 var map = new Map;
989 map.set(0, 0);
990
991 var buffer = [];
992 map.forEach(function(v) {
993 buffer.push(v);
994 if (v === 0) {
995 for (var i = 1; i < 8; i++) {
996 map.set(i, i);
997 }
998 }
999
1000 if (v === 4) {
1001 for (var i = 0; i < 8; i++) {
1002 map.delete(i);
1003 }
1004 }
1005 });
1006
1007 assertArrayEquals([0, 1, 2, 3, 4], buffer);
1008})();
1009
1010
1011(function TestMapForEachNoMoreElementsAfterTransition() {
1012 var map = new Map;
1013 map.set(0, 0);
1014
1015 var buffer = [];
1016 map.forEach(function(v) {
1017 buffer.push(v);
1018 if (v === 0) {
1019 for (var i = 1; i < 16; i++) {
1020 map.set(i, i);
1021 }
1022 }
1023
1024 if (v === 4) {
1025 for (var i = 5; i < 16; i++) {
1026 map.delete(i);
1027 }
1028 }
1029 });
1030
1031 assertArrayEquals([0, 1, 2, 3, 4], buffer);
1032})();
1033
1034
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001035(function TestMapForEachReceiverAsObject() {
1036 var map = new Map();
1037 map.set("key1", "value1");
1038 map.set("key2", "value2");
1039
1040 // Create a new object in each function call when receiver is a
1041 // primitive value. See ECMA-262, Annex C.
1042 var a = [];
1043 map.forEach(function() { a.push(this) }, "");
1044 assertTrue(a[0] !== a[1]);
1045
1046 // Do not create a new object otherwise.
1047 a = [];
1048 map.forEach(function() { a.push(this); }, {});
1049 assertEquals(a[0], a[1]);
1050})();
1051
1052
1053(function TestMapForEachReceiverAsObjectInStrictMode() {
1054 var map = new Map();
1055 map.set("key1", "value1");
1056 map.set("key2", "value2");
1057
1058 // In strict mode primitive values should not be coerced to an object.
1059 var a = [];
1060 map.forEach(function() { 'use strict'; a.push(this); }, "");
1061 assertTrue(a[0] === "" && a[0] === a[1]);
1062})();
1063
1064
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001065// Allows testing iterator-based constructors easily.
1066var oneAndTwo = new Map();
1067var k0 = {key: 0};
1068var k1 = {key: 1};
1069var k2 = {key: 2};
1070oneAndTwo.set(k1, 1);
1071oneAndTwo.set(k2, 2);
1072
1073
1074function TestSetConstructor(ctor) {
1075 var s = new ctor(null);
1076 assertSize(0, s);
1077
1078 s = new ctor(undefined);
1079 assertSize(0, s);
1080
1081 // No @@iterator
1082 assertThrows(function() {
1083 new ctor({});
1084 }, TypeError);
1085 assertThrows(function() {
1086 new ctor(true);
1087 }, TypeError);
1088
1089 // @@iterator not callable
1090 assertThrows(function() {
1091 var object = {};
1092 object[Symbol.iterator] = 42;
1093 new ctor(object);
1094 }, TypeError);
1095
1096 // @@iterator result not object
1097 assertThrows(function() {
1098 var object = {};
1099 object[Symbol.iterator] = function() {
1100 return 42;
1101 };
1102 new ctor(object);
1103 }, TypeError);
1104
1105 var s2 = new Set();
1106 s2.add(k0);
1107 s2.add(k1);
1108 s2.add(k2);
1109 s = new ctor(s2.values());
1110 assertSize(3, s);
1111 assertTrue(s.has(k0));
1112 assertTrue(s.has(k1));
1113 assertTrue(s.has(k2));
1114}
1115TestSetConstructor(Set);
1116TestSetConstructor(WeakSet);
1117
1118
1119function TestSetConstructorAddNotCallable(ctor) {
1120 var originalPrototypeAdd = ctor.prototype.add;
1121 assertThrows(function() {
1122 ctor.prototype.add = 42;
1123 new ctor(oneAndTwo.values());
1124 }, TypeError);
1125 ctor.prototype.add = originalPrototypeAdd;
1126}
1127TestSetConstructorAddNotCallable(Set);
1128TestSetConstructorAddNotCallable(WeakSet);
1129
1130
1131function TestSetConstructorGetAddOnce(ctor) {
1132 var originalPrototypeAdd = ctor.prototype.add;
1133 var getAddCount = 0;
1134 Object.defineProperty(ctor.prototype, 'add', {
1135 get: function() {
1136 getAddCount++;
1137 return function() {};
1138 }
1139 });
1140 var s = new ctor(oneAndTwo.values());
1141 assertEquals(1, getAddCount);
1142 assertSize(0, s);
1143 Object.defineProperty(ctor.prototype, 'add', {
1144 value: originalPrototypeAdd,
1145 writable: true
1146 });
1147}
1148TestSetConstructorGetAddOnce(Set);
1149TestSetConstructorGetAddOnce(WeakSet);
1150
1151
1152function TestSetConstructorAddReplaced(ctor) {
1153 var originalPrototypeAdd = ctor.prototype.add;
1154 var addCount = 0;
1155 ctor.prototype.add = function(value) {
1156 addCount++;
1157 originalPrototypeAdd.call(this, value);
1158 ctor.prototype.add = null;
1159 };
1160 var s = new ctor(oneAndTwo.keys());
1161 assertEquals(2, addCount);
1162 assertSize(2, s);
1163 ctor.prototype.add = originalPrototypeAdd;
1164}
1165TestSetConstructorAddReplaced(Set);
1166TestSetConstructorAddReplaced(WeakSet);
1167
1168
1169function TestSetConstructorOrderOfDoneValue(ctor) {
1170 var valueCount = 0, doneCount = 0;
1171 var iterator = {
1172 next: function() {
1173 return {
1174 get value() {
1175 valueCount++;
1176 },
1177 get done() {
1178 doneCount++;
1179 throw new Error();
1180 }
1181 };
1182 }
1183 };
1184 iterator[Symbol.iterator] = function() {
1185 return this;
1186 };
1187 assertThrows(function() {
1188 new ctor(iterator);
1189 });
1190 assertEquals(1, doneCount);
1191 assertEquals(0, valueCount);
1192}
1193TestSetConstructorOrderOfDoneValue(Set);
1194TestSetConstructorOrderOfDoneValue(WeakSet);
1195
1196
1197function TestSetConstructorNextNotAnObject(ctor) {
1198 var iterator = {
1199 next: function() {
1200 return 'abc';
1201 }
1202 };
1203 iterator[Symbol.iterator] = function() {
1204 return this;
1205 };
1206 assertThrows(function() {
1207 new ctor(iterator);
1208 }, TypeError);
1209}
1210TestSetConstructorNextNotAnObject(Set);
1211TestSetConstructorNextNotAnObject(WeakSet);
1212
1213
1214(function TestWeakSetConstructorNonObjectKeys() {
1215 assertThrows(function() {
1216 new WeakSet([1]);
1217 }, TypeError);
1218})();
1219
1220
1221function TestSetConstructorIterableValue(ctor) {
1222 'use strict';
1223 // Strict mode is required to prevent implicit wrapping in the getter.
1224 Object.defineProperty(Number.prototype, Symbol.iterator, {
1225 get: function() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001226 assertEquals('number', typeof this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001227 return function() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001228 assertEquals('number', typeof this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001229 return oneAndTwo.keys();
1230 };
1231 },
1232 configurable: true
1233 });
1234
1235 var set = new ctor(42);
1236 assertSize(2, set);
1237 assertTrue(set.has(k1));
1238 assertTrue(set.has(k2));
1239
1240 delete Number.prototype[Symbol.iterator];
1241}
1242TestSetConstructorIterableValue(Set);
1243TestSetConstructorIterableValue(WeakSet);
1244
1245
1246(function TestSetConstructorStringValue() {
1247 var s = new Set('abc');
1248 assertSize(3, s);
1249 assertTrue(s.has('a'));
1250 assertTrue(s.has('b'));
1251 assertTrue(s.has('c'));
1252})();
1253
1254
1255function TestMapConstructor(ctor) {
1256 var m = new ctor(null);
1257 assertSize(0, m);
1258
1259 m = new ctor(undefined);
1260 assertSize(0, m);
1261
1262 // No @@iterator
1263 assertThrows(function() {
1264 new ctor({});
1265 }, TypeError);
1266 assertThrows(function() {
1267 new ctor(true);
1268 }, TypeError);
1269
1270 // @@iterator not callable
1271 assertThrows(function() {
1272 var object = {};
1273 object[Symbol.iterator] = 42;
1274 new ctor(object);
1275 }, TypeError);
1276
1277 // @@iterator result not object
1278 assertThrows(function() {
1279 var object = {};
1280 object[Symbol.iterator] = function() {
1281 return 42;
1282 };
1283 new ctor(object);
1284 }, TypeError);
1285
1286 var m2 = new Map();
1287 m2.set(k0, 'a');
1288 m2.set(k1, 'b');
1289 m2.set(k2, 'c');
1290 m = new ctor(m2.entries());
1291 assertSize(3, m);
1292 assertEquals('a', m.get(k0));
1293 assertEquals('b', m.get(k1));
1294 assertEquals('c', m.get(k2));
1295}
1296TestMapConstructor(Map);
1297TestMapConstructor(WeakMap);
1298
1299
1300function TestMapConstructorSetNotCallable(ctor) {
1301 var originalPrototypeSet = ctor.prototype.set;
1302 assertThrows(function() {
1303 ctor.prototype.set = 42;
1304 new ctor(oneAndTwo.entries());
1305 }, TypeError);
1306 ctor.prototype.set = originalPrototypeSet;
1307}
1308TestMapConstructorSetNotCallable(Map);
1309TestMapConstructorSetNotCallable(WeakMap);
1310
1311
1312function TestMapConstructorGetAddOnce(ctor) {
1313 var originalPrototypeSet = ctor.prototype.set;
1314 var getSetCount = 0;
1315 Object.defineProperty(ctor.prototype, 'set', {
1316 get: function() {
1317 getSetCount++;
1318 return function() {};
1319 }
1320 });
1321 var m = new ctor(oneAndTwo.entries());
1322 assertEquals(1, getSetCount);
1323 assertSize(0, m);
1324 Object.defineProperty(ctor.prototype, 'set', {
1325 value: originalPrototypeSet,
1326 writable: true
1327 });
1328}
1329TestMapConstructorGetAddOnce(Map);
1330TestMapConstructorGetAddOnce(WeakMap);
1331
1332
1333function TestMapConstructorSetReplaced(ctor) {
1334 var originalPrototypeSet = ctor.prototype.set;
1335 var setCount = 0;
1336 ctor.prototype.set = function(key, value) {
1337 setCount++;
1338 originalPrototypeSet.call(this, key, value);
1339 ctor.prototype.set = null;
1340 };
1341 var m = new ctor(oneAndTwo.entries());
1342 assertEquals(2, setCount);
1343 assertSize(2, m);
1344 ctor.prototype.set = originalPrototypeSet;
1345}
1346TestMapConstructorSetReplaced(Map);
1347TestMapConstructorSetReplaced(WeakMap);
1348
1349
1350function TestMapConstructorOrderOfDoneValue(ctor) {
1351 var valueCount = 0, doneCount = 0;
1352 function FakeError() {}
1353 var iterator = {
1354 next: function() {
1355 return {
1356 get value() {
1357 valueCount++;
1358 },
1359 get done() {
1360 doneCount++;
1361 throw new FakeError();
1362 }
1363 };
1364 }
1365 };
1366 iterator[Symbol.iterator] = function() {
1367 return this;
1368 };
1369 assertThrows(function() {
1370 new ctor(iterator);
1371 }, FakeError);
1372 assertEquals(1, doneCount);
1373 assertEquals(0, valueCount);
1374}
1375TestMapConstructorOrderOfDoneValue(Map);
1376TestMapConstructorOrderOfDoneValue(WeakMap);
1377
1378
1379function TestMapConstructorNextNotAnObject(ctor) {
1380 var iterator = {
1381 next: function() {
1382 return 'abc';
1383 }
1384 };
1385 iterator[Symbol.iterator] = function() {
1386 return this;
1387 };
1388 assertThrows(function() {
1389 new ctor(iterator);
1390 }, TypeError);
1391}
1392TestMapConstructorNextNotAnObject(Map);
1393TestMapConstructorNextNotAnObject(WeakMap);
1394
1395
1396function TestMapConstructorIteratorNotObjectValues(ctor) {
1397 assertThrows(function() {
1398 new ctor(oneAndTwo.values());
1399 }, TypeError);
1400}
1401TestMapConstructorIteratorNotObjectValues(Map);
1402TestMapConstructorIteratorNotObjectValues(WeakMap);
1403
1404
1405(function TestWeakMapConstructorNonObjectKeys() {
1406 assertThrows(function() {
1407 new WeakMap([[1, 2]])
1408 }, TypeError);
1409})();
1410
1411
1412function TestMapConstructorIterableValue(ctor) {
1413 'use strict';
1414 // Strict mode is required to prevent implicit wrapping in the getter.
1415 Object.defineProperty(Number.prototype, Symbol.iterator, {
1416 get: function() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001417 assertEquals('number', typeof this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001418 return function() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001419 assertEquals('number', typeof this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001420 return oneAndTwo.entries();
1421 };
1422 },
1423 configurable: true
1424 });
1425
1426 var map = new ctor(42);
1427 assertSize(2, map);
1428 assertEquals(1, map.get(k1));
1429 assertEquals(2, map.get(k2));
1430
1431 delete Number.prototype[Symbol.iterator];
1432}
1433TestMapConstructorIterableValue(Map);
1434TestMapConstructorIterableValue(WeakMap);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001435
1436function TestCollectionToString(C) {
1437 assertEquals("[object " + C.name + "]",
1438 Object.prototype.toString.call(new C()));
1439}
1440TestCollectionToString(Map);
1441TestCollectionToString(Set);
1442TestCollectionToString(WeakMap);
1443TestCollectionToString(WeakSet);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001444
1445
1446function TestConstructorOrderOfAdderIterator(ctor, adderName) {
1447 var iterable = new Map();
1448 iterable.set({}, {});
1449 iterable.set({}, {});
1450 var iterableFunction = iterable[Symbol.iterator];
1451 Object.defineProperty(iterable, Symbol.iterator, {
1452 get: function() {
1453 log += 'iterator';
1454 return iterableFunction;
1455 }
1456 });
1457
1458 var log = '';
1459 var adderFunction = ctor.prototype[adderName];
1460
1461 Object.defineProperty(ctor.prototype, adderName, {
1462 get: function() {
1463 log += adderName;
1464 return adderFunction;
1465 }
1466 });
1467
1468 new ctor(iterable);
1469 assertEquals(adderName + 'iterator', log);
1470
1471 Object.defineProperty(ctor.prototype, adderName, {
1472 value: adderFunction
1473 });
1474}
1475TestConstructorOrderOfAdderIterator(Map, 'set');
1476TestConstructorOrderOfAdderIterator(Set, 'add');
1477TestConstructorOrderOfAdderIterator(WeakMap, 'set');
1478TestConstructorOrderOfAdderIterator(WeakSet, 'add');