|
1 |
| -/// <reference path="..\harness.ts" /> |
2 |
| -/// <reference path="tsserverProjectSystem.ts" /> |
| 1 | +/// <reference path="extractTestHelpers.ts" /> |
3 | 2 |
|
4 | 3 | namespace ts {
|
5 |
| - interface Range { |
6 |
| - start: number; |
7 |
| - end: number; |
8 |
| - name: string; |
9 |
| - } |
10 |
| - |
11 |
| - interface Test { |
12 |
| - source: string; |
13 |
| - ranges: Map<Range>; |
14 |
| - } |
15 |
| - |
16 |
| - // TODO (acasey): share |
17 |
| - function extractTest(source: string): Test { |
18 |
| - const activeRanges: Range[] = []; |
19 |
| - let text = ""; |
20 |
| - let lastPos = 0; |
21 |
| - let pos = 0; |
22 |
| - const ranges = createMap<Range>(); |
23 |
| - |
24 |
| - while (pos < source.length) { |
25 |
| - if (source.charCodeAt(pos) === CharacterCodes.openBracket && |
26 |
| - (source.charCodeAt(pos + 1) === CharacterCodes.hash || source.charCodeAt(pos + 1) === CharacterCodes.$)) { |
27 |
| - const saved = pos; |
28 |
| - pos += 2; |
29 |
| - const s = pos; |
30 |
| - consumeIdentifier(); |
31 |
| - const e = pos; |
32 |
| - if (source.charCodeAt(pos) === CharacterCodes.bar) { |
33 |
| - pos++; |
34 |
| - text += source.substring(lastPos, saved); |
35 |
| - const name = s === e |
36 |
| - ? source.charCodeAt(saved + 1) === CharacterCodes.hash ? "selection" : "extracted" |
37 |
| - : source.substring(s, e); |
38 |
| - activeRanges.push({ name, start: text.length, end: undefined }); |
39 |
| - lastPos = pos; |
40 |
| - continue; |
41 |
| - } |
42 |
| - else { |
43 |
| - pos = saved; |
44 |
| - } |
45 |
| - } |
46 |
| - else if (source.charCodeAt(pos) === CharacterCodes.bar && source.charCodeAt(pos + 1) === CharacterCodes.closeBracket) { |
47 |
| - text += source.substring(lastPos, pos); |
48 |
| - activeRanges[activeRanges.length - 1].end = text.length; |
49 |
| - const range = activeRanges.pop(); |
50 |
| - if (range.name in ranges) { |
51 |
| - throw new Error(`Duplicate name of range ${range.name}`); |
52 |
| - } |
53 |
| - ranges.set(range.name, range); |
54 |
| - pos += 2; |
55 |
| - lastPos = pos; |
56 |
| - continue; |
57 |
| - } |
58 |
| - pos++; |
59 |
| - } |
60 |
| - text += source.substring(lastPos, pos); |
61 |
| - |
62 |
| - function consumeIdentifier() { |
63 |
| - while (isIdentifierPart(source.charCodeAt(pos), ScriptTarget.Latest)) { |
64 |
| - pos++; |
65 |
| - } |
66 |
| - } |
67 |
| - return { source: text, ranges }; |
68 |
| - } |
69 |
| - |
70 |
| - // TODO (acasey): share |
71 |
| - const newLineCharacter = "\n"; |
72 |
| - function getRuleProvider(action?: (opts: FormatCodeSettings) => void) { |
73 |
| - const options = { |
74 |
| - indentSize: 4, |
75 |
| - tabSize: 4, |
76 |
| - newLineCharacter, |
77 |
| - convertTabsToSpaces: true, |
78 |
| - indentStyle: ts.IndentStyle.Smart, |
79 |
| - insertSpaceAfterConstructor: false, |
80 |
| - insertSpaceAfterCommaDelimiter: true, |
81 |
| - insertSpaceAfterSemicolonInForStatements: true, |
82 |
| - insertSpaceBeforeAndAfterBinaryOperators: true, |
83 |
| - insertSpaceAfterKeywordsInControlFlowStatements: true, |
84 |
| - insertSpaceAfterFunctionKeywordForAnonymousFunctions: false, |
85 |
| - insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, |
86 |
| - insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, |
87 |
| - insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true, |
88 |
| - insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, |
89 |
| - insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, |
90 |
| - insertSpaceBeforeFunctionParenthesis: false, |
91 |
| - placeOpenBraceOnNewLineForFunctions: false, |
92 |
| - placeOpenBraceOnNewLineForControlBlocks: false, |
93 |
| - }; |
94 |
| - if (action) { |
95 |
| - action(options); |
96 |
| - } |
97 |
| - const rulesProvider = new formatting.RulesProvider(); |
98 |
| - rulesProvider.ensureUpToDate(options); |
99 |
| - return rulesProvider; |
100 |
| - } |
101 |
| - |
102 | 4 | describe("extractConstants", () => {
|
103 | 5 | testExtractConstant("extractConstant_TopLevel",
|
104 | 6 | `let x = [#|1|];`);
|
@@ -168,83 +70,11 @@ namespace ts {
|
168 | 70 | }`);
|
169 | 71 | });
|
170 | 72 |
|
171 |
| - // TODO (acasey): share? |
172 | 73 | function testExtractConstant(caption: string, text: string) {
|
173 |
| - it(caption, () => { |
174 |
| - Harness.Baseline.runBaseline(`extractConstant/${caption}.ts`, () => { |
175 |
| - const t = extractTest(text); |
176 |
| - const selectionRange = t.ranges.get("selection"); |
177 |
| - if (!selectionRange) { |
178 |
| - throw new Error(`Test ${caption} does not specify selection range`); |
179 |
| - } |
180 |
| - const f = { |
181 |
| - path: "/a.ts", |
182 |
| - content: t.source |
183 |
| - }; |
184 |
| - const host = projectSystem.createServerHost([f, projectSystem.libFile]); |
185 |
| - const projectService = projectSystem.createProjectService(host); |
186 |
| - projectService.openClientFile(f.path); |
187 |
| - const program = projectService.inferredProjects[0].getLanguageService().getProgram(); |
188 |
| - const sourceFile = program.getSourceFile(f.path); |
189 |
| - const context: RefactorContext = { |
190 |
| - cancellationToken: { throwIfCancellationRequested() { }, isCancellationRequested() { return false; } }, |
191 |
| - newLineCharacter, |
192 |
| - program, |
193 |
| - file: sourceFile, |
194 |
| - startPosition: selectionRange.start, |
195 |
| - endPosition: selectionRange.end, |
196 |
| - rulesProvider: getRuleProvider() |
197 |
| - }; |
198 |
| - const rangeToExtract = refactor.extractSymbol.getRangeToExtract(sourceFile, createTextSpanFromBounds(selectionRange.start, selectionRange.end)); |
199 |
| - assert.equal(rangeToExtract.errors, undefined, rangeToExtract.errors && "Range error: " + rangeToExtract.errors[0].messageText); |
200 |
| - const infos = refactor.extractSymbol.getAvailableActions(context); |
201 |
| - const actions = find(infos, info => info.description === Diagnostics.Extract_constant.message).actions; |
202 |
| - const data: string[] = []; |
203 |
| - data.push(`// ==ORIGINAL==`); |
204 |
| - data.push(sourceFile.text); |
205 |
| - for (const action of actions) { |
206 |
| - const { renameLocation, edits } = refactor.extractSymbol.getEditsForAction(context, action.name); |
207 |
| - assert.lengthOf(edits, 1); |
208 |
| - data.push(`// ==SCOPE::${action.description}==`); |
209 |
| - const newText = textChanges.applyChanges(sourceFile.text, edits[0].textChanges); |
210 |
| - const newTextWithRename = newText.slice(0, renameLocation) + "/*RENAME*/" + newText.slice(renameLocation); |
211 |
| - data.push(newTextWithRename); |
212 |
| - } |
213 |
| - return data.join(newLineCharacter); |
214 |
| - }); |
215 |
| - }); |
| 74 | + testExtractSymbol(caption, text, "extractConstant", Diagnostics.Extract_constant); |
216 | 75 | }
|
217 | 76 |
|
218 |
| - // TODO (acasey): share? |
219 | 77 | function testExtractConstantFailed(caption: string, text: string) {
|
220 |
| - it(caption, () => { |
221 |
| - const t = extractTest(text); |
222 |
| - const selectionRange = t.ranges.get("selection"); |
223 |
| - if (!selectionRange) { |
224 |
| - throw new Error(`Test ${caption} does not specify selection range`); |
225 |
| - } |
226 |
| - const f = { |
227 |
| - path: "/a.ts", |
228 |
| - content: t.source |
229 |
| - }; |
230 |
| - const host = projectSystem.createServerHost([f, projectSystem.libFile]); |
231 |
| - const projectService = projectSystem.createProjectService(host); |
232 |
| - projectService.openClientFile(f.path); |
233 |
| - const program = projectService.inferredProjects[0].getLanguageService().getProgram(); |
234 |
| - const sourceFile = program.getSourceFile(f.path); |
235 |
| - const context: RefactorContext = { |
236 |
| - cancellationToken: { throwIfCancellationRequested() { }, isCancellationRequested() { return false; } }, |
237 |
| - newLineCharacter, |
238 |
| - program, |
239 |
| - file: sourceFile, |
240 |
| - startPosition: selectionRange.start, |
241 |
| - endPosition: selectionRange.end, |
242 |
| - rulesProvider: getRuleProvider() |
243 |
| - }; |
244 |
| - const rangeToExtract = refactor.extractSymbol.getRangeToExtract(sourceFile, createTextSpanFromBounds(selectionRange.start, selectionRange.end)); |
245 |
| - assert.isUndefined(rangeToExtract.errors, rangeToExtract.errors && "Range error: " + rangeToExtract.errors[0].messageText); |
246 |
| - const infos = refactor.extractSymbol.getAvailableActions(context); |
247 |
| - assert.isUndefined(find(infos, info => info.description === Diagnostics.Extract_constant.message)); |
248 |
| - }); |
| 78 | + testExtractSymbolFailed(caption, text, Diagnostics.Extract_constant); |
249 | 79 | }
|
250 | 80 | }
|
0 commit comments