| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // Flags: --harmony-destructuring-assignment --harmony-destructuring-bind | |
| 6 | |
| 7 // script-level tests | |
| 8 var ox, oy = {}, oz; | |
| 9 ({ | |
| 10 x: ox, | |
| 11 y: oy.value, | |
| 12 y2: oy["value2"], | |
| 13 z: ({ set v(val) { oz = val; } }).v | |
| 14 } = { | |
| 15 x: "value of x", | |
| 16 y: "value of y1", | |
| 17 y2: "value of y2", | |
| 18 z: "value of z" | |
| 19 }); | |
| 20 assertEquals("value of x", ox); | |
| 21 assertEquals("value of y1", oy.value); | |
| 22 assertEquals("value of y2", oy.value2); | |
| 23 assertEquals("value of z", oz); | |
| 24 | |
| 25 [ox, oy.value, oy["value2"], ...{ set v(val) { oz = val; } }.v] = [ | |
| 26 1007, | |
| 27 798432, | |
| 28 555, | |
| 29 1, 2, 3, 4, 5 | |
| 30 ]; | |
| 31 assertEquals(ox, 1007); | |
| 32 assertEquals(oy.value, 798432); | |
| 33 assertEquals(oy.value2, 555); | |
| 34 assertEquals(oz, [1, 2, 3, 4, 5]); | |
| 35 | |
| 36 | |
| 37 (function testInFunction() { | |
| 38 var x, y = {}, z; | |
| 39 ({ | |
| 40 x: x, | |
| 41 y: y.value, | |
| 42 y2: y["value2"], | |
| 43 z: ({ set v(val) { z = val; } }).v | |
| 44 } = { | |
| 45 x: "value of x", | |
| 46 y: "value of y1", | |
| 47 y2: "value of y2", | |
| 48 z: "value of z" | |
| 49 }); | |
| 50 assertEquals("value of x", x); | |
| 51 assertEquals("value of y1", y.value); | |
| 52 assertEquals("value of y2", y.value2); | |
| 53 assertEquals("value of z", z); | |
| 54 | |
| 55 [x, y.value, y["value2"], ...{ set v(val) { z = val; } }.v] = [ | |
| 56 1007, | |
| 57 798432, | |
| 58 555, | |
| 59 1, 2, 3, 4, 5 | |
| 60 ]; | |
| 61 assertEquals(x, 1007); | |
| 62 assertEquals(y.value, 798432); | |
| 63 assertEquals(y.value2, 555); | |
| 64 assertEquals(z, [1, 2, 3, 4, 5]); | |
| 65 })(); | |
| 66 | |
| 67 | |
| 68 (function testArrowFunctionInitializers() { | |
| 69 var fn = (config = { | |
| 70 value: defaults.value, | |
| 71 nada: { nada: defaults.nada } = { nada: "nothing" } | |
| 72 } = { value: "BLAH" }) => config; | |
| 73 var defaults = {}; | |
| 74 assertEquals({ value: "BLAH" }, fn()); | |
| 75 assertEquals("BLAH", defaults.value); | |
| 76 assertEquals("nothing", defaults.nada); | |
| 77 })(); | |
| 78 | |
| 79 | |
| 80 (function testArrowFunctionInitializers2() { | |
| 81 var fn = (config = [ | |
| 82 defaults.value, | |
| 83 { nada: defaults.nada } = { nada: "nothing" } | |
| 84 ] = ["BLAH"]) => config; | |
| 85 var defaults = {}; | |
| 86 assertEquals(["BLAH"], fn()); | |
| 87 assertEquals("BLAH", defaults.value); | |
| 88 assertEquals("nothing", defaults.nada); | |
| 89 })(); | |
| 90 | |
| 91 | |
| 92 (function testFunctionInitializers() { | |
| 93 function fn(config = { | |
| 94 value: defaults.value, | |
| 95 nada: { nada: defaults.nada } = { nada: "nothing" } | |
| 96 } = { value: "BLAH" }) { | |
| 97 return config; | |
| 98 } | |
| 99 var defaults = {}; | |
| 100 assertEquals({ value: "BLAH" }, fn()); | |
| 101 assertEquals("BLAH", defaults.value); | |
| 102 assertEquals("nothing", defaults.nada); | |
| 103 })(); | |
| 104 | |
| 105 | |
| 106 (function testFunctionInitializers2() { | |
| 107 function fn(config = [ | |
| 108 defaults.value, | |
| 109 { nada: defaults.nada } = { nada: "nothing" } | |
| 110 ] = ["BLAH"]) { return config; } | |
| 111 var defaults = {}; | |
| 112 assertEquals(["BLAH"], fn()); | |
| 113 assertEquals("BLAH", defaults.value); | |
| 114 assertEquals("nothing", defaults.nada); | |
| 115 })(); | |
| 116 | |
| 117 | |
| 118 (function testDeclarationInitializers() { | |
| 119 var defaults = {}; | |
| 120 var { value } = { value: defaults.value } = { value: "BLAH" }; | |
| 121 assertEquals("BLAH", value); | |
| 122 assertEquals("BLAH", defaults.value); | |
| 123 })(); | |
| 124 | |
| 125 | |
| 126 (function testDeclarationInitializers2() { | |
| 127 var defaults = {}; | |
| 128 var [value] = [defaults.value] = ["BLAH"]; | |
| 129 assertEquals("BLAH", value); | |
| 130 assertEquals("BLAH", defaults.value); | |
| 131 })(); | |
| 132 | |
| 133 | |
| 134 (function testObjectLiteralProperty() { | |
| 135 var ext = {}; | |
| 136 var obj = { | |
| 137 a: { b: ext.b, c: ext["c"], d: { set v(val) { ext.d = val; } }.v } = { | |
| 138 b: "b", c: "c", d: "d" } | |
| 139 }; | |
| 140 assertEquals({ b: "b", c: "c", d: "d" }, ext); | |
| 141 assertEquals({ a: { b: "b", c: "c", d: "d" } }, obj); | |
| 142 })(); | |
| 143 | |
| 144 | |
| 145 (function testArrayLiteralProperty() { | |
| 146 var ext = {}; | |
| 147 var obj = [ | |
| 148 ...[ ext.b, ext["c"], { set v(val) { ext.d = val; } }.v ] = [ | |
| 149 "b", "c", "d" ] | |
| 150 ]; | |
| 151 assertEquals({ b: "b", c: "c", d: "d" }, ext); | |
| 152 assertEquals([ "b", "c", "d" ], obj); | |
| 153 })(); | |
| 154 | |
| 155 | |
| 156 // TODO(caitp): add similar test for ArrayPatterns, once Proxies support | |
| 157 // delegating symbol-keyed get/set. | |
| 158 (function testObjectPatternOperationOrder() { | |
| 159 var steps = []; | |
| 160 var store = {}; | |
| 161 function computePropertyName(name) { | |
| 162 steps.push("compute name: " + name); | |
| 163 return name; | |
| 164 } | |
| 165 function loadValue(descr, value) { | |
| 166 steps.push("load: " + descr + " > " + value); | |
| 167 return value; | |
| 168 } | |
| 169 function storeValue(descr, name, value) { | |
| 170 steps.push("store: " + descr + " = " + value); | |
| 171 store[name] = value; | |
| 172 } | |
| 173 var result = { | |
| 174 get a() { assertUnreachable(); }, | |
| 175 set a(value) { storeValue("result.a", "a", value); }, | |
| 176 get b() { assertUnreachable(); }, | |
| 177 set b(value) { storeValue("result.b", "b", value); } | |
| 178 }; | |
| 179 | |
| 180 ({ | |
| 181 obj: { | |
| 182 x: result.a = 10, | |
| 183 [computePropertyName("y")]: result.b = false, | |
| 184 } = {} | |
| 185 } = { obj: { | |
| 186 get x() { return loadValue(".temp.obj.x", undefined); }, | |
| 187 set x(value) { assertUnreachable(); }, | |
| 188 get y() { return loadValue(".temp.obj.y", undefined); }, | |
| 189 set y(value) { assertUnreachable(); } | |
| 190 }}); | |
| 191 | |
| 192 assertPropertiesEqual({ | |
| 193 a: 10, | |
| 194 b: false | |
| 195 }, store); | |
| 196 | |
| 197 assertArrayEquals([ | |
| 198 "load: .temp.obj.x > undefined", | |
| 199 "store: result.a = 10", | |
| 200 | |
| 201 "compute name: y", | |
| 202 "load: .temp.obj.y > undefined", | |
| 203 "store: result.b = false" | |
| 204 ], steps); | |
| 205 | |
| 206 steps = []; | |
| 207 | |
| 208 ({ | |
| 209 obj: { | |
| 210 x: result.a = 50, | |
| 211 [computePropertyName("y")]: result.b = "hello", | |
| 212 } = {} | |
| 213 } = { obj: { | |
| 214 get x() { return loadValue(".temp.obj.x", 20); }, | |
| 215 set x(value) { assertUnreachable(); }, | |
| 216 get y() { return loadValue(".temp.obj.y", true); }, | |
| 217 set y(value) { assertUnreachable(); } | |
| 218 }}); | |
| 219 | |
| 220 assertPropertiesEqual({ | |
| 221 a: 20, | |
| 222 b: true | |
| 223 }, store); | |
| 224 | |
| 225 assertArrayEquals([ | |
| 226 "load: .temp.obj.x > 20", | |
| 227 "store: result.a = 20", | |
| 228 "compute name: y", | |
| 229 "load: .temp.obj.y > true", | |
| 230 "store: result.b = true", | |
| 231 ], steps); | |
| 232 })(); | |
| 233 | |
| 234 // Credit to Mike Pennisi and other Test262 contributors for originally writing | |
| 235 // the testse the following are based on. | |
| 236 (function testArrayElision() { | |
| 237 var value = [1, 2, 3, 4, 5, 6, 7, 8, 9]; | |
| 238 var a, obj = {}; | |
| 239 var result = [, a, , obj.b, , ...obj["rest"]] = value; | |
| 240 | |
| 241 assertEquals(result, value); | |
| 242 assertEquals(2, a); | |
| 243 assertEquals(4, obj.b); | |
| 244 assertArrayEquals([6, 7, 8, 9], obj.rest); | |
| 245 })(); | |
| 246 | |
| 247 (function testArrayElementInitializer() { | |
| 248 function test(value, initializer, expected) { | |
| 249 var a, obj = {}; | |
| 250 var initialized = false; | |
| 251 var shouldBeInitialized = value[0] === undefined; | |
| 252 assertEquals(value, [ a = (initialized = true, initializer) ] = value); | |
| 253 assertEquals(expected, a); | |
| 254 assertEquals(shouldBeInitialized, initialized); | |
| 255 | |
| 256 var initialized2 = false; | |
| 257 assertEquals(value, [ obj.a = (initialized2 = true, initializer) ] = value); | |
| 258 assertEquals(expected, obj.a); | |
| 259 assertEquals(shouldBeInitialized, initialized2); | |
| 260 } | |
| 261 | |
| 262 test([], "BAM!", "BAM!"); | |
| 263 test([], "BOOP!", "BOOP!"); | |
| 264 test([null], 123, null); | |
| 265 test([undefined], 456, 456); | |
| 266 test([,], "PUPPIES", "PUPPIES"); | |
| 267 | |
| 268 (function accept_IN() { | |
| 269 var value = [], x; | |
| 270 assertEquals(value, [ x = 'x' in {} ] = value); | |
| 271 assertEquals(false, x); | |
| 272 })(); | |
| 273 | |
| 274 (function ordering() { | |
| 275 var x = 0, a, b, value = []; | |
| 276 assertEquals(value, [ a = x += 1, b = x *= 2 ] = value); | |
| 277 assertEquals(1, a); | |
| 278 assertEquals(2, b); | |
| 279 assertEquals(2, x); | |
| 280 })(); | |
| 281 | |
| 282 (function yieldExpression() { | |
| 283 var value = [], it, result, x; | |
| 284 it = (function*() { | |
| 285 result = [ x = yield ] = value; | |
| 286 })(); | |
| 287 var next = it.next(); | |
| 288 | |
| 289 assertEquals(undefined, result); | |
| 290 assertEquals(undefined, next.value); | |
| 291 assertEquals(false, next.done); | |
| 292 assertEquals(undefined, x); | |
| 293 | |
| 294 next = it.next(86); | |
| 295 | |
| 296 assertEquals(value, result); | |
| 297 assertEquals(undefined, next.value); | |
| 298 assertEquals(true, next.done); | |
| 299 assertEquals(86, x); | |
| 300 })(); | |
| 301 | |
| 302 (function yieldIdentifier() { | |
| 303 var value = [], yield = "BOOP!", x; | |
| 304 assertEquals(value, [ x = yield ] = value); | |
| 305 assertEquals("BOOP!", x); | |
| 306 })(); | |
| 307 | |
| 308 assertThrows(function let_TDZ() { | |
| 309 "use strict"; | |
| 310 var x; | |
| 311 [ x = y ] = []; | |
| 312 let y; | |
| 313 }, ReferenceError); | |
| 314 })(); | |
| 315 | |
| 316 | |
| 317 (function testArrayElementNestedPattern() { | |
| 318 assertThrows(function nestedArrayRequireObjectCoercibleNull() { | |
| 319 var x; [ [ x ] ] = [ null ]; | |
| 320 }, TypeError); | |
| 321 | |
| 322 assertThrows(function nestedArrayRequireObjectCoercibleUndefined() { | |
| 323 var x; [ [ x ] ] = [ undefined ]; | |
| 324 }, TypeError); | |
| 325 | |
| 326 assertThrows(function nestedArrayRequireObjectCoercibleUndefined2() { | |
| 327 var x; [ [ x ] ] = [ ]; | |
| 328 }, TypeError); | |
| 329 | |
| 330 assertThrows(function nestedArrayRequireObjectCoercibleUndefined3() { | |
| 331 var x; [ [ x ] ] = [ , ]; | |
| 332 }, TypeError); | |
| 333 | |
| 334 assertThrows(function nestedObjectRequireObjectCoercibleNull() { | |
| 335 var x; [ { x } ] = [ null ]; | |
| 336 }, TypeError); | |
| 337 | |
| 338 assertThrows(function nestedObjectRequireObjectCoercibleUndefined() { | |
| 339 var x; [ { x } ] = [ undefined ]; | |
| 340 }, TypeError); | |
| 341 | |
| 342 assertThrows(function nestedObjectRequireObjectCoercibleUndefined2() { | |
| 343 var x; [ { x } ] = [ ]; | |
| 344 }, TypeError); | |
| 345 | |
| 346 assertThrows(function nestedObjectRequireObjectCoercibleUndefined3() { | |
| 347 var x; [ { x } ] = [ , ]; | |
| 348 }, TypeError); | |
| 349 | |
| 350 (function nestedArray() { | |
| 351 var x, value = [ [ "zap", "blonk" ] ]; | |
| 352 assertEquals(value, [ [ , x ] ] = value); | |
| 353 assertEquals("blonk", x); | |
| 354 })(); | |
| 355 | |
| 356 (function nestedObject() { | |
| 357 var x, value = [ { a: "zap", b: "blonk" } ]; | |
| 358 assertEquals(value, [ { b: x } ] = value); | |
| 359 assertEquals("blonk", x); | |
| 360 })(); | |
| 361 })(); | |
| 362 | |
| 363 (function testArrayRestElement() { | |
| 364 (function testBasic() { | |
| 365 var x, rest, array = [1, 2, 3]; | |
| 366 assertEquals(array, [x, ...rest] = array); | |
| 367 assertEquals(1, x); | |
| 368 assertEquals([2, 3], rest); | |
| 369 | |
| 370 array = [4, 5, 6]; | |
| 371 assertEquals(array, [, ...rest] = array); | |
| 372 assertEquals([5, 6], rest); | |
| 373 | |
| 374 })(); | |
| 375 | |
| 376 (function testNestedRestObject() { | |
| 377 var value = [1, 2, 3], x; | |
| 378 assertEquals(value, [...{ 1: x }] = value); | |
| 379 assertEquals(2, x); | |
| 380 })(); | |
| 381 | |
| 382 (function iterable() { | |
| 383 var count = 0; | |
| 384 var x, y, z; | |
| 385 function* g() { | |
| 386 count++; | |
| 387 yield; | |
| 388 count++; | |
| 389 yield; | |
| 390 count++; | |
| 391 yield; | |
| 392 } | |
| 393 var it = g(); | |
| 394 assertEquals(it, [...x] = it); | |
| 395 assertEquals([undefined, undefined, undefined], x); | |
| 396 assertEquals(3, count); | |
| 397 | |
| 398 it = [g()]; | |
| 399 assertEquals(it, [ [...y] ] = it); | |
| 400 assertEquals([undefined, undefined, undefined], y); | |
| 401 assertEquals(6, count); | |
| 402 | |
| 403 it = { a: g() }; | |
| 404 assertEquals(it, { a: [...z] } = it); | |
| 405 assertEquals([undefined, undefined, undefined], z); | |
| 406 assertEquals(9, count); | |
| 407 })(); | |
| 408 })(); | |
| 409 | |
| 410 (function testRequireObjectCoercible() { | |
| 411 assertThrows(() => ({} = undefined), TypeError); | |
| 412 assertThrows(() => ({} = null), TypeError); | |
| 413 assertThrows(() => [] = undefined, TypeError); | |
| 414 assertThrows(() => [] = null, TypeError); | |
| 415 assertEquals("test", ({} = "test")); | |
| 416 assertEquals("test", [] = "test"); | |
| 417 assertEquals(123, ({} = 123)); | |
| 418 })(); | |
| 419 | |
| 420 (function testConstReassignment() { | |
| 421 "use strict"; | |
| 422 const c = "untouchable"; | |
| 423 assertThrows(() => { [ c ] = [ "nope!" ]; }, TypeError); | |
| 424 assertThrows(() => { [ [ c ] ] = [ [ "nope!" ] ]; }, TypeError); | |
| 425 assertThrows(() => { [ { c } ] = [ { c: "nope!" } ]; }, TypeError); | |
| 426 assertThrows(() => { ({ c } = { c: "nope!" }); }, TypeError); | |
| 427 assertThrows(() => { ({ a: { c } } = { a: { c: "nope!" } }); }, TypeError); | |
| 428 assertThrows(() => { ({ a: [ c ] } = { a: [ "nope!" ] }); }, TypeError); | |
| 429 assertEquals("untouchable", c); | |
| 430 })(); | |
| 431 | |
| 432 (function testForIn() { | |
| 433 var log = []; | |
| 434 var x = {}; | |
| 435 var object = { | |
| 436 "Apenguin": 1, | |
| 437 "\u{1F382}cake": 2, | |
| 438 "Bpuppy": 3, | |
| 439 "Cspork": 4 | |
| 440 }; | |
| 441 for ([x.firstLetter, ...x.rest] in object) { | |
| 442 if (x.firstLetter === "A") { | |
| 443 assertEquals(["p", "e", "n", "g", "u", "i", "n"], x.rest); | |
| 444 continue; | |
| 445 } | |
| 446 if (x.firstLetter === "C") { | |
| 447 assertEquals(["s", "p", "o", "r", "k"], x.rest); | |
| 448 break; | |
| 449 } | |
| 450 log.push({ firstLetter: x.firstLetter, rest: x.rest }); | |
| 451 } | |
| 452 assertEquals([ | |
| 453 { firstLetter: "\u{1F382}", rest: ["c", "a", "k", "e"] }, | |
| 454 { firstLetter: "B", rest: ["p", "u", "p", "p", "y"] }, | |
| 455 ], log); | |
| 456 })(); | |
| 457 | |
| 458 (function testForOf() { | |
| 459 var log = []; | |
| 460 var x = {}; | |
| 461 var names = [ | |
| 462 "Apenguin", | |
| 463 "\u{1F382}cake", | |
| 464 "Bpuppy", | |
| 465 "Cspork" | |
| 466 ]; | |
| 467 for ([x.firstLetter, ...x.rest] of names) { | |
| 468 if (x.firstLetter === "A") { | |
| 469 assertEquals(["p", "e", "n", "g", "u", "i", "n"], x.rest); | |
| 470 continue; | |
| 471 } | |
| 472 if (x.firstLetter === "C") { | |
| 473 assertEquals(["s", "p", "o", "r", "k"], x.rest); | |
| 474 break; | |
| 475 } | |
| 476 log.push({ firstLetter: x.firstLetter, rest: x.rest }); | |
| 477 } | |
| 478 assertEquals([ | |
| 479 { firstLetter: "\u{1F382}", rest: ["c", "a", "k", "e"] }, | |
| 480 { firstLetter: "B", rest: ["p", "u", "p", "p", "y"] }, | |
| 481 ], log); | |
| 482 })(); | |
| OLD | NEW |