• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1namespace ts {
2    describe("unittests:: services:: extract:: extractConstants", () => {
3        testExtractConstant("extractConstant_TopLevel",
4            `let x = [#|1|];`);
5
6        testExtractConstant("extractConstant_Namespace",
7            `namespace N {
8    let x = [#|1|];
9}`);
10
11        testExtractConstant("extractConstant_Class",
12            `class C {
13    x = [#|1|];
14}`);
15
16        testExtractConstant("extractConstant_Method",
17            `class C {
18    M() {
19        let x = [#|1|];
20    }
21}`);
22
23        testExtractConstant("extractConstant_Function",
24            `function F() {
25    let x = [#|1|];
26}`);
27
28        testExtractConstant("extractConstant_ExpressionStatement",
29            `[#|"hello";|]`);
30
31        testExtractConstant("extractConstant_ExpressionStatementExpression",
32            `[#|"hello"|];`);
33
34        testExtractConstant("extractConstant_ExpressionStatementInNestedScope", `
35let i = 0;
36function F() {
37    [#|i++|];
38}
39        `);
40
41        testExtractConstant("extractConstant_ExpressionStatementConsumesLocal", `
42function F() {
43    let i = 0;
44    [#|i++|];
45}
46        `);
47
48        testExtractConstant("extractConstant_BlockScopes_NoDependencies",
49            `for (let i = 0; i < 10; i++) {
50    for (let j = 0; j < 10; j++) {
51        let x = [#|1|];
52    }
53}`);
54
55        testExtractConstant("extractConstant_ClassInsertionPosition1",
56            `class C {
57    a = 1;
58    b = 2;
59    M1() { }
60    M2() { }
61    M3() {
62        let x = [#|1|];
63    }
64}`);
65
66        testExtractConstant("extractConstant_ClassInsertionPosition2",
67            `class C {
68    a = 1;
69    M1() { }
70    b = 2;
71    M2() { }
72    M3() {
73        let x = [#|1|];
74    }
75}`);
76
77        testExtractConstant("extractConstant_ClassInsertionPosition3",
78            `class C {
79    M1() { }
80    a = 1;
81    b = 2;
82    M2() { }
83    M3() {
84        let x = [#|1|];
85    }
86}`);
87
88        testExtractConstant("extractConstant_Parameters",
89            `function F() {
90    let w = 1;
91    let x = [#|w + 1|];
92}`);
93
94        testExtractConstant("extractConstant_TypeParameters",
95            `function F<T>(t: T) {
96    let x = [#|t + 1|];
97}`);
98
99        testExtractConstant("extractConstant_RepeatedSubstitution",
100            `namespace X {
101    export const j = 10;
102    export const y = [#|j * j|];
103}`);
104
105        testExtractConstant("extractConstant_VariableList_const",
106            `const a = 1, b = [#|a + 1|];`);
107
108        // NOTE: this test isn't normative - it just documents our sub-optimal behavior.
109        testExtractConstant("extractConstant_VariableList_let",
110            `let a = 1, b = [#|a + 1|];`);
111
112        // NOTE: this test isn't normative - it just documents our sub-optimal behavior.
113        testExtractConstant("extractConstant_VariableList_MultipleLines",
114            `const /*About A*/a = 1,
115    /*About B*/b = [#|a + 1|];`);
116
117        testExtractConstant("extractConstant_BlockScopeMismatch", `
118for (let i = 0; i < 10; i++) {
119    for (let j = 0; j < 10; j++) {
120        const x = [#|i + 1|];
121    }
122}
123        `);
124
125        testExtractConstant("extractConstant_StatementInsertionPosition1", `
126const i = 0;
127for (let j = 0; j < 10; j++) {
128    const x = [#|i + 1|];
129}
130        `);
131
132        testExtractConstant("extractConstant_StatementInsertionPosition2", `
133const i = 0;
134function F() {
135    for (let j = 0; j < 10; j++) {
136        const x = [#|i + 1|];
137    }
138}
139        `);
140
141        testExtractConstant("extractConstant_StatementInsertionPosition3", `
142for (let j = 0; j < 10; j++) {
143    const x = [#|2 + 1|];
144}
145        `);
146
147        testExtractConstant("extractConstant_StatementInsertionPosition4", `
148function F() {
149    for (let j = 0; j < 10; j++) {
150        const x = [#|2 + 1|];
151    }
152}
153        `);
154
155        testExtractConstant("extractConstant_StatementInsertionPosition5", `
156function F0() {
157    function F1() {
158        function F2(x = [#|2 + 1|]) {
159        }
160    }
161}
162        `);
163
164        testExtractConstant("extractConstant_StatementInsertionPosition6", `
165class C {
166    x = [#|2 + 1|];
167}
168        `);
169
170        testExtractConstant("extractConstant_StatementInsertionPosition7", `
171const i = 0;
172class C {
173    M() {
174        for (let j = 0; j < 10; j++) {
175            x = [#|i + 1|];
176        }
177    }
178}
179        `);
180
181        testExtractConstant("extractConstant_TripleSlash", `
182/// <reference path="path.js"/>
183
184const x = [#|2 + 1|];
185        `);
186
187        testExtractConstant("extractConstant_PinnedComment", `
188/*! Copyright */
189
190const x = [#|2 + 1|];
191        `);
192
193        testExtractConstant("extractConstant_Directive", `
194"strict";
195
196const x = [#|2 + 1|];
197        `);
198
199        testExtractConstant("extractConstant_MultipleHeaders", `
200/*! Copyright */
201
202/// <reference path="path.js"/>
203
204"strict";
205
206const x = [#|2 + 1|];
207        `);
208
209        testExtractConstant("extractConstant_PinnedCommentAndDocComment", `
210/*! Copyright */
211
212/* About x */
213const x = [#|2 + 1|];
214        `);
215
216        testExtractConstant("extractConstant_ArrowFunction_Block", `
217const f = () => {
218    return [#|2 + 1|];
219};`);
220
221        testExtractConstant("extractConstant_ArrowFunction_Expression",
222            `const f = () => [#|2 + 1|];`);
223
224        testExtractConstant("extractConstant_PreserveTrivia", `
225// a
226var q = /*b*/ //c
227    /*d*/ [#|1 /*e*/ //f
228    /*g*/ + /*h*/ //i
229    /*j*/ 2|] /*k*/ //l
230    /*m*/; /*n*/ //o`);
231
232        testExtractConstantFailed("extractConstant_Void", `
233function f(): void { }
234[#|f();|]`);
235
236        testExtractConstantFailed("extractConstant_Never", `
237function f(): never { }
238[#|f();|]`);
239
240        testExtractConstant("extractConstant_This_Constructor", `
241class C {
242    constructor() {
243        [#|this.m2()|];
244    }
245    m2() { return 1; }
246}`);
247
248        testExtractConstant("extractConstant_This_Method", `
249class C {
250    m1() {
251        [#|this.m2()|];
252    }
253    m2() { return 1; }
254}`);
255
256        testExtractConstant("extractConstant_This_Property", `
257namespace N { // Force this test to be TS-only
258    class C {
259        x = 1;
260        y = [#|this.x|];
261    }
262}`);
263
264        // TODO (https://github.com/Microsoft/TypeScript/issues/20727): the extracted constant should have a type annotation.
265        testExtractConstant("extractConstant_ContextualType", `
266interface I { a: 1 | 2 | 3 }
267let i: I = [#|{ a: 1 }|];
268`);
269
270        testExtractConstant("extractConstant_ContextualType_Lambda", `
271const myObj: { member(x: number, y: string): void } = {
272    member: [#|(x, y) => x + y|],
273}
274`);
275
276        testExtractConstant("extractConstant_CaseClauseExpression", `
277switch (1) {
278    case [#|1|]:
279        break;
280}
281`);
282    });
283
284    function testExtractConstant(caption: string, text: string) {
285        testExtractSymbol(caption, text, "extractConstant", Diagnostics.Extract_constant);
286    }
287
288    function testExtractConstantFailed(caption: string, text: string) {
289        testExtractSymbolFailed(caption, text, Diagnostics.Extract_constant);
290    }
291}
292