• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1namespace ts.projectSystem {
2    describe("unittests:: tsserver:: projects with references: invoking when references are already built", () => {
3        it("on sample project", () => {
4            const coreConfig = TestFSWithWatch.getTsBuildProjectFile("sample1", "core/tsconfig.json");
5            const coreIndex = TestFSWithWatch.getTsBuildProjectFile("sample1", "core/index.ts");
6            const coreAnotherModule = TestFSWithWatch.getTsBuildProjectFile("sample1", "core/anotherModule.ts");
7            const coreSomeDecl = TestFSWithWatch.getTsBuildProjectFile("sample1", "core/some_decl.d.ts");
8            const logicConfig = TestFSWithWatch.getTsBuildProjectFile("sample1", "logic/tsconfig.json");
9            const logicIndex = TestFSWithWatch.getTsBuildProjectFile("sample1", "logic/index.ts");
10            const testsConfig = TestFSWithWatch.getTsBuildProjectFile("sample1", "tests/tsconfig.json");
11            const testsIndex = TestFSWithWatch.getTsBuildProjectFile("sample1", "tests/index.ts");
12            const host = createServerHost([libFile, coreConfig, coreIndex, coreAnotherModule, coreSomeDecl, logicConfig, logicIndex, testsConfig, testsIndex]);
13            const logger = createLoggerWithInMemoryLogs(host);
14            const service = createProjectService(host, { logger });
15            service.openClientFile(testsIndex.path);
16
17            // local edit in ts file
18            host.appendFile(logicIndex.path, `function foo() {}`);
19            host.checkTimeoutQueueLengthAndRun(2);
20
21            // non local edit in ts file
22            host.appendFile(logicIndex.path, `export function gfoo() {}`);
23            host.checkTimeoutQueueLengthAndRun(2);
24
25            // change in project reference config file
26            host.writeFile(logicConfig.path, JSON.stringify({
27                compilerOptions: { composite: true, declaration: true, declarationDir: "decls" },
28                references: [{ path: "../core" }]
29            }));
30            host.checkTimeoutQueueLengthAndRun(2);
31            baselineTsserverLogs("projectsWithReferences", "sample project", service);
32        });
33
34        describe("on transitive references in different folders", () => {
35            function createService() {
36                const aConfig: File = {
37                    path: `${tscWatch.projectRoot}/a/tsconfig.json`,
38                    content: JSON.stringify({
39                        compilerOptions: { composite: true },
40                        files: ["index.ts"]
41                    }),
42                };
43                const bConfig: File = {
44                    path: `${tscWatch.projectRoot}/b/tsconfig.json`,
45                    content: JSON.stringify({
46                        compilerOptions: { composite: true, baseUrl: "./", paths: { "@ref/*": ["../*"] } },
47                        files: ["index.ts"],
48                        references: [{ path: `../a` }]
49                    }),
50                };
51                const cConfig: File = {
52                    path: `${tscWatch.projectRoot}/c/tsconfig.json`,
53                    content: JSON.stringify({
54                        compilerOptions: { baseUrl: "./", paths: { "@ref/*": ["../refs/*"] } },
55                        files: ["index.ts"],
56                        references: [{ path: `../b` }]
57                    }),
58                };
59                const aTs: File = {
60                    path: `${tscWatch.projectRoot}/a/index.ts`,
61                    content: `export class A {}`,
62                };
63                const bTs: File = {
64                    path: `${tscWatch.projectRoot}/b/index.ts`,
65                    content: `import {A} from '@ref/a';
66export const b = new A();`,
67                };
68                const cTs: File = {
69                    path: `${tscWatch.projectRoot}/c/index.ts`,
70                    content: `import {b} from '../b';
71import {X} from "@ref/a";
72b;
73X;`,
74                };
75                const refsTs: File = {
76                    path: `${tscWatch.projectRoot}/refs/a.d.ts`,
77                    content: `export class X {}
78export class A {}`
79                };
80                const host = createServerHost([libFile, aConfig, bConfig, cConfig, aTs, bTs, cTs, refsTs]);
81                const service = createProjectService(host, { logger: createLoggerWithInMemoryLogs(host) });
82                service.openClientFile(cTs.path);
83                return { host, service, aConfig, bConfig, cConfig, aTs, bTs, cTs, refsTs };
84            }
85
86            it("non local edit", () => {
87                const { host, service, bTs } = createService();
88                checkNumberOfProjects(service, { configuredProjects: 1 });
89
90                // non local edit
91                host.appendFile(bTs.path, `export function gFoo() { }`);
92                host.checkTimeoutQueueLengthAndRun(2);
93                baselineTsserverLogs("projectsWithReferences", "transitive references with non local edit", service);
94            });
95
96            it("edit on config file", () => {
97                const { host, service, cConfig, refsTs } = createService();
98                const nRefsTs: File = {
99                    path: `${tscWatch.projectRoot}/nrefs/a.d.ts`,
100                    content: refsTs.content
101                };
102                const cTsConfigJson = JSON.parse(cConfig.content);
103                host.ensureFileOrFolder(nRefsTs);
104                cTsConfigJson.compilerOptions.paths = { "@ref/*": ["../nrefs/*"] };
105                host.writeFile(cConfig.path, JSON.stringify(cTsConfigJson));
106                host.checkTimeoutQueueLengthAndRun(2);
107
108                // revert the edit on config file
109                host.writeFile(cConfig.path, cConfig.content);
110                host.checkTimeoutQueueLengthAndRun(2);
111                baselineTsserverLogs("projectsWithReferences", "transitive references with edit on config file", service);
112            });
113
114            it("edit in referenced config file", () => {
115                const { host, service, bConfig, refsTs } = createService();
116                const nRefsTs: File = {
117                    path: `${tscWatch.projectRoot}/nrefs/a.d.ts`,
118                    content: refsTs.content
119                };
120                const bTsConfigJson = JSON.parse(bConfig.content);
121                host.ensureFileOrFolder(nRefsTs);
122                bTsConfigJson.compilerOptions.paths = { "@ref/*": ["../nrefs/*"] };
123                host.writeFile(bConfig.path, JSON.stringify(bTsConfigJson));
124                host.checkTimeoutQueueLengthAndRun(2);
125
126                // revert the edit on config file
127                host.writeFile(bConfig.path, bConfig.content);
128                host.checkTimeoutQueueLengthAndRun(2);
129                baselineTsserverLogs("projectsWithReferences", "transitive references with edit in referenced config file", service);
130            });
131
132            it("deleting referenced config file", () => {
133                const { host, service, bConfig } = createService();
134                host.deleteFile(bConfig.path);
135                host.checkTimeoutQueueLengthAndRun(3); // Schedules failed lookup invalidation
136
137                // revert
138                host.writeFile(bConfig.path, bConfig.content);
139                host.checkTimeoutQueueLengthAndRun(3); // Schedules failed lookup invalidation
140                baselineTsserverLogs("projectsWithReferences", "transitive references with deleting referenced config file", service);
141            });
142
143            it("deleting transitively referenced config file", () => {
144                const { host, service, aConfig } = createService();
145                host.deleteFile(aConfig.path);
146                host.checkTimeoutQueueLengthAndRun(3); // Schedules failed lookup invalidation
147
148                // revert
149                host.writeFile(aConfig.path, aConfig.content);
150                host.checkTimeoutQueueLengthAndRun(3); // Schedules failed lookup invalidation
151                baselineTsserverLogs("projectsWithReferences", "transitive references with deleting transitively referenced config file", service);
152            });
153        });
154
155        describe("on transitive references in different folders without files", () => {
156            function createService() {
157                const aConfig: File = {
158                    path: `${tscWatch.projectRoot}/a/tsconfig.json`,
159                    content: JSON.stringify({ compilerOptions: { composite: true } }),
160                };
161                const bConfig: File = {
162                    path: `${tscWatch.projectRoot}/b/tsconfig.json`,
163                    content: JSON.stringify({
164                        compilerOptions: { composite: true, baseUrl: "./", paths: { "@ref/*": ["../*"] } },
165                        references: [{ path: `../a` }]
166                    }),
167                };
168                const cConfig: File = {
169                    path: `${tscWatch.projectRoot}/c/tsconfig.json`,
170                    content: JSON.stringify({
171                        compilerOptions: { baseUrl: "./", paths: { "@ref/*": ["../refs/*"] } },
172                        references: [{ path: `../b` }]
173                    }),
174                };
175                const aTs: File = {
176                    path: `${tscWatch.projectRoot}/a/index.ts`,
177                    content: `export class A {}`,
178                };
179                const bTs: File = {
180                    path: `${tscWatch.projectRoot}/b/index.ts`,
181                    content: `import {A} from '@ref/a';
182export const b = new A();`,
183                };
184                const cTs: File = {
185                    path: `${tscWatch.projectRoot}/c/index.ts`,
186                    content: `import {b} from '../b';
187import {X} from "@ref/a";
188b;
189X;`,
190                };
191                const refsTs: File = {
192                    path: `${tscWatch.projectRoot}/refs/a.d.ts`,
193                    content: `export class X {}
194export class A {}`
195                };
196                const host = createServerHost([libFile, aConfig, bConfig, cConfig, aTs, bTs, cTs, refsTs]);
197                const service = createProjectService(host, { logger: createLoggerWithInMemoryLogs(host) });
198                service.openClientFile(cTs.path);
199                return { host, service, aConfig, bConfig, cConfig, aTs, bTs, cTs, refsTs };
200            }
201
202            it("non local edit", () => {
203                const { host, service, bTs } = createService();
204
205                // non local edit
206                host.appendFile(bTs.path, `export function gFoo() { }`);
207                host.checkTimeoutQueueLengthAndRun(2);
208                baselineTsserverLogs("projectsWithReferences", "trasitive references without files with non local edit", service);
209            });
210
211            it("edit on config file", () => {
212                const { host, service, cConfig, refsTs } = createService();
213                const nRefsTs: File = {
214                    path: `${tscWatch.projectRoot}/nrefs/a.d.ts`,
215                    content: refsTs.content
216                };
217                const cTsConfigJson = JSON.parse(cConfig.content);
218                host.ensureFileOrFolder(nRefsTs);
219                cTsConfigJson.compilerOptions.paths = { "@ref/*": ["../nrefs/*"] };
220                host.writeFile(cConfig.path, JSON.stringify(cTsConfigJson));
221                host.checkTimeoutQueueLengthAndRun(2);
222
223                // revert the edit on config file
224                host.writeFile(cConfig.path, cConfig.content);
225                host.checkTimeoutQueueLengthAndRun(2);
226                baselineTsserverLogs("projectsWithReferences", "trasitive references without files with edit on config file", service);
227            });
228
229            it("edit in referenced config file", () => {
230                const { host, service, bConfig, refsTs } = createService();
231                const nRefsTs: File = {
232                    path: `${tscWatch.projectRoot}/nrefs/a.d.ts`,
233                    content: refsTs.content
234                };
235                const bTsConfigJson = JSON.parse(bConfig.content);
236                host.ensureFileOrFolder(nRefsTs);
237                bTsConfigJson.compilerOptions.paths = { "@ref/*": ["../nrefs/*"] };
238                host.writeFile(bConfig.path, JSON.stringify(bTsConfigJson));
239                host.checkTimeoutQueueLengthAndRun(2);
240
241                // revert the edit on config file
242                host.writeFile(bConfig.path, bConfig.content);
243                host.checkTimeoutQueueLengthAndRun(2);
244                baselineTsserverLogs("projectsWithReferences", "trasitive references without files with edit in referenced config file", service);
245            });
246
247            it("deleting referenced config file", () => {
248                const { host, service, bConfig } = createService();
249                host.deleteFile(bConfig.path);
250                host.checkTimeoutQueueLengthAndRun(3); // Schedules failed lookup invalidation
251
252                // revert
253                host.writeFile(bConfig.path, bConfig.content);
254                host.checkTimeoutQueueLengthAndRun(3); // Schedules failed lookup invalidation
255                baselineTsserverLogs("projectsWithReferences", "trasitive references without files with deleting referenced config file", service);
256            });
257
258            it("deleting transitively referenced config file", () => {
259                const { host, service, aConfig } = createService();
260                host.deleteFile(aConfig.path);
261                host.checkTimeoutQueueLengthAndRun(3); // Schedules failed lookup invalidation
262
263                // revert
264                host.writeFile(aConfig.path, aConfig.content);
265                host.checkTimeoutQueueLengthAndRun(3); // Schedules failed lookup invalidation
266                baselineTsserverLogs("projectsWithReferences", "trasitive references without files with deleting transitively referenced config file", service);
267            });
268        });
269    });
270}