• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1namespace ts.tscWatch {
2    describe("unittests:: tsc-watch:: projects with references: invoking when references are already built", () => {
3        verifyTscWatch({
4            scenario: "projectsWithReferences",
5            subScenario: "on sample project",
6            sys: () => createSystemWithSolutionBuild(
7                ["tests"],
8                [
9                    libFile,
10                    TestFSWithWatch.getTsBuildProjectFile("sample1", "core/tsconfig.json"),
11                    TestFSWithWatch.getTsBuildProjectFile("sample1", "core/index.ts"),
12                    TestFSWithWatch.getTsBuildProjectFile("sample1", "core/anotherModule.ts"),
13                    TestFSWithWatch.getTsBuildProjectFile("sample1", "core/some_decl.d.ts"),
14                    TestFSWithWatch.getTsBuildProjectFile("sample1", "logic/tsconfig.json"),
15                    TestFSWithWatch.getTsBuildProjectFile("sample1", "logic/index.ts"),
16                    TestFSWithWatch.getTsBuildProjectFile("sample1", "tests/tsconfig.json"),
17                    TestFSWithWatch.getTsBuildProjectFile("sample1", "tests/index.ts"),
18                ],
19                { currentDirectory: `${TestFSWithWatch.tsbuildProjectsLocation}/sample1` }
20            ),
21            commandLineArgs: ["-w", "-p", "tests"],
22            changes: [
23                {
24                    caption: "local edit in logic ts, and build logic",
25                    change: sys => {
26                        sys.appendFile(TestFSWithWatch.getTsBuildProjectFilePath("sample1", "logic/index.ts"), `function foo() { }`);
27                        const solutionBuilder = createSolutionBuilder(sys, ["logic"]);
28                        solutionBuilder.build();
29                    },
30                    // not ideal, but currently because of d.ts but no new file is written
31                    // There will be timeout queued even though file contents are same
32                    timeouts: sys => sys.checkTimeoutQueueLength(0),
33                },
34                {
35                    caption: "non local edit in logic ts, and build logic",
36                    change: sys => {
37                        sys.appendFile(TestFSWithWatch.getTsBuildProjectFilePath("sample1", "logic/index.ts"), `export function gfoo() { }`);
38                        const solutionBuilder = createSolutionBuilder(sys, ["logic"]);
39                        solutionBuilder.build();
40                    },
41                    timeouts: checkSingleTimeoutQueueLengthAndRun
42                },
43                {
44                    caption: "change in project reference config file builds correctly",
45                    change: sys => {
46                        sys.writeFile(TestFSWithWatch.getTsBuildProjectFilePath("sample1", "logic/tsconfig.json"), JSON.stringify({
47                            compilerOptions: { composite: true, declaration: true, declarationDir: "decls" },
48                            references: [{ path: "../core" }]
49                        }));
50                        const solutionBuilder = createSolutionBuilder(sys, ["logic"]);
51                        solutionBuilder.build();
52                    },
53                    timeouts: checkSingleTimeoutQueueLengthAndRun
54                },
55            ],
56            baselineDependencies: true
57        });
58
59        function changeCompilerOpitonsPaths(sys: WatchedSystem, config: string, newPaths: object) {
60            const configJson = JSON.parse(sys.readFile(config)!);
61            configJson.compilerOptions.paths = newPaths;
62            sys.writeFile(config, JSON.stringify(configJson));
63        }
64
65        verifyTscWatch({
66            scenario: "projectsWithReferences",
67            subScenario: "on transitive references",
68            sys: () => createSystemWithSolutionBuild(
69                ["tsconfig.c.json"],
70                [
71                    libFile,
72                    TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.a.json"),
73                    TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.b.json"),
74                    TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.c.json"),
75                    TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "a.ts"),
76                    TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "b.ts"),
77                    TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "c.ts"),
78                    TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "refs/a.d.ts"),
79                ],
80                { currentDirectory: `${TestFSWithWatch.tsbuildProjectsLocation}/transitiveReferences` }
81            ),
82            commandLineArgs: ["-w", "-p", "tsconfig.c.json"],
83            changes: [
84                {
85                    caption: "non local edit b ts, and build b",
86                    change: sys => {
87                        sys.appendFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b.ts"), `export function gfoo() { }`);
88                        const solutionBuilder = createSolutionBuilder(sys, ["tsconfig.b.json"]);
89                        solutionBuilder.build();
90                    },
91                    timeouts: checkSingleTimeoutQueueLengthAndRun
92                },
93                {
94                    caption: "edit on config file",
95                    change: sys => {
96                        sys.ensureFileOrFolder({
97                            path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "nrefs/a.d.ts"),
98                            content: sys.readFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "refs/a.d.ts"))!
99                        });
100                        changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.c.json"), { "@ref/*": ["./nrefs/*"] });
101                    },
102                    timeouts: checkSingleTimeoutQueueLengthAndRun
103                },
104                {
105                    caption: "Revert config file edit",
106                    change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.c.json"), { "@ref/*": ["./refs/*"] }),
107                    timeouts: checkSingleTimeoutQueueLengthAndRun
108                },
109                {
110                    caption: "edit in referenced config file",
111                    change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.b.json"), { "@ref/*": ["./nrefs/*"] }),
112                    timeouts: checkSingleTimeoutQueueLengthAndRun
113                },
114                {
115                    caption: "Revert referenced config file edit",
116                    change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.b.json"), { "@ref/*": ["./refs/*"] }),
117                    timeouts: checkSingleTimeoutQueueLengthAndRun
118                },
119                {
120                    caption: "deleting referenced config file",
121                    change: sys => sys.deleteFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.b.json")),
122                    timeouts: checkSingleTimeoutQueueLengthAndRun
123                },
124                {
125                    caption: "Revert deleting referenced config file",
126                    change: sys => sys.ensureFileOrFolder(TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.b.json")),
127                    timeouts: checkSingleTimeoutQueueLengthAndRun
128                },
129                {
130                    caption: "deleting transitively referenced config file",
131                    change: sys => sys.deleteFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.a.json")),
132                    timeouts: checkSingleTimeoutQueueLengthAndRun
133                },
134                {
135                    caption: "Revert deleting transitively referenced config file",
136                    change: sys => sys.ensureFileOrFolder(TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.a.json")),
137                    timeouts: checkSingleTimeoutQueueLengthAndRun
138                },
139            ],
140            baselineDependencies: true,
141        });
142
143        verifyTscWatch({
144            scenario: "projectsWithReferences",
145            subScenario: "when referenced project uses different module resolution",
146            sys: () => createSystemWithSolutionBuild(
147                ["tsconfig.c.json"],
148                [
149                    libFile,
150                    TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.a.json"),
151                    {
152                        path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "tsconfig.b.json"),
153                        content: JSON.stringify({
154                            compilerOptions: { composite: true, moduleResolution: "classic" },
155                            files: ["b.ts"],
156                            references: [{ path: "tsconfig.a.json" }]
157                        })
158                    },
159                    TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "tsconfig.c.json"),
160                    TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "a.ts"),
161                    {
162                        path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b.ts"),
163                        content: `import {A} from "a";export const b = new A();`
164                    },
165                    TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "c.ts"),
166                    TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "refs/a.d.ts"),
167                ],
168                { currentDirectory: `${TestFSWithWatch.tsbuildProjectsLocation}/transitiveReferences` }
169            ),
170            commandLineArgs: ["-w", "-p", "tsconfig.c.json"],
171            changes: emptyArray,
172            baselineDependencies: true,
173        });
174
175        verifyTscWatch({
176            scenario: "projectsWithReferences",
177            subScenario: "on transitive references in different folders",
178            sys: () => createSystemWithSolutionBuild(
179                ["c"],
180                [
181                    libFile,
182                    {
183                        path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json"),
184                        content: JSON.stringify({
185                            compilerOptions: { composite: true },
186                            files: ["index.ts"]
187                        }),
188                    },
189                    {
190                        path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"),
191                        content: JSON.stringify({
192                            compilerOptions: { composite: true, baseUrl: "./", paths: { "@ref/*": ["../*"] } },
193                            files: ["index.ts"],
194                            references: [{ path: `../a` }]
195                        }),
196                    },
197                    {
198                        path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"),
199                        content: JSON.stringify({
200                            compilerOptions: { baseUrl: "./", paths: { "@ref/*": ["../refs/*"] } },
201                            files: ["index.ts"],
202                            references: [{ path: `../b` }]
203                        }),
204                    },
205                    {
206                        path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/index.ts"),
207                        content: `export class A {}`,
208                    },
209                    {
210                        path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/index.ts"),
211                        content: `import {A} from '@ref/a';
212export const b = new A();`,
213                    },
214                    {
215                        path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/index.ts"),
216                        content: `import {b} from '../b';
217import {X} from "@ref/a";
218b;
219X;`,
220                    },
221                    TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "refs/a.d.ts"),
222                ],
223                { currentDirectory: `${TestFSWithWatch.tsbuildProjectsLocation}/transitiveReferences` }
224            ),
225            commandLineArgs: ["-w", "-p", "c"],
226            changes: [
227                {
228                    caption: "non local edit b ts, and build b",
229                    change: sys => {
230                        sys.appendFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/index.ts"), `export function gfoo() { }`);
231                        const solutionBuilder = createSolutionBuilder(sys, ["b"]);
232                        solutionBuilder.build();
233                    },
234                    timeouts: checkSingleTimeoutQueueLengthAndRun
235                },
236                {
237                    caption: "edit on config file",
238                    change: sys => {
239                        sys.ensureFileOrFolder({
240                            path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "nrefs/a.d.ts"),
241                            content: sys.readFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "refs/a.d.ts"))!
242                        });
243                        changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), { "@ref/*": ["../nrefs/*"] });
244                    },
245                    timeouts: checkSingleTimeoutQueueLengthAndRun
246                },
247                {
248                    caption: "Revert config file edit",
249                    change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), { "@ref/*": ["../refs/*"] }),
250                    timeouts: checkSingleTimeoutQueueLengthAndRun
251                },
252                {
253                    caption: "edit in referenced config file",
254                    change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), { "@ref/*": ["../nrefs/*"] }),
255                    timeouts: checkSingleTimeoutQueueLengthAndRun
256                },
257                {
258                    caption: "Revert referenced config file edit",
259                    change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), { "@ref/*": ["../refs/*"] }),
260                    timeouts: checkSingleTimeoutQueueLengthAndRun
261                },
262                {
263                    caption: "deleting referenced config file",
264                    change: sys => sys.deleteFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json")),
265                    timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2)
266                },
267                {
268                    caption: "Revert deleting referenced config file",
269                    change: sys => sys.writeFile(
270                        TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"),
271                        JSON.stringify({
272                            compilerOptions: { composite: true, baseUrl: "./", paths: { "@ref/*": ["../*"] } },
273                            files: ["index.ts"],
274                            references: [{ path: `../a` }]
275                        })
276                    ),
277                    timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2)
278                },
279                {
280                    caption: "deleting transitively referenced config file",
281                    change: sys => sys.deleteFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json")),
282                    timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2)
283                },
284                {
285                    caption: "Revert deleting transitively referenced config file",
286                    change: sys => sys.writeFile(
287                        TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json"),
288                        JSON.stringify({
289                            compilerOptions: { composite: true },
290                            files: ["index.ts"]
291                        }),
292                    ),
293                    timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2)
294                },
295            ],
296            baselineDependencies: true,
297        });
298
299        verifyTscWatch({
300            scenario: "projectsWithReferences",
301            subScenario: "on transitive references in different folders with no files clause",
302            sys: () => createSystemWithSolutionBuild(
303                ["c"],
304                [
305                    libFile,
306                    {
307                        path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json"),
308                        content: JSON.stringify({ compilerOptions: { composite: true } }),
309                    },
310                    {
311                        path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"),
312                        content: JSON.stringify({
313                            compilerOptions: { composite: true, baseUrl: "./", paths: { "@ref/*": ["../*"] } },
314                            references: [{ path: `../a` }]
315                        }),
316                    },
317                    {
318                        path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"),
319                        content: JSON.stringify({
320                            compilerOptions: { baseUrl: "./", paths: { "@ref/*": ["../refs/*"] } },
321                            references: [{ path: `../b` }]
322                        }),
323                    },
324                    {
325                        path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/index.ts"),
326                        content: `export class A {}`,
327                    },
328                    {
329                        path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/index.ts"),
330                        content: `import {A} from '@ref/a';
331export const b = new A();`,
332                    },
333                    {
334                        path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/index.ts"),
335                        content: `import {b} from '../b';
336import {X} from "@ref/a";
337b;
338X;`,
339                    },
340                    TestFSWithWatch.getTsBuildProjectFile("transitiveReferences", "refs/a.d.ts"),
341                ],
342                { currentDirectory: `${TestFSWithWatch.tsbuildProjectsLocation}/transitiveReferences` }
343            ),
344            commandLineArgs: ["-w", "-p", "c"],
345            changes: [
346                {
347                    caption: "non local edit b ts, and build b",
348                    change: sys => {
349                        sys.appendFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/index.ts"), `export function gfoo() { }`);
350                        const solutionBuilder = createSolutionBuilder(sys, ["b"]);
351                        solutionBuilder.build();
352                    },
353                    timeouts: checkSingleTimeoutQueueLengthAndRun
354                },
355                {
356                    caption: "edit on config file",
357                    change: sys => {
358                        sys.ensureFileOrFolder({
359                            path: TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "nrefs/a.d.ts"),
360                            content: sys.readFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "refs/a.d.ts"))!
361                        });
362                        changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), { "@ref/*": ["../nrefs/*"] });
363                    },
364                    timeouts: checkSingleTimeoutQueueLengthAndRun
365                },
366                {
367                    caption: "Revert config file edit",
368                    change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "c/tsconfig.json"), { "@ref/*": ["../refs/*"] }),
369                    timeouts: checkSingleTimeoutQueueLengthAndRun
370                },
371                {
372                    caption: "edit in referenced config file",
373                    change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), { "@ref/*": ["../nrefs/*"] }),
374                    timeouts: checkSingleTimeoutQueueLengthAndRun
375                },
376                {
377                    caption: "Revert referenced config file edit",
378                    change: sys => changeCompilerOpitonsPaths(sys, TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"), { "@ref/*": ["../refs/*"] }),
379                    timeouts: checkSingleTimeoutQueueLengthAndRun
380                },
381                {
382                    caption: "deleting referenced config file",
383                    change: sys => sys.deleteFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json")),
384                    timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2)
385                },
386                {
387                    caption: "Revert deleting referenced config file",
388                    change: sys => sys.writeFile(
389                        TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "b/tsconfig.json"),
390                        JSON.stringify({
391                            compilerOptions: { composite: true, baseUrl: "./", paths: { "@ref/*": ["../*"] } },
392                            references: [{ path: `../a` }]
393                        })
394                    ),
395                    timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2)
396                },
397                {
398                    caption: "deleting transitively referenced config file",
399                    change: sys => sys.deleteFile(TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json")),
400                    timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2)
401                },
402                {
403                    caption: "Revert deleting transitively referenced config file",
404                    change: sys => sys.writeFile(
405                        TestFSWithWatch.getTsBuildProjectFilePath("transitiveReferences", "a/tsconfig.json"),
406                        JSON.stringify({ compilerOptions: { composite: true } }),
407                    ),
408                    timeouts: sys => sys.checkTimeoutQueueLengthAndRun(2)
409                },
410            ],
411            baselineDependencies: true,
412        });
413    });
414}