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 })(); |
OLD | NEW |