• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1namespace ts {
2    function testExtractRangeFailed(caption: string, s: string, expectedErrors: string[]) {
3        return it(caption, () => {
4            const t = extractTest(s);
5            const file = createSourceFile("a.ts", t.source, ScriptTarget.Latest, /*setParentNodes*/ true);
6            const selectionRange = t.ranges.get("selection");
7            if (!selectionRange) {
8                throw new Error(`Test ${s} does not specify selection range`);
9            }
10            const result = refactor.extractSymbol.getRangeToExtract(file, createTextSpanFromRange(selectionRange), /*userRequested*/ false);
11            const sortedErrors = result.errors!.map(e => e.messageText as string).sort();
12            assert.deepEqual(sortedErrors, expectedErrors.sort(), "unexpected errors");
13        });
14    }
15
16    function testExtractRange(caption: string, s: string) {
17        return it(caption, () => {
18            const t = extractTest(s);
19            const f = createSourceFile("a.ts", t.source, ScriptTarget.Latest, /*setParentNodes*/ true);
20            const selectionRange = t.ranges.get("selection");
21            if (!selectionRange) {
22                throw new Error(`Test ${s} does not specify selection range`);
23            }
24            const result = refactor.extractSymbol.getRangeToExtract(f, createTextSpanFromRange(selectionRange));
25            const expectedRange = t.ranges.get("extracted");
26            if (expectedRange) {
27                let pos: number, end: number;
28                const targetRange = result.targetRange!;
29                if (isArray(targetRange.range)) {
30                    pos = targetRange.range[0].getStart(f);
31                    end = last(targetRange.range).getEnd();
32                }
33                else {
34                    pos = targetRange.range.getStart(f);
35                    end = targetRange.range.getEnd();
36                }
37                assert.equal(pos, expectedRange.pos, "incorrect pos of range");
38                assert.equal(end, expectedRange.end, "incorrect end of range");
39            }
40            else {
41                assert.isTrue(!result.targetRange, `expected range to extract to be undefined`);
42            }
43        });
44    }
45
46    describe("unittests:: services:: extract:: extractRanges", () => {
47        describe("get extract range from selection", () => {
48            testExtractRange("extractRange1", `
49                [#|
50                [$|var x = 1;
51                var y = 2;|]|]
52            `);
53            testExtractRange("extractRange2", `
54                [$|[#|var x = 1;
55                var y = 2|];|]
56            `);
57            testExtractRange("extractRange3", `
58                [#|var x = [$|1|]|];
59                var y = 2;
60            `);
61            testExtractRange("extractRange4", `
62                var x = [$|10[#|00|]|];
63            `);
64            testExtractRange("extractRange5", `
65                [$|va[#|r foo = 1;
66                var y = 200|]0;|]
67            `);
68            testExtractRange("extractRange6", `
69                var x = [$|fo[#|o.bar.baz()|]|];
70            `);
71            testExtractRange("extractRange7", `
72                if ([#|[#extracted|a && b && c && d|]|]) {
73                }
74            `);
75            testExtractRange("extractRange8", `
76                if [#|(a && b && c && d|]) {
77                }
78            `);
79            testExtractRange("extractRange9", `
80                if ([$|a[#|a && b && c && d|]d|]) {
81                }
82            `);
83            testExtractRange("extractRange10", `
84                if (a && b && c && d) {
85                [#|    [$|var x = 1;
86                    console.log(x);|]    |]
87                }
88            `);
89            testExtractRange("extractRange11", `
90                [#|
91                if (a) {
92                    return 100;
93                } |]
94            `);
95            testExtractRange("extractRange12", `
96                function foo() {
97                [#|    [$|if (a) {
98                    }
99                    return 100|] |]
100                }
101            `);
102            testExtractRange("extractRange13", `
103                [#|
104                [$|l1:
105                if (x) {
106                    break l1;
107                }|]|]
108            `);
109            testExtractRange("extractRange14", `
110                [#|
111                [$|l2:
112                {
113                    if (x) {
114                    }
115                    break l2;
116                }|]|]
117            `);
118            testExtractRange("extractRange15", `
119                while (true) {
120                [#|    if(x) {
121                    }
122                    break;  |]
123                }
124            `);
125            testExtractRange("extractRange16", `
126                while (true) {
127                [#|    if(x) {
128                    }
129                    continue;  |]
130                }
131            `);
132            testExtractRange("extractRange17", `
133                l3:
134                {
135                    [#|
136                    if (x) {
137                    }
138                    break l3; |]
139                }
140            `);
141            testExtractRange("extractRange18", `
142                function f() {
143                    while (true) {
144                [#|
145                        if (x) {
146                            return;
147                        } |]
148                    }
149                }
150            `);
151            testExtractRange("extractRange19", `
152                function f() {
153                    while (true) {
154                [#|
155                        [$|if (x) {
156                        }
157                        return;|]
158                |]
159                    }
160                }
161            `);
162            testExtractRange("extractRange20", `
163                function f() {
164                    return [#|  [$|1 + 2|]  |]+ 3;
165                    }
166                }
167            `);
168            testExtractRange("extractRange21", `
169                function f(x: number) {
170                    [#|[$|try {
171                        x++;
172                    }
173                    finally {
174                        return 1;
175                    }|]|]
176                }
177            `);
178
179            // Variable statements
180            testExtractRange("extractRange22", `[#|let x = [$|1|];|]`);
181            testExtractRange("extractRange23", `[#|let x = [$|1|], y;|]`);
182            testExtractRange("extractRange24", `[#|[$|let x = 1, y = 1;|]|]`);
183
184            // Variable declarations
185            testExtractRange("extractRange25", `let [#|x = [$|1|]|];`);
186            testExtractRange("extractRange26", `let [#|x = [$|1|]|], y = 2;`);
187            testExtractRange("extractRange27", `let x = 1, [#|y = [$|2|]|];`);
188
189            // Return statements
190            testExtractRange("extractRange28", `[#|return [$|1|];|]`);
191
192            // For statements
193            testExtractRange("extractRange29", `for ([#|var i = [$|1|]|]; i < 2; i++) {}`);
194            testExtractRange("extractRange30", `for (var i = [#|[$|1|]|]; i < 2; i++) {}`);
195        });
196
197        testExtractRangeFailed("extractRangeFailed1",
198            `
199namespace A {
200function f() {
201    [#|
202    let x = 1
203    if (x) {
204        return 10;
205    }
206    |]
207}
208}
209            `,
210            [refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalReturnStatement.message]);
211
212        testExtractRangeFailed("extractRangeFailed2",
213            `
214namespace A {
215function f() {
216    while (true) {
217    [#|
218        let x = 1
219        if (x) {
220            break;
221        }
222    |]
223    }
224}
225}
226            `,
227            [refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message]);
228
229        testExtractRangeFailed("extractRangeFailed3",
230            `
231namespace A {
232function f() {
233    while (true) {
234    [#|
235        let x = 1
236        if (x) {
237            continue;
238        }
239    |]
240    }
241}
242}
243            `,
244            [refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message]);
245
246        testExtractRangeFailed("extractRangeFailed4",
247            `
248namespace A {
249function f() {
250    l1: {
251    [#|
252        let x = 1
253        if (x) {
254            break l1;
255        }
256    |]
257    }
258}
259}
260            `,
261            [refactor.extractSymbol.Messages.cannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange.message]);
262
263        testExtractRangeFailed("extractRangeFailed5",
264            `
265namespace A {
266function f() {
267    [#|
268    try {
269        f2()
270        return 10;
271    }
272    catch (e) {
273    }
274    |]
275}
276function f2() {
277}
278}
279            `,
280            [refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalReturnStatement.message]);
281
282        testExtractRangeFailed("extractRangeFailed6",
283            `
284namespace A {
285function f() {
286    [#|
287    try {
288        f2()
289    }
290    catch (e) {
291        return 10;
292    }
293    |]
294}
295function f2() {
296}
297}
298            `,
299            [refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalReturnStatement.message]);
300
301        testExtractRangeFailed("extractRangeFailed7",
302            `
303function test(x: number) {
304while (x) {
305    x--;
306    [#|break;|]
307}
308}
309            `,
310            [refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message]);
311
312        testExtractRangeFailed("extractRangeFailed8",
313            `
314function test(x: number) {
315switch (x) {
316    case 1:
317        [#|break;|]
318}
319}
320            `,
321            [refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message]);
322
323        testExtractRangeFailed("extractRangeFailed9",
324            `var x = ([#||]1 + 2);`,
325            [refactor.extractSymbol.Messages.cannotExtractEmpty.message]);
326
327        testExtractRangeFailed("extractRangeFailed10",
328            `
329                function f() {
330                    return 1 + [#|2 + 3|];
331                    }
332                }
333            `,
334            [refactor.extractSymbol.Messages.cannotExtractRange.message]);
335
336        testExtractRangeFailed("extractRangeFailed11",
337            `
338                function f(x: number) {
339                    while (true) {
340                        [#|try {
341                            x++;
342                        }
343                        finally {
344                            break;
345                        }|]
346                    }
347                }
348            `,
349            [refactor.extractSymbol.Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements.message]);
350
351        testExtractRangeFailed("extractRangeFailed12",
352            `let [#|x|];`,
353            [refactor.extractSymbol.Messages.statementOrExpressionExpected.message]);
354
355        testExtractRangeFailed("extractRangeFailed13",
356            `[#|return;|]`,
357            [refactor.extractSymbol.Messages.cannotExtractRange.message]);
358
359        testExtractRangeFailed("extractRangeFailed14",
360            `
361                switch(1) {
362                    case [#|1:
363                        break;|]
364                }
365            `,
366            [refactor.extractSymbol.Messages.cannotExtractRange.message]);
367
368        testExtractRangeFailed("extractRangeFailed15",
369            `
370                switch(1) {
371                    case [#|1:
372                        break|];
373                }
374            `,
375            [refactor.extractSymbol.Messages.cannotExtractRange.message]);
376
377        // Documentation only - it would be nice if the result were [$|1|]
378        testExtractRangeFailed("extractRangeFailed16",
379            `
380                switch(1) {
381                    [#|case 1|]:
382                        break;
383                }
384            `,
385            [refactor.extractSymbol.Messages.cannotExtractRange.message]);
386
387        // Documentation only - it would be nice if the result were [$|1|]
388        testExtractRangeFailed("extractRangeFailed17",
389            `
390                switch(1) {
391                    [#|case 1:|]
392                        break;
393                }
394            `,
395            [refactor.extractSymbol.Messages.cannotExtractRange.message]);
396
397        testExtractRangeFailed("extractRangeFailed18",
398            `[#|{ 1;|] }`,
399            [refactor.extractSymbol.Messages.cannotExtractRange.message]);
400
401        testExtractRangeFailed("extractRangeFailed19",
402            `[#|/** @type {number} */|] const foo = 1;`,
403            [refactor.extractSymbol.Messages.cannotExtractJSDoc.message]);
404
405        testExtractRangeFailed("extract-method-not-for-token-expression-statement", `[#|a|]`, [refactor.extractSymbol.Messages.cannotExtractIdentifier.message]);
406    });
407}
408