From e1a63fedb722a0dd03a49a6fd5be72ee99d79ef1 Mon Sep 17 00:00:00 2001 From: Evan Wallace <4257481+bonbonman74@users.noreply.github.com> Date: Sun, 12 May 2024 16:03:36 -0400 Subject: [PATCH] test: https://github.com/evanw/esbuild/issues/3761 --- README.md | 89 ++++++++++++++++++++++++++++- decorator-tests.js | 138 +++++++++++++++++++++++++++------------------ decorator-tests.ts | 132 ++++++++++++++++++++++++++----------------- 3 files changed, 249 insertions(+), 110 deletions(-) diff --git a/README.md b/README.md index 4228754..121573d 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,94 @@ You can use `node run.mjs` after `npm install` to run and update the tests below ### esbuild (`esbuild@0.21.0`) -✅ All checks passed +
+❌ 16 checks failed (click for details) + +``` +❌ Field decorators: Shim (instance field) + Code: this instanceof Foo2 + Expected: true + Observed: false + +❌ Field decorators: Shim (instance field) + Code: this instanceof Foo2 + Expected: true + Observed: false + +❌ Field decorators: Shim (instance field) + Code: log + "" + Expected: "false,false,123,true,false," + Observed: "false,false,123,false,false," + +❌ Field decorators: Shim (static field) + Code: this + Expected: class + Observed: [object global] + +❌ Field decorators: Shim (static field) + Code: this + Expected: class + Observed: [object global] + +❌ Field decorators: Shim (static field) + Code: log + "" + Expected: "false,false,123,true,false," + Observed: "false,false,123,false,false," + +❌ Field decorators: Shim (private instance field) + Code: this instanceof Foo2 + Expected: true + Observed: false + +❌ Field decorators: Shim (private instance field) + Code: this instanceof Foo2 + Expected: true + Observed: false + +❌ Field decorators: Shim (private instance field) + Code: log + "" + Expected: "false,false,123,true,false," + Observed: "false,false,123,false,false," + +❌ Field decorators: Shim (private static field) + Code: this + Expected: class + Observed: [object global] + +❌ Field decorators: Shim (private static field) + Code: this + Expected: class + Observed: [object global] + +❌ Field decorators: Shim (private static field) + Code: log + "" + Expected: "false,false,123,true,false," + Observed: "false,false,123,false,false," + +❌ Auto-accessor decorators: Shim (instance auto-accessor) + Code: this instanceof Foo2 + Expected: true + Observed: false + +❌ Auto-accessor decorators: Shim (static auto-accessor) + Code: this + Expected: class + Observed: [object global] + +❌ Auto-accessor decorators: Shim (private instance auto-accessor) + Code: this instanceof Foo2 + Expected: true + Observed: false + +❌ Auto-accessor decorators: Shim (private static auto-accessor) + Code: this + Expected: class + Observed: [object global] + +❌ 16 checks failed +``` + +
### Babel (`@babel/plugin-proposal-decorators@7.24.1`) diff --git a/decorator-tests.js b/decorator-tests.js index 3418b2a..2f12b1a 100644 --- a/decorator-tests.js +++ b/decorator-tests.js @@ -916,7 +916,10 @@ const tests = { 'Field decorators: Shim (instance field)': () => { let log = []; const dec = (value, ctx) => { - return (x) => log.push(x); + return function (x) { + assertEq(() => this instanceof Foo, true); + return log.push('foo' in this, 'bar' in this, x); + }; }; class Foo { @dec @@ -926,40 +929,43 @@ const tests = { } assertEq(() => log + '', ''); var obj = new Foo; - assertEq(() => obj.foo, 1); - assertEq(() => obj.bar, 2); - assertEq(() => log + '', '123,'); - var obj = new Foo; assertEq(() => obj.foo, 3); - assertEq(() => obj.bar, 4); - assertEq(() => log + '', '123,,123,'); + assertEq(() => obj.bar, 6); + assertEq(() => log + '', 'false,false,123,true,false,'); }, 'Field decorators: Shim (static field)': () => { + let foo; let log = []; const dec = (value, ctx) => { - return (x) => log.push(x); - }; - const fn = (foo, bar) => { - class Foo { - @dec - static foo = 123; - @dec - static bar; - } - assertEq(() => Foo.foo, foo); - assertEq(() => Foo.bar, bar); + return function (x) { + assertEq(() => this, foo); + return log.push('foo' in this, 'bar' in this, x); + }; }; assertEq(() => log + '', ''); - fn(1, 2); - assertEq(() => log + '', '123,'); - fn(3, 4); - assertEq(() => log + '', '123,,123,'); + class Foo { + static { + foo = Foo; + } + @dec + static foo = 123; + @dec + static bar; + } + assertEq(() => Foo.foo, 3); + assertEq(() => Foo.bar, 6); + assertEq(() => log + '', 'false,false,123,true,false,'); }, 'Field decorators: Shim (private instance field)': () => { let log = []; const dec = (value, ctx) => { - return (x) => log.push(x); + return function (x) { + assertEq(() => this instanceof Foo, true); + return log.push(has$foo(this), has$bar(this), x); + }; }; + let has$foo; + let has$bar; let get$foo; let get$bar; class Foo { @@ -968,46 +974,48 @@ const tests = { @dec #bar; static { + has$foo = x => #foo in x; + has$bar = x => #bar in x; get$foo = x => x.#foo; get$bar = x => x.#bar; } } assertEq(() => log + '', ''); var obj = new Foo; - assertEq(() => get$foo(obj), 1); - assertEq(() => get$bar(obj), 2); - assertEq(() => log + '', '123,'); - var obj = new Foo; assertEq(() => get$foo(obj), 3); - assertEq(() => get$bar(obj), 4); - assertEq(() => log + '', '123,,123,'); + assertEq(() => get$bar(obj), 6); + assertEq(() => log + '', 'false,false,123,true,false,'); }, 'Field decorators: Shim (private static field)': () => { + let foo; let log = []; const dec = (value, ctx) => { - return (x) => log.push(x); - }; - const fn = (foo, bar) => { - let get$foo; - let get$bar; - class Foo { - @dec - static #foo = 123; - @dec - static #bar; - static { - get$foo = x => x.#foo; - get$bar = x => x.#bar; - } - } - assertEq(() => get$foo(Foo), foo); - assertEq(() => get$bar(Foo), bar); + return function (x) { + assertEq(() => this, foo); + return log.push(has$foo(this), has$bar(this), x); + }; }; assertEq(() => log + '', ''); - fn(1, 2); - assertEq(() => log + '', '123,'); - fn(3, 4); - assertEq(() => log + '', '123,,123,'); + let has$foo; + let has$bar; + let get$foo; + let get$bar; + class Foo { + static { + foo = Foo; + has$foo = x => #foo in x; + has$bar = x => #bar in x; + get$foo = x => x.#foo; + get$bar = x => x.#bar; + } + @dec + static #foo = 123; + @dec + static #bar; + } + assertEq(() => get$foo(Foo), 3); + assertEq(() => get$bar(Foo), 6); + assertEq(() => log + '', 'false,false,123,true,false,'); }, 'Field decorators: Order (instance field)': () => { const log = []; @@ -2386,7 +2394,10 @@ const tests = { let get; let set; const dec = (target, ctx) => { - const init = (x) => x + 1; + function init(x) { + assertEq(() => this instanceof Foo, true); + return x + 1; + } get = function () { return target.get.call(this) * 10; }; set = function (x) { target.set.call(this, x * 2); }; return { get, set, init }; @@ -2403,15 +2414,22 @@ const tests = { assertEq(() => obj.foo, (321 * 2) * 10); }, 'Auto-accessor decorators: Shim (static auto-accessor)': () => { + let foo; let get; let set; const dec = (target, ctx) => { - const init = (x) => x + 1; + function init(x) { + assertEq(() => this, foo); + return x + 1; + } get = function () { return target.get.call(this) * 10; }; set = function (x) { target.set.call(this, x * 2); }; return { get, set, init }; }; class Foo { + static { + foo = Foo; + } @dec static accessor foo = 123; } @@ -2425,7 +2443,10 @@ const tests = { let get; let set; const dec = (target, ctx) => { - const init = (x) => x + 1; + function init(x) { + assertEq(() => this instanceof Foo, true); + return x + 1; + } get = function () { return target.get.call(this) * 10; }; set = function (x) { target.set.call(this, x * 2); }; return { get, set, init }; @@ -2446,10 +2467,14 @@ const tests = { assertEq(() => get$foo(obj), (321 * 2) * 10); }, 'Auto-accessor decorators: Shim (private static auto-accessor)': () => { + let foo; let get; let set; const dec = (target, ctx) => { - const init = (x) => x + 1; + function init(x) { + assertEq(() => this, foo); + return x + 1; + } get = function () { return target.get.call(this) * 10; }; set = function (x) { target.set.call(this, x * 2); }; return { get, set, init }; @@ -2457,12 +2482,13 @@ const tests = { let get$foo; let set$foo; class Foo { - @dec - static accessor #foo = 123; static { + foo = Foo; get$foo = x => x.#foo; set$foo = (x, y) => { x.#foo = y; }; } + @dec + static accessor #foo = 123; } assertEq(() => get$foo(Foo), (123 + 1) * 10); assertEq(() => set$foo(Foo, 321), undefined); diff --git a/decorator-tests.ts b/decorator-tests.ts index 9e0adf7..294e1ec 100644 --- a/decorator-tests.ts +++ b/decorator-tests.ts @@ -799,9 +799,12 @@ const tests: Record Promise | void> = { lateAsserts!() }, 'Field decorators: Shim (instance field)': () => { - let log: number[] = [] + let log: (boolean | number)[] = [] const dec = (value: undefined, ctx: ClassFieldDecoratorContext) => { - return (x: number) => log.push(x) + return function (this: Foo, x: number) { + assertEq(() => this instanceof Foo, true) + return log.push('foo' in this, 'bar' in this, x) + } } class Foo { @dec foo = 123 @@ -809,82 +812,87 @@ const tests: Record Promise | void> = { } assertEq(() => log + '', '') var obj = new Foo - assertEq(() => obj.foo, 1) - assertEq(() => obj.bar, 2) - assertEq(() => log + '', '123,') - var obj = new Foo assertEq(() => obj.foo, 3) - assertEq(() => obj.bar, 4) - assertEq(() => log + '', '123,,123,') + assertEq(() => obj.bar, 6) + assertEq(() => log + '', 'false,false,123,true,false,') }, 'Field decorators: Shim (static field)': () => { - let log: number[] = [] + let foo: typeof Foo + let log: (boolean | number)[] = [] const dec = (value: undefined, ctx: ClassFieldDecoratorContext) => { - return (x: number) => log.push(x) - } - const fn = (foo: number, bar: number) => { - class Foo { - @dec static foo = 123 - @dec static bar: number + return function (this: typeof Foo, x: number) { + assertEq(() => this, foo) + return log.push('foo' in this, 'bar' in this, x) } - assertEq(() => Foo.foo, foo) - assertEq(() => Foo.bar, bar) } assertEq(() => log + '', '') - fn(1, 2) - assertEq(() => log + '', '123,') - fn(3, 4) - assertEq(() => log + '', '123,,123,') + class Foo { + static { + foo = Foo + } + @dec static foo = 123 + @dec static bar: number + } + assertEq(() => Foo.foo, 3) + assertEq(() => Foo.bar, 6) + assertEq(() => log + '', 'false,false,123,true,false,') }, 'Field decorators: Shim (private instance field)': () => { - let log: number[] = [] + let log: (boolean | number)[] = [] const dec = (value: undefined, ctx: ClassFieldDecoratorContext) => { - return (x: number) => log.push(x) + return function (this: Foo, x: number) { + assertEq(() => this instanceof Foo, true) + return log.push(has$foo(this), has$bar(this), x) + } } + let has$foo: (x: Foo) => boolean + let has$bar: (x: Foo) => boolean let get$foo: (x: Foo) => number let get$bar: (x: Foo) => number class Foo { @dec #foo = 123 @dec #bar!: number static { + has$foo = x => #foo in x + has$bar = x => #bar in x get$foo = x => x.#foo get$bar = x => x.#bar } } assertEq(() => log + '', '') var obj = new Foo - assertEq(() => get$foo(obj), 1) - assertEq(() => get$bar(obj), 2) - assertEq(() => log + '', '123,') - var obj = new Foo assertEq(() => get$foo(obj), 3) - assertEq(() => get$bar(obj), 4) - assertEq(() => log + '', '123,,123,') + assertEq(() => get$bar(obj), 6) + assertEq(() => log + '', 'false,false,123,true,false,') }, 'Field decorators: Shim (private static field)': () => { - let log: number[] = [] + let foo: typeof Foo + let log: (boolean | number)[] = [] const dec = (value: undefined, ctx: ClassFieldDecoratorContext) => { - return (x: number) => log.push(x) - } - const fn = (foo: number, bar: number) => { - let get$foo: (x: typeof Foo) => number - let get$bar: (x: typeof Foo) => number - class Foo { - @dec static #foo = 123 - @dec static #bar: number - static { - get$foo = x => x.#foo - get$bar = x => x.#bar - } + return function (this: typeof Foo, x: number) { + assertEq(() => this, foo) + return log.push(has$foo(this), has$bar(this), x) } - assertEq(() => get$foo(Foo), foo) - assertEq(() => get$bar(Foo), bar) } assertEq(() => log + '', '') - fn(1, 2) - assertEq(() => log + '', '123,') - fn(3, 4) - assertEq(() => log + '', '123,,123,') + let has$foo: (x: typeof Foo) => boolean + let has$bar: (x: typeof Foo) => boolean + let get$foo: (x: typeof Foo) => number + let get$bar: (x: typeof Foo) => number + class Foo { + static { + foo = Foo + has$foo = x => #foo in x + has$bar = x => #bar in x + get$foo = x => x.#foo + get$bar = x => x.#bar + } + @dec static #foo = 123 + @dec static #bar: number + } + assertEq(() => get$foo(Foo), 3) + assertEq(() => get$bar(Foo), 6) + assertEq(() => log + '', 'false,false,123,true,false,') }, 'Field decorators: Order (instance field)': () => { const log: number[] = [] @@ -2084,7 +2092,10 @@ const tests: Record Promise | void> = { let get: (this: Foo) => number let set: (this: Foo, x: number) => void const dec = (target: ClassAccessorDecoratorTarget, ctx: ClassAccessorDecoratorContext): ClassAccessorDecoratorResult => { - const init = (x: number) => x + 1 + function init(this: Foo, x: number): number { + assertEq(() => this instanceof Foo, true) + return x + 1 + } get = function () { return target.get.call(this) * 10 } set = function (x) { target.set.call(this, x * 2) } return { get, set, init } @@ -2100,15 +2111,22 @@ const tests: Record Promise | void> = { assertEq(() => obj.foo, (321 * 2) * 10) }, 'Auto-accessor decorators: Shim (static auto-accessor)': () => { + let foo: typeof Foo let get: (this: typeof Foo) => number let set: (this: typeof Foo, x: number) => void const dec = (target: ClassAccessorDecoratorTarget, ctx: ClassAccessorDecoratorContext): ClassAccessorDecoratorResult => { - const init = (x: number) => x + 1 + function init(this: typeof Foo, x: number): number { + assertEq(() => this, foo) + return x + 1 + } get = function () { return target.get.call(this) * 10 } set = function (x) { target.set.call(this, x * 2) } return { get, set, init } } class Foo { + static { + foo = Foo + } @dec static accessor foo = 123 } assertEq(() => Object.getOwnPropertyDescriptor(Foo, 'foo')!.get, get!) @@ -2121,7 +2139,10 @@ const tests: Record Promise | void> = { let get: (this: Foo) => number let set: (this: Foo, x: number) => void const dec = (target: ClassAccessorDecoratorTarget, ctx: ClassAccessorDecoratorContext): ClassAccessorDecoratorResult => { - const init = (x: number) => x + 1 + function init(this: Foo, x: number): number { + assertEq(() => this instanceof Foo, true) + return x + 1 + } get = function () { return target.get.call(this) * 10 } set = function (x) { target.set.call(this, x * 2) } return { get, set, init } @@ -2141,10 +2162,14 @@ const tests: Record Promise | void> = { assertEq(() => get$foo(obj), (321 * 2) * 10) }, 'Auto-accessor decorators: Shim (private static auto-accessor)': () => { + let foo: typeof Foo let get: (this: typeof Foo) => number let set: (this: typeof Foo, x: number) => void const dec = (target: ClassAccessorDecoratorTarget, ctx: ClassAccessorDecoratorContext): ClassAccessorDecoratorResult => { - const init = (x: number) => x + 1 + function init(this: typeof Foo, x: number): number { + assertEq(() => this, foo) + return x + 1 + } get = function () { return target.get.call(this) * 10 } set = function (x) { target.set.call(this, x * 2) } return { get, set, init } @@ -2152,11 +2177,12 @@ const tests: Record Promise | void> = { let get$foo: (x: typeof Foo) => number let set$foo: (x: typeof Foo, y: number) => void class Foo { - @dec static accessor #foo = 123 static { + foo = Foo get$foo = x => x.#foo set$foo = (x, y) => { x.#foo = y } } + @dec static accessor #foo = 123 } assertEq(() => get$foo(Foo), (123 + 1) * 10) assertEq(() => set$foo(Foo, 321), undefined)