mirror of https://github.com/tc39/test262.git
Add tests for Logical Assignment
This commit is contained in:
parent
6499fa6794
commit
fdf4675da9
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: Logical And Assignment Operator
|
||||
features: [BigInt]
|
||||
info: |
|
||||
AssignmentExpression:
|
||||
LeftHandSideExpression &&= AssignmentExpression
|
||||
|
||||
1. Let lref be the result of evaluating LeftHandSideExpression.
|
||||
2. Let lval be ? GetValue(lref).
|
||||
3. Let lbool be ! ToBoolean(lval).
|
||||
4. If lbool is false, return lval.
|
||||
5. Let rref be the result of evaluating AssignmentExpression.
|
||||
6. Let rval be ? GetValue(rref).
|
||||
7. Perform ? PutValue(lref, rval).
|
||||
8. Return rval.
|
||||
|
||||
---*/
|
||||
|
||||
var value = 0n;
|
||||
assert.sameValue(value &&= 1n, "test", "(value &&= 1n) === 0n; where value = 0n");
|
||||
|
||||
var value = 2n;
|
||||
assert.sameValue(value &&= 1n, "test", "(value &&= 1n) === 1n; where value = 2n");
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
The LeftHandSideExpression is evaluated before the AssignmentExpression.
|
||||
|
||||
---*/
|
||||
|
||||
function DummyError() { }
|
||||
|
||||
assert.throws(DummyError, function() {
|
||||
var base = null;
|
||||
var prop = function() {
|
||||
throw new DummyError();
|
||||
};
|
||||
var expr = function() {
|
||||
throw new Test262Error("right-hand side expression evaluated");
|
||||
};
|
||||
|
||||
base[prop()] &&= expr();
|
||||
});
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
var base = null;
|
||||
var prop = {
|
||||
toString: function() {
|
||||
throw new Test262Error("property key evaluated");
|
||||
}
|
||||
};
|
||||
var expr = function() {
|
||||
throw new Test262Error("right-hand side expression evaluated");
|
||||
};
|
||||
|
||||
base[prop] &&= expr();
|
||||
});
|
||||
|
||||
var count = 0;
|
||||
var obj = {};
|
||||
function incr() {
|
||||
return ++count;
|
||||
}
|
||||
|
||||
assert.sameValue(obj[incr()] &&= incr(), undefined, "obj[incr()] &&= incr()");
|
||||
assert.sameValue(obj[1], undefined, "obj[1]");
|
||||
assert.sameValue(count, 1, "count");
|
||||
|
||||
obj[2] = 1;
|
||||
assert.sameValue(obj[incr()] &&= incr(), 3, "obj[incr()] &&= incr()");
|
||||
assert.sameValue(obj[2], 3, "obj[2]");
|
||||
assert.sameValue(count, 3, "count");
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
Strict Mode - TypeError is thrown if the LeftHandSide of a Logical
|
||||
Assignment operator(&&=) is a reference to a data property with the
|
||||
attribute value {[[Set]]:undefined} and PutValue step is reached.
|
||||
flags: [onlyStrict]
|
||||
|
||||
---*/
|
||||
|
||||
var obj = {};
|
||||
Object.defineProperty(obj, "prop", {
|
||||
get: function() {
|
||||
return 2;
|
||||
},
|
||||
set: undefined,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
assert.throws(ReferenceError, function() {
|
||||
obj.prop &&= 1;
|
||||
});
|
||||
assert.sameValue(obj.prop, 2, "obj.prop");
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
Strict Mode - TypeError is not thrown if the LeftHandSide of a Logical
|
||||
Assignment operator(&&=) is a reference to a data property with the
|
||||
attribute value {[[Set]]:undefined} and PutValue step is not reached.
|
||||
flags: [onlyStrict]
|
||||
|
||||
---*/
|
||||
|
||||
var obj = {};
|
||||
Object.defineProperty(obj, "prop", {
|
||||
get: function() {
|
||||
return 0;
|
||||
},
|
||||
set: undefined,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
assert.sameValue(obj.prop &&= 1, 0, "obj.prop");
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
Strict Mode - TypeError is not thrown if The LeftHandSide of a Logical
|
||||
Assignment operator(&&=) is a reference to a non-existent property of an
|
||||
object whose [[Extensible]] internal property is false.
|
||||
flags: [onlyStrict]
|
||||
|
||||
---*/
|
||||
|
||||
var obj = {};
|
||||
Object.preventExtensions(obj);
|
||||
|
||||
obj.prop &&= 1;
|
||||
assert.sameValue(obj.prop, undefined, "obj.prop");
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-static-semantics-early-errors
|
||||
description: >
|
||||
It is a Syntax Error if AssignmentTargetType of LeftHandSideExpression is
|
||||
not simple.
|
||||
negative:
|
||||
phase: parse
|
||||
type: SyntaxError
|
||||
|
||||
---*/
|
||||
|
||||
$DONOTEVALUATE();
|
||||
|
||||
function test() {}
|
||||
test() &&= 1;
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
Strict Mode - TypeError is thrown if the LeftHandSide of a Logical
|
||||
Assignment operator(&&=) is a reference to a data property with the
|
||||
attribute value {[[Writable]]:false} and PutValue step is reached.
|
||||
flags: [onlyStrict]
|
||||
|
||||
---*/
|
||||
|
||||
var obj = {};
|
||||
Object.defineProperty(obj, "prop", {
|
||||
value: 2,
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
assert.throws(ReferenceError, function() {
|
||||
obj.prop &&= 1;
|
||||
});
|
||||
assert.sameValue(obj.prop, 2, "obj.prop");
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
Strict Mode - TypeError is not thrown if the LeftHandSide of a Logical
|
||||
Assignment operator(&&=) is a reference to a data property with the
|
||||
attribute value {[[Writable]]:false} and PutValue step is not reached.
|
||||
flags: [onlyStrict]
|
||||
|
||||
---*/
|
||||
|
||||
var obj = {};
|
||||
Object.defineProperty(obj, "prop", {
|
||||
value: 0,
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
assert.sameValue(obj.prop &&= 1, 0, "obj.prop");
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
ReferenceError is thrown if the LeftHandSideExpression of a Logical
|
||||
Assignment operator(&&=) evaluates to an unresolvable reference
|
||||
flags: [onlyStrict]
|
||||
|
||||
---*/
|
||||
|
||||
assert.throws(ReferenceError, function() {
|
||||
unresolved &&= 1;
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
ReferenceError is thrown if the AssignmentExpression of a Logical
|
||||
Assignment operator(&&=) evaluates to an unresolvable reference and the
|
||||
AssignmentExpression is evaluated.
|
||||
|
||||
---*/
|
||||
|
||||
var value = 2;
|
||||
|
||||
assert.throws(ReferenceError, function() {
|
||||
value &&= unresolved;
|
||||
});
|
||||
assert.sameValue(value, 2, "value");
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
ReferenceError is not thrown if the AssignmentExpression of a Logical
|
||||
Assignment operator(&&=) evaluates to an unresolvable reference and the
|
||||
AssignmentExpression is not evaluated.
|
||||
|
||||
---*/
|
||||
|
||||
var value = 0;
|
||||
|
||||
assert.sameValue(value &&= unresolved, 0, "value");
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: Logical And Assignment Operator
|
||||
info: |
|
||||
AssignmentExpression:
|
||||
LeftHandSideExpression &&= AssignmentExpression
|
||||
|
||||
1. Let lref be the result of evaluating LeftHandSideExpression.
|
||||
2. Let lval be ? GetValue(lref).
|
||||
3. Let lbool be ! ToBoolean(lval).
|
||||
4. If lbool is false, return lval.
|
||||
5. Let rref be the result of evaluating AssignmentExpression.
|
||||
6. Let rval be ? GetValue(rref).
|
||||
7. Perform ? PutValue(lref, rval).
|
||||
8. Return rval.
|
||||
|
||||
---*/
|
||||
|
||||
var value = undefined;
|
||||
assert.sameValue(value &&= 1, undefined, "(value &&= 1) === undefined; where value = undefined");
|
||||
|
||||
value = null;
|
||||
assert.sameValue(value &&= 1, null, "(value &&= 1) === null where value = null");
|
||||
|
||||
value = false;
|
||||
assert.sameValue(value &&= 1, false, "(value &&= 1) === false; where value = false");
|
||||
|
||||
value = 0;
|
||||
assert.sameValue(value &&= 1, 0, "(value &&= 1) === 0; where value = 0");
|
||||
|
||||
value = -0;
|
||||
assert.sameValue(value &&= 1, -0, "(value &&= 1) === -0; where value = -0");
|
||||
|
||||
value = NaN;
|
||||
assert.sameValue(value &&= 1, NaN, "(value &&= 1) === NaN; where value = NaN");
|
||||
|
||||
value = "";
|
||||
assert.sameValue(value &&= 1, "", '(value &&= 1) === "" where value = ""');
|
||||
|
||||
|
||||
|
||||
value = true;
|
||||
assert.sameValue(value &&= 1, 1, "(value &&= 1) === 1; where value = true");
|
||||
|
||||
value = 2;
|
||||
assert.sameValue(value &&= 1, 1, "(value &&= 1) === 1; where value = 2");
|
||||
|
||||
value = "test";
|
||||
assert.sameValue(value &&= 1, 1, '(value &&= 1) === 1; where value = "test"');
|
||||
|
||||
var sym = Symbol("");
|
||||
value = sym;
|
||||
assert.sameValue(value &&= 1, 1, "(value &&= 1) === 1; where value = Symbol()");
|
||||
|
||||
var obj = {};
|
||||
value = obj;
|
||||
assert.sameValue(value &&= 1, 1, "(value &&= 1) === 1; where value = {}");
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: Logical Nullish Assignment Operator
|
||||
features: [BigInt]
|
||||
info: |
|
||||
AssignmentExpression:
|
||||
LeftHandSideExpression ??= AssignmentExpression
|
||||
|
||||
1. Let lref be the result of evaluating LeftHandSideExpression.
|
||||
2. Let lval be ? GetValue(lref).
|
||||
3. If lval is neither undefined nor null, return lval.
|
||||
4. Let rref be the result of evaluating AssignmentExpression.
|
||||
5. Let rval be ? GetValue(rref).
|
||||
6. Perform ? PutValue(lref, rval).
|
||||
7. Return rval.
|
||||
|
||||
---*/
|
||||
|
||||
var value = 0n;
|
||||
assert.sameValue(value ??= 1n, "test", "(value ??= 1n) === 0n; where value = 0n");
|
||||
|
||||
var value = 2n;
|
||||
assert.sameValue(value ??= 1n, "test", "(value ??= 1n) === 2n; where value = 2n");
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
The LeftHandSideExpression is evaluated before the AssignmentExpression.
|
||||
|
||||
---*/
|
||||
|
||||
function DummyError() { }
|
||||
|
||||
assert.throws(DummyError, function() {
|
||||
var base = null;
|
||||
var prop = function() {
|
||||
throw new DummyError();
|
||||
};
|
||||
var expr = function() {
|
||||
throw new Test262Error("right-hand side expression evaluated");
|
||||
};
|
||||
|
||||
base[prop()] ??= expr();
|
||||
});
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
var base = null;
|
||||
var prop = {
|
||||
toString: function() {
|
||||
throw new Test262Error("property key evaluated");
|
||||
}
|
||||
};
|
||||
var expr = function() {
|
||||
throw new Test262Error("right-hand side expression evaluated");
|
||||
};
|
||||
|
||||
base[prop] ??= expr();
|
||||
});
|
||||
|
||||
var count = 0;
|
||||
var obj = {};
|
||||
function incr() {
|
||||
return ++count;
|
||||
}
|
||||
|
||||
assert.sameValue(obj[incr()] ??= incr(), 2, "obj[incr()] ??= incr()");
|
||||
assert.sameValue(obj[1], 2, "obj[1]");
|
||||
assert.sameValue(count, 1, "count");
|
||||
|
||||
obj[2] = 1;
|
||||
assert.sameValue(obj[incr()] ??= incr(), 3, "obj[incr()] ??= incr()");
|
||||
assert.sameValue(obj[3], 1, "obj[3]");
|
||||
assert.sameValue(count, 3, "count");
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
Strict Mode - TypeError is thrown if the LeftHandSide of a Logical
|
||||
Assignment operator(??=) is a reference to a data property with the
|
||||
attribute value {[[Set]]:undefined} and PutValue step is reached.
|
||||
flags: [onlyStrict]
|
||||
|
||||
---*/
|
||||
|
||||
var obj = {};
|
||||
Object.defineProperty(obj, "prop", {
|
||||
get: function() {
|
||||
return undefined;
|
||||
},
|
||||
set: undefined,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
assert.throws(ReferenceError, function() {
|
||||
obj.prop ??= 1;
|
||||
});
|
||||
assert.sameValue(obj.prop, undefined, "obj.prop");
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
Strict Mode - TypeError is not thrown if the LeftHandSide of a Logical
|
||||
Assignment operator(??=) is a reference to a data property with the
|
||||
attribute value {[[Set]]:undefined} and PutValue step is not reached.
|
||||
flags: [onlyStrict]
|
||||
|
||||
---*/
|
||||
|
||||
var obj = {};
|
||||
Object.defineProperty(obj, "prop", {
|
||||
get: function() {
|
||||
return 0;
|
||||
},
|
||||
set: undefined,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
assert.sameValue(obj.prop ??= 1, 0, "obj.prop");
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
Strict Mode - TypeError is thrown if The LeftHandSide of a Logical
|
||||
Assignment operator(??=) is a reference to a non-existent property
|
||||
of an object whose [[Extensible]] internal property is false.
|
||||
flags: [onlyStrict]
|
||||
|
||||
---*/
|
||||
|
||||
var obj = {};
|
||||
Object.preventExtensions(obj);
|
||||
|
||||
assert.throws(ReferenceError, function() {
|
||||
obj.prop ??= 1;
|
||||
});
|
||||
assert.sameValue(obj.prop, undefined, "obj.prop");
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-static-semantics-early-errors
|
||||
description: >
|
||||
It is a Syntax Error if AssignmentTargetType of LeftHandSideExpression is
|
||||
not simple.
|
||||
negative:
|
||||
phase: parse
|
||||
type: SyntaxError
|
||||
|
||||
---*/
|
||||
|
||||
$DONOTEVALUATE();
|
||||
|
||||
function test() {}
|
||||
test() ??= 1;
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
Strict Mode - TypeError is thrown if the LeftHandSide of a Logical
|
||||
Assignment operator(??=) is a reference to a data property with the
|
||||
attribute value {[[Writable]]:false} and PutValue step is reached.
|
||||
flags: [onlyStrict]
|
||||
|
||||
---*/
|
||||
|
||||
var obj = {};
|
||||
Object.defineProperty(obj, "prop", {
|
||||
value: undefined,
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
assert.throws(ReferenceError, function() {
|
||||
obj.prop ??= 1;
|
||||
});
|
||||
assert.sameValue(obj.prop, undefined, "obj.prop");
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
Strict Mode - TypeError is not thrown if the LeftHandSide of a Logical
|
||||
Assignment operator(??=) is a reference to a data property with the
|
||||
attribute value {[[Writable]]:false} and PutValue step is not reached.
|
||||
flags: [onlyStrict]
|
||||
|
||||
---*/
|
||||
|
||||
var obj = {};
|
||||
Object.defineProperty(obj, "prop", {
|
||||
value: 0,
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
assert.sameValue(obj.prop ??= 1, 0, "obj.prop");
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
ReferenceError is thrown if the LeftHandSideExpression of a Logical
|
||||
Assignment operator(??=) evaluates to an unresolvable reference
|
||||
flags: [onlyStrict]
|
||||
|
||||
---*/
|
||||
|
||||
assert.throws(ReferenceError, function() {
|
||||
unresolved ??= 1;
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
ReferenceError is thrown if the AssignmentExpression of a Logical
|
||||
Assignment operator(??=) evaluates to an unresolvable reference and the
|
||||
AssignmentExpression is evaluated.
|
||||
|
||||
---*/
|
||||
|
||||
var value = undefined;
|
||||
|
||||
assert.throws(ReferenceError, function() {
|
||||
value ??= unresolved;
|
||||
});
|
||||
assert.sameValue(value, undefined, "value");
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
ReferenceError is not thrown if the AssignmentExpression of a Logical
|
||||
Assignment operator(??=) evaluates to an unresolvable reference and the
|
||||
AssignmentExpression is not evaluated.
|
||||
|
||||
---*/
|
||||
|
||||
var value = 0;
|
||||
|
||||
assert.sameValue(value ??= unresolved, 0, "value");
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: Logical Nullish Assignment Operator
|
||||
info: |
|
||||
AssignmentExpression:
|
||||
LeftHandSideExpression ??= AssignmentExpression
|
||||
|
||||
1. Let lref be the result of evaluating LeftHandSideExpression.
|
||||
2. Let lval be ? GetValue(lref).
|
||||
3. If lval is neither undefined nor null, return lval.
|
||||
4. Let rref be the result of evaluating AssignmentExpression.
|
||||
5. Let rval be ? GetValue(rref).
|
||||
6. Perform ? PutValue(lref, rval).
|
||||
7. Return rval.
|
||||
|
||||
---*/
|
||||
|
||||
var value = undefined;
|
||||
assert.sameValue(value ??= 1, 1, "(value ??= 1) === 1; where value = undefined");
|
||||
|
||||
value = null;
|
||||
assert.sameValue(value ??= 1, 1, "(value ??= 1) === 1; where value = null");
|
||||
|
||||
value = false;
|
||||
assert.sameValue(value ??= 1, false, "(value ??= 1) === false; where value = false");
|
||||
|
||||
value = 0;
|
||||
assert.sameValue(value ??= 1, 0, "(value ??= 1) === 0; where value = 0");
|
||||
|
||||
value = -0;
|
||||
assert.sameValue(value ??= 1, -0, "(value ??= 1) === -0; where value = -0");
|
||||
|
||||
value = NaN;
|
||||
assert.sameValue(value ??= 1, NaN, "(value ??= 1) === NaN; where value = NaN");
|
||||
|
||||
value = "";
|
||||
assert.sameValue(value ??= 1, "", '(value ??= 1) === "" where value = ""');
|
||||
|
||||
|
||||
|
||||
value = true;
|
||||
assert.sameValue(value ??= 1, true, "(value ??= 1) === true; where value = true");
|
||||
|
||||
value = 2;
|
||||
assert.sameValue(value ??= 1, 2, "(value ??= 1) === 2; where value = 2");
|
||||
|
||||
value = "test";
|
||||
assert.sameValue(value ??= 1, "test", '(value ??= 1) === "test"; where value = "test"');
|
||||
|
||||
var sym = Symbol("");
|
||||
value = sym;
|
||||
assert.sameValue(value ??= 1, sym, "(value ??= 1) === Symbol(); where value = Symbol()");
|
||||
|
||||
var obj = {};
|
||||
value = obj;
|
||||
assert.sameValue(value ??= 1, obj, "(value ??= 1) === {}; where value = {}");
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: Logical Or Assignment Operator
|
||||
features: [BigInt]
|
||||
info: |
|
||||
AssignmentExpression:
|
||||
LeftHandSideExpression ||= AssignmentExpression
|
||||
|
||||
1. Let lref be the result of evaluating LeftHandSideExpression.
|
||||
2. Let lval be ? GetValue(lref).
|
||||
3. Let lbool be ! ToBoolean(lval).
|
||||
4. If lbool is true, return lval.
|
||||
5. Let rref be the result of evaluating AssignmentExpression.
|
||||
6. Let rval be ? GetValue(rref).
|
||||
7. Perform ? PutValue(lref, rval).
|
||||
8. Return rval.
|
||||
|
||||
---*/
|
||||
|
||||
var value = 0n;
|
||||
assert.sameValue(value ||= 1n, "test", "(value ||= 1n) === 1n; where value = 0n");
|
||||
|
||||
var value = 2n;
|
||||
assert.sameValue(value ||= 1n, "test", "(value ||= 1n) === 2n; where value = 2n");
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
The LeftHandSideExpression is evaluated before the AssignmentExpression.
|
||||
|
||||
---*/
|
||||
|
||||
function DummyError() { }
|
||||
|
||||
assert.throws(DummyError, function() {
|
||||
var base = null;
|
||||
var prop = function() {
|
||||
throw new DummyError();
|
||||
};
|
||||
var expr = function() {
|
||||
throw new Test262Error("right-hand side expression evaluated");
|
||||
};
|
||||
|
||||
base[prop()] ||= expr();
|
||||
});
|
||||
|
||||
assert.throws(Test262Error, function() {
|
||||
var base = null;
|
||||
var prop = {
|
||||
toString: function() {
|
||||
throw new Test262Error("property key evaluated");
|
||||
}
|
||||
};
|
||||
var expr = function() {
|
||||
throw new Test262Error("right-hand side expression evaluated");
|
||||
};
|
||||
|
||||
base[prop] ||= expr();
|
||||
});
|
||||
|
||||
var count = 0;
|
||||
var obj = {};
|
||||
function incr() {
|
||||
return ++count;
|
||||
}
|
||||
|
||||
assert.sameValue(obj[incr()] ||= incr(), 2, "obj[incr()] ||= incr()");
|
||||
assert.sameValue(obj[1], 2, "obj[1]");
|
||||
assert.sameValue(count, 2, "count");
|
||||
|
||||
obj[3] = 1;
|
||||
assert.sameValue(obj[incr()] ||= incr(), 1, "obj[incr()] ||= incr()");
|
||||
assert.sameValue(obj[3], 1, "obj[3]");
|
||||
assert.sameValue(count, 3, "count");
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
Strict Mode - TypeError is thrown if the LeftHandSide of a Logical
|
||||
Assignment operator(||=) is a reference to a data property with the
|
||||
attribute value {[[Set]]:undefined} and PutValue step is reached.
|
||||
flags: [onlyStrict]
|
||||
|
||||
---*/
|
||||
|
||||
var obj = {};
|
||||
Object.defineProperty(obj, "prop", {
|
||||
get: function() {
|
||||
return 0;
|
||||
},
|
||||
set: undefined,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
assert.throws(ReferenceError, function() {
|
||||
obj.prop ||= 1;
|
||||
});
|
||||
assert.sameValue(obj.prop, 0, "obj.prop");
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
Strict Mode - TypeError is not thrown if the LeftHandSide of a Logical
|
||||
Assignment operator(||=) is a reference to a data property with the
|
||||
attribute value {[[Set]]:undefined} and PutValue step is not reached.
|
||||
flags: [onlyStrict]
|
||||
|
||||
---*/
|
||||
|
||||
var obj = {};
|
||||
Object.defineProperty(obj, "prop", {
|
||||
get: function() {
|
||||
return 2;
|
||||
},
|
||||
set: undefined,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
assert.sameValue(obj.prop ||= 1, 2, "obj.prop");
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
Strict Mode - TypeError is thrown if The LeftHandSide of a Logical
|
||||
Assignment operator(||=) is a reference to a non-existent property
|
||||
of an object whose [[Extensible]] internal property is false.
|
||||
flags: [onlyStrict]
|
||||
|
||||
---*/
|
||||
|
||||
var obj = {};
|
||||
Object.preventExtensions(obj);
|
||||
|
||||
assert.throws(ReferenceError, function() {
|
||||
obj.prop ||= 1;
|
||||
});
|
||||
assert.sameValue(obj.prop, undefined, "obj.prop");
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-static-semantics-early-errors
|
||||
description: >
|
||||
It is a Syntax Error if AssignmentTargetType of LeftHandSideExpression is
|
||||
not simple.
|
||||
negative:
|
||||
phase: parse
|
||||
type: SyntaxError
|
||||
|
||||
---*/
|
||||
|
||||
$DONOTEVALUATE();
|
||||
|
||||
function test() {}
|
||||
test() ||= 1;
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
Strict Mode - TypeError is thrown if the LeftHandSide of a Logical
|
||||
Assignment operator(||=) is a reference to a data property with the
|
||||
attribute value {[[Writable]]:false} and PutValue step is reached.
|
||||
flags: [onlyStrict]
|
||||
|
||||
---*/
|
||||
|
||||
var obj = {};
|
||||
Object.defineProperty(obj, "prop", {
|
||||
value: 0,
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
assert.throws(ReferenceError, function() {
|
||||
obj.prop ||= 1;
|
||||
});
|
||||
assert.sameValue(obj.prop, 0, "obj.prop");
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
Strict Mode - TypeError is not thrown if the LeftHandSide of a Logical
|
||||
Assignment operator(||=) is a reference to a data property with the
|
||||
attribute value {[[Writable]]:false} and PutValue step is not reached.
|
||||
flags: [onlyStrict]
|
||||
|
||||
---*/
|
||||
|
||||
var obj = {};
|
||||
Object.defineProperty(obj, "prop", {
|
||||
value: 2,
|
||||
writable: false,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
assert.sameValue(obj.prop ||= 1, 2, "obj.prop");
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
ReferenceError is thrown if the LeftHandSideExpression of a Logical
|
||||
Assignment operator(||=) evaluates to an unresolvable reference
|
||||
flags: [onlyStrict]
|
||||
|
||||
---*/
|
||||
|
||||
assert.throws(ReferenceError, function() {
|
||||
unresolved ||= 1;
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
ReferenceError is thrown if the AssignmentExpression of a Logical
|
||||
Assignment operator(||=) evaluates to an unresolvable reference and the
|
||||
AssignmentExpression is evaluated.
|
||||
|
||||
---*/
|
||||
|
||||
var value = 0;
|
||||
|
||||
assert.throws(ReferenceError, function() {
|
||||
value ||= unresolved;
|
||||
});
|
||||
assert.sameValue(value, 0, "value");
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: >
|
||||
ReferenceError is not thrown if the AssignmentExpression of a Logical
|
||||
Assignment operator(||=) evaluates to an unresolvable reference and the
|
||||
AssignmentExpression is not evaluated.
|
||||
|
||||
---*/
|
||||
|
||||
var value = 2;
|
||||
|
||||
assert.sameValue(value ||= unresolved, 2, "value");
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright (c) 2020 Ecma International. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-assignment-operators-runtime-semantics-evaluation
|
||||
description: Logical Or Assignment Operator
|
||||
info: |
|
||||
AssignmentExpression:
|
||||
LeftHandSideExpression ||= AssignmentExpression
|
||||
|
||||
1. Let lref be the result of evaluating LeftHandSideExpression.
|
||||
2. Let lval be ? GetValue(lref).
|
||||
3. Let lbool be ! ToBoolean(lval).
|
||||
4. If lbool is true, return lval.
|
||||
5. Let rref be the result of evaluating AssignmentExpression.
|
||||
6. Let rval be ? GetValue(rref).
|
||||
7. Perform ? PutValue(lref, rval).
|
||||
8. Return rval.
|
||||
|
||||
---*/
|
||||
|
||||
var value = undefined;
|
||||
assert.sameValue(value ||= 1, 1, "(value ||= 1) === 1; where value = undefined");
|
||||
|
||||
value = null;
|
||||
assert.sameValue(value ||= 1, 1, "(value ||= 1) === 1; where value = null");
|
||||
|
||||
value = false;
|
||||
assert.sameValue(value ||= 1, 1, "(value ||= 1) === 1; where value = false");
|
||||
|
||||
value = 0;
|
||||
assert.sameValue(value ||= 1, 1, "(value ||= 1) === 1; where value = 0");
|
||||
|
||||
value = -0;
|
||||
assert.sameValue(value ||= 1, 1, "(value ||= 1) === 1; where value = -0");
|
||||
|
||||
value = NaN;
|
||||
assert.sameValue(value ||= 1, 1, "(value ||= 1) === 1; where value = NaN");
|
||||
|
||||
value = "";
|
||||
assert.sameValue(value ||= 1, 1, '(value ||= 1) === 1; where value = ""');
|
||||
|
||||
|
||||
|
||||
value = true;
|
||||
assert.sameValue(value ||= 1, true, "(value ||= 1) === true; where value = true");
|
||||
|
||||
value = 2;
|
||||
assert.sameValue(value ||= 1, 2, "(value ||= 1) === 2; where value = 2");
|
||||
|
||||
value = "test";
|
||||
assert.sameValue(value ||= 1, "test", '(value ||= 1) === "test"; where value = "test"');
|
||||
|
||||
var sym = Symbol("");
|
||||
value = sym;
|
||||
assert.sameValue(value ||= 1, sym, "(value ||= 1) === Symbol(); where value = Symbol()");
|
||||
|
||||
var obj = {};
|
||||
value = obj;
|
||||
assert.sameValue(value ||= 1, obj, "(value ||= 1) === {}; where value = {}");
|
Loading…
Reference in New Issue