From dcf3cc248b825ee2c7fcd7ea16c8f60695f228c8 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Wed, 29 Jun 2016 22:35:54 -0700 Subject: [PATCH] more tests --- src/server/editorServices.ts | 14 ++- .../cases/unittests/tsserverProjectSystem.ts | 89 ++++++++++++++++++- 2 files changed, 95 insertions(+), 8 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 65b34d817f8..56a7dae4389 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -983,10 +983,11 @@ namespace ts.server { if (configFiles) { for (const configFile of configFiles) { const configuredProject = this.findConfiguredProjectByProjectName(configFile); - if (configuredProject) { + if (configuredProject && configuredProject.deleteOpenRef() === 0) { this.removeProject(configuredProject); } } + // TODO: do this only if ownership of files is changed this.refreshInferredProjects(); } else { @@ -1019,9 +1020,14 @@ namespace ts.server { // store the list of tsconfig files that belong to the external project this.externalProjectToConfiguredProjectMap[proj.projectFileName] = tsConfigFiles; for (const tsconfigFile of tsConfigFiles) { - const { success, project, errors } = this.openConfigFile(tsconfigFile); - if (success) { - // keep project alive - its lifetime is bound to the lifetime of containing external project + let project = this.findConfiguredProjectByProjectName(tsconfigFile); + if (!project) { + const result = this.openConfigFile(tsconfigFile); + // TODO: save errors + project = result.success && result.project; + } + if (project) { + // keep project alive even if no documents are opened - its lifetime is bound to the lifetime of containing external project project.addOpenRef(); } } diff --git a/tests/cases/unittests/tsserverProjectSystem.ts b/tests/cases/unittests/tsserverProjectSystem.ts index 9495a4a4403..8b4a9304efd 100644 --- a/tests/cases/unittests/tsserverProjectSystem.ts +++ b/tests/cases/unittests/tsserverProjectSystem.ts @@ -857,13 +857,14 @@ namespace ts { projectService.closeExternalProject(externalProjectName); checkNumberOfExternalProjects(projectService, 0); - // open file 'file1' from configured project is moved to its own inferred project + inferred project for file3 - checkNumberOfInferredProjects(projectService, 2); + // open file 'file1' from configured project keeps project alive + checkNumberOfConfiguredProjects(projectService, 1); + checkNumberOfInferredProjects(projectService, 1); projectService.closeClientFile(file3.path); checkNumberOfExternalProjects(projectService, 0); - checkNumberOfConfiguredProjects(projectService, 0); - checkNumberOfInferredProjects(projectService, 1); + checkNumberOfConfiguredProjects(projectService, 1); + checkNumberOfInferredProjects(projectService, 0); projectService.closeClientFile(file1.path); checkNumberOfExternalProjects(projectService, 0); @@ -871,5 +872,85 @@ namespace ts { checkNumberOfInferredProjects(projectService, 0); }); + it("external project with included config file opened after configured project", () => { + const file1 = { + path: "/a/b/f1.ts", + content: "let x = 1" + }; + const configFile = { + path: "/a/b/tsconfig.json", + content: JSON.stringify({ compilerOptions: {} }) + }; + const externalProjectName = "externalproject"; + const host = createServerHost({ fileOrFolderList: [file1, configFile], libFile }); + const projectService = new server.ProjectService(host, nullLogger, nullCancellationToken, /*useOneInferredProject*/ false); + + projectService.openClientFile(file1.path); + checkNumberOfExternalProjects(projectService, 0); + checkNumberOfConfiguredProjects(projectService, 1); + checkNumberOfInferredProjects(projectService, 0); + + projectService.openExternalProject({ + rootFiles: [ configFile.path ], + options: {}, + projectFileName: externalProjectName + }); + + checkNumberOfExternalProjects(projectService, 0); + checkNumberOfConfiguredProjects(projectService, 1); + checkNumberOfInferredProjects(projectService, 0); + + projectService.closeClientFile(file1.path); + checkNumberOfExternalProjects(projectService, 0); + // configured project is alive since it is opened as part of external project + checkNumberOfConfiguredProjects(projectService, 1); + checkNumberOfInferredProjects(projectService, 0); + + projectService.closeExternalProject(externalProjectName); + checkNumberOfExternalProjects(projectService, 0); + // configured project is alive since it is opened as part of external project + checkNumberOfConfiguredProjects(projectService, 0); + checkNumberOfInferredProjects(projectService, 0); + }); + it("external project with included config file opened after configured project and then closed", () => { + const file1 = { + path: "/a/b/f1.ts", + content: "let x = 1" + }; + const configFile = { + path: "/a/b/tsconfig.json", + content: JSON.stringify({ compilerOptions: {} }) + }; + const externalProjectName = "externalproject"; + const host = createServerHost({ fileOrFolderList: [file1, configFile], libFile }); + const projectService = new server.ProjectService(host, nullLogger, nullCancellationToken, /*useOneInferredProject*/ false); + + projectService.openClientFile(file1.path); + checkNumberOfExternalProjects(projectService, 0); + checkNumberOfConfiguredProjects(projectService, 1); + checkNumberOfInferredProjects(projectService, 0); + + projectService.openExternalProject({ + rootFiles: [ configFile.path ], + options: {}, + projectFileName: externalProjectName + }); + + checkNumberOfExternalProjects(projectService, 0); + checkNumberOfConfiguredProjects(projectService, 1); + checkNumberOfInferredProjects(projectService, 0); + + projectService.closeExternalProject(externalProjectName); + checkNumberOfExternalProjects(projectService, 0); + // configured project is alive since file is still open + checkNumberOfConfiguredProjects(projectService, 1); + checkNumberOfInferredProjects(projectService, 0); + + projectService.closeClientFile(file1.path); + checkNumberOfExternalProjects(projectService, 0); + // configured project is alive since it is opened as part of external project + checkNumberOfConfiguredProjects(projectService, 0); + checkNumberOfInferredProjects(projectService, 0); + }); }); } \ No newline at end of file