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});