Merge pull request #30107 from Microsoft/applyChangesToOpenFiles

Add UpdateOpen to request
This commit is contained in:
Sheetal Nandi
2019-03-05 15:54:34 -08:00
committed by GitHub
10 changed files with 368 additions and 51 deletions
+1
View File
@@ -96,6 +96,7 @@
"unittests/tscWatch/resolutionCache.ts",
"unittests/tscWatch/watchEnvironment.ts",
"unittests/tscWatch/watchApi.ts",
"unittests/tsserver/applyChangesToOpenFiles.ts",
"unittests/tsserver/cachingFileSystemInformation.ts",
"unittests/tsserver/cancellationToken.ts",
"unittests/tsserver/compileOnSave.ts",
@@ -0,0 +1,148 @@
namespace ts.projectSystem {
describe("unittests:: tsserver:: applyChangesToOpenFiles", () => {
const configFile: File = {
path: "/a/b/tsconfig.json",
content: "{}"
};
const file3: File = {
path: "/a/b/file3.ts",
content: "let xyz = 1;"
};
const app: File = {
path: "/a/b/app.ts",
content: "let z = 1;"
};
function fileContentWithComment(file: File) {
return `// some copy right notice
${file.content}`;
}
function verifyText(service: server.ProjectService, file: string, expected: string) {
const info = service.getScriptInfo(file)!;
const snap = info.getSnapshot();
// Verified applied in reverse order
assert.equal(snap.getText(0, snap.getLength()), expected, `Text of changed file: ${file}`);
}
function verifyProjectVersion(project: server.Project, expected: number) {
assert.equal(Number(project.getProjectVersion()), expected);
}
function verify(applyChangesToOpen: (session: TestSession) => void) {
const host = createServerHost([app, file3, commonFile1, commonFile2, libFile, configFile]);
const session = createSession(host);
session.executeCommandSeq<protocol.OpenRequest>({
command: protocol.CommandTypes.Open,
arguments: { file: app.path }
});
const service = session.getProjectService();
const project = service.configuredProjects.get(configFile.path)!;
assert.isDefined(project);
verifyProjectVersion(project, 1);
session.executeCommandSeq<protocol.OpenRequest>({
command: protocol.CommandTypes.Open,
arguments: {
file: file3.path,
fileContent: fileContentWithComment(file3)
}
});
verifyProjectVersion(project, 2);
// Verify Texts
verifyText(service, commonFile1.path, commonFile1.content);
verifyText(service, commonFile2.path, commonFile2.content);
verifyText(service, app.path, app.content);
verifyText(service, file3.path, fileContentWithComment(file3));
// Apply changes
applyChangesToOpen(session);
// Verify again
verifyProjectVersion(project, 3);
// Open file contents
verifyText(service, commonFile1.path, fileContentWithComment(commonFile1));
verifyText(service, commonFile2.path, fileContentWithComment(commonFile2));
verifyText(service, app.path, "let zzz = 10;let zz = 10;let z = 1;");
verifyText(service, file3.path, file3.content);
}
it("with applyChangedToOpenFiles request", () => {
verify(session =>
session.executeCommandSeq<protocol.ApplyChangedToOpenFilesRequest>({
command: protocol.CommandTypes.ApplyChangedToOpenFiles,
arguments: {
openFiles: [
{
fileName: commonFile1.path,
content: fileContentWithComment(commonFile1)
},
{
fileName: commonFile2.path,
content: fileContentWithComment(commonFile2)
}
],
changedFiles: [
{
fileName: app.path,
changes: [
{
span: { start: 0, length: 0 },
newText: "let zzz = 10;"
},
{
span: { start: 0, length: 0 },
newText: "let zz = 10;"
}
]
}
],
closedFiles: [
file3.path
]
}
})
);
});
it("with updateOpen request", () => {
verify(session =>
session.executeCommandSeq<protocol.UpdateOpenRequest>({
command: protocol.CommandTypes.UpdateOpen,
arguments: {
openFiles: [
{
file: commonFile1.path,
fileContent: fileContentWithComment(commonFile1)
},
{
file: commonFile2.path,
fileContent: fileContentWithComment(commonFile2)
}
],
changedFiles: [
{
fileName: app.path,
textChanges: [
{
start: { line: 1, offset: 1 },
end: { line: 1, offset: 1 },
newText: "let zzz = 10;",
},
{
start: { line: 1, offset: 1 },
end: { line: 1, offset: 1 },
newText: "let zz = 10;",
}
]
}
],
closedFiles: [
file3.path
]
}
})
);
});
});
}
@@ -41,13 +41,13 @@ namespace ts.projectSystem {
function changeFileToNotImportModule(service: TestProjectService) {
const info = service.getScriptInfo(file.path)!;
service.applyChangesToFile(info, [{ span: { start: 0, length: importModuleContent.length }, newText: "" }]);
service.applyChangesToFile(info, singleIterator({ span: { start: 0, length: importModuleContent.length }, newText: "" }));
checkProject(service, /*moduleIsOrphan*/ true);
}
function changeFileToImportModule(service: TestProjectService) {
const info = service.getScriptInfo(file.path)!;
service.applyChangesToFile(info, [{ span: { start: 0, length: 0 }, newText: importModuleContent }]);
service.applyChangesToFile(info, singleIterator({ span: { start: 0, length: 0 }, newText: importModuleContent }));
checkProject(service, /*moduleIsOrphan*/ false);
}
@@ -161,7 +161,7 @@ namespace ts.projectSystem {
checkNumberOfInferredProjects(projectService, 0);
externalFiles[0].content = "let x =1;";
projectService.applyChangesInOpenFiles(externalFiles, [], []);
projectService.applyChangesInOpenFiles(arrayIterator(externalFiles));
});
it("external project that included config files", () => {
@@ -790,9 +790,7 @@ namespace ts.projectSystem {
rootFiles: [{ fileName: tsconfig.path }, { fileName: jsFilePath }],
options: { allowJs: false }
}]);
service.applyChangesInOpenFiles([
{ fileName: jsFilePath, scriptKind: ScriptKind.JS, content: "" }
], /*changedFiles*/ undefined, /*closedFiles*/ undefined);
service.applyChangesInOpenFiles(singleIterator({ fileName: jsFilePath, scriptKind: ScriptKind.JS, content: "" }));
checkNumberOfProjects(service, { configuredProjects: 1, inferredProjects: 1 });
checkProjectActualFiles(configProject, [tsconfig.path]);
const inferredProject = service.inferredProjects[0];
+10 -9
View File
@@ -202,7 +202,7 @@ namespace ts.projectSystem {
const host = createServerHost([file1, config1]);
const projectService = createProjectService(host, { useSingleInferredProject: true }, { syntaxOnly: true });
projectService.applyChangesInOpenFiles([{ fileName: file1.path, content: file1.content }], [], []);
projectService.applyChangesInOpenFiles(singleIterator({ fileName: file1.path, content: file1.content }));
checkNumberOfProjects(projectService, { inferredProjects: 1 });
const proj = projectService.inferredProjects[0];
@@ -588,11 +588,11 @@ namespace ts.projectSystem {
const host = createServerHost([]);
const projectService = createProjectService(host);
projectService.applyChangesInOpenFiles([tsFile], [], []);
projectService.applyChangesInOpenFiles(singleIterator(tsFile));
const projs = projectService.synchronizeProjectList([]);
projectService.findProject(projs[0].info!.projectName)!.getLanguageService().getNavigationBarItems(tsFile.fileName);
projectService.synchronizeProjectList([projs[0].info!]);
projectService.applyChangesInOpenFiles([jsFile], [], []);
projectService.applyChangesInOpenFiles(singleIterator(jsFile));
});
it("config file is deleted", () => {
@@ -696,11 +696,12 @@ namespace ts.projectSystem {
checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]);
// Open HTML file
projectService.applyChangesInOpenFiles(
/*openFiles*/[{ fileName: file2.path, hasMixedContent: true, scriptKind: ScriptKind.JS, content: `var hello = "hello";` }],
/*changedFiles*/ undefined,
/*closedFiles*/ undefined);
projectService.applyChangesInOpenFiles(singleIterator({
fileName: file2.path,
hasMixedContent: true,
scriptKind: ScriptKind.JS,
content: `var hello = "hello";`
}));
// Now HTML file is included in the project
checkNumberOfProjects(projectService, { configuredProjects: 1 });
checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]);
@@ -853,7 +854,7 @@ namespace ts.projectSystem {
checkNumberOfProjects(projectService, { inferredProjects: 1 });
projectService.applyChangesInOpenFiles(
/*openFiles*/ undefined,
/*changedFiles*/[{ fileName: file1.path, changes: [{ span: createTextSpan(0, file1.path.length), newText: "let y = 1" }] }],
/*changedFiles*/singleIterator({ fileName: file1.path, changes: singleIterator({ span: createTextSpan(0, file1.path.length), newText: "let y = 1" }) }),
/*closedFiles*/ undefined);
checkNumberOfProjects(projectService, { inferredProjects: 1 });