test(es/transforms): Copy execution tests from babel (#5578)

This commit is contained in:
Donny/강동윤 2022-08-23 11:10:52 +09:00 committed by GitHub
parent 13b0476da3
commit e2fedb9345
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
357 changed files with 6251 additions and 7 deletions

View File

@ -0,0 +1,3 @@
## Execution tests copied from babel
See https://github.com/babel/babel/blob/main/LICENSE for license

View File

@ -0,0 +1,23 @@
class Bar {
test() {
// pass
(() => {
expect(this.constructor).toBe(Bar);
})();
// pass
(() => {
expect(this.constructor).toBe(Bar);
}).call(this);
(async () => {
expect(this.constructor).toBe(Bar);
})();
(async () => {
expect(this.constructor).toBe(Bar);
}).call(this);
}
}
(new Bar()).test();

View File

@ -0,0 +1,6 @@
function* foo(bar = "bar") {
return bar;
}
expect(foo().next().value).toBe("bar");
expect(foo("foo").next().value).toBe("foo");

View File

@ -0,0 +1,5 @@
function* foo({ bar }) {
return bar;
}
expect(foo({ bar: "bar" }).next().value).toBe("bar");

View File

@ -0,0 +1,57 @@
function* foo() {
var { bar } = { bar: "bar" };
return bar;
}
expect(foo().next().value).toBe("bar");;
function* foo2({ bar = 0 }) {
return bar;
}
expect(foo2({ bar: undefined }).next().value).toBe(0);
expect(foo2({ bar: 3 }).next().value).toBe(3);
function* foo3() {
loop:
while(true) {
// Changing "let" to "var" makes the tests pass.
let { what, value } = yield "iteration";
switch(what) {
case "one":
// Removing these 5 lines makes the tests pass.
if(value === 1) {
break loop;
} else if(value === 2) {
break loop;
}
break;
case "two":
// Removing these 3 lines makes the tests pass.
["a", "b"].map(function(v) {
return value + v;
});
break loop;
break;
case "three":
break loop;
break;
}
}
}
var gen3 = foo3();
expect(gen3.next().value).toBe("iteration");
expect(gen3.next({what: "one", value: 3}).done).toBe(false);
expect(gen3.next({what: "one", value: 2}).done).toBe(true);
var gen4 = foo3();
expect(gen4.next().value).toBe("iteration");
expect(gen4.next({what: "two", value: "sometext"}).done).toBe(true);
var gen5 = foo3();
expect(gen5.next().value).toBe("iteration");
expect(gen5.next({what: "three"}).done).toBe(true);

View File

@ -0,0 +1,5 @@
function* foo(...items) {
return items;
}
expect(foo(1, 2, 3).next().value).toEqual([1, 2, 3]);

View File

@ -0,0 +1,38 @@
const actualOrder = [];
const track = i => {
actualOrder.push(i);
return i;
};
class MyClass {
static [track(1)] = track(10);
[track(2)] = track(13);
get [track(3)]() {
return "foo";
}
set [track(4)](value) {
this.bar = value;
}
[track(5)] = track(14);
static [track(6)] = track(11);
static [track(7)] = track(12);
[track(8)]() {}
[track(9)] = track(15);
}
const inst = new MyClass();
const expectedOrder = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
expect(actualOrder).toEqual(expectedOrder);
expect(MyClass[1]).toBe(10);
expect(inst[2]).toBe(13);
expect(inst[3]).toBe("foo");
inst[4] = "baz";
expect(inst.bar).toBe("baz");
expect(inst[5]).toBe(14);
expect(MyClass[6]).toBe(11);
expect(MyClass[7]).toBe(12);
expect(typeof inst[8]).toBe("function");
expect(inst[9]).toBe(15);

View File

@ -0,0 +1,13 @@
function test(x) {
class F {
[x] = 1;
constructor() {}
}
x = 'deadbeef';
expect(new F().foo).toBe(1);
x = 'wrong';
expect(new F().foo).toBe(1);
}
test('foo');

View File

@ -0,0 +1,15 @@
class A {
static prop = 1;
}
class B extends A {
static prop = 2;
static propA = super.prop;
static getPropA = () => super.prop;
}
const { prop, propA, getPropA } = B;
expect(prop).toBe(2);
expect(propA).toBe(1);
expect(getPropA()).toBe(1);

View File

@ -0,0 +1,9 @@
class A {
static self = this;
static getA = () => this;
}
const { self, getA } = A;
expect(self).toBe(A);
expect(getA()).toBe(A);

View File

@ -0,0 +1,6 @@
class Foo {
static num;
}
expect("num" in Foo).toBe(true);
expect(Foo.num).toBeUndefined();

View File

@ -0,0 +1,9 @@
class Foo {
static num = 0;
static str = "foo";
}
expect(Foo.num).toBe(0);
expect(Foo.num = 1).toBe(1);
expect(Foo.str).toBe("foo");
expect(Foo.str = "bar").toBe("bar");

View File

@ -0,0 +1,22 @@
"use strict";
class Hello {
constructor() {
return {
toString() {
return 'hello';
},
};
}
}
class Outer extends Hello {
constructor() {
class Inner {
[super()] = "hello";
}
return new Inner();
}
}
expect(new Outer().hello).toBe('hello');

View File

@ -0,0 +1,15 @@
class Foo {
#foo = function() {
return this;
}
test(other) {
return [this.#foo(), other.#foo()];
}
}
const f = new Foo;
const o = new Foo;
const test = f.test(o);
expect(test[0]).toBe(f);
expect(test[1]).toBe(o);

View File

@ -0,0 +1,73 @@
class Point {
#x;
#y;
constructor(x = 0, y = 0) {
this.#x = +x;
this.#y = +y;
}
get x() { return this.#x }
set x(value) { this.#x = +value }
get y() { return this.#y }
set y(value) { this.#y = +value }
equals(p) { return this.#x === p.#x && this.#y === p.#y }
toString() { return `Point<${ this.#x },${ this.#y }>` }
}
const p1 = new Point(1, 2);
const p2 = new Point(2, 3);
const p3 = new Point(1, 2);
expect(p1.x).toBe(1);
expect(p1.y).toBe(2);
expect(p2.x).toBe(2);
expect(p2.y).toBe(3);
expect(p3.x).toBe(1);
expect(p3.y).toBe(2);
expect(p1.equals(p1)).toBe(true)
expect(p1.equals(p2)).toBe(false)
expect(p1.equals(p3)).toBe(true)
expect(p2.equals(p1)).toBe(false)
expect(p2.equals(p2)).toBe(true)
expect(p2.equals(p3)).toBe(false)
expect(p3.equals(p1)).toBe(true)
expect(p3.equals(p2)).toBe(false)
expect(p3.equals(p3)).toBe(true)
expect(p1.toString()).toBe("Point<1,2>")
expect(p2.toString()).toBe("Point<2,3>")
expect(p3.toString()).toBe("Point<1,2>")
p1.x += 1;
p1.y = 3;
p2.x -= 1;
p2.y = 3;
p3.x = 0;
p3.y = 0;
expect(p1.x).toBe(2);
expect(p1.y).toBe(3);
expect(p2.x).toBe(1);
expect(p2.y).toBe(3);
expect(p3.x).toBe(0);
expect(p3.y).toBe(0);
expect(p1.equals(p1)).toBe(true)
expect(p1.equals(p2)).toBe(false)
expect(p1.equals(p3)).toBe(false)
expect(p2.equals(p1)).toBe(false)
expect(p2.equals(p2)).toBe(true)
expect(p2.equals(p3)).toBe(false)
expect(p3.equals(p1)).toBe(false)
expect(p3.equals(p2)).toBe(false)
expect(p3.equals(p3)).toBe(true)
expect(p1.toString()).toBe("Point<2,3>")
expect(p2.toString()).toBe("Point<1,3>")
expect(p3.toString()).toBe("Point<0,0>")

View File

@ -0,0 +1,17 @@
var foo = "bar";
class Foo {
#bar = foo;
constructor() {
var foo = "foo";
}
test() {
return this.#bar;
}
}
const f = new Foo;
expect(f.test()).toBe(foo);
expect("bar" in f).toBe(false);

View File

@ -0,0 +1,8 @@
class C {
y = this.#x;
#x;
}
expect(() => {
new C();
}).toThrow();

View File

@ -0,0 +1,22 @@
class Foo {
#prop = "foo";
foo() {
return this.#prop;
}
}
class Bar extends Foo {
#prop = "bar";
bar() {
return this.#prop;
}
}
const f = new Foo;
expect(f.foo()).toBe("foo");
const b = new Bar;
expect(b.foo()).toBe("foo");
expect(b.bar()).toBe("bar");

View File

@ -0,0 +1,17 @@
class Foo {
#client
constructor(props) {
this.#client = 1;
;([this.x = this.#client, this.#client, this.y = this.#client] = props);
}
getClient() {
return this.#client;
}
}
const foo = new Foo([undefined, 'bar']);
expect(foo.getClient()).toBe('bar');
expect(foo.x).toBe(1);
expect(foo.y).toBe('bar');

View File

@ -0,0 +1,15 @@
class Foo {
#client
constructor(props) {
let x;
;([x, ...this.#client] = props);
}
getClient() {
return this.#client;
}
}
const foo = new Foo(['foo', 'bar', 'baz', 'quu']);
expect(foo.getClient()).toEqual(['bar', 'baz', 'quu']);

View File

@ -0,0 +1,14 @@
class Foo {
#client
constructor(props) {
([this.#client = 5] = props);
}
getClient() {
return this.#client;
}
}
const foo = new Foo([]);
expect(foo.getClient()).toEqual(5);

View File

@ -0,0 +1,14 @@
class Foo {
static #client
constructor(props) {
;([Foo.#client] = props);
}
getClient() {
return Foo.#client;
}
}
const foo = new Foo(['bar']);
expect(foo.getClient()).toBe('bar');

View File

@ -0,0 +1,14 @@
class Foo {
#client
constructor(props) {
;([this.#client] = props);
}
getClient() {
return this.#client;
}
}
const foo = new Foo(['bar']);
expect(foo.getClient()).toBe('bar');

View File

@ -0,0 +1,17 @@
class Foo {
#client
constructor(props) {
this.#client = 'foo';
;({ x: this.x = this.#client, y: this.#client, z: this.z = this.#client } = props)
}
getClient() {
return this.#client;
}
}
const foo = new Foo({ y: 'bar' });
expect(foo.getClient()).toBe('bar');
expect(foo.x).toBe('foo');
expect(foo.z).toBe('bar');

View File

@ -0,0 +1,15 @@
class Foo {
#client
constructor(props) {
let x;
;({ x, ...this.#client } = props)
}
getClient() {
return this.#client;
}
}
const foo = new Foo({ x: 'foo', y: 'bar', z: 'baz' });
expect(foo.getClient()).toEqual({ y: 'bar', z: 'baz' });

View File

@ -0,0 +1,14 @@
class Foo {
#client
constructor(props) {
({ client: this.#client = 5 } = props);
}
getClient() {
return this.#client;
}
}
const foo = new Foo({});
expect(foo.getClient()).toEqual(5);

View File

@ -0,0 +1,14 @@
class Foo {
static #client
constructor(props) {
;({ client: Foo.#client } = props)
}
getClient() {
return Foo.#client;
}
}
const foo = new Foo({ client: 'bar' });
expect(foo.getClient()).toBe('bar');

View File

@ -0,0 +1,14 @@
class Foo {
#client
constructor(props) {
;({ client: this.#client } = props)
}
getClient() {
return this.#client;
}
}
const foo = new Foo({ client: 'bar' });
expect(foo.getClient()).toBe('bar');

View File

@ -0,0 +1,9 @@
class Foo {
#bar;
test() {
return this.#bar;
}
}
expect(new Foo().test()).toBe(undefined);

View File

@ -0,0 +1,16 @@
class Foo {
#bar = "foo";
test() {
return this.#bar;
}
static test(foo) {
return foo.#bar;
}
}
const f = new Foo();
expect(f.test()).toBe("foo");
expect(Foo.test(f)).toBe("foo");
expect("bar" in f).toBe(false);

View File

@ -0,0 +1,11 @@
class Foo {
#x = 0;
#y = this.#x + 1;
test() {
return this.#y;
}
}
const f = new Foo();
expect(f.test()).toBe(1);

View File

@ -0,0 +1,19 @@
class Foo {
#foo = 1;
test() {
class Nested {
#foo = 2;
[this.#foo]() {
}
}
return new Nested();
}
}
const f = new Foo();
expect(() => {
f.test();
}).toThrow();

View File

@ -0,0 +1,19 @@
class Foo {
#m;
init() {
this.#m = (...args) => args;
}
static test() {
const f = new Foo();
f.init();
return f.#m?.(...arguments);
}
static testNull() {
const f = new Foo();
return f.#m?.(...arguments);
}
}
expect(Foo.test(1, 2)).toEqual([1, 2]);
expect(Foo.testNull(1, 2)).toBe(undefined);

View File

@ -0,0 +1,13 @@
class Foo {
static #foo = function(x) {
return x;
}
test(x) {
return Foo.#foo(x);
}
}
const f = new Foo;
const test = f.test();
expect(f.test("bar")).toBe("bar");

View File

@ -0,0 +1,69 @@
class Base {
static #foo = 1;
static getThis() {
return this.#foo;
}
static updateThis(val) {
return (this.#foo = val);
}
static getClass() {
return Base.#foo;
}
static updateClass(val) {
return (Base.#foo = val);
}
}
class Sub1 extends Base {
static #foo = 2;
static update(val) {
return (this.#foo = val);
}
}
class Sub2 extends Base {}
expect(Base.getThis()).toBe(1);
expect(Base.getClass()).toBe(1);
expect(() => Sub1.getThis()).toThrow();
expect(Sub1.getClass()).toBe(1);
expect(() => Sub2.getThis()).toThrow();
expect(Sub2.getClass()).toBe(1);
expect(Sub1.update(3)).toBe(3);
expect(Base.getThis()).toBe(1);
expect(Base.getClass()).toBe(1);
expect(() => Sub1.getThis()).toThrow();
expect(Sub1.getClass()).toBe(1);
expect(() => Sub2.getThis()).toThrow();
expect(Sub2.getClass()).toBe(1);
expect(Base.updateThis(4)).toBe(4);
expect(Base.getThis()).toBe(4);
expect(Base.getClass()).toBe(4);
expect(() => Sub1.getThis()).toThrow();
expect(Sub1.getClass()).toBe(4);
expect(() => Sub2.getThis()).toThrow();
expect(Sub2.getClass()).toBe(4);
expect(Base.updateClass(5)).toBe(5);
expect(Base.getThis()).toBe(5);
expect(Base.getClass()).toBe(5);
expect(() => Sub1.getThis()).toThrow();
expect(Sub1.getClass()).toBe(5);
expect(() => Sub2.getThis()).toThrow();
expect(Sub2.getClass()).toBe(5);
expect(() => Sub2.updateThis(6)).toThrow();
expect(Sub2.updateClass(7)).toBe(7);
expect(Base.getThis()).toBe(7);
expect(Base.getClass()).toBe(7);
expect(() => Sub1.getThis()).toThrow();
expect(Sub1.getClass()).toBe(7);
expect(() => Sub2.getThis()).toThrow();
expect(Sub2.getClass()).toBe(7);

View File

@ -0,0 +1,15 @@
class Test {
static #x = 1
static method() {
const Test = 2;
const func = () => {
const Test = 3;
return this.#x + Test;
}
return func() + Test;
}
}
expect(Test.method()).toBe(6)

View File

@ -0,0 +1,13 @@
class A {
static #self = this;
static #getA = () => this;
static extract() {
return { self: A.#self, getA: A.#getA };
}
}
const { self, getA } = A.extract();
expect(self).toBe(A);
expect(getA()).toBe(A);

View File

@ -0,0 +1,15 @@
class Foo {
static #bar;
static test() {
return Foo.#bar;
}
test() {
return Foo.#bar;
}
}
expect("bar" in Foo).toBe(false);
expect(Foo.test()).toBe(undefined);
expect(Foo.test()).toBe(undefined);

View File

@ -0,0 +1,15 @@
class Foo {
static #bar = "foo";
static test() {
return Foo.#bar;
}
test() {
return Foo.#bar;
}
}
expect("bar" in Foo).toBe(false);
expect(Foo.test()).toBe("foo");
expect(Foo.test()).toBe("foo");

View File

@ -0,0 +1,27 @@
class Foo {
#foo = 0;
test(other) {
return [
this.#foo++,
this.#foo,
++this.#foo,
this.#foo,
other.obj.#foo++,
other.obj.#foo,
++other.obj.#foo,
other.obj.#foo,
];
}
}
const f = new Foo;
const results = f.test({ obj: f });
expect(results[0]).toBe(0);
expect(results[1]).toBe(1);
expect(results[2]).toBe(2);
expect(results[3]).toBe(2);
expect(results[4]).toBe(2);
expect(results[5]).toBe(3);
expect(results[6]).toBe(4);
expect(results[7]).toBe(4);

View File

@ -0,0 +1,15 @@
class Foo {
#foo = function() {
return this;
}
test(other) {
return [this.#foo(), other.#foo()];
}
}
const f = new Foo;
const o = new Foo;
const test = f.test(o);
expect(test[0]).toBe(f);
expect(test[1]).toBe(o);

View File

@ -0,0 +1,73 @@
class Point {
#x;
#y;
constructor(x = 0, y = 0) {
this.#x = +x;
this.#y = +y;
}
get x() { return this.#x }
set x(value) { this.#x = +value }
get y() { return this.#y }
set y(value) { this.#y = +value }
equals(p) { return this.#x === p.#x && this.#y === p.#y }
toString() { return `Point<${ this.#x },${ this.#y }>` }
}
const p1 = new Point(1, 2);
const p2 = new Point(2, 3);
const p3 = new Point(1, 2);
expect(p1.x).toBe(1);
expect(p1.y).toBe(2);
expect(p2.x).toBe(2);
expect(p2.y).toBe(3);
expect(p3.x).toBe(1);
expect(p3.y).toBe(2);
expect(p1.equals(p1)).toBe(true)
expect(p1.equals(p2)).toBe(false)
expect(p1.equals(p3)).toBe(true)
expect(p2.equals(p1)).toBe(false)
expect(p2.equals(p2)).toBe(true)
expect(p2.equals(p3)).toBe(false)
expect(p3.equals(p1)).toBe(true)
expect(p3.equals(p2)).toBe(false)
expect(p3.equals(p3)).toBe(true)
expect(p1.toString()).toBe("Point<1,2>")
expect(p2.toString()).toBe("Point<2,3>")
expect(p3.toString()).toBe("Point<1,2>")
p1.x += 1;
p1.y = 3;
p2.x -= 1;
p2.y = 3;
p3.x = 0;
p3.y = 0;
expect(p1.x).toBe(2);
expect(p1.y).toBe(3);
expect(p2.x).toBe(1);
expect(p2.y).toBe(3);
expect(p3.x).toBe(0);
expect(p3.y).toBe(0);
expect(p1.equals(p1)).toBe(true)
expect(p1.equals(p2)).toBe(false)
expect(p1.equals(p3)).toBe(false)
expect(p2.equals(p1)).toBe(false)
expect(p2.equals(p2)).toBe(true)
expect(p2.equals(p3)).toBe(false)
expect(p3.equals(p1)).toBe(false)
expect(p3.equals(p2)).toBe(false)
expect(p3.equals(p3)).toBe(true)
expect(p1.toString()).toBe("Point<2,3>")
expect(p2.toString()).toBe("Point<1,3>")
expect(p3.toString()).toBe("Point<0,0>")

View File

@ -0,0 +1,17 @@
var foo = "bar";
class Foo {
#bar = foo;
constructor() {
var foo = "foo";
}
test() {
return this.#bar;
}
}
const f = new Foo;
expect(f.test()).toBe(foo);
expect("bar" in f).toBe(false);

View File

@ -0,0 +1,8 @@
class C {
y = this.#x;
#x;
}
expect(() => {
new C();
}).toThrow();

View File

@ -0,0 +1,22 @@
class Foo {
#prop = "foo";
foo() {
return this.#prop;
}
}
class Bar extends Foo {
#prop = "bar";
bar() {
return this.#prop;
}
}
const f = new Foo;
expect(f.foo()).toBe("foo");
const b = new Bar;
expect(b.foo()).toBe("foo");
expect(b.bar()).toBe("bar");

View File

@ -0,0 +1,17 @@
class Foo {
#client
constructor(props) {
this.#client = 1;
;([this.x = this.#client, this.#client, this.y = this.#client] = props);
}
getClient() {
return this.#client;
}
}
const foo = new Foo([undefined, 'bar']);
expect(foo.getClient()).toBe('bar');
expect(foo.x).toBe(1);
expect(foo.y).toBe('bar');

View File

@ -0,0 +1,15 @@
class Foo {
#client
constructor(props) {
let x;
;([x, ...this.#client] = props);
}
getClient() {
return this.#client;
}
}
const foo = new Foo(['foo', 'bar', 'baz', 'quu']);
expect(foo.getClient()).toEqual(['bar', 'baz', 'quu']);

View File

@ -0,0 +1,14 @@
class Foo {
#client
constructor(props) {
([this.#client = 5] = props);
}
getClient() {
return this.#client;
}
}
const foo = new Foo([]);
expect(foo.getClient()).toEqual(5);

View File

@ -0,0 +1,14 @@
class Foo {
static #client
constructor(props) {
;([Foo.#client] = props);
}
getClient() {
return Foo.#client;
}
}
const foo = new Foo(['bar']);
expect(foo.getClient()).toBe('bar');

View File

@ -0,0 +1,14 @@
class Foo {
#client
constructor(props) {
;([this.#client] = props);
}
getClient() {
return this.#client;
}
}
const foo = new Foo(['bar']);
expect(foo.getClient()).toBe('bar');

View File

@ -0,0 +1,17 @@
class Foo {
#client
constructor(props) {
this.#client = 'foo';
;({ x: this.x = this.#client, y: this.#client, z: this.z = this.#client } = props)
}
getClient() {
return this.#client;
}
}
const foo = new Foo({ y: 'bar' });
expect(foo.getClient()).toBe('bar');
expect(foo.x).toBe('foo');
expect(foo.z).toBe('bar');

View File

@ -0,0 +1,15 @@
class Foo {
#client
constructor(props) {
let x;
;({ x, ...this.#client } = props)
}
getClient() {
return this.#client;
}
}
const foo = new Foo({ x: 'foo', y: 'bar', z: 'baz' });
expect(foo.getClient()).toEqual({ y: 'bar', z: 'baz' });

View File

@ -0,0 +1,14 @@
class Foo {
#client
constructor(props) {
({x: this.#client = 5} = props);
}
getClient() {
return this.#client;
}
}
const foo = new Foo({});
expect(foo.getClient()).toEqual(5);

View File

@ -0,0 +1,14 @@
class Foo {
static #client
constructor(props) {
;({ client: Foo.#client } = props)
}
getClient() {
return Foo.#client;
}
}
const foo = new Foo({ client: 'bar' });
expect(foo.getClient()).toBe('bar');

View File

@ -0,0 +1,14 @@
class Foo {
#client
constructor(props) {
;({ client: this.#client } = props)
}
getClient() {
return this.#client;
}
}
const foo = new Foo({ client: 'bar' });
expect(foo.getClient()).toBe('bar');

View File

@ -0,0 +1,9 @@
class Foo {
#bar;
test() {
return this.#bar;
}
}
expect(new Foo().test()).toBe(undefined);

View File

@ -0,0 +1,35 @@
class Foo {
#bar = "foo";
test() {
return this.#bar;
}
update() {
this.#bar++;
}
set(val) {
this.#bar = val;
}
static test(foo) {
return foo.#bar;
}
static update(foo) {
foo.#bar **= 2;
}
}
const f = new Foo();
expect(f.test()).toBe("foo");
expect(Foo.test(f)).toBe("foo");
expect("bar" in f).toBe(false);
f.set(1);
expect(f.test()).toBe(1);
f.update();
expect(Foo.test(f)).toBe(2);
Foo.update(f);
expect(f.test()).toBe(4);

View File

@ -0,0 +1,11 @@
class Foo {
#x = 0;
#y = this.#x + 1;
test() {
return this.#y;
}
}
const f = new Foo();
expect(f.test()).toBe(1);

View File

@ -0,0 +1,18 @@
class Foo {
static #foo = "foo";
#bar = "bar";
static test() {
return Foo.#foo;
}
test() {
return this.#bar;
}
}
const f = new Foo();
expect("foo" in Foo).toBe(false)
expect("bar" in f).toBe(false)
expect(Foo.test()).toBe("foo")
expect(f.test()).toBe("bar")

View File

@ -0,0 +1,19 @@
class Foo {
#foo = 1;
test() {
class Nested {
#foo = 2;
[this.#foo]() {
}
}
return new Nested();
}
}
const f = new Foo();
expect(() => {
f.test();
}).toThrow();

View File

@ -0,0 +1,19 @@
class Foo {
#m;
init() {
this.#m = (...args) => args;
}
static test() {
const f = new Foo();
f.init();
return f.#m?.(...arguments);
}
static testNull() {
const f = new Foo();
return f.#m?.(...arguments);
}
}
expect(Foo.test(1, 2)).toEqual([1, 2]);
expect(Foo.testNull(1, 2)).toBe(undefined);

View File

@ -0,0 +1,51 @@
function classFactory() {
return class Foo {
#foo = "foo";
static #bar = "bar";
instance() {
return this.#foo;
}
static() {
return Foo.#bar;
}
static instance(inst) {
return inst.#foo;
}
static static() {
return Foo.#bar;
}
};
}
const Foo1 = classFactory();
const Foo2 = classFactory();
const f1 = new Foo1();
const f2 = new Foo2();
expect(f1.instance()).toBe("foo");
expect(f1.static()).toBe("bar");
expect(f2.instance()).toBe("foo");
expect(f2.static()).toBe("bar");
expect(Foo1.instance(f1)).toBe("foo");
expect(Foo1.static()).toBe("bar");
expect(Foo2.instance(f2)).toBe("foo");
expect(Foo2.static()).toBe("bar");
expect(() => {
f1.instance.call(f2), undefined;
}).toThrow();
expect(() => {
f2.instance.call(f1), undefined;
}).toThrow();
expect(() => {
Foo1.instance(f2), undefined;
}).toThrow();
expect(() => {
Foo2.instance(f1), undefined;
}).toThrow();

View File

@ -0,0 +1,13 @@
class Foo {
static #foo = function(x) {
return x;
}
test(x) {
return Foo.#foo(x);
}
}
const f = new Foo;
const test = f.test();
expect(f.test("bar")).toBe("bar");

View File

@ -0,0 +1,69 @@
class Base {
static #foo = 1;
static getThis() {
return this.#foo;
}
static updateThis(val) {
return (this.#foo = val);
}
static getClass() {
return Base.#foo;
}
static updateClass(val) {
return (Base.#foo = val);
}
}
class Sub1 extends Base {
static #foo = 2;
static update(val) {
return (this.#foo = val);
}
}
class Sub2 extends Base {}
expect(Base.getThis()).toBe(1);
expect(Base.getClass()).toBe(1);
expect(() => Sub1.getThis()).toThrow();
expect(Sub1.getClass()).toBe(1);
expect(() => Sub2.getThis()).toThrow();
expect(Sub2.getClass()).toBe(1);
expect(Sub1.update(3)).toBe(3);
expect(Base.getThis()).toBe(1);
expect(Base.getClass()).toBe(1);
expect(() => Sub1.getThis()).toThrow();
expect(Sub1.getClass()).toBe(1);
expect(() => Sub2.getThis()).toThrow();
expect(Sub2.getClass()).toBe(1);
expect(Base.updateThis(4)).toBe(4);
expect(Base.getThis()).toBe(4);
expect(Base.getClass()).toBe(4);
expect(() => Sub1.getThis()).toThrow();
expect(Sub1.getClass()).toBe(4);
expect(() => Sub2.getThis()).toThrow();
expect(Sub2.getClass()).toBe(4);
expect(Base.updateClass(5)).toBe(5);
expect(Base.getThis()).toBe(5);
expect(Base.getClass()).toBe(5);
expect(() => Sub1.getThis()).toThrow();
expect(Sub1.getClass()).toBe(5);
expect(() => Sub2.getThis()).toThrow();
expect(Sub2.getClass()).toBe(5);
expect(() => Sub2.updateThis(6)).toThrow();
expect(Sub2.updateClass(7)).toBe(7);
expect(Base.getThis()).toBe(7);
expect(Base.getClass()).toBe(7);
expect(() => Sub1.getThis()).toThrow();
expect(Sub1.getClass()).toBe(7);
expect(() => Sub2.getThis()).toThrow();
expect(Sub2.getClass()).toBe(7);

View File

@ -0,0 +1,15 @@
const f = class Foo {
static #x = Foo;
static y = Foo;
static extract() {
return {
x: Foo.#x,
y: Foo.y,
}
}
};
const { x, y } = f.extract();
expect(x).toBe(f)
expect(y).toBe(f)

View File

@ -0,0 +1,31 @@
const f = class Foo {
static #bar() {
return Foo;
}
static #method() {
return function inner() {
return Foo;
};
}
static #method_shadowed() {
new Foo();
return function inner() {
let Foo = 3;
return Foo;
}
}
static extract() {
return {
bar: Foo.#bar,
method: Foo.#method,
method_shadowed: Foo.#method_shadowed
}
}
};
const { bar, method, method_shadowed } = f.extract();
expect(bar()).toBe(f)
expect(method()()).toBe(f)
expect(method_shadowed()()).toBe(3)

View File

@ -0,0 +1,15 @@
class Test {
static #x = 1
static method() {
const Test = 2;
const func = () => {
const Test = 3;
return this.#x + Test;
}
return func() + Test;
}
}
expect(Test.method()).toBe(6)

View File

@ -0,0 +1,13 @@
class A {
static #self = this;
static #getA = () => this;
static extract() {
return { self: A.#self, getA: A.#getA };
}
}
const { self, getA } = A.extract();
expect(self).toBe(A);
expect(getA()).toBe(A);

View File

@ -0,0 +1,15 @@
class Foo {
static #bar;
static test() {
return Foo.#bar;
}
test() {
return Foo.#bar;
}
}
expect("bar" in Foo).toBe(false);
expect(Foo.test()).toBe(undefined);
expect(Foo.test()).toBe(undefined);

View File

@ -0,0 +1,9 @@
class Foo {
static #tag = function () { return this };
static getReceiver() {
return this.#tag``;
}
}
expect(Foo.getReceiver()).toBe(Foo);

View File

@ -0,0 +1,17 @@
class Foo {
#tag() {
return this;
}
#tag2 = function() { return this; };
constructor() {
const receiver = this.#tag`tagged template`;
expect(receiver).toBe(this);
const receiver2 = this.#tag2`tagged template`;
expect(receiver2).toBe(this);
}
}
new Foo();

View File

@ -0,0 +1,27 @@
class Foo {
#foo = 0;
test(other) {
return [
this.#foo++,
this.#foo,
++this.#foo,
this.#foo,
other.obj.#foo++,
other.obj.#foo,
++other.obj.#foo,
other.obj.#foo,
];
}
}
const f = new Foo;
const results = f.test({ obj: f });
expect(results[0]).toBe(0);
expect(results[1]).toBe(1);
expect(results[2]).toBe(2);
expect(results[3]).toBe(2);
expect(results[4]).toBe(2);
expect(results[5]).toBe(3);
expect(results[6]).toBe(4);
expect(results[7]).toBe(4);

View File

@ -0,0 +1,38 @@
const actualOrder = [];
const track = i => {
actualOrder.push(i);
return i;
};
class MyClass {
static [track(1)] = track(10);
[track(2)] = track(13);
get [track(3)]() {
return "foo";
}
set [track(4)](value) {
this.bar = value;
}
[track(5)] = track(14);
static [track(6)] = track(11);
static [track(7)] = track(12);
[track(8)]() {}
[track(9)] = track(15);
}
const inst = new MyClass();
const expectedOrder = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
expect(actualOrder).toEqual(expectedOrder);
expect(MyClass[1]).toBe(10);
expect(inst[2]).toBe(13);
expect(inst[3]).toBe("foo");
inst[4] = "baz";
expect(inst.bar).toBe("baz");
expect(inst[5]).toBe(14);
expect(MyClass[6]).toBe(11);
expect(MyClass[7]).toBe(12);
expect(typeof inst[8]).toBe("function");
expect(inst[9]).toBe(15);

View File

@ -0,0 +1,13 @@
function test(x) {
class F {
[x] = 1;
constructor() {}
}
x = 'deadbeef';
expect(new F().foo).toBe(1);
x = 'wrong';
expect(new F().foo).toBe(1);
}
test('foo');

View File

@ -0,0 +1,15 @@
class A {
static prop = 1;
}
class B extends A {
static prop = 2;
static propA = super.prop;
static getPropA = () => super.prop;
}
const { prop, propA, getPropA } = B;
expect(prop).toBe(2);
expect(propA).toBe(1);
expect(getPropA()).toBe(1);

View File

@ -0,0 +1,9 @@
class A {
static self = this;
static getA = () => this;
}
const { self, getA } = A;
expect(self).toBe(A);
expect(getA()).toBe(A);

View File

@ -0,0 +1,6 @@
class Foo {
static num;
}
expect("num" in Foo).toBe(true);
expect(Foo.num).toBeUndefined();

View File

@ -0,0 +1,9 @@
class Foo {
static num = 0;
static str = "foo";
}
expect(Foo.num).toBe(0);
expect(Foo.num = 1).toBe(1);
expect(Foo.str).toBe("foo");
expect(Foo.str = "bar").toBe("bar");

View File

@ -0,0 +1,15 @@
class Foo {
foo = function() {
return this;
}
test(other) {
return [this.foo(), other.foo()];
}
}
const f = new Foo;
const o = new Foo;
const test = f.test(o);
expect(test[0]).toBe(f);
expect(test[1]).toBe(o);

View File

@ -0,0 +1,38 @@
const actualOrder = [];
const track = i => {
actualOrder.push(i);
return i;
};
class MyClass {
static [track(1)] = track(10);
[track(2)] = track(13);
get [track(3)]() {
return "foo";
}
set [track(4)](value) {
this.bar = value;
}
[track(5)] = track(14);
static [track(6)] = track(11);
static [track(7)] = track(12);
[track(8)]() {}
[track(9)] = track(15);
}
const inst = new MyClass();
const expectedOrder = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
expect(actualOrder).toEqual(expectedOrder);
expect(MyClass[1]).toBe(10);
expect(inst[2]).toBe(13);
expect(inst[3]).toBe("foo");
inst[4] = "baz";
expect(inst.bar).toBe("baz");
expect(inst[5]).toBe(14);
expect(MyClass[6]).toBe(11);
expect(MyClass[7]).toBe(12);
expect(typeof inst[8]).toBe("function");
expect(inst[9]).toBe(15);

View File

@ -0,0 +1,5 @@
const createClass = (k) => class { [k()] = 2 };
const clazz = createClass(() => 'foo');
const instance = new clazz();
expect(instance.foo).toBe(2);

View File

@ -0,0 +1,13 @@
function test(x) {
class F {
[x] = 1;
constructor() {}
}
x = 'deadbeef';
expect(new F().foo).toBe(1);
x = 'wrong';
expect(new F().foo).toBe(1);
}
test('foo');

View File

@ -0,0 +1,18 @@
class Foo {
static foo = "foo";
bar = "bar";
static test() {
return Foo.foo;
}
test() {
return this.bar;
}
}
const f = new Foo();
expect("foo" in Foo).toBe(true)
expect("bar" in f).toBe(true)
expect(Foo.test()).toBe("foo")
expect(f.test()).toBe("bar")

View File

@ -0,0 +1,15 @@
class A {
static prop = 1;
}
class B extends A {
static prop = 2;
static propA = super.prop;
static getPropA = () => super.prop;
}
const { prop, propA, getPropA } = B;
expect(prop).toBe(2);
expect(propA).toBe(1);
expect(getPropA()).toBe(1);

View File

@ -0,0 +1,9 @@
class A {
static self = this;
static getA = () => this;
}
const { self, getA } = A;
expect(self).toBe(A);
expect(getA()).toBe(A);

View File

@ -0,0 +1,6 @@
class Foo {
static num;
}
expect("num" in Foo).toBe(true);
expect(Foo.num).toBeUndefined();

View File

@ -0,0 +1,9 @@
class Foo {
static num = 0;
static str = "foo";
}
expect(Foo.num).toBe(0);
expect(Foo.num = 1).toBe(1);
expect(Foo.str).toBe("foo");
expect(Foo.str = "bar").toBe("bar");

View File

@ -0,0 +1,27 @@
class Foo {
foo = 0;
test(other) {
return [
this.foo++,
this.foo,
++this.foo,
this.foo,
other.obj.foo++,
other.obj.foo,
++other.obj.foo,
other.obj.foo,
];
}
}
const f = new Foo;
const results = f.test({ obj: f });
expect(results[0]).toBe(0);
expect(results[1]).toBe(1);
expect(results[2]).toBe(2);
expect(results[3]).toBe(2);
expect(results[4]).toBe(2);
expect(results[5]).toBe(3);
expect(results[6]).toBe(4);
expect(results[7]).toBe(4);

View File

@ -0,0 +1,99 @@
"use strict";
class C {
}
class A extends C {
field = 1;
constructor() {
super();
class B extends C {
constructor() {
super();
expect(this.field).toBeUndefined();
}
}
expect(this.field).toBe(1)
new B();
}
}
new A();
class Obj {
constructor() {
return {};
}
}
// ensure superClass is still transformed
class SuperClass extends Obj {
field = 1;
constructor() {
class B extends (super(), Obj) {
constructor() {
super();
expect(this.field).toBeUndefined()
}
}
expect(this.field).toBe(1)
new B();
}
}
new SuperClass();
// ensure ComputedKey Method is still transformed
class ComputedMethod extends Obj {
field = 1;
constructor() {
class B extends Obj {
constructor() {
super();
expect(this.field).toBeUndefined()
}
[super()]() { }
}
expect(this.field).toBe(1)
new B();
}
}
new ComputedMethod();
// ensure ComputedKey Field is still transformed
class ComputedField extends Obj {
field = 1;
constructor() {
class B extends Obj {
constructor() {
super();
expect(this.field).toBeUndefined()
}
[super()] = 1;
}
expect(this.field).toBe(1)
new B();
}
}
new ComputedField();

View File

@ -0,0 +1,23 @@
const classes = [];
for (let i = 0; i <= 10; ++i) {
classes.push(
class A {
[i] = `computed field ${i}`;
static foo = `static field ${i}`;
#bar = `private field ${i}`;
getBar() {
return this.#bar;
}
}
);
}
for(let i=0; i<= 10; ++i) {
const clazz = classes[i];
expect(clazz.foo).toBe('static field ' + i);
const instance = new clazz();
expect(Object.getOwnPropertyNames(instance)).toEqual([String(i)])
expect(instance[i]).toBe('computed field ' + i);
expect(instance.getBar()).toBe('private field ' + i);
}

View File

@ -0,0 +1,7 @@
class Foo {
static bar = 42;
static {
this.foo = Foo.bar;
}
}
expect(Foo.foo).toBe(42);

View File

@ -0,0 +1,7 @@
class Foo {
static bar = 42;
static {
this.foo = this.bar;
}
}
expect(Foo.foo).toBe(42);

View File

@ -0,0 +1,6 @@
class Foo {
static {
this.foo = 42;
}
}
expect(Foo.foo).toBe(42);

View File

@ -0,0 +1,14 @@
class Foo extends class extends class Base {
static {
this.qux = 21;
}
} {
static {
this.bar = 21;
}
} {
static {
this.foo = this.bar + this.qux;
}
}
expect(Foo.foo).toBe(42);

View File

@ -0,0 +1,14 @@
class Foo {
static #bar = 21;
static {
this.foo = this.#bar;
this.qux1 = this.qux;
}
static qux = 21;
static {
this.qux2 = this.qux;
}
}
expect(Foo.foo).toBe(21);
expect(Foo.qux1).toBe(undefined);
expect(Foo.qux2).toBe(21);

View File

@ -0,0 +1,8 @@
class Foo {
static #_ = 42;
// static block can not be tranformed as `#_` here
static {
this.foo = this.#_;
}
}
expect(Foo.foo).toBe(42);

View File

@ -0,0 +1,10 @@
class Base {
constructor() {
this.Foo = class {
static {
this.foo = new.target;
}
}
}
}
expect((new Base).Foo.foo).toBe(undefined);

View File

@ -0,0 +1,7 @@
class Foo {
bar = 21;
static {
this.foo = this.bar;
}
}
expect(Foo.foo).toBe(undefined);

View File

@ -0,0 +1,8 @@
let getFoo;
class Foo {
static #foo = 42;
static {
getFoo = () => this.#foo;
}
}
expect(getFoo()).toBe(42);

View File

@ -0,0 +1,7 @@
class Foo {
static bar = 42;
static {
this.foo = Foo.bar;
}
}
expect(Foo.foo).toBe(42);

Some files were not shown because too many files have changed in this diff Show More