mirror of
				https://github.com/tc39/test262.git
				synced 2025-10-31 03:34:08 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			632 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			632 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // Copyright 2015 the V8 project authors. All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style license that can be
 | |
| // found in the LICENSE file.
 | |
| 
 | |
| // script-level tests
 | |
| var ox, oy = {}, oz;
 | |
| ({
 | |
|   x: ox,
 | |
|   y: oy.value,
 | |
|   y2: oy["value2"],
 | |
|   z: ({ set v(val) { oz = val; } }).v
 | |
| } = {
 | |
|   x: "value of x",
 | |
|   y: "value of y1",
 | |
|   y2: "value of y2",
 | |
|   z: "value of z"
 | |
| });
 | |
| assertEquals("value of x", ox);
 | |
| assertEquals("value of y1", oy.value);
 | |
| assertEquals("value of y2", oy.value2);
 | |
| assertEquals("value of z", oz);
 | |
| 
 | |
| [ox, oy.value, oy["value2"], ...{ set v(val) { oz = val; } }.v] = [
 | |
|   1007,
 | |
|   798432,
 | |
|   555,
 | |
|   1, 2, 3, 4, 5
 | |
| ];
 | |
| assertEquals(ox, 1007);
 | |
| assertEquals(oy.value, 798432);
 | |
| assertEquals(oy.value2, 555);
 | |
| assertEquals(oz, [1, 2, 3, 4, 5]);
 | |
| 
 | |
| 
 | |
