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