mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-25 05:29:07 -05:00
feat(53461): Implement decorator metadata proposal (#54657)
This commit is contained in:
@@ -37,6 +37,7 @@ import "./unittests/evaluation/awaiter";
|
||||
import "./unittests/evaluation/destructuring";
|
||||
import "./unittests/evaluation/externalModules";
|
||||
import "./unittests/evaluation/esDecorators";
|
||||
import "./unittests/evaluation/esDecoratorsMetadata";
|
||||
import "./unittests/evaluation/forAwaitOf";
|
||||
import "./unittests/evaluation/forOf";
|
||||
import "./unittests/evaluation/generator";
|
||||
|
||||
141
src/testRunner/unittests/evaluation/esDecoratorsMetadata.ts
Normal file
141
src/testRunner/unittests/evaluation/esDecoratorsMetadata.ts
Normal file
@@ -0,0 +1,141 @@
|
||||
import * as evaluator from "../../_namespaces/evaluator";
|
||||
import * as ts from "../../_namespaces/ts";
|
||||
import { ScriptTarget } from "../../_namespaces/ts";
|
||||
|
||||
describe("unittests:: evaluation:: esDecoratorsMetadata", () => {
|
||||
const nodeVersion = new ts.Version(process.versions.node);
|
||||
const supportsClassStaticBlock = nodeVersion.major >= 16;
|
||||
|
||||
const targets = [
|
||||
// NOTE: Class static blocks weren't supported in Node v14
|
||||
...(supportsClassStaticBlock ? [ScriptTarget.ES2022] : []),
|
||||
ScriptTarget.ES2021,
|
||||
ScriptTarget.ES2015,
|
||||
];
|
||||
|
||||
for (const target of targets) {
|
||||
const targetName = ts.Debug.formatEnum(target, (ts as any).ScriptTarget);
|
||||
const options: ts.CompilerOptions = { target };
|
||||
const exec = (array: TemplateStringsArray) => evaluator.evaluateTypeScript(array[0], options);
|
||||
|
||||
describe("examples", () => {
|
||||
// see https://github.com/tc39/proposal-decorator-metadata
|
||||
it(`@meta (${targetName})`, () => {
|
||||
const { output } = exec`
|
||||
export const output: unknown[] = [];
|
||||
|
||||
function meta(key: string, value: string) {
|
||||
return (_, context) => {
|
||||
context.metadata[key] = value;
|
||||
};
|
||||
}
|
||||
|
||||
@meta('a', 'x')
|
||||
class C {
|
||||
@meta('b', 'y')
|
||||
m() { }
|
||||
}
|
||||
|
||||
output.push(C[Symbol.metadata].a);
|
||||
output.push(C[Symbol.metadata].b);
|
||||
`;
|
||||
assert.deepEqual(output, ["x", "y"]);
|
||||
});
|
||||
|
||||
// see https://github.com/tc39/proposal-decorator-metadata#inheritance
|
||||
it(`inheritance (${targetName})`, () => {
|
||||
const { output } = exec`
|
||||
export const output: unknown[] = [];
|
||||
|
||||
function meta(key: string, value: string) {
|
||||
return (_, context) => {
|
||||
context.metadata[key] = value;
|
||||
};
|
||||
}
|
||||
|
||||
@meta('a', 'x')
|
||||
class C {
|
||||
@meta('b', 'y')
|
||||
m() {}
|
||||
}
|
||||
|
||||
output.push(C[Symbol.metadata].a);
|
||||
output.push(C[Symbol.metadata].b);
|
||||
|
||||
class D extends C {
|
||||
@meta('b', 'z')
|
||||
m() {}
|
||||
}
|
||||
|
||||
output.push(D[Symbol.metadata].a);
|
||||
output.push(D[Symbol.metadata].b);
|
||||
`;
|
||||
assert.deepEqual(output, [
|
||||
"x",
|
||||
"y",
|
||||
"x",
|
||||
"z",
|
||||
]);
|
||||
});
|
||||
|
||||
// see https://github.com/tc39/proposal-decorator-metadata#inheritance
|
||||
it(`inheritance append(${targetName})`, () => {
|
||||
const { output } = exec`
|
||||
export const output: unknown[] = [];
|
||||
|
||||
function appendMeta(key: string, value: string) {
|
||||
return (_, context) => {
|
||||
const existing = context.metadata[key] ?? [];
|
||||
context.metadata[key] = [...existing, value];
|
||||
};
|
||||
}
|
||||
|
||||
@appendMeta('a', 'x')
|
||||
class C { }
|
||||
|
||||
@appendMeta('a', 'z')
|
||||
class D extends C { }
|
||||
|
||||
output.push(C[Symbol.metadata].a);
|
||||
output.push(D[Symbol.metadata].a);
|
||||
`;
|
||||
assert.deepEqual(output, [
|
||||
["x"],
|
||||
["x", "z"],
|
||||
]);
|
||||
});
|
||||
|
||||
// see https://github.com/tc39/proposal-decorator-metadata#private-metadata
|
||||
it(`private metadata (${targetName})`, () => {
|
||||
const { output } = exec`
|
||||
export const output: unknown[] = [];
|
||||
|
||||
const PRIVATE_METADATA = new WeakMap();
|
||||
function meta(key: string, value: string) {
|
||||
return (_, context) => {
|
||||
let metadata = PRIVATE_METADATA.get(context.metadata);
|
||||
if (!metadata) {
|
||||
metadata = {};
|
||||
PRIVATE_METADATA.set(context.metadata, metadata);
|
||||
}
|
||||
metadata[key] = value;
|
||||
};
|
||||
}
|
||||
|
||||
@meta('a', 'x')
|
||||
class C {
|
||||
@meta('b', 'y')
|
||||
m() { }
|
||||
}
|
||||
|
||||
output.push(PRIVATE_METADATA.get(C[Symbol.metadata]).a);
|
||||
output.push(PRIVATE_METADATA.get(C[Symbol.metadata]).b);
|
||||
`;
|
||||
assert.deepEqual(output, [
|
||||
"x",
|
||||
"y",
|
||||
]);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user