| OLD | NEW |
| (Empty) |
| 1 // 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 | |
| 28 // Flags: --harmony-collections --harmony-iteration | |
| 29 // Flags: --expose-gc --allow-natives-syntax | |
| 30 | |
| 31 | |
| 32 // Test valid getter and setter calls on Sets and WeakSets | |
| 33 function TestValidSetCalls(m) { | |
| 34 assertDoesNotThrow(function () { m.add(new Object) }); | |
| 35 assertDoesNotThrow(function () { m.has(new Object) }); | |
| 36 assertDoesNotThrow(function () { m.delete(new Object) }); | |
| 37 } | |
| 38 TestValidSetCalls(new Set); | |
| 39 TestValidSetCalls(new WeakSet); | |
| 40 | |
| 41 | |
| 42 // Test valid getter and setter calls on Maps and WeakMaps | |
| 43 function TestValidMapCalls(m) { | |
| 44 assertDoesNotThrow(function () { m.get(new Object) }); | |
| 45 assertDoesNotThrow(function () { m.set(new Object) }); | |
| 46 assertDoesNotThrow(function () { m.has(new Object) }); | |
| 47 assertDoesNotThrow(function () { m.delete(new Object) }); | |
| 48 } | |
| 49 TestValidMapCalls(new Map); | |
| 50 TestValidMapCalls(new WeakMap); | |
| 51 | |
| 52 | |
| 53 // Test invalid getter and setter calls for WeakMap only | |
| 54 function TestInvalidCalls(m) { | |
| 55 assertThrows(function () { m.get(undefined) }, TypeError); | |
| 56 assertThrows(function () { m.set(undefined, 0) }, TypeError); | |
| 57 assertThrows(function () { m.get(null) }, TypeError); | |
| 58 assertThrows(function () { m.set(null, 0) }, TypeError); | |
| 59 assertThrows(function () { m.get(0) }, TypeError); | |
| 60 assertThrows(function () { m.set(0, 0) }, TypeError); | |
| 61 assertThrows(function () { m.get('a-key') }, TypeError); | |
| 62 assertThrows(function () { m.set('a-key', 0) }, TypeError); | |
| 63 } | |
| 64 TestInvalidCalls(new WeakMap); | |
| 65 | |
| 66 | |
| 67 // Test expected behavior for Sets and WeakSets | |
| 68 function TestSet(set, key) { | |
| 69 assertFalse(set.has(key)); | |
| 70 assertSame(set, set.add(key)); | |
| 71 assertTrue(set.has(key)); | |
| 72 assertTrue(set.delete(key)); | |
| 73 assertFalse(set.has(key)); | |
| 74 assertFalse(set.delete(key)); | |
| 75 assertFalse(set.has(key)); | |
| 76 } | |
| 77 function TestSetBehavior(set) { | |
| 78 for (var i = 0; i < 20; i++) { | |
| 79 TestSet(set, new Object); | |
| 80 TestSet(set, i); | |
| 81 TestSet(set, i / 100); | |
| 82 TestSet(set, 'key-' + i); | |
| 83 } | |
| 84 var keys = [ +0, -0, +Infinity, -Infinity, true, false, null, undefined ]; | |
| 85 for (var i = 0; i < keys.length; i++) { | |
| 86 TestSet(set, keys[i]); | |
| 87 } | |
| 88 } | |
| 89 TestSetBehavior(new Set); | |
| 90 TestSet(new WeakSet, new Object); | |
| 91 | |
| 92 | |
| 93 // Test expected mapping behavior for Maps and WeakMaps | |
| 94 function TestMapping(map, key, value) { | |
| 95 assertSame(map, map.set(key, value)); | |
| 96 assertSame(value, map.get(key)); | |
| 97 } | |
| 98 function TestMapBehavior1(m) { | |
| 99 TestMapping(m, new Object, 23); | |
| 100 TestMapping(m, new Object, 'the-value'); | |
| 101 TestMapping(m, new Object, new Object); | |
| 102 } | |
| 103 TestMapBehavior1(new Map); | |
| 104 TestMapBehavior1(new WeakMap); | |
| 105 | |
| 106 | |
| 107 // Test expected mapping behavior for Maps only | |
| 108 function TestMapBehavior2(m) { | |
| 109 for (var i = 0; i < 20; i++) { | |
| 110 TestMapping(m, i, new Object); | |
| 111 TestMapping(m, i / 10, new Object); | |
| 112 TestMapping(m, 'key-' + i, new Object); | |
| 113 } | |
| 114 var keys = [ +0, -0, +Infinity, -Infinity, true, false, null, undefined ]; | |
| 115 for (var i = 0; i < keys.length; i++) { | |
| 116 TestMapping(m, keys[i], new Object); | |
| 117 } | |
| 118 } | |
| 119 TestMapBehavior2(new Map); | |
| 120 | |
| 121 | |
| 122 // Test expected querying behavior of Maps and WeakMaps | |
| 123 function TestQuery(m) { | |
| 124 var key = new Object; | |
| 125 var values = [ 'x', 0, +Infinity, -Infinity, true, false, null, undefined ]; | |
| 126 for (var i = 0; i < values.length; i++) { | |
| 127 TestMapping(m, key, values[i]); | |
| 128 assertTrue(m.has(key)); | |
| 129 assertFalse(m.has(new Object)); | |
| 130 } | |
| 131 } | |
| 132 TestQuery(new Map); | |
| 133 TestQuery(new WeakMap); | |
| 134 | |
| 135 | |
| 136 // Test expected deletion behavior of Maps and WeakMaps | |
| 137 function TestDelete(m) { | |
| 138 var key = new Object; | |
| 139 TestMapping(m, key, 'to-be-deleted'); | |
| 140 assertTrue(m.delete(key)); | |
| 141 assertFalse(m.delete(key)); | |
| 142 assertFalse(m.delete(new Object)); | |
| 143 assertSame(m.get(key), undefined); | |
| 144 } | |
| 145 TestDelete(new Map); | |
| 146 TestDelete(new WeakMap); | |
| 147 | |
| 148 | |
| 149 // Test GC of Maps and WeakMaps with entry | |
| 150 function TestGC1(m) { | |
| 151 var key = new Object; | |
| 152 m.set(key, 'not-collected'); | |
| 153 gc(); | |
| 154 assertSame('not-collected', m.get(key)); | |
| 155 } | |
| 156 TestGC1(new Map); | |
| 157 TestGC1(new WeakMap); | |
| 158 | |
| 159 | |
| 160 // Test GC of Maps and WeakMaps with chained entries | |
| 161 function TestGC2(m) { | |
| 162 var head = new Object; | |
| 163 for (key = head, i = 0; i < 10; i++, key = m.get(key)) { | |
| 164 m.set(key, new Object); | |
| 165 } | |
| 166 gc(); | |
| 167 var count = 0; | |
| 168 for (key = head; key != undefined; key = m.get(key)) { | |
| 169 count++; | |
| 170 } | |
| 171 assertEquals(11, count); | |
| 172 } | |
| 173 TestGC2(new Map); | |
| 174 TestGC2(new WeakMap); | |
| 175 | |
| 176 | |
| 177 // Test property attribute [[Enumerable]] | |
| 178 function TestEnumerable(func) { | |
| 179 function props(x) { | |
| 180 var array = []; | |
| 181 for (var p in x) array.push(p); | |
| 182 return array.sort(); | |
| 183 } | |
| 184 assertArrayEquals([], props(func)); | |
| 185 assertArrayEquals([], props(func.prototype)); | |
| 186 assertArrayEquals([], props(new func())); | |
| 187 } | |
| 188 TestEnumerable(Set); | |
| 189 TestEnumerable(Map); | |
| 190 TestEnumerable(WeakMap); | |
| 191 TestEnumerable(WeakSet); | |
| 192 | |
| 193 | |
| 194 // Test arbitrary properties on Maps and WeakMaps | |
| 195 function TestArbitrary(m) { | |
| 196 function TestProperty(map, property, value) { | |
| 197 map[property] = value; | |
| 198 assertEquals(value, map[property]); | |
| 199 } | |
| 200 for (var i = 0; i < 20; i++) { | |
| 201 TestProperty(m, i, 'val' + i); | |
| 202 TestProperty(m, 'foo' + i, 'bar' + i); | |
| 203 } | |
| 204 TestMapping(m, new Object, 'foobar'); | |
| 205 } | |
| 206 TestArbitrary(new Map); | |
| 207 TestArbitrary(new WeakMap); | |
| 208 | |
| 209 | |
| 210 // Test direct constructor call | |
| 211 assertThrows(function() { Set(); }, TypeError); | |
| 212 assertThrows(function() { Map(); }, TypeError); | |
| 213 assertThrows(function() { WeakMap(); }, TypeError); | |
| 214 assertThrows(function() { WeakSet(); }, TypeError); | |
| 215 | |
| 216 | |
| 217 // Test whether NaN values as keys are treated correctly. | |
| 218 var s = new Set; | |
| 219 assertFalse(s.has(NaN)); | |
| 220 assertFalse(s.has(NaN + 1)); | |
| 221 assertFalse(s.has(23)); | |
| 222 s.add(NaN); | |
| 223 assertTrue(s.has(NaN)); | |
| 224 assertTrue(s.has(NaN + 1)); | |
| 225 assertFalse(s.has(23)); | |
| 226 var m = new Map; | |
| 227 assertFalse(m.has(NaN)); | |
| 228 assertFalse(m.has(NaN + 1)); | |
| 229 assertFalse(m.has(23)); | |
| 230 m.set(NaN, 'a-value'); | |
| 231 assertTrue(m.has(NaN)); | |
| 232 assertTrue(m.has(NaN + 1)); | |
| 233 assertFalse(m.has(23)); | |
| 234 | |
| 235 | |
| 236 // Test some common JavaScript idioms for Sets | |
| 237 var s = new Set; | |
| 238 assertTrue(s instanceof Set); | |
| 239 assertTrue(Set.prototype.add instanceof Function) | |
| 240 assertTrue(Set.prototype.has instanceof Function) | |
| 241 assertTrue(Set.prototype.delete instanceof Function) | |
| 242 assertTrue(Set.prototype.clear instanceof Function) | |
| 243 | |
| 244 | |
| 245 // Test some common JavaScript idioms for Maps | |
| 246 var m = new Map; | |
| 247 assertTrue(m instanceof Map); | |
| 248 assertTrue(Map.prototype.set instanceof Function) | |
| 249 assertTrue(Map.prototype.get instanceof Function) | |
| 250 assertTrue(Map.prototype.has instanceof Function) | |
| 251 assertTrue(Map.prototype.delete instanceof Function) | |
| 252 assertTrue(Map.prototype.clear instanceof Function) | |
| 253 | |
| 254 | |
| 255 // Test some common JavaScript idioms for WeakMaps | |
| 256 var m = new WeakMap; | |
| 257 assertTrue(m instanceof WeakMap); | |
| 258 assertTrue(WeakMap.prototype.set instanceof Function) | |
| 259 assertTrue(WeakMap.prototype.get instanceof Function) | |
| 260 assertTrue(WeakMap.prototype.has instanceof Function) | |
| 261 assertTrue(WeakMap.prototype.delete instanceof Function) | |
| 262 assertTrue(WeakMap.prototype.clear instanceof Function) | |
| 263 | |
| 264 | |
| 265 // Test some common JavaScript idioms for WeakSets | |
| 266 var s = new WeakSet; | |
| 267 assertTrue(s instanceof WeakSet); | |
| 268 assertTrue(WeakSet.prototype.add instanceof Function) | |
| 269 assertTrue(WeakSet.prototype.has instanceof Function) | |
| 270 assertTrue(WeakSet.prototype.delete instanceof Function) | |
| 271 assertTrue(WeakSet.prototype.clear instanceof Function) | |
| 272 | |
| 273 | |
| 274 // Test class of instance and prototype. | |
| 275 assertEquals("Set", %_ClassOf(new Set)) | |
| 276 assertEquals("Object", %_ClassOf(Set.prototype)) | |
| 277 assertEquals("Map", %_ClassOf(new Map)) | |
| 278 assertEquals("Object", %_ClassOf(Map.prototype)) | |
| 279 assertEquals("WeakMap", %_ClassOf(new WeakMap)) | |
| 280 assertEquals("Object", %_ClassOf(WeakMap.prototype)) | |
| 281 assertEquals("WeakSet", %_ClassOf(new WeakSet)) | |
| 282 assertEquals("Object", %_ClassOf(WeakMap.prototype)) | |
| 283 | |
| 284 | |
| 285 // Test name of constructor. | |
| 286 assertEquals("Set", Set.name); | |
| 287 assertEquals("Map", Map.name); | |
| 288 assertEquals("WeakMap", WeakMap.name); | |
| 289 assertEquals("WeakSet", WeakSet.name); | |
| 290 | |
| 291 | |
| 292 // Test prototype property of Set, Map, WeakMap and WeakSet. | |
| 293 // TODO(2793): Should all be non-writable, and the extra flag removed. | |
| 294 function TestPrototype(C, writable) { | |
| 295 assertTrue(C.prototype instanceof Object); | |
| 296 assertEquals({ | |
| 297 value: {}, | |
| 298 writable: writable, | |
| 299 enumerable: false, | |
| 300 configurable: false | |
| 301 }, Object.getOwnPropertyDescriptor(C, "prototype")); | |
| 302 } | |
| 303 TestPrototype(Set, true); | |
| 304 TestPrototype(Map, true); | |
| 305 TestPrototype(WeakMap, false); | |
| 306 TestPrototype(WeakSet, false); | |
| 307 | |
| 308 | |
| 309 // Test constructor property of the Set, Map, WeakMap and WeakSet prototype. | |
| 310 function TestConstructor(C) { | |
| 311 assertFalse(C === Object.prototype.constructor); | |
| 312 assertSame(C, C.prototype.constructor); | |
| 313 assertSame(C, (new C).__proto__.constructor); | |
| 314 } | |
| 315 TestConstructor(Set); | |
| 316 TestConstructor(Map); | |
| 317 TestConstructor(WeakMap); | |
| 318 TestConstructor(WeakSet); | |
| 319 | |
| 320 | |
| 321 // Test the Set, Map, WeakMap and WeakSet global properties themselves. | |
| 322 function TestDescriptor(global, C) { | |
| 323 assertEquals({ | |
| 324 value: C, | |
| 325 writable: true, | |
| 326 enumerable: false, | |
| 327 configurable: true | |
| 328 }, Object.getOwnPropertyDescriptor(global, C.name)); | |
| 329 } | |
| 330 TestDescriptor(this, Set); | |
| 331 TestDescriptor(this, Map); | |
| 332 TestDescriptor(this, WeakMap); | |
| 333 TestDescriptor(this, WeakSet); | |
| 334 | |
| 335 | |
| 336 // Regression test for WeakMap prototype. | |
| 337 assertTrue(WeakMap.prototype.constructor === WeakMap) | |
| 338 assertTrue(Object.getPrototypeOf(WeakMap.prototype) === Object.prototype) | |
| 339 | |
| 340 | |
| 341 // Regression test for issue 1617: The prototype of the WeakMap constructor | |
| 342 // needs to be unique (i.e. different from the one of the Object constructor). | |
| 343 assertFalse(WeakMap.prototype === Object.prototype); | |
| 344 var o = Object.create({}); | |
| 345 assertFalse("get" in o); | |
| 346 assertFalse("set" in o); | |
| 347 assertEquals(undefined, o.get); | |
| 348 assertEquals(undefined, o.set); | |
| 349 var o = Object.create({}, { myValue: { | |
| 350 value: 10, | |
| 351 enumerable: false, | |
| 352 configurable: true, | |
| 353 writable: true | |
| 354 }}); | |
| 355 assertEquals(10, o.myValue); | |
| 356 | |
| 357 | |
| 358 // Regression test for issue 1884: Invoking any of the methods for Harmony | |
| 359 // maps, sets, or weak maps, with a wrong type of receiver should be throwing | |
| 360 // a proper TypeError. | |
| 361 var alwaysBogus = [ undefined, null, true, "x", 23, {} ]; | |
| 362 var bogusReceiversTestSet = [ | |
| 363 { proto: Set.prototype, | |
| 364 funcs: [ 'add', 'has', 'delete' ], | |
| 365 receivers: alwaysBogus.concat([ new Map, new WeakMap, new WeakSet ]), | |
| 366 }, | |
| 367 { proto: Map.prototype, | |
| 368 funcs: [ 'get', 'set', 'has', 'delete' ], | |
| 369 receivers: alwaysBogus.concat([ new Set, new WeakMap, new WeakSet ]), | |
| 370 }, | |
| 371 { proto: WeakMap.prototype, | |
| 372 funcs: [ 'get', 'set', 'has', 'delete' ], | |
| 373 receivers: alwaysBogus.concat([ new Set, new Map, new WeakSet ]), | |
| 374 }, | |
| 375 { proto: WeakSet.prototype, | |
| 376 funcs: [ 'add', 'has', 'delete' ], | |
| 377 receivers: alwaysBogus.concat([ new Set, new Map, new WeakMap ]), | |
| 378 }, | |
| 379 ]; | |
| 380 function TestBogusReceivers(testSet) { | |
| 381 for (var i = 0; i < testSet.length; i++) { | |
| 382 var proto = testSet[i].proto; | |
| 383 var funcs = testSet[i].funcs; | |
| 384 var receivers = testSet[i].receivers; | |
| 385 for (var j = 0; j < funcs.length; j++) { | |
| 386 var func = proto[funcs[j]]; | |
| 387 for (var k = 0; k < receivers.length; k++) { | |
| 388 assertThrows(function () { func.call(receivers[k], {}) }, TypeError); | |
| 389 } | |
| 390 } | |
| 391 } | |
| 392 } | |
| 393 TestBogusReceivers(bogusReceiversTestSet); | |
| 394 | |
| 395 | |
| 396 // Stress Test | |
| 397 // There is a proposed stress-test available at the es-discuss mailing list | |
| 398 // which cannot be reasonably automated. Check it out by hand if you like: | |
| 399 // https://mail.mozilla.org/pipermail/es-discuss/2011-May/014096.html | |
| 400 | |
| 401 | |
| 402 // Set and Map size getters | |
| 403 var setSizeDescriptor = Object.getOwnPropertyDescriptor(Set.prototype, 'size'); | |
| 404 assertEquals(undefined, setSizeDescriptor.value); | |
| 405 assertEquals(undefined, setSizeDescriptor.set); | |
| 406 assertTrue(setSizeDescriptor.get instanceof Function); | |
| 407 assertEquals(undefined, setSizeDescriptor.get.prototype); | |
| 408 assertFalse(setSizeDescriptor.enumerable); | |
| 409 assertTrue(setSizeDescriptor.configurable); | |
| 410 | |
| 411 var s = new Set(); | |
| 412 assertFalse(s.hasOwnProperty('size')); | |
| 413 for (var i = 0; i < 10; i++) { | |
| 414 assertEquals(i, s.size); | |
| 415 s.add(i); | |
| 416 } | |
| 417 for (var i = 9; i >= 0; i--) { | |
| 418 s.delete(i); | |
| 419 assertEquals(i, s.size); | |
| 420 } | |
| 421 | |
| 422 | |
| 423 var mapSizeDescriptor = Object.getOwnPropertyDescriptor(Map.prototype, 'size'); | |
| 424 assertEquals(undefined, mapSizeDescriptor.value); | |
| 425 assertEquals(undefined, mapSizeDescriptor.set); | |
| 426 assertTrue(mapSizeDescriptor.get instanceof Function); | |
| 427 assertEquals(undefined, mapSizeDescriptor.get.prototype); | |
| 428 assertFalse(mapSizeDescriptor.enumerable); | |
| 429 assertTrue(mapSizeDescriptor.configurable); | |
| 430 | |
| 431 var m = new Map(); | |
| 432 assertFalse(m.hasOwnProperty('size')); | |
| 433 for (var i = 0; i < 10; i++) { | |
| 434 assertEquals(i, m.size); | |
| 435 m.set(i, i); | |
| 436 } | |
| 437 for (var i = 9; i >= 0; i--) { | |
| 438 m.delete(i); | |
| 439 assertEquals(i, m.size); | |
| 440 } | |
| 441 | |
| 442 | |
| 443 // Test Set clear | |
| 444 (function() { | |
| 445 var s = new Set(); | |
| 446 s.add(42); | |
| 447 assertTrue(s.has(42)); | |
| 448 assertEquals(1, s.size); | |
| 449 s.clear(); | |
| 450 assertFalse(s.has(42)); | |
| 451 assertEquals(0, s.size); | |
| 452 })(); | |
| 453 | |
| 454 | |
| 455 // Test Map clear | |
| 456 (function() { | |
| 457 var m = new Map(); | |
| 458 m.set(42, true); | |
| 459 assertTrue(m.has(42)); | |
| 460 assertEquals(1, m.size); | |
| 461 m.clear(); | |
| 462 assertFalse(m.has(42)); | |
| 463 assertEquals(0, m.size); | |
| 464 })(); | |
| 465 | |
| 466 | |
| 467 // Test WeakMap clear | |
| 468 (function() { | |
| 469 var k = new Object(); | |
| 470 var w = new WeakMap(); | |
| 471 w.set(k, 23); | |
| 472 assertTrue(w.has(k)); | |
| 473 assertEquals(23, w.get(k)); | |
| 474 w.clear(); | |
| 475 assertFalse(w.has(k)); | |
| 476 assertEquals(undefined, w.get(k)); | |
| 477 })(); | |
| 478 | |
| 479 | |
| 480 // Test WeakSet clear | |
| 481 (function() { | |
| 482 var k = new Object(); | |
| 483 var w = new WeakSet(); | |
| 484 w.add(k); | |
| 485 assertTrue(w.has(k)); | |
| 486 w.clear(); | |
| 487 assertFalse(w.has(k)); | |
| 488 })(); | |
| 489 | |
| 490 | |
| 491 (function TestMinusZeroSet() { | |
| 492 var m = new Set(); | |
| 493 m.add(0); | |
| 494 m.add(-0); | |
| 495 assertEquals(1, m.size); | |
| 496 assertTrue(m.has(0)); | |
| 497 assertTrue(m.has(-0)); | |
| 498 })(); | |
| 499 | |
| 500 | |
| 501 (function TestMinusZeroMap() { | |
| 502 var m = new Map(); | |
| 503 m.set(0, 'plus'); | |
| 504 m.set(-0, 'minus'); | |
| 505 assertEquals(1, m.size); | |
| 506 assertTrue(m.has(0)); | |
| 507 assertTrue(m.has(-0)); | |
| 508 assertEquals('minus', m.get(0)); | |
| 509 assertEquals('minus', m.get(-0)); | |
| 510 })(); | |
| 511 | |
| 512 | |
| 513 (function TestSetForEachInvalidTypes() { | |
| 514 assertThrows(function() { | |
| 515 Set.prototype.set.forEach.call({}); | |
| 516 }, TypeError); | |
| 517 | |
| 518 var set = new Set(); | |
| 519 assertThrows(function() { | |
| 520 set.forEach({}); | |
| 521 }, TypeError); | |
| 522 })(); | |
| 523 | |
| 524 | |
| 525 (function TestSetForEach() { | |
| 526 var set = new Set(); | |
| 527 set.add('a'); | |
| 528 set.add('b'); | |
| 529 set.add('c'); | |
| 530 | |
| 531 var buffer = ''; | |
| 532 var receiver = {}; | |
| 533 set.forEach(function(v, k, s) { | |
| 534 assertSame(v, k); | |
| 535 assertSame(set, s); | |
| 536 assertSame(this, receiver); | |
| 537 buffer += v; | |
| 538 if (v === 'a') { | |
| 539 set.delete('b'); | |
| 540 set.add('d'); | |
| 541 set.add('e'); | |
| 542 set.add('f'); | |
| 543 } else if (v === 'c') { | |
| 544 set.add('b'); | |
| 545 set.delete('e'); | |
| 546 } | |
| 547 }, receiver); | |
| 548 | |
| 549 assertEquals('acdfb', buffer); | |
| 550 })(); | |
| 551 | |
| 552 | |
| 553 (function TestSetForEachAddAtEnd() { | |
| 554 var set = new Set(); | |
| 555 set.add('a'); | |
| 556 set.add('b'); | |
| 557 | |
| 558 var buffer = ''; | |
| 559 set.forEach(function(v) { | |
| 560 buffer += v; | |
| 561 if (v === 'b') { | |
| 562 set.add('c'); | |
| 563 } | |
| 564 }); | |
| 565 | |
| 566 assertEquals('abc', buffer); | |
| 567 })(); | |
| 568 | |
| 569 | |
| 570 (function TestSetForEachDeleteNext() { | |
| 571 var set = new Set(); | |
| 572 set.add('a'); | |
| 573 set.add('b'); | |
| 574 set.add('c'); | |
| 575 | |
| 576 var buffer = ''; | |
| 577 set.forEach(function(v) { | |
| 578 buffer += v; | |
| 579 if (v === 'b') { | |
| 580 set.delete('c'); | |
| 581 } | |
| 582 }); | |
| 583 | |
| 584 assertEquals('ab', buffer); | |
| 585 })(); | |
| 586 | |
| 587 | |
| 588 (function TestSetForEachDeleteVisitedAndAddAgain() { | |
| 589 var set = new Set(); | |
| 590 set.add('a'); | |
| 591 set.add('b'); | |
| 592 set.add('c'); | |
| 593 | |
| 594 var buffer = ''; | |
| 595 set.forEach(function(v) { | |
| 596 buffer += v; | |
| 597 if (v === 'b') { | |
| 598 set.delete('a'); | |
| 599 } else if (v === 'c') { | |
| 600 set.add('a'); | |
| 601 } | |
| 602 }); | |
| 603 | |
| 604 assertEquals('abca', buffer); | |
| 605 })(); | |
| 606 | |
| 607 | |
| 608 (function TestSetForEachClear() { | |
| 609 var set = new Set(); | |
| 610 set.add('a'); | |
| 611 set.add('b'); | |
| 612 set.add('c'); | |
| 613 | |
| 614 var buffer = ''; | |
| 615 set.forEach(function(v) { | |
| 616 buffer += v; | |
| 617 if (v === 'a') { | |
| 618 set.clear(); | |
| 619 set.add('d'); | |
| 620 set.add('e'); | |
| 621 } | |
| 622 }); | |
| 623 | |
| 624 assertEquals('ade', buffer); | |
| 625 })(); | |
| 626 | |
| 627 | |
| 628 (function TestSetForEachNested() { | |
| 629 var set = new Set(); | |
| 630 set.add('a'); | |
| 631 set.add('b'); | |
| 632 set.add('c'); | |
| 633 | |
| 634 var buffer = ''; | |
| 635 set.forEach(function(v) { | |
| 636 buffer += v; | |
| 637 set.forEach(function(v) { | |
| 638 buffer += v; | |
| 639 if (v === 'a') { | |
| 640 set.delete('b'); | |
| 641 } | |
| 642 }); | |
| 643 }); | |
| 644 | |
| 645 assertEquals('aaccac', buffer); | |
| 646 })(); | |
| 647 | |
| 648 | |
| 649 (function TestSetForEachEarlyExit() { | |
| 650 var set = new Set(); | |
| 651 set.add('a'); | |
| 652 set.add('b'); | |
| 653 set.add('c'); | |
| 654 | |
| 655 var buffer = ''; | |
| 656 var ex = {}; | |
| 657 try { | |
| 658 set.forEach(function(v) { | |
| 659 buffer += v; | |
| 660 throw ex; | |
| 661 }); | |
| 662 } catch (e) { | |
| 663 assertEquals(ex, e); | |
| 664 } | |
| 665 assertEquals('a', buffer); | |
| 666 })(); | |
| 667 | |
| 668 | |
| 669 (function TestSetForEachGC() { | |
| 670 var set = new Set(); | |
| 671 for (var i = 0; i < 100; i++) { | |
| 672 set.add(i); | |
| 673 } | |
| 674 | |
| 675 var accumulated = 0; | |
| 676 set.forEach(function(v) { | |
| 677 accumulated += v; | |
| 678 if (v % 10 === 0) { | |
| 679 gc(); | |
| 680 } | |
| 681 }); | |
| 682 assertEquals(4950, accumulated); | |
| 683 })(); | |
| 684 | |
| 685 (function TestMapForEachInvalidTypes() { | |
| 686 assertThrows(function() { | |
| 687 Map.prototype.map.forEach.call({}); | |
| 688 }, TypeError); | |
| 689 | |
| 690 var map = new Map(); | |
| 691 assertThrows(function() { | |
| 692 map.forEach({}); | |
| 693 }, TypeError); | |
| 694 })(); | |
| 695 | |
| 696 | |
| 697 (function TestMapForEach() { | |
| 698 var map = new Map(); | |
| 699 map.set(0, 'a'); | |
| 700 map.set(1, 'b'); | |
| 701 map.set(2, 'c'); | |
| 702 | |
| 703 var buffer = []; | |
| 704 var receiver = {}; | |
| 705 map.forEach(function(v, k, m) { | |
| 706 assertEquals(map, m); | |
| 707 assertEquals(this, receiver); | |
| 708 buffer.push(k, v); | |
| 709 if (k === 0) { | |
| 710 map.delete(1); | |
| 711 map.set(3, 'd'); | |
| 712 map.set(4, 'e'); | |
| 713 map.set(5, 'f'); | |
| 714 } else if (k === 2) { | |
| 715 map.set(1, 'B'); | |
| 716 map.delete(4); | |
| 717 } | |
| 718 }, receiver); | |
| 719 | |
| 720 assertArrayEquals([0, 'a', 2, 'c', 3, 'd', 5, 'f', 1, 'B'], buffer); | |
| 721 })(); | |
| 722 | |
| 723 | |
| 724 (function TestMapForEachAddAtEnd() { | |
| 725 var map = new Map(); | |
| 726 map.set(0, 'a'); | |
| 727 map.set(1, 'b'); | |
| 728 | |
| 729 var buffer = []; | |
| 730 map.forEach(function(v, k) { | |
| 731 buffer.push(k, v); | |
| 732 if (k === 1) { | |
| 733 map.set(2, 'c'); | |
| 734 } | |
| 735 }); | |
| 736 | |
| 737 assertArrayEquals([0, 'a', 1, 'b', 2, 'c'], buffer); | |
| 738 })(); | |
| 739 | |
| 740 | |
| 741 (function TestMapForEachDeleteNext() { | |
| 742 var map = new Map(); | |
| 743 map.set(0, 'a'); | |
| 744 map.set(1, 'b'); | |
| 745 map.set(2, 'c'); | |
| 746 | |
| 747 var buffer = []; | |
| 748 map.forEach(function(v, k) { | |
| 749 buffer.push(k, v); | |
| 750 if (k === 1) { | |
| 751 map.delete(2); | |
| 752 } | |
| 753 }); | |
| 754 | |
| 755 assertArrayEquals([0, 'a', 1, 'b'], buffer); | |
| 756 })(); | |
| 757 | |
| 758 | |
| 759 (function TestSetForEachDeleteVisitedAndAddAgain() { | |
| 760 var map = new Map(); | |
| 761 map.set(0, 'a'); | |
| 762 map.set(1, 'b'); | |
| 763 map.set(2, 'c'); | |
| 764 | |
| 765 var buffer = []; | |
| 766 map.forEach(function(v, k) { | |
| 767 buffer.push(k, v); | |
| 768 if (k === 1) { | |
| 769 map.delete(0); | |
| 770 } else if (k === 2) { | |
| 771 map.set(0, 'a'); | |
| 772 } | |
| 773 }); | |
| 774 | |
| 775 assertArrayEquals([0, 'a', 1, 'b', 2, 'c', 0, 'a'], buffer); | |
| 776 })(); | |
| 777 | |
| 778 | |
| 779 (function TestMapForEachClear() { | |
| 780 var map = new Map(); | |
| 781 map.set(0, 'a'); | |
| 782 map.set(1, 'b'); | |
| 783 map.set(2, 'c'); | |
| 784 | |
| 785 var buffer = []; | |
| 786 map.forEach(function(v, k) { | |
| 787 buffer.push(k, v); | |
| 788 if (k === 0) { | |
| 789 map.clear(); | |
| 790 map.set(3, 'd'); | |
| 791 map.set(4, 'e'); | |
| 792 } | |
| 793 }); | |
| 794 | |
| 795 assertArrayEquals([0, 'a', 3, 'd', 4, 'e'], buffer); | |
| 796 })(); | |
| 797 | |
| 798 | |
| 799 (function TestMapForEachNested() { | |
| 800 var map = new Map(); | |
| 801 map.set(0, 'a'); | |
| 802 map.set(1, 'b'); | |
| 803 map.set(2, 'c'); | |
| 804 | |
| 805 var buffer = []; | |
| 806 map.forEach(function(v, k) { | |
| 807 buffer.push(k, v); | |
| 808 map.forEach(function(v, k) { | |
| 809 buffer.push(k, v); | |
| 810 if (k === 0) { | |
| 811 map.delete(1); | |
| 812 } | |
| 813 }); | |
| 814 }); | |
| 815 | |
| 816 assertArrayEquals([0, 'a', 0, 'a', 2, 'c', 2, 'c', 0, 'a', 2, 'c'], buffer); | |
| 817 })(); | |
| 818 | |
| 819 | |
| 820 (function TestMapForEachEarlyExit() { | |
| 821 var map = new Map(); | |
| 822 map.set(0, 'a'); | |
| 823 map.set(1, 'b'); | |
| 824 map.set(2, 'c'); | |
| 825 | |
| 826 var buffer = []; | |
| 827 var ex = {}; | |
| 828 try { | |
| 829 map.forEach(function(v, k) { | |
| 830 buffer.push(k, v); | |
| 831 throw ex; | |
| 832 }); | |
| 833 } catch (e) { | |
| 834 assertEquals(ex, e); | |
| 835 } | |
| 836 assertArrayEquals([0, 'a'], buffer); | |
| 837 })(); | |
| 838 | |
| 839 | |
| 840 (function TestMapForEachGC() { | |
| 841 var map = new Map(); | |
| 842 for (var i = 0; i < 100; i++) { | |
| 843 map.set(i, i); | |
| 844 } | |
| 845 | |
| 846 var accumulated = 0; | |
| 847 map.forEach(function(v) { | |
| 848 accumulated += v; | |
| 849 if (v % 10 === 0) { | |
| 850 gc(); | |
| 851 } | |
| 852 }); | |
| 853 assertEquals(4950, accumulated); | |
| 854 })(); | |
| 855 | |
| 856 | |
| 857 (function TestMapForEachAllRemovedTransition() { | |
| 858 var map = new Map; | |
| 859 map.set(0, 0); | |
| 860 | |
| 861 var buffer = []; | |
| 862 map.forEach(function(v) { | |
| 863 buffer.push(v); | |
| 864 if (v === 0) { | |
| 865 for (var i = 1; i < 4; i++) { | |
| 866 map.set(i, i); | |
| 867 } | |
| 868 } | |
| 869 | |
| 870 if (v === 3) { | |
| 871 for (var i = 0; i < 4; i++) { | |
| 872 map.delete(i); | |
| 873 } | |
| 874 for (var i = 4; i < 8; i++) { | |
| 875 map.set(i, i); | |
| 876 } | |
| 877 } | |
| 878 }); | |
| 879 | |
| 880 assertArrayEquals([0, 1, 2, 3, 4, 5, 6, 7], buffer); | |
| 881 })(); | |
| 882 | |
| 883 | |
| 884 (function TestMapForEachClearTransition() { | |
| 885 var map = new Map; | |
| 886 map.set(0, 0); | |
| 887 | |
| 888 var i = 0; | |
| 889 var buffer = []; | |
| 890 map.forEach(function(v) { | |
| 891 buffer.push(v); | |
| 892 if (++i < 5) { | |
| 893 for (var j = 0; j < 5; j++) { | |
| 894 map.clear(); | |
| 895 map.set(i, i); | |
| 896 } | |
| 897 } | |
| 898 }); | |
| 899 | |
| 900 assertArrayEquals([0, 1, 2, 3, 4], buffer); | |
| 901 })(); | |
| 902 | |
| 903 | |
| 904 (function TestMapForEachNestedNonTrivialTransition() { | |
| 905 var map = new Map; | |
| 906 map.set(0, 0); | |
| 907 map.set(1, 1); | |
| 908 map.set(2, 2); | |
| 909 map.set(3, 3); | |
| 910 map.delete(0); | |
| 911 | |
| 912 var i = 0; | |
| 913 var buffer = []; | |
| 914 map.forEach(function(v) { | |
| 915 if (++i > 10) return; | |
| 916 | |
| 917 buffer.push(v); | |
| 918 | |
| 919 if (v == 3) { | |
| 920 map.delete(1); | |
| 921 for (var j = 4; j < 10; j++) { | |
| 922 map.set(j, j); | |
| 923 } | |
| 924 for (var j = 4; j < 10; j += 2) { | |
| 925 map.delete(j); | |
| 926 } | |
| 927 map.delete(2); | |
| 928 | |
| 929 for (var j = 10; j < 20; j++) { | |
| 930 map.set(j, j); | |
| 931 } | |
| 932 for (var j = 10; j < 20; j += 2) { | |
| 933 map.delete(j); | |
| 934 } | |
| 935 | |
| 936 map.delete(3); | |
| 937 } | |
| 938 }); | |
| 939 | |
| 940 assertArrayEquals([1, 2, 3, 5, 7, 9, 11, 13, 15, 17], buffer); | |
| 941 })(); | |
| 942 | |
| 943 | |
| 944 (function TestMapForEachAllRemovedTransitionNoClear() { | |
| 945 var map = new Map; | |
| 946 map.set(0, 0); | |
| 947 | |
| 948 var buffer = []; | |
| 949 map.forEach(function(v) { | |
| 950 buffer.push(v); | |
| 951 if (v === 0) { | |
| 952 for (var i = 1; i < 8; i++) { | |
| 953 map.set(i, i); | |
| 954 } | |
| 955 } | |
| 956 | |
| 957 if (v === 4) { | |
| 958 for (var i = 0; i < 8; i++) { | |
| 959 map.delete(i); | |
| 960 } | |
| 961 } | |
| 962 }); | |
| 963 | |
| 964 assertArrayEquals([0, 1, 2, 3, 4], buffer); | |
| 965 })(); | |
| 966 | |
| 967 | |
| 968 (function TestMapForEachNoMoreElementsAfterTransition() { | |
| 969 var map = new Map; | |
| 970 map.set(0, 0); | |
| 971 | |
| 972 var buffer = []; | |
| 973 map.forEach(function(v) { | |
| 974 buffer.push(v); | |
| 975 if (v === 0) { | |
| 976 for (var i = 1; i < 16; i++) { | |
| 977 map.set(i, i); | |
| 978 } | |
| 979 } | |
| 980 | |
| 981 if (v === 4) { | |
| 982 for (var i = 5; i < 16; i++) { | |
| 983 map.delete(i); | |
| 984 } | |
| 985 } | |
| 986 }); | |
| 987 | |
| 988 assertArrayEquals([0, 1, 2, 3, 4], buffer); | |
| 989 })(); | |
| 990 | |
| 991 | |
| 992 (function TestSetConstructor() { | |
| 993 var s = new Set(null); | |
| 994 assertEquals(s.size, 0); | |
| 995 | |
| 996 s = new Set(undefined); | |
| 997 assertEquals(s.size, 0); | |
| 998 | |
| 999 // No @@iterator | |
| 1000 assertThrows(function() { | |
| 1001 new Set({}); | |
| 1002 }, TypeError); | |
| 1003 | |
| 1004 // @@iterator not callable | |
| 1005 assertThrows(function() { | |
| 1006 var object = {}; | |
| 1007 object[Symbol.iterator] = 42; | |
| 1008 new Set(object); | |
| 1009 }, TypeError); | |
| 1010 | |
| 1011 // @@iterator result not object | |
| 1012 assertThrows(function() { | |
| 1013 var object = {}; | |
| 1014 object[Symbol.iterator] = function() { | |
| 1015 return 42; | |
| 1016 }; | |
| 1017 new Set(object); | |
| 1018 }, TypeError); | |
| 1019 | |
| 1020 var s2 = new Set(); | |
| 1021 s2.add('a'); | |
| 1022 s2.add('b'); | |
| 1023 s2.add('c'); | |
| 1024 s = new Set(s2.values()); | |
| 1025 assertEquals(s.size, 3); | |
| 1026 assertTrue(s.has('a')); | |
| 1027 assertTrue(s.has('b')); | |
| 1028 assertTrue(s.has('c')); | |
| 1029 })(); | |
| 1030 | |
| 1031 | |
| 1032 (function TestSetConstructorAddNotCallable() { | |
| 1033 var originalSetPrototypeAdd = Set.prototype.add; | |
| 1034 assertThrows(function() { | |
| 1035 Set.prototype.add = 42; | |
| 1036 new Set([1, 2].values()); | |
| 1037 }, TypeError); | |
| 1038 Set.prototype.add = originalSetPrototypeAdd; | |
| 1039 })(); | |
| 1040 | |
| 1041 | |
| 1042 (function TestSetConstructorGetAddOnce() { | |
| 1043 var originalSetPrototypeAdd = Set.prototype.add; | |
| 1044 var getAddCount = 0; | |
| 1045 Object.defineProperty(Set.prototype, 'add', { | |
| 1046 get: function() { | |
| 1047 getAddCount++; | |
| 1048 return function() {}; | |
| 1049 } | |
| 1050 }); | |
| 1051 var s = new Set([1, 2].values()); | |
| 1052 assertEquals(getAddCount, 1); | |
| 1053 assertEquals(s.size, 0); | |
| 1054 Object.defineProperty(Set.prototype, 'add', { | |
| 1055 value: originalSetPrototypeAdd, | |
| 1056 writable: true | |
| 1057 }); | |
| 1058 })(); | |
| 1059 | |
| 1060 | |
| 1061 (function TestSetConstructorAddReplaced() { | |
| 1062 var originalSetPrototypeAdd = Set.prototype.add; | |
| 1063 var addCount = 0; | |
| 1064 Set.prototype.add = function(value) { | |
| 1065 addCount++; | |
| 1066 originalSetPrototypeAdd.call(this, value); | |
| 1067 Set.prototype.add = null; | |
| 1068 }; | |
| 1069 var s = new Set([1, 2].values()); | |
| 1070 assertEquals(addCount, 2); | |
| 1071 assertEquals(s.size, 2); | |
| 1072 Set.prototype.add = originalSetPrototypeAdd; | |
| 1073 })(); | |
| 1074 | |
| 1075 | |
| 1076 (function TestSetConstructorOrderOfDoneValue() { | |
| 1077 var valueCount = 0, doneCount = 0; | |
| 1078 var iterator = { | |
| 1079 next: function() { | |
| 1080 return { | |
| 1081 get value() { | |
| 1082 valueCount++; | |
| 1083 }, | |
| 1084 get done() { | |
| 1085 doneCount++; | |
| 1086 throw new Error(); | |
| 1087 } | |
| 1088 }; | |
| 1089 } | |
| 1090 }; | |
| 1091 iterator[Symbol.iterator] = function() { | |
| 1092 return this; | |
| 1093 }; | |
| 1094 assertThrows(function() { | |
| 1095 new Set(iterator); | |
| 1096 }); | |
| 1097 assertEquals(doneCount, 1); | |
| 1098 assertEquals(valueCount, 0); | |
| 1099 })(); | |
| 1100 | |
| 1101 | |
| 1102 (function TestSetConstructorNextNotAnObject() { | |
| 1103 var iterator = { | |
| 1104 next: function() { | |
| 1105 return 'abc'; | |
| 1106 } | |
| 1107 }; | |
| 1108 iterator[Symbol.iterator] = function() { | |
| 1109 return this; | |
| 1110 }; | |
| 1111 assertThrows(function() { | |
| 1112 new Set(iterator); | |
| 1113 }, TypeError); | |
| 1114 })(); | |
| 1115 | |
| 1116 | |
| 1117 (function TestMapConstructor() { | |
| 1118 var m = new Map(null); | |
| 1119 assertEquals(m.size, 0); | |
| 1120 | |
| 1121 m = new Map(undefined); | |
| 1122 assertEquals(m.size, 0); | |
| 1123 | |
| 1124 // No @@iterator | |
| 1125 assertThrows(function() { | |
| 1126 new Map({}); | |
| 1127 }, TypeError); | |
| 1128 | |
| 1129 // @@iterator not callable | |
| 1130 assertThrows(function() { | |
| 1131 var object = {}; | |
| 1132 object[Symbol.iterator] = 42; | |
| 1133 new Map(object); | |
| 1134 }, TypeError); | |
| 1135 | |
| 1136 // @@iterator result not object | |
| 1137 assertThrows(function() { | |
| 1138 var object = {}; | |
| 1139 object[Symbol.iterator] = function() { | |
| 1140 return 42; | |
| 1141 }; | |
| 1142 new Map(object); | |
| 1143 }, TypeError); | |
| 1144 | |
| 1145 var m2 = new Map(); | |
| 1146 m2.set(0, 'a'); | |
| 1147 m2.set(1, 'b'); | |
| 1148 m2.set(2, 'c'); | |
| 1149 m = new Map(m2.entries()); | |
| 1150 assertEquals(m.size, 3); | |
| 1151 assertEquals(m.get(0), 'a'); | |
| 1152 assertEquals(m.get(1), 'b'); | |
| 1153 assertEquals(m.get(2), 'c'); | |
| 1154 })(); | |
| 1155 | |
| 1156 | |
| 1157 (function TestMapConstructorSetNotCallable() { | |
| 1158 var originalMapPrototypeSet = Map.prototype.set; | |
| 1159 assertThrows(function() { | |
| 1160 Map.prototype.set = 42; | |
| 1161 new Map([1, 2].entries()); | |
| 1162 }, TypeError); | |
| 1163 Map.prototype.set = originalMapPrototypeSet; | |
| 1164 })(); | |
| 1165 | |
| 1166 | |
| 1167 (function TestMapConstructorGetAddOnce() { | |
| 1168 var originalMapPrototypeSet = Map.prototype.set; | |
| 1169 var getSetCount = 0; | |
| 1170 Object.defineProperty(Map.prototype, 'set', { | |
| 1171 get: function() { | |
| 1172 getSetCount++; | |
| 1173 return function() {}; | |
| 1174 } | |
| 1175 }); | |
| 1176 var m = new Map([1, 2].entries()); | |
| 1177 assertEquals(getSetCount, 1); | |
| 1178 assertEquals(m.size, 0); | |
| 1179 Object.defineProperty(Map.prototype, 'set', { | |
| 1180 value: originalMapPrototypeSet, | |
| 1181 writable: true | |
| 1182 }); | |
| 1183 })(); | |
| 1184 | |
| 1185 | |
| 1186 (function TestMapConstructorSetReplaced() { | |
| 1187 var originalMapPrototypeSet = Map.prototype.set; | |
| 1188 var setCount = 0; | |
| 1189 Map.prototype.set = function(key, value) { | |
| 1190 setCount++; | |
| 1191 originalMapPrototypeSet.call(this, key, value); | |
| 1192 Map.prototype.set = null; | |
| 1193 }; | |
| 1194 var m = new Map([1, 2].entries()); | |
| 1195 assertEquals(setCount, 2); | |
| 1196 assertEquals(m.size, 2); | |
| 1197 Map.prototype.set = originalMapPrototypeSet; | |
| 1198 })(); | |
| 1199 | |
| 1200 | |
| 1201 (function TestMapConstructorOrderOfDoneValue() { | |
| 1202 var valueCount = 0, doneCount = 0; | |
| 1203 function FakeError() {} | |
| 1204 var iterator = { | |
| 1205 next: function() { | |
| 1206 return { | |
| 1207 get value() { | |
| 1208 valueCount++; | |
| 1209 }, | |
| 1210 get done() { | |
| 1211 doneCount++; | |
| 1212 throw new FakeError(); | |
| 1213 } | |
| 1214 }; | |
| 1215 } | |
| 1216 }; | |
| 1217 iterator[Symbol.iterator] = function() { | |
| 1218 return this; | |
| 1219 }; | |
| 1220 assertThrows(function() { | |
| 1221 new Map(iterator); | |
| 1222 }, FakeError); | |
| 1223 assertEquals(doneCount, 1); | |
| 1224 assertEquals(valueCount, 0); | |
| 1225 })(); | |
| 1226 | |
| 1227 | |
| 1228 (function TestMapConstructorNextNotAnObject() { | |
| 1229 var iterator = { | |
| 1230 next: function() { | |
| 1231 return 'abc'; | |
| 1232 } | |
| 1233 }; | |
| 1234 iterator[Symbol.iterator] = function() { | |
| 1235 return this; | |
| 1236 }; | |
| 1237 assertThrows(function() { | |
| 1238 new Map(iterator); | |
| 1239 }, TypeError); | |
| 1240 })(); | |
| 1241 | |
| 1242 | |
| 1243 (function TestMapConstructorIteratorNotObjectValues() { | |
| 1244 assertThrows(function() { | |
| 1245 new Map([1, 2].values()); | |
| 1246 }, TypeError); | |
| 1247 })(); | |
| OLD | NEW |