jerryscript/tests/jerry/es.next/optional-chaining.js
Gergo Csizi f54f2d3a7b
Implement optional chaining (#5164)
The work is based on PR #4843, only fixed some conflicts and cppcheck errors.

Co-authored-by: Robert Fancsik robert.fancsik@h-lab.eu
JerryScript-DCO-1.0-Signed-off-by: Gergo Csizi gergocs@inf.u-szeged.hu
2024-11-20 11:57:58 +01:00

168 lines
3.9 KiB
JavaScript

// Copyright JS Foundation and other contributors, http://js.foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
function expectSyntaxError(str) {
try {
eval(str);
assert(false);
} catch (e) {
assert(e instanceof SyntaxError);
}
}
function expectTypeError(cb) {
try {
cb();
assert(false);
} catch (e) {
assert(e instanceof TypeError);
}
}
expectSyntaxError("this?.a``");
expectSyntaxError("this?.['a']``");
expectSyntaxError("this?.``");
expectSyntaxError("this.a?.``");
expectSyntaxError("this['a']?.``");
expectSyntaxError("this?.a = 9");
expectSyntaxError("this.a.a.a.a.a?.a = 9");
expectSyntaxError("this?.a.a.a.a.a.a = 9");
expectSyntaxError("this?.a++");
expectSyntaxError("this?.a.a.a.a.a.a++");
expectSyntaxError("this.a.a.a.a.?a.a++");
expectSyntaxError("this?.a--");
expectSyntaxError("this?.a.a.a.a.a.a--");
expectSyntaxError("this.a.a.a.a.?a.a--");
var o = {
a: 4.1,
b() {
return 4.2;
},
c: {
a: 4.3,
b() {
return 4.4
}
},
e(...args) {
return args.reduce((p, c) => p + c);
}
}
assert(o?.a === 4.1);
assert(o?.a2 === undefined);
assert(this.o?.a === 4.1);
assert(this.o?.a2 === undefined);
assert(this.o?.['a'] === 4.1);
assert(this.o?.['a2'] === undefined);
assert(typeof o?.a === 'number');
assert(typeof o?.a2 === 'undefined');
assert(o?.c?.a === 4.3);
assert(o?.c?.a2 === undefined);
assert(this.o?.c?.a === 4.3);
assert(this.o?.c?.a2 === undefined);
assert(this.o?.c?.['a'] === 4.3);
assert(this.o?.c?.['a2'] === undefined);
assert(typeof o?.c?.a === 'number');
assert(typeof o?.c?.a2 === 'undefined');
assert(o?.d === undefined);
assert(o?.d?.d === undefined);
assert(o?.d?.d?.['d'] === undefined);
assert(o?.b?.() === 4.2);
assert(o?.b2?.() === undefined);
assert(o?.c?.b?.() === 4.4);
assert(o?.c?.b2?.() === undefined);
assert(o?.e(...[1.25, 2.25, 3.25]) === 6.75);
assert(o?.e(...[1.25, 2.25, 3.25], ...[0.25]) === 7);
assert(o?.['e'](...[1.25, 2.25, 3.25]) === 6.75);
assert(o?.['e'](...[1.25, 2.25, 3.25], ...[0.25]) === 7);
assert(o?.e?.(...[1.25, 2.25, 3.25]) === 6.75);
assert(o?.e?.(...[1.25, 2.25, 3.25], ...[0.25]) === 7);
assert(o?.['e']?.(...[1.25, 2.25, 3.25]) === 6.75);
assert(o?.['e']?.(...[1.25, 2.25, 3.25], ...[0.25]) === 7);
// Test short circuit
let count = 0;
assert(undefined?.[count++] === undefined);
assert(undefined?.[count++]() === undefined);
assert(undefined?.[count++]()() === undefined);
assert(null?.[count++] === undefined);
assert(null?.[count++]() === undefined);
assert(null?.[count++]()() === undefined);
assert(count === 0);
// Test optional call
var g = undefined;
function f () {
return 4.5;
}
assert(g?.() === undefined);
assert(this?.g?.() === undefined);
assert(this.g?.() === undefined);
expectTypeError(_ => {
this.g();
});
assert(f?.() === 4.5);
assert(this?.f?.() === 4.5);
assert(this.f?.() === 4.5);
assert(f() === 4.5);
// test direct eval
var a = 5.1;
eval('a = 5.2');
assert(a === 5.2);
eval?.('a = 5.3');
assert(a === 5.3);
eval?.(...['a = 5.4']);
assert(a === 5.4);
const saved_eval = eval;
eval = undefined;
eval?.('a = 5.5')
assert(a === 5.4);
eval?.(...['a = 5.5'])
assert(a === 5.4);
eval = saved_eval;
// test optional private property access
class A {
#a = 5.1;
test(o) {
return o?.#a;
}
}
let instance = new A;
assert(instance.test(instance) === 5.1);
assert(instance.test(undefined) === undefined);
assert(instance.test(null) === undefined);
expectTypeError(_ => {
instance.test({});
});