93 lines
2.4 KiB
TypeScript
93 lines
2.4 KiB
TypeScript
import { expect, test } from "bun:test";
|
|
import { bunEnv, bunExe, tempDir } from "harness";
|
|
|
|
// When emitDecoratorMetadata is true in tsconfig but experimentalDecorators is
|
|
// absent, Bun should use legacy decorator semantics (not TC39 standard).
|
|
// emitDecoratorMetadata only makes sense with legacy decorators.
|
|
test("legacy decorators work when emitDecoratorMetadata is true without experimentalDecorators", async () => {
|
|
using dir = tempDir("issue-27526", {
|
|
"tsconfig.json": JSON.stringify({
|
|
compilerOptions: {
|
|
target: "ES2021",
|
|
module: "commonjs",
|
|
strict: true,
|
|
esModuleInterop: true,
|
|
emitDecoratorMetadata: true,
|
|
},
|
|
}),
|
|
"index.ts": `
|
|
function MyDecorator(target: any, key: string, descriptor: PropertyDescriptor) {
|
|
const original = descriptor.value;
|
|
descriptor.value = function(...args: any[]) {
|
|
return "decorated:" + original.apply(this, args);
|
|
};
|
|
}
|
|
|
|
class Foo {
|
|
@MyDecorator
|
|
hello() {
|
|
return "world";
|
|
}
|
|
}
|
|
|
|
console.log(new Foo().hello());
|
|
`,
|
|
});
|
|
|
|
await using proc = Bun.spawn({
|
|
cmd: [bunExe(), "index.ts"],
|
|
env: bunEnv,
|
|
cwd: String(dir),
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
|
|
|
|
expect(stdout.trim()).toBe("decorated:world");
|
|
expect(exitCode).toBe(0);
|
|
});
|
|
|
|
// When neither emitDecoratorMetadata nor experimentalDecorators is set,
|
|
// TypeScript files should use TC39 standard decorators.
|
|
test("TC39 standard decorators work when neither emitDecoratorMetadata nor experimentalDecorators is set", async () => {
|
|
using dir = tempDir("issue-27526-standard", {
|
|
"tsconfig.json": JSON.stringify({
|
|
compilerOptions: {
|
|
target: "ES2021",
|
|
module: "commonjs",
|
|
strict: true,
|
|
},
|
|
}),
|
|
"index.ts": `
|
|
function MyDecorator(value: Function, context: ClassMethodDecoratorContext) {
|
|
return function(this: any, ...args: any[]) {
|
|
return "decorated:" + (value as any).apply(this, args);
|
|
};
|
|
}
|
|
|
|
class Foo {
|
|
@MyDecorator
|
|
hello() {
|
|
return "world";
|
|
}
|
|
}
|
|
|
|
console.log(new Foo().hello());
|
|
`,
|
|
});
|
|
|
|
await using proc = Bun.spawn({
|
|
cmd: [bunExe(), "index.ts"],
|
|
env: bunEnv,
|
|
cwd: String(dir),
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
|
|
|
|
expect(stdout.trim()).toBe("decorated:world");
|
|
expect(exitCode).toBe(0);
|
|
});
|