Skip to content

Commit 697bce7

Browse files
committed
Split range tests and helpers out of extractFunctions.ts
1 parent 52ab05e commit 697bce7

File tree

6 files changed

+505
-628
lines changed

6 files changed

+505
-628
lines changed

Jakefile.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ var harnessSources = harnessCoreSources.concat([
140140
"initializeTSConfig.ts",
141141
"extractConstants.ts",
142142
"extractFunctions.ts",
143+
"extractRanges.ts",
144+
"extractTestHelpers.ts",
143145
"printer.ts",
144146
"textChanges.ts",
145147
"telemetry.ts",

src/harness/tsconfig.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@
130130
"./unittests/customTransforms.ts",
131131
"./unittests/extractConstants.ts",
132132
"./unittests/extractFunctions.ts",
133+
"./unittests/extractRanges.ts",
134+
"./unittests/extractTestHelpers.ts",
133135
"./unittests/textChanges.ts",
134136
"./unittests/telemetry.ts",
135137
"./unittests/languageService.ts",
Lines changed: 3 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,6 @@
1-
/// <reference path="..\harness.ts" />
2-
/// <reference path="tsserverProjectSystem.ts" />
1+
/// <reference path="extractTestHelpers.ts" />
32

43
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-
1024
describe("extractConstants", () => {
1035
testExtractConstant("extractConstant_TopLevel",
1046
`let x = [#|1|];`);
@@ -168,83 +70,11 @@ namespace ts {
16870
}`);
16971
});
17072

171-
// TODO (acasey): share?
17273
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);
21675
}
21776

218-
// TODO (acasey): share?
21977
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);
24979
}
25080
}

0 commit comments

Comments
 (0)