| 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 | 
|---|