• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1namespace ts.projectSystem {
2    describe("unittests:: tsserver:: forceConsistentCasingInFileNames", () => {
3        it("works when extends is specified with a case insensitive file system", () => {
4            const rootPath = "/Users/username/dev/project";
5            const file1: File = {
6                path: `${rootPath}/index.ts`,
7                content: 'import {x} from "file2";',
8            };
9            const file2: File = {
10                path: `${rootPath}/file2.js`,
11                content: "",
12            };
13            const file2Dts: File = {
14                path: `${rootPath}/types/file2/index.d.ts`,
15                content: "export declare const x: string;",
16            };
17            const tsconfigAll: File = {
18                path: `${rootPath}/tsconfig.all.json`,
19                content: JSON.stringify({
20                    compilerOptions: {
21                        baseUrl: ".",
22                        paths: { file2: ["./file2.js"] },
23                        typeRoots: ["./types"],
24                        forceConsistentCasingInFileNames: true,
25                    },
26                }),
27            };
28            const tsconfig: File = {
29                path: `${rootPath}/tsconfig.json`,
30                content: JSON.stringify({ extends: "./tsconfig.all.json" }),
31            };
32
33            const host = createServerHost([file1, file2, file2Dts, libFile, tsconfig, tsconfigAll], { useCaseSensitiveFileNames: false });
34            const session = createSession(host);
35
36            openFilesForSession([file1], session);
37            const projectService = session.getProjectService();
38
39            checkNumberOfProjects(projectService, { configuredProjects: 1 });
40
41            const diagnostics = configuredProjectAt(projectService, 0).getLanguageService().getCompilerOptionsDiagnostics();
42            assert.deepEqual(diagnostics, []);
43        });
44
45        it("works when renaming file with different casing", () => {
46            const loggerFile: File = {
47                path: `${tscWatch.projectRoot}/Logger.ts`,
48                content: `export class logger { }`
49            };
50            const anotherFile: File = {
51                path: `${tscWatch.projectRoot}/another.ts`,
52                content: `import { logger } from "./Logger"; new logger();`
53            };
54            const tsconfig: File = {
55                path: `${tscWatch.projectRoot}/tsconfig.json`,
56                content: JSON.stringify({
57                    compilerOptions: { forceConsistentCasingInFileNames: true }
58                })
59            };
60
61            const host = createServerHost([loggerFile, anotherFile, tsconfig, libFile, tsconfig]);
62            const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) });
63            openFilesForSession([{ file: loggerFile, projectRootPath: tscWatch.projectRoot }], session);
64            verifyGetErrRequest({ session, host, files: [loggerFile] });
65
66            const newLoggerPath = loggerFile.path.toLowerCase();
67            host.renameFile(loggerFile.path, newLoggerPath);
68            closeFilesForSession([loggerFile], session);
69            openFilesForSession([{ file: newLoggerPath, content: loggerFile.content, projectRootPath: tscWatch.projectRoot }], session);
70
71            // Apply edits for rename
72            openFilesForSession([{ file: anotherFile, projectRootPath: tscWatch.projectRoot }], session);
73            session.executeCommandSeq<protocol.UpdateOpenRequest>({
74                command: protocol.CommandTypes.UpdateOpen,
75                arguments: {
76                    changedFiles: [{
77                        fileName: anotherFile.path,
78                        textChanges: [{
79                            newText: "./logger",
80                            ...protocolTextSpanFromSubstring(
81                                anotherFile.content,
82                                "./Logger"
83                            )
84                        }]
85                    }]
86                }
87            });
88
89            // Check errors in both files
90            verifyGetErrRequest({ session, host, files: [newLoggerPath, anotherFile] });
91            baselineTsserverLogs("forceConsistentCasingInFileNames", "works when renaming file with different casing", session);
92        });
93
94        it("when changing module name with different casing", () => {
95            const loggerFile: File = {
96                path: `${tscWatch.projectRoot}/Logger.ts`,
97                content: `export class logger { }`
98            };
99            const anotherFile: File = {
100                path: `${tscWatch.projectRoot}/another.ts`,
101                content: `import { logger } from "./Logger"; new logger();`
102            };
103            const tsconfig: File = {
104                path: `${tscWatch.projectRoot}/tsconfig.json`,
105                content: JSON.stringify({
106                    compilerOptions: { forceConsistentCasingInFileNames: true }
107                })
108            };
109
110            const host = createServerHost([loggerFile, anotherFile, tsconfig, libFile, tsconfig]);
111            const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) });
112            openFilesForSession([{ file: anotherFile, projectRootPath: tscWatch.projectRoot }], session);
113            verifyGetErrRequest({ session, host, files: [anotherFile] });
114
115            session.executeCommandSeq<protocol.UpdateOpenRequest>({
116                command: protocol.CommandTypes.UpdateOpen,
117                arguments: {
118                    changedFiles: [{
119                        fileName: anotherFile.path,
120                        textChanges: [{
121                            newText: "./logger",
122                            ...protocolTextSpanFromSubstring(
123                                anotherFile.content,
124                                "./Logger"
125                            )
126                        }]
127                    }]
128                }
129            });
130
131            // Check errors in both files
132            verifyGetErrRequest({ host, session, files: [anotherFile] });
133            baselineTsserverLogs("forceConsistentCasingInFileNames", "when changing module name with different casing", session);
134        });
135    });
136}
137