1namespace ts.projectSystem { 2 const tsConfig: File = { 3 path: "/tsconfig.json", 4 content: "{}" 5 }; 6 const packageJsonContent = { 7 dependencies: { 8 redux: "*" 9 }, 10 peerDependencies: { 11 react: "*" 12 }, 13 optionalDependencies: { 14 typescript: "*" 15 }, 16 devDependencies: { 17 webpack: "*" 18 } 19 }; 20 const packageJson: File = { 21 path: "/package.json", 22 content: JSON.stringify(packageJsonContent, undefined, 2) 23 }; 24 25 describe("unittests:: tsserver:: packageJsonInfo", () => { 26 it("detects new package.json files that are added, caches them, and watches them", () => { 27 // Initialize project without package.json 28 const { projectService, host } = setup([tsConfig]); 29 assert.isUndefined(projectService.packageJsonCache.getInDirectory("/" as Path)); 30 31 // Add package.json 32 host.writeFile(packageJson.path, packageJson.content); 33 let packageJsonInfo = projectService.packageJsonCache.getInDirectory("/" as Path)!; 34 assert.ok(packageJsonInfo); 35 assert.ok(packageJsonInfo.dependencies); 36 assert.ok(packageJsonInfo.devDependencies); 37 assert.ok(packageJsonInfo.peerDependencies); 38 assert.ok(packageJsonInfo.optionalDependencies); 39 40 // Edit package.json 41 host.writeFile(packageJson.path, JSON.stringify({ 42 ...packageJsonContent, 43 dependencies: undefined 44 })); 45 packageJsonInfo = projectService.packageJsonCache.getInDirectory("/" as Path)!; 46 assert.isUndefined(packageJsonInfo.dependencies); 47 }); 48 49 it("finds package.json on demand, watches for deletion, and removes them from cache", () => { 50 // Initialize project with package.json 51 const { projectService, host } = setup(); 52 projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as Path); 53 assert.ok(projectService.packageJsonCache.getInDirectory("/" as Path)); 54 55 // Delete package.json 56 host.deleteFile(packageJson.path); 57 assert.isUndefined(projectService.packageJsonCache.getInDirectory("/" as Path)); 58 }); 59 60 it("finds multiple package.json files when present", () => { 61 // Initialize project with package.json at root 62 const { projectService, host } = setup(); 63 // Add package.json in /src 64 host.writeFile("/src/package.json", packageJson.content); 65 assert.lengthOf(projectService.getPackageJsonsVisibleToFile("/a.ts" as Path), 1); 66 assert.lengthOf(projectService.getPackageJsonsVisibleToFile("/src/b.ts" as Path), 2); 67 }); 68 69 it("handles errors in json parsing of package.json", () => { 70 const packageJsonContent = `{ "mod" }`; 71 const { projectService, host } = setup([tsConfig, { path: packageJson.path, content: packageJsonContent }]); 72 projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as Path); 73 const packageJsonInfo = projectService.packageJsonCache.getInDirectory("/" as Path)!; 74 assert.isFalse(packageJsonInfo.parseable); 75 76 host.writeFile(packageJson.path, packageJson.content); 77 projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as Path); 78 const packageJsonInfo2 = projectService.packageJsonCache.getInDirectory("/" as Path)!; 79 assert.ok(packageJsonInfo2); 80 assert.ok(packageJsonInfo2.dependencies); 81 assert.ok(packageJsonInfo2.devDependencies); 82 assert.ok(packageJsonInfo2.peerDependencies); 83 assert.ok(packageJsonInfo2.optionalDependencies); 84 }); 85 86 it("handles empty package.json", () => { 87 const packageJsonContent = ""; 88 const { projectService, host } = setup([tsConfig, { path: packageJson.path, content: packageJsonContent }]); 89 projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as Path); 90 const packageJsonInfo = projectService.packageJsonCache.getInDirectory("/" as Path)!; 91 assert.isFalse(packageJsonInfo.parseable); 92 93 host.writeFile(packageJson.path, packageJson.content); 94 projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as Path); 95 const packageJsonInfo2 = projectService.packageJsonCache.getInDirectory("/" as Path)!; 96 assert.ok(packageJsonInfo2); 97 assert.ok(packageJsonInfo2.dependencies); 98 assert.ok(packageJsonInfo2.devDependencies); 99 assert.ok(packageJsonInfo2.peerDependencies); 100 assert.ok(packageJsonInfo2.optionalDependencies); 101 }); 102 }); 103 104 function setup(files: readonly File[] = [tsConfig, packageJson]) { 105 const host = createServerHost(files); 106 const session = createSession(host); 107 const projectService = session.getProjectService(); 108 projectService.openClientFile(files[0].path); 109 const project = configuredProjectAt(projectService, 0); 110 return { host, session, project, projectService }; 111 } 112} 113