• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1describe("unittests:: evaluation:: autoAccessors", () => {
2    const editions = [
3        { name: "es2022", target: ts.ScriptTarget.ES2022 },
4        { name: "es2015", target: ts.ScriptTarget.ES2015 },
5    ];
6    for (const { name, target } of editions) {
7        describe(name, () => {
8            it("generates accessor pair", async () => {
9                const { C } = evaluator.evaluateTypeScript(`
10                    export class C {
11                        accessor x;
12                    }
13                `, { target });
14
15                const desc = Object.getOwnPropertyDescriptor(C.prototype, "x");
16                assert.isDefined(desc);
17                assert.isFunction(desc!.get);
18                assert.isFunction(desc!.set);
19            });
20
21            it("storage is private", async () => {
22                const { C } = evaluator.evaluateTypeScript(`
23                    export class C {
24                        accessor x;
25                    }
26                `, { target });
27
28                const desc = Object.getOwnPropertyDescriptor(C.prototype, "x");
29                const obj = Object.create(C.prototype);
30                assert.throws(() => desc!.get!.call(obj), /private/);
31            });
32
33            it("getter and setter wrap same field", async () => {
34                const { C } = evaluator.evaluateTypeScript(`
35                    export class C {
36                        accessor x;
37                    }
38                `, { target });
39                const obj = new C();
40                obj.x = 1;
41                assert.equal(obj.x, 1);
42
43                obj.x = 2;
44                assert.equal(obj.x, 2);
45            });
46
47            it("supports initializer", async () => {
48                const { C } = evaluator.evaluateTypeScript(`
49                    export class C {
50                        accessor x = 1;
51                    }
52                `, { target });
53                const obj = new C();
54                assert.equal(obj.x, 1);
55            });
56
57            it("legacy decorator can intercept getter/setter", async () => {
58                const { actions, C } = evaluator.evaluateTypeScript(`
59                    function dec(target, key, descriptor) {
60                        const { get, set } = descriptor;
61                        actions.push({ kind: "decorate", target, key });
62                        descriptor.get = function() {
63                            actions.push({ kind: "get", this: this });
64                            return get.call(this);
65                        };
66                        descriptor.set = function(value) {
67                            actions.push({ kind: "set", this: this, value });
68                            set.call(this, value);
69                        };
70                    }
71                    export const actions = [];
72                    export class C {
73                        @dec
74                        accessor x;
75                    }
76                `, { target, experimentalDecorators: true });
77
78                assert.deepEqual(actions, [
79                    { kind: "decorate", target: C.prototype, key: "x" }
80                ]);
81                const obj = new C();
82                obj.x = 1;
83                assert.equal(obj.x, 1);
84                assert.deepEqual(actions, [
85                    { kind: "decorate", target: C.prototype, key: "x" },
86                    { kind: "set", this: obj, value: 1 },
87                    { kind: "get", this: obj },
88                ]);
89            });
90
91            it("legacy decorator cannot intercept initializer", async () => {
92                const { actions, C } = evaluator.evaluateTypeScript(`
93                    function dec(target, key, descriptor) {
94                        const { get, set } = descriptor;
95                        descriptor.set = function(value) {
96                            actions.push({ kind: "set", this: this, value });
97                            set.call(this, value);
98                        };
99                    }
100                    export const actions = [];
101                    export class C {
102                        @dec
103                        accessor x = 1;
104                    }
105                `, { target, experimentalDecorators: true });
106
107                const obj = new C();
108                assert.equal(obj.x, 1);
109                assert.deepEqual(actions, []);
110            });
111        });
112    }
113});