1namespace ts.projectSystem { 2 describe("unittests:: tsserver:: reloadProjects", () => { 3 const configFile: File = { 4 path: `${tscWatch.projectRoot}/tsconfig.json`, 5 content: JSON.stringify({ 6 watchOptions: { excludeDirectories: ["node_modules"] } 7 }) 8 }; 9 const file1: File = { 10 path: `${tscWatch.projectRoot}/file1.ts`, 11 content: `import { foo } from "module1"; 12 foo(); 13 import { bar } from "./file2"; 14 bar();` 15 }; 16 const file2: File = { 17 path: `${tscWatch.projectRoot}/file2.ts`, 18 content: `export function bar(){}` 19 }; 20 const moduleFile: File = { 21 path: `${tscWatch.projectRoot}/node_modules/module1/index.d.ts`, 22 content: `export function foo(): string;` 23 }; 24 25 function verifyFileUpdates(host: TestServerHost, service: TestProjectService, project: server.Project) { 26 // update file 27 const updatedText = `${file2.content} 28 bar();`; 29 host.writeFile(file2.path, updatedText); 30 host.checkTimeoutQueueLength(0); 31 service.reloadProjects(); 32 assert.equal(project.getCurrentProgram()?.getSourceFile(file2.path)?.text, updatedText); 33 34 // delete file 35 host.deleteFile(file2.path); 36 host.checkTimeoutQueueLength(0); 37 service.reloadProjects(); 38 assert.isUndefined(project.getCurrentProgram()?.getSourceFile(file2.path)?.text); 39 assert.isUndefined(service.getScriptInfo(file2.path)); 40 } 41 42 it("configured project", () => { 43 const host = createServerHost([configFile, libFile, file1, file2]); 44 const service = createProjectService(host); 45 service.setHostConfiguration({ watchOptions: { excludeFiles: [file2.path] } }); 46 service.openClientFile(file1.path); 47 checkNumberOfProjects(service, { configuredProjects: 1 }); 48 const project = service.configuredProjects.get(configFile.path)!; 49 checkProjectActualFiles(project, [libFile.path, file1.path, file2.path, configFile.path]); 50 51 // Install module1 52 host.ensureFileOrFolder(moduleFile); 53 host.checkTimeoutQueueLength(0); 54 55 service.reloadProjects(); 56 checkNumberOfProjects(service, { configuredProjects: 1 }); 57 assert.strictEqual(service.configuredProjects.get(configFile.path), project); 58 checkProjectActualFiles(project, [libFile.path, file1.path, file2.path, configFile.path, moduleFile.path]); 59 60 verifyFileUpdates(host, service, project); 61 }); 62 63 it("inferred project", () => { 64 const host = createServerHost([libFile, file1, file2]); 65 const service = createProjectService(host, { useInferredProjectPerProjectRoot: true, }); 66 service.setHostConfiguration({ watchOptions: { excludeFiles: [file2.path] } }); 67 const timeoutId = host.getNextTimeoutId(); 68 service.setCompilerOptionsForInferredProjects({ excludeDirectories: ["node_modules"] }, tscWatch.projectRoot); 69 host.clearTimeout(timeoutId); 70 service.openClientFile(file1.path, /*fileContent*/ undefined, /*scriptKind*/ undefined, tscWatch.projectRoot); 71 checkNumberOfProjects(service, { inferredProjects: 1 }); 72 const project = service.inferredProjects[0]; 73 checkProjectActualFiles(project, [libFile.path, file1.path, file2.path]); 74 75 // Install module1 76 host.ensureFileOrFolder(moduleFile); 77 host.checkTimeoutQueueLength(0); 78 79 service.reloadProjects(); 80 checkNumberOfProjects(service, { inferredProjects: 1 }); 81 assert.strictEqual(service.inferredProjects[0], project); 82 checkProjectActualFiles(project, [libFile.path, file1.path, file2.path, moduleFile.path]); 83 84 verifyFileUpdates(host, service, project); 85 }); 86 87 it("external project", () => { 88 const host = createServerHost([libFile, file1, file2]); 89 const service = createProjectService(host); 90 service.setHostConfiguration({ watchOptions: { excludeFiles: [file2.path] } }); 91 service.openExternalProject({ 92 projectFileName: `${tscWatch.projectRoot}/project.sln`, 93 options: { excludeDirectories: ["node_modules"] }, 94 rootFiles: [{ fileName: file1.path }, { fileName: file2.path }] 95 }); 96 service.openClientFile(file1.path); 97 checkNumberOfProjects(service, { externalProjects: 1 }); 98 const project = service.externalProjects[0]; 99 checkProjectActualFiles(project, [libFile.path, file1.path, file2.path]); 100 101 // Install module1 102 host.ensureFileOrFolder(moduleFile); 103 host.checkTimeoutQueueLength(0); 104 105 service.reloadProjects(); 106 checkNumberOfProjects(service, { externalProjects: 1 }); 107 assert.strictEqual(service.externalProjects[0], project); 108 checkProjectActualFiles(project, [libFile.path, file1.path, file2.path, moduleFile.path]); 109 110 verifyFileUpdates(host, service, project); 111 }); 112 113 it("external project with config file", () => { 114 const host = createServerHost([libFile, file1, file2, configFile]); 115 const service = createProjectService(host); 116 service.setHostConfiguration({ watchOptions: { excludeFiles: [file2.path] } }); 117 service.openExternalProject({ 118 projectFileName: `${tscWatch.projectRoot}/project.sln`, 119 options: { excludeDirectories: ["node_modules"] }, 120 rootFiles: [{ fileName: file1.path }, { fileName: file2.path }, { fileName: configFile.path }] 121 }); 122 service.openClientFile(file1.path); 123 checkNumberOfProjects(service, { configuredProjects: 1 }); 124 const project = service.configuredProjects.get(configFile.path)!; 125 checkProjectActualFiles(project, [libFile.path, file1.path, file2.path, configFile.path]); 126 127 // Install module1 128 host.ensureFileOrFolder(moduleFile); 129 host.checkTimeoutQueueLength(0); 130 131 service.reloadProjects(); 132 checkNumberOfProjects(service, { configuredProjects: 1 }); 133 assert.strictEqual(service.configuredProjects.get(configFile.path), project); 134 checkProjectActualFiles(project, [libFile.path, file1.path, file2.path, configFile.path, moduleFile.path]); 135 136 verifyFileUpdates(host, service, project); 137 }); 138 }); 139} 140