| (function testInFunction() {
 | |
|   var x, y = {}, z;
 | |
|   ({
 | |
|     x: x,
 | |
|     y: y.value,
 | |
|     y2: y["value2"],
 | |
|     z: ({ set v(val) { z = val; } }).v
 | |
|   } = {
 | |
|     x: "value of x",
 | |
|     y: "value of y1",
 | |
|     y2: "value of y2",
 | |
|     z: "value of z"
 | |
|   });
 | |
|   assertEquals("value of x", x);
 | |
|   assertEquals("value of y1", y.value);
 | |
|   assertEquals("value of y2", y.value2);
 | |
|   assertEquals("value of z", z);
 | |
| 
 | |
|   [x, y.value, y["value2"], ...{ set v(val) { z = val; } }.v] = [
 | |
|     1007,
 | |
|     798432,
 | |
|     555,
 | |
|     1, 2, 3, 4, 5
 | |
|   ];
 | |
|   assertEquals(x, 1007);
 | |
|   assertEquals(y.value, 798432);
 | |
|   assertEquals(y.value2, 555);
 | |
|   assertEquals(z, [1, 2, 3, 4, 5]);
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function testArrowFunctionInitializers() {
 | |
|   var fn = (config = {
 | |
|     value: defaults.value,
 | |
|     nada: { nada: defaults.nada } = { nada: "nothing" }
 | |
|   } = { value: "BLAH" }) => config;
 | |
|   var defaults = {};
 | |
|   assertEquals({ value: "BLAH" }, fn());
 | |
|   assertEquals("BLAH", defaults.value);
 | |
|   assertEquals("nothing", defaults.nada);
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function testArrowFunctionInitializers2() {
 | |
|   var fn = (config = [
 | |
|     defaults.value,
 | |
|     { nada: defaults.nada } = { nada: "nothing" }
 | |
|   ] = ["BLAH"]) => config;
 | |
|   var defaults = {};
 | |
|   assertEquals(["BLAH"], fn());
 | |
|   assertEquals("BLAH", defaults.value);
 | |
|   assertEquals("nothing", defaults.nada);
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function testFunctionInitializers() {
 | |
|   function fn(config = {
 | |
|     value: defaults.value,
 | |
|     nada: { nada: defaults.nada } = { nada: "nothing" }
 | |
|   } = { value: "BLAH" }) {
 | |
|     return config;
 | |
|   }
 | |
|   var defaults = {};
 | |
|   assertEquals({ value: "BLAH" }, fn());
 | |
|   assertEquals("BLAH", defaults.value);
 | |
|   assertEquals("nothing", defaults.nada);
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function testFunctionInitializers2() {
 | |
|   function fn(config = [
 | |
|     defaults.value,
 | |
|     { nada: defaults.nada } = { nada: "nothing" }
 | |
|   ] = ["BLAH"]) { return config; }
 | |
|   var defaults = {};
 | |
|   assertEquals(["BLAH"], fn());
 | |
|   assertEquals("BLAH", defaults.value);
 | |
|   assertEquals("nothing", defaults.nada);
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function testDeclarationInitializers() {
 | |
|   var defaults = {};
 | |
|   var { value } = { value: defaults.value } = { value: "BLAH" };
 | |
|   assertEquals("BLAH", value);
 | |
|   assertEquals("BLAH", defaults.value);
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function testDeclarationInitializers2() {
 | |
|   var defaults = {};
 | |
|   var [value] = [defaults.value] = ["BLAH"];
 | |
|   assertEquals("BLAH", value);
 | |
|   assertEquals("BLAH", defaults.value);
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function testObjectLiteralProperty() {
 | |
|   var ext = {};
 | |
|   var obj = {
 | |
|     a: { b: ext.b, c: ext["c"], d: { set v(val) { ext.d = val; } }.v } = {
 | |
|       b: "b", c: "c", d: "d" }
 | |
|   };
 | |
|   assertEquals({ b: "b", c: "c", d: "d" }, ext);
 | |
|   assertEquals({ a: { b: "b", c: "c", d: "d" } }, obj);
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function testArrayLiteralProperty() {
 | |
|   var ext = {};
 | |
|   var obj = [
 | |
|     ...[ ext.b, ext["c"], { set v(val) { ext.d = val; } }.v ] = [
 | |
|       "b", "c", "d" ]
 | |
|   ];
 | |
|   assertEquals({ b: "b", c: "c", d: "d" }, ext);
 | |
|   assertEquals([ "b", "c", "d" ], obj);
 | |
| })();
 | |
| 
 | |
| 
 | |
| // TODO(caitp): add similar test for ArrayPatterns, once Proxies support
 | |
| // delegating symbol-keyed get/set.
 | |
| (function testObjectPatternOperationOrder() {
 | |
|   var steps = [];
 | |
|   var store = {};
 | |
|   function computePropertyName(name) {
 | |
|     steps.push("compute name: " + name);
 | |
|     return name;
 | |
|   }
 | |
|   function loadValue(descr, value) {
 | |
|     steps.push("load: " + descr + " > " + value);
 | |
|     return value;
 | |
|   }
 | |
|   function storeValue(descr, name, value) {
 | |
|     steps.push("store: " + descr + " = " + value);
 | |
|     store[name] = value;
 | |
|   }
 | |
|   var result = {
 | |
|     get a() { assertUnreachable(); },
 | |
|     set a(value) { storeValue("result.a", "a", value); },
 | |
|     get b() { assertUnreachable(); },
 | |
|     set b(value) { storeValue("result.b", "b", value); }
 | |
|   };
 | |
| 
 | |
|   ({
 | |
|     obj: {
 | |
|       x: result.a = 10,
 | |
|       [computePropertyName("y")]: result.b = false,
 | |
|     } = {}
 | |
|   } = { obj: {
 | |
|     get x() { return loadValue(".temp.obj.x", undefined); },
 | |
|     set x(value) { assertUnreachable(); },
 | |
|     get y() { return loadValue(".temp.obj.y", undefined); },
 | |
|     set y(value) { assertUnreachable(); }
 | |
|   }});
 | |
| 
 | |
|   assertPropertiesEqual({
 | |
|     a: 10,
 | |
|     b: false
 | |
|   }, store);
 | |
| 
 | |
|   assertArrayEquals([
 | |
|     "load: .temp.obj.x > undefined",
 | |
|     "store: result.a = 10",
 | |
| 
 | |
|     "compute name: y",
 | |
|     "load: .temp.obj.y > undefined",
 | |
|     "store: result.b = false"
 | |
|   ], steps);
 | |
| 
 | |
|   steps = [];
 | |
| 
 | |
|   ({
 | |
|     obj: {
 | |
|       x: result.a = 50,
 | |
|       [computePropertyName("y")]: result.b = "hello",
 | |
|     } = {}
 | |
|   } = { obj: {
 | |
|     get x() { return loadValue(".temp.obj.x", 20); },
 | |
|     set x(value) { assertUnreachable(); },
 | |
|     get y() { return loadValue(".temp.obj.y", true); },
 | |
|     set y(value) { assertUnreachable(); }
 | |
|   }});
 | |
| 
 | |
|   assertPropertiesEqual({
 | |
|     a: 20,
 | |
|     b: true
 | |
|   }, store);
 | |
| 
 | |
|   assertArrayEquals([
 | |
|     "load: .temp.obj.x > 20",
 | |
|     "store: result.a = 20",
 | |
|     "compute name: y",
 | |
|     "load: .temp.obj.y > true",
 | |
|     "store: result.b = true",
 | |
|   ], steps);
 | |
| })();
 | |
| 
 | |
| // Credit to Mike Pennisi and other Test262 contributors for originally writing
 | |
| // the testse the following are based on.
 | |
| (function testArrayElision() {
 | |
|   var value = [1, 2, 3, 4, 5, 6, 7, 8, 9];
 | |
|   var a, obj = {};
 | |
|   var result = [, a, , obj.b, , ...obj["rest"]] = value;
 | |
| 
 | |
|   assertEquals(result, value);
 | |
|   assertEquals(2, a);
 | |
|   assertEquals(4, obj.b);
 | |
|   assertArrayEquals([6, 7, 8, 9], obj.rest);
 | |
| })();
 | |
| 
 | |
| (function testArrayElementInitializer() {
 | |
|   function test(value, initializer, expected) {
 | |
|     var a, obj = {};
 | |
|     var initialized = false;
 | |
|     var shouldBeInitialized = value[0] === undefined;
 | |
|     assertEquals(value, [ a = (initialized = true, initializer) ] = value);
 | |
|     assertEquals(expected, a);
 | |
|     assertEquals(shouldBeInitialized, initialized);
 | |
| 
 | |
|     var initialized2 = false;
 | |
|     assertEquals(value, [ obj.a = (initialized2 = true, initializer) ] = value);
 | |
|     assertEquals(expected, obj.a);
 | |
|     assertEquals(shouldBeInitialized, initialized2);
 | |
|   }
 | |
| 
 | |
|   test([], "BAM!", "BAM!");
 | |
|   test([], "BOOP!", "BOOP!");
 | |
|   test([null], 123, null);
 | |
|   test([undefined], 456, 456);
 | |
|   test([,], "PUPPIES", "PUPPIES");
 | |
| 
 | |
|   (function accept_IN() {
 | |
|     var value = [], x;
 | |
|     assertEquals(value, [ x = 'x' in {} ] = value);
 | |
|     assertEquals(false, x);
 | |
|   })();
 | |
| 
 | |
|   (function ordering() {
 | |
|     var x = 0, a, b, value = [];
 | |
|     assertEquals(value, [ a = x += 1, b = x *= 2 ] = value);
 | |
|     assertEquals(1, a);
 | |
|     assertEquals(2, b);
 | |
|     assertEquals(2, x);
 | |
|   })();
 | |
| 
 | |
|   (function yieldExpression() {
 | |
|     var value = [], it, result, x;
 | |
|     it = (function*() {
 | |
|       result = [ x = yield ] = value;
 | |
|     })();
 | |
|     var next = it.next();
 | |
| 
 | |
|     assertEquals(undefined, result);
 | |
|     assertEquals(undefined, next.value);
 | |
|     assertEquals(false, next.done);
 | |
|     assertEquals(undefined, x);
 | |
| 
 | |
|     next = it.next(86);
 | |
| 
 | |
|     assertEquals(value, result);
 | |
|     assertEquals(undefined, next.value);
 | |
|     assertEquals(true, next.done);
 | |
|     assertEquals(86, x);
 | |
|   })();
 | |
| 
 | |
|   (function yieldIdentifier() {
 | |
|     var value = [], yield = "BOOP!", x;
 | |
|     assertEquals(value, [ x = yield ] = value);
 | |
|     assertEquals("BOOP!", x);
 | |
|   })();
 | |
| 
 | |
|   assertThrows(function let_TDZ() {
 | |
|     "use strict";
 | |
|     var x;
 | |
|     [ x = y ] = [];
 | |
|     let y;
 | |
|   }, ReferenceError);
 | |
| })();
 | |
| 
 | |
| 
 | |
| (function testArrayElementNestedPattern() {
 | |
|   assertThrows(function nestedArrayRequireObjectCoercibleNull() {
 | |
|     var x; [ [ x ] ] = [ null ];
 | |
|   }, TypeError);
 | |
| 
 | |
|   assertThrows(function nestedArrayRequireObjectCoercibleUndefined() {
 | |
|     var x; [ [ x ] ] = [ undefined ];
 | |
|   }, TypeError);
 | |
| 
 | |
|   assertThrows(function nestedArrayRequireObjectCoercibleUndefined2() {
 | |
|     var x; [ [ x ] ] = [ ];
 | |
|   }, TypeError);
 | |
| 
 | |
|   assertThrows(function nestedArrayRequireObjectCoercibleUndefined3() {
 | |
|     var x; [ [ x ] ] = [ , ];
 | |
|   }, TypeError);
 | |
| 
 | |
|   assertThrows(function nestedObjectRequireObjectCoercibleNull() {
 | |
|     var x; [ { x } ] = [ null ];
 | |
|   }, TypeError);
 | |
| 
 | |
|   assertThrows(function nestedObjectRequireObjectCoercibleUndefined() {
 | |
|     var x; [ { x } ] = [ undefined ];
 | |
|   }, TypeError);
 | |
| 
 | |
|   assertThrows(function nestedObjectRequireObjectCoercibleUndefined2() {
 | |
|     var x; [ { x } ] = [ ];
 | |
|   }, TypeError);
 | |
| 
 | |
|   assertThrows(function nestedObjectRequireObjectCoercibleUndefined3() {
 | |
|     var x; [ { x } ] = [ , ];
 | |
|   }, TypeError);
 | |
| 
 | |
|   (function nestedArray() {
 | |
|     var x, value = [ [ "zap", "blonk" ] ];
 | |
|     assertEquals(value, [ [ , x ] ] = value);
 | |
|     assertEquals("blonk", x);
 | |
|   })();
 | |
| 
 | |
|   (function nestedObject() {
 | |
|     var x, value = [ { a: "zap", b: "blonk" } ];
 | |
|     assertEquals(value, [ { b: x } ] = value);
 | |
|     assertEquals("blonk", x);
 | |
|   })();
 | |
| })();
 | |
| 
 | |
| (function testArrayRestElement() {
 | |
|   (function testBasic() {
 | |
|     var x, rest, array = [1, 2, 3];
 | |
|     assertEquals(array, [x, ...rest] = array);
 | |
|     assertEquals(1, x);
 | |
|     assertEquals([2, 3], rest);
 | |
| 
 | |
|     array = [4, 5, 6];
 | |
|     assertEquals(array, [, ...rest] = array);
 | |
|     assertEquals([5, 6], rest);
 | |
| 
 | |
|   })();
 | |
| 
 | |
|   (function testNestedRestObject() {
 | |
|     var value = [1, 2, 3], x;
 | |
|     assertEquals(value, [...{ 1: x }] = value);
 | |
|     assertEquals(2, x);
 | |
|   })();
 | |
| 
 | |
|   (function iterable() {
 | |
|     var count = 0;
 | |
|     var x, y, z;
 | |
|     function* g() {
 | |
|       count++;
 | |
|       yield;
 | |
|       count++;
 | |
|       yield;
 | |
|       count++;
 | |
|       yield;
 | |
|     }
 | |
|     var it = g();
 | |
|     assertEquals(it, [...x] = it);
 | |
|     assertEquals([undefined, undefined, undefined], x);
 | |
|     assertEquals(3, count);
 | |
| 
 | |
|     it = [g()];
 | |
|     assertEquals(it, [ [...y] ] = it);
 | |
|     assertEquals([undefined, undefined, undefined], y);
 | |
|     assertEquals(6, count);
 | |
| 
 | |
|     it = { a: g() };
 | |
|     assertEquals(it, { a: [...z] } = it);
 | |
|     assertEquals([undefined, undefined, undefined], z);
 | |
|     assertEquals(9, count);
 | |
|   })();
 | |
| })();
 | |
| 
 | |
| (function testRequireObjectCoercible() {
 | |
|   assertThrows(() => ({} = undefined), TypeError);
 | |
|   assertThrows(() => ({} = null), TypeError);
 | |
|   assertThrows(() => [] = undefined, TypeError);
 | |
|   assertThrows(() => [] = null, TypeError);
 | |
|   assertEquals("test", ({} = "test"));
 | |
|   assertEquals("test", [] = "test");
 | |
|   assertEquals(123, ({} = 123));
 | |
| })();
 | |
| 
 | |
| (function testConstReassignment() {
 | |
|   "use strict";
 | |
|   const c = "untouchable";
 | |
|   assertThrows(() => { [ c ] = [ "nope!" ]; }, TypeError);
 | |
|   assertThrows(() => { [ [ c ] ]  = [ [ "nope!" ] ]; }, TypeError);
 | |
|   assertThrows(() => { [ { c } ]  = [ { c: "nope!" } ]; }, TypeError);
 | |
|   assertThrows(() => { ({ c } = { c: "nope!" }); }, TypeError);
 | |
|   assertThrows(() => { ({ a: { c } } = { a: { c: "nope!" } }); }, TypeError);
 | |
|   assertThrows(() => { ({ a: [ c ] } = { a: [ "nope!" ] }); }, TypeError);
 | |
|   assertEquals("untouchable", c);
 | |
| })();
 | |
| 
 | |
| (function testForIn() {
 | |
|   var log = [];
 | |
|   var x = {};
 | |
|   var object = {
 | |
|     "Apenguin": 1,
 | |
|     "\u{1F382}cake": 2,
 | |
|     "Bpuppy": 3,
 | |
|     "Cspork": 4
 | |
|   };
 | |
|   for ([x.firstLetter, ...x.rest] in object) {
 | |
|     if (x.firstLetter === "A") {
 | |
|       assertEquals(["p", "e", "n", "g", "u", "i", "n"], x.rest);
 | |
|       continue;
 | |
|     }
 | |
|     if (x.firstLetter === "C") {
 | |
|       assertEquals(["s", "p", "o", "r", "k"], x.rest);
 | |
|       break;
 | |
|     }
 | |
|     log.push({ firstLetter: x.firstLetter, rest: x.rest });
 | |
|   }
 | |
|   assertEquals([
 | |
|     { firstLetter: "\u{1F382}", rest: ["c", "a", "k", "e"] },
 | |
|     { firstLetter: "B", rest: ["p", "u", "p", "p", "y"] },
 | |
|   ], log);
 | |
| })();
 | |
| 
 | |
| (function testForOf() {
 | |
|   var log = [];
 | |
|   var x = {};
 | |
|   var names = [
 | |
|     "Apenguin",
 | |
|     "\u{1F382}cake",
 | |
|     "Bpuppy",
 | |
|     "Cspork"
 | |
|   ];
 | |
|   for ([x.firstLetter, ...x.rest] of names) {
 | |
|     if (x.firstLetter === "A") {
 | |
|       assertEquals(["p", "e", "n", "g", "u", "i", "n"], x.rest);
 | |
|       continue;
 | |
|     }
 | |
|     if (x.firstLetter === "C") {
 | |
|       assertEquals(["s", "p", "o", "r", "k"], x.rest);
 | |
|       break;
 | |
|     }
 | |
|     log.push({ firstLetter: x.firstLetter, rest: x.rest });
 | |
|   }
 | |
|   assertEquals([
 | |
|     { firstLetter: "\u{1F382}", rest: ["c", "a", "k", "e"] },
 | |
|     { firstLetter: "B", rest: ["p", "u", "p", "p", "y"] },
 | |
|   ], log);
 | |
| })();
 | |
| 
 | |
| (function testNewTarget() {
 | |
|   assertThrows("(function() { [...new.target] = []; })", SyntaxError);
 | |
|   assertThrows("(function() { [a] = [...new.target] = []; })", SyntaxError);
 | |
|   assertThrows("(function() { [new.target] = []; })", SyntaxError);
 | |
|   assertThrows("(function() { [a] = [new.target] = []; })", SyntaxError);
 | |
|   assertThrows("(function() { ({ a: new.target] = {a: 0}); })", SyntaxError);
 | |
|   assertThrows("(function() { ({ a } = { a: new.target } = {}); })",
 | |
|                SyntaxError);
 | |
| 
 | |
|   function ReturnNewTarget1() {
 | |
|     var result;
 | |
|     [result = new.target] = [];
 | |
|     return result;
 | |
|   }
 | |
| 
 | |
|   function ReturnNewTarget2() {
 | |
|     var result;
 | |
|     [result] = [new.target];
 | |
|     return result;
 | |
|   }
 | |
| 
 | |
|   function ReturnNewTarget3() {
 | |
|     var result;
 | |
|     ({ result = new.target } = {});
 | |
|     return result;
 | |
|   }
 | |
| 
 | |
|   function ReturnNewTarget4() {
 | |
|     var result;
 | |
|     ({ result } = { result: new.target });
 | |
|     return result;
 | |
|   }
 | |
| 
 | |
|   function FakeNewTarget() {}
 | |
| 
 | |
|   function construct() {
 | |
|     assertEquals(undefined, ReturnNewTarget1());
 | |
|     assertEquals(ReturnNewTarget1, new ReturnNewTarget1());
 | |
|     assertEquals(FakeNewTarget,
 | |
|                  Reflect.construct(ReturnNewTarget1, [], FakeNewTarget));
 | |
| 
 | |
|     assertEquals(undefined, ReturnNewTarget2());
 | |
|     assertEquals(ReturnNewTarget2, new ReturnNewTarget2());
 | |
|     assertEquals(FakeNewTarget,
 | |
|                  Reflect.construct(ReturnNewTarget2, [], FakeNewTarget));
 | |
| 
 | |
|     assertEquals(undefined, ReturnNewTarget3());
 | |
|     assertEquals(ReturnNewTarget3, new ReturnNewTarget3());
 | |
|     assertEquals(FakeNewTarget,
 | |
|                  Reflect.construct(ReturnNewTarget3, [], FakeNewTarget));
 | |
| 
 | |
|     assertEquals(undefined, ReturnNewTarget4());
 | |
|     assertEquals(ReturnNewTarget4, new ReturnNewTarget4());
 | |
|     assertEquals(FakeNewTarget,
 | |
|                  Reflect.construct(ReturnNewTarget4, [], FakeNewTarget));
 | |
|   }
 | |
|   construct();
 | |
|   FakeNewTarget.prototype = 1;
 | |
|   construct();
 | |
| })();
 | |
| 
 | |
| (function testSuperCall() {
 | |
|   function ctor(body) {
 | |
|     return () => eval("(class extends Object { \n" +
 | |
|                       "  constructor() {\n" +
 | |
|                       body +
 | |
|                       "\n  }\n" +
 | |
|                       "})");
 | |
|   }
 | |
|   assertThrows(ctor("({ new: super() } = {})"), SyntaxError);
 | |
|   assertThrows(ctor("({ new: x } = { new: super() } = {})"), SyntaxError);
 | |
|   assertThrows(ctor("[super()] = []"), SyntaxError);
 | |
|   assertThrows(ctor("[x] = [super()] = []"), SyntaxError);
 | |
|   assertThrows(ctor("[...super()] = []"), SyntaxError);
 | |
|   assertThrows(ctor("[x] = [...super()] = []"), SyntaxError);
 | |
| 
 | |
|   class Base { get foo() { return 1; } }
 | |
|   function ext(body) {
 | |
|     return eval("new (class extends Base {\n" +
 | |
|                 "  constructor() {\n" +
 | |
|                 body + ";\n" +
 | |
|                 "  return { x: super.foo }" +
 | |
|                 "\n  }\n" +
 | |
|                 "})");
 | |
|   }
 | |
|   assertEquals(1, ext("let x; [x = super()] = []").x);
 | |
|   assertEquals(1, ext("let x, y; [y] = [x = super()] = []").x);
 | |
|   assertEquals(1, ext("let x; [x] = [super()]").x);
 | |
|   assertEquals(1, ext("let x, y; [y] = [x] = [super()]").x);
 | |
| 
 | |
|   assertEquals(1, ext("let x; ({x = super()} = {})").x);
 | |
|   assertEquals(1, ext("let x, y; ({ x: y } = { x = super() } = {})").x);
 | |
|   assertEquals(1, ext("let x; ({x} = { x: super() })").x);
 | |
|   assertEquals(1, ext("let x, y; ({ x: y } = { x } = { x: super() })").x);
 | |
| })();
 | |
| 
 | |
| (function testInvalidReturn() {
 | |
|   function* g() { yield 1; }
 | |
| 
 | |
|   let executed_x_setter;
 | |
|   let executed_return;
 | |
|   var a = {
 | |
|     set x(val) {
 | |
|       executed_x_setter = true;
 | |
|       throw 3;
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   // The exception from the execution of g().return() should be suppressed by
 | |
|   // the setter error.
 | |
|   executed_x_setter = false;
 | |
|   executed_return = false;
 | |
|   g.prototype.return = function() {
 | |
|     executed_return = true;
 | |
|     throw 4;
 | |
|   };
 | |
|   assertThrowsEquals("[a.x] = g()", 3);
 | |
|   assertTrue(executed_x_setter);
 | |
|   assertTrue(executed_return);
 | |
| 
 | |
|   // The exception from g().return() not returning an object should be
 | |
|   // suppressed by the setter error.
 | |
|   executed_x_setter = false;
 | |
|   executed_return = false;
 | |
|   g.prototype.return = function() {
 | |
|     assertTrue(executed_return);
 | |
|     return null;
 | |
|   };
 | |
|   assertThrowsEquals("[a.x] = g()", 3);
 | |
|   assertTrue(executed_x_setter);
 | |
|   assertTrue(executed_return);
 | |
| 
 | |
|   // The TypeError from g().return not being a method should suppress the setter
 | |
|   // error.
 | |
|   executed_x_setter = false;
 | |
|   g.prototype.return = "not a method";
 | |
|   assertThrows("[a.x] = g()", TypeError);
 | |
|   assertTrue(executed_x_setter);
 | |
| 
 | |
|   // The exception from the access of g().return should suppress the setter
 | |
|   // error.
 | |
|   executed_x_setter = false;
 | |
|   Object.setPrototypeOf(g.prototype, {
 | |
|     get return() {
 | |
|       throw 4;
 | |
|     }
 | |
|   });
 | |
|   assertThrowsEquals("[a.x] = g()", 4);
 | |
|   assertTrue(executed_x_setter);
 | |
| })
 |