• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1namespace ts.tscWatch {
2    describe("unittests:: tsbuild:: watchEnvironment:: tsbuild:: watchMode:: with different watch environments", () => {
3        describe("when watchFile can create multiple watchers per file", () => {
4            verifyWatchFileOnMultipleProjects(/*singleWatchPerFile*/ false);
5        });
6
7        describe("when watchFile is single watcher per file", () => {
8            verifyWatchFileOnMultipleProjects(
9                /*singleWatchPerFile*/ true,
10                arrayToMap(["TSC_WATCHFILE"], identity, () => TestFSWithWatch.Tsc_WatchFile.SingleFileWatcherPerName)
11            );
12        });
13
14        function verifyWatchFileOnMultipleProjects(singleWatchPerFile: boolean, environmentVariables?: ESMap<string, string>) {
15            it("watchFile on same file multiple times because file is part of multiple projects", () => {
16                const project = `${TestFSWithWatch.tsbuildProjectsLocation}/myproject`;
17                let maxPkgs = 4;
18                const configPath = `${project}/tsconfig.json`;
19                const typing: File = {
20                    path: `${project}/typings/xterm.d.ts`,
21                    content: "export const typing = 10;"
22                };
23
24                const allPkgFiles = pkgs(pkgFiles);
25                const system = createWatchedSystem([libFile, typing, ...flatArray(allPkgFiles)], { currentDirectory: project, environmentVariables });
26                writePkgReferences();
27                const host = createSolutionBuilderWithWatchHost(system);
28                const solutionBuilder = createSolutionBuilderWithWatch(host, ["tsconfig.json"], { watch: true, verbose: true });
29                solutionBuilder.build();
30                checkOutputErrorsInitial(system, emptyArray, /*disableConsoleClears*/ undefined, [
31                    `Projects in this build: \r\n${
32                        concatenate(
33                            pkgs(index => `    * pkg${index}/tsconfig.json`),
34                            ["    * tsconfig.json"]
35                        ).join("\r\n")}\n\n`,
36                    ...flatArray(pkgs(index => [
37                        `Project 'pkg${index}/tsconfig.json' is out of date because output file 'pkg${index}/index.js' does not exist\n\n`,
38                        `Building project '${project}/pkg${index}/tsconfig.json'...\n\n`
39                    ]))
40                ]);
41
42                const watchFilesDetailed = arrayToMap(flatArray(allPkgFiles), f => f.path, () => 1);
43                watchFilesDetailed.set(configPath, 1);
44                watchFilesDetailed.set(typing.path, singleWatchPerFile ? 1 : maxPkgs);
45                checkWatchedFilesDetailed(system, watchFilesDetailed);
46                system.writeFile(typing.path, `${typing.content}export const typing1 = 10;`);
47                verifyInvoke();
48
49                // Make change
50                maxPkgs--;
51                writePkgReferences();
52                system.checkTimeoutQueueLengthAndRun(1);
53                checkOutputErrorsIncremental(system, emptyArray);
54                const lastFiles = last(allPkgFiles);
55                lastFiles.forEach(f => watchFilesDetailed.delete(f.path));
56                watchFilesDetailed.set(typing.path, singleWatchPerFile ? 1 : maxPkgs);
57                checkWatchedFilesDetailed(system, watchFilesDetailed);
58                system.writeFile(typing.path, typing.content);
59                verifyInvoke();
60
61                // Make change to remove all the watches
62                maxPkgs = 0;
63                writePkgReferences();
64                system.checkTimeoutQueueLengthAndRun(1);
65                checkOutputErrorsIncremental(system, [
66                    `tsconfig.json(1,10): error TS18002: The 'files' list in config file '${configPath}' is empty.\n`
67                ]);
68                checkWatchedFilesDetailed(system, [configPath], 1);
69
70                system.writeFile(typing.path, `${typing.content}export const typing1 = 10;`);
71                system.checkTimeoutQueueLength(0);
72
73                function flatArray<T>(arr: T[][]): readonly T[] {
74                    return flatMap(arr, identity);
75                }
76                function pkgs<T>(cb: (index: number) => T): T[] {
77                    const result: T[] = [];
78                    for (let index = 0; index < maxPkgs; index++) {
79                        result.push(cb(index));
80                    }
81                    return result;
82                }
83                function createPkgReference(index: number) {
84                    return { path: `./pkg${index}` };
85                }
86                function pkgFiles(index: number): File[] {
87                    return [
88                        {
89                            path: `${project}/pkg${index}/index.ts`,
90                            content: `export const pkg${index} = ${index};`
91                        },
92                        {
93                            path: `${project}/pkg${index}/tsconfig.json`,
94                            content: JSON.stringify({
95                                complerOptions: { composite: true },
96                                include: [
97                                    "**/*.ts",
98                                    "../typings/xterm.d.ts"
99                                ]
100                            })
101                        }
102                    ];
103                }
104                function writePkgReferences() {
105                    system.writeFile(configPath, JSON.stringify({
106                        files: [],
107                        include: [],
108                        references: pkgs(createPkgReference)
109                    }));
110                }
111                function verifyInvoke() {
112                    pkgs(() => system.checkTimeoutQueueLengthAndRun(1));
113                    checkOutputErrorsIncremental(system, emptyArray, /*disableConsoleClears*/ undefined, /*logsBeforeWatchDiagnostics*/ undefined, [
114                        ...flatArray(pkgs(index => [
115                            `Project 'pkg${index}/tsconfig.json' is out of date because oldest output 'pkg${index}/index.js' is older than newest input 'typings/xterm.d.ts'\n\n`,
116                            `Building project '${project}/pkg${index}/tsconfig.json'...\n\n`,
117                            `Updating unchanged output timestamps of project '${project}/pkg${index}/tsconfig.json'...\n\n`
118                        ]))
119                    ]);
120                }
121            });
122        }
123    });
124}
125