• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1namespace ts {
2    describe("unittests:: config:: tsconfigParsingWatchOptions:: parseConfigFileTextToJson", () => {
3        function createParseConfigHost(additionalFiles?: vfs.FileSet) {
4            return new fakes.ParseConfigHost(
5                new vfs.FileSystem(
6                    /*ignoreCase*/ false,
7                    {
8                        cwd: "/",
9                        files: { "/": {}, "/a.ts": "", ...additionalFiles }
10                    }
11                )
12            );
13        }
14        function getParsedCommandJson(json: object, additionalFiles?: vfs.FileSet, existingWatchOptions?: WatchOptions) {
15            return parseJsonConfigFileContent(
16                json,
17                createParseConfigHost(additionalFiles),
18                "/",
19                /*existingOptions*/ undefined,
20                "tsconfig.json",
21                /*resolutionStack*/ undefined,
22                /*extraFileExtensions*/ undefined,
23                /*extendedConfigCache*/ undefined,
24                existingWatchOptions,
25            );
26        }
27
28        function getParsedCommandJsonNode(json: object, additionalFiles?: vfs.FileSet, existingWatchOptions?: WatchOptions) {
29            const parsed = parseJsonText("tsconfig.json", JSON.stringify(json));
30            return parseJsonSourceFileConfigFileContent(
31                parsed,
32                createParseConfigHost(additionalFiles),
33                "/",
34                /*existingOptions*/ undefined,
35                "tsconfig.json",
36                /*resolutionStack*/ undefined,
37                /*extraFileExtensions*/ undefined,
38                /*extendedConfigCache*/ undefined,
39                existingWatchOptions,
40            );
41        }
42
43        interface VerifyWatchOptions {
44            json: object;
45            expectedOptions: WatchOptions | undefined;
46            additionalFiles?: vfs.FileSet;
47            existingWatchOptions?: WatchOptions | undefined;
48            expectedErrors?: (sourceFile?: SourceFile) => Diagnostic[];
49        }
50
51        function verifyWatchOptions(scenario: () => VerifyWatchOptions[]) {
52            it("with json api", () => {
53                for (const { json, expectedOptions, additionalFiles, existingWatchOptions, expectedErrors } of scenario()) {
54                    const parsed = getParsedCommandJson(json, additionalFiles, existingWatchOptions);
55                    assert.deepEqual(parsed.watchOptions, expectedOptions, `With ${JSON.stringify(json)}`);
56                    if (length(parsed.errors)) {
57                        assert.deepEqual(parsed.errors, expectedErrors?.());
58                    }
59                    else {
60                        assert.equal(0, length(expectedErrors?.()), `Expected no errors`);
61                    }
62                }
63            });
64
65            it("with json source file api", () => {
66                for (const { json, expectedOptions, additionalFiles, existingWatchOptions, expectedErrors } of scenario()) {
67                    const parsed = getParsedCommandJsonNode(json, additionalFiles, existingWatchOptions);
68                    assert.deepEqual(parsed.watchOptions, expectedOptions);
69                    if (length(parsed.errors)) {
70                        assert.deepEqual(parsed.errors, expectedErrors?.(parsed.options.configFile));
71                    }
72                    else {
73                        assert.equal(0, length(expectedErrors?.(parsed.options.configFile)), `Expected no errors`);
74                    }
75                }
76            });
77        }
78
79        describe("no watchOptions specified option", () => {
80            verifyWatchOptions(() => [{
81                json: {},
82                expectedOptions: undefined
83            }]);
84        });
85
86        describe("empty watchOptions specified option", () => {
87            verifyWatchOptions(() => [{
88                json: { watchOptions: {} },
89                expectedOptions: undefined
90            }]);
91        });
92
93        describe("extending config file", () => {
94            describe("when extending config file without watchOptions", () => {
95                verifyWatchOptions(() => [
96                    {
97                        json: {
98                            extends: "./base.json",
99                            watchOptions: { watchFile: "UseFsEvents" }
100                        },
101                        expectedOptions: { watchFile: WatchFileKind.UseFsEvents },
102                        additionalFiles: { "/base.json": "{}" }
103                    },
104                    {
105                        json: { extends: "./base.json", },
106                        expectedOptions: undefined,
107                        additionalFiles: { "/base.json": "{}" }
108                    }
109                ]);
110            });
111
112            describe("when extending config file with watchOptions", () => {
113                verifyWatchOptions(() => [
114                    {
115                        json: {
116                            extends: "./base.json",
117                            watchOptions: {
118                                watchFile: "UseFsEvents",
119                            }
120                        },
121                        expectedOptions: {
122                            watchFile: WatchFileKind.UseFsEvents,
123                            watchDirectory: WatchDirectoryKind.FixedPollingInterval
124                        },
125                        additionalFiles: {
126                            "/base.json": JSON.stringify({
127                                watchOptions: {
128                                    watchFile: "UseFsEventsOnParentDirectory",
129                                    watchDirectory: "FixedPollingInterval"
130                                }
131                            })
132                        }
133                    },
134                    {
135                        json: {
136                            extends: "./base.json",
137                        },
138                        expectedOptions: {
139                            watchFile: WatchFileKind.UseFsEventsOnParentDirectory,
140                            watchDirectory: WatchDirectoryKind.FixedPollingInterval
141                        },
142                        additionalFiles: {
143                            "/base.json": JSON.stringify({
144                                watchOptions: {
145                                    watchFile: "UseFsEventsOnParentDirectory",
146                                    watchDirectory: "FixedPollingInterval"
147                                }
148                            })
149                        }
150                    }
151                ]);
152            });
153        });
154
155        describe("different options", () => {
156            verifyWatchOptions(() => [
157                {
158                    json: { watchOptions: { watchFile: "UseFsEvents" } },
159                    expectedOptions: { watchFile: WatchFileKind.UseFsEvents }
160                },
161                {
162                    json: { watchOptions: { watchDirectory: "UseFsEvents" } },
163                    expectedOptions: { watchDirectory: WatchDirectoryKind.UseFsEvents }
164                },
165                {
166                    json: { watchOptions: { fallbackPolling: "DynamicPriority" } },
167                    expectedOptions: { fallbackPolling: PollingWatchKind.DynamicPriority }
168                },
169                {
170                    json: { watchOptions: { synchronousWatchDirectory: true } },
171                    expectedOptions: { synchronousWatchDirectory: true }
172                },
173                {
174                    json: { watchOptions: { excludeDirectories: ["**/temp"] } },
175                    expectedOptions: { excludeDirectories: ["/**/temp"] }
176                },
177                {
178                    json: { watchOptions: { excludeFiles: ["**/temp/*.ts"] } },
179                    expectedOptions: { excludeFiles: ["/**/temp/*.ts"] }
180                },
181                {
182                    json: { watchOptions: { excludeDirectories: ["**/../*"] } },
183                    expectedOptions: { excludeDirectories: [] },
184                    expectedErrors: sourceFile => [
185                        {
186                            messageText: `File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '**/../*'.`,
187                            category: Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.category,
188                            code: Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.code,
189                            file: sourceFile,
190                            start: sourceFile && sourceFile.text.indexOf(`"**/../*"`),
191                            length: sourceFile && `"**/../*"`.length,
192                            reportsDeprecated: undefined,
193                            reportsUnnecessary: undefined
194                        }
195                    ]
196                },
197                {
198                    json: { watchOptions: { excludeFiles: ["**/../*"] } },
199                    expectedOptions: { excludeFiles: [] },
200                    expectedErrors: sourceFile => [
201                        {
202                            messageText: `File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '**/../*'.`,
203                            category: Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.category,
204                            code: Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0.code,
205                            file: sourceFile,
206                            start: sourceFile && sourceFile.text.indexOf(`"**/../*"`),
207                            length: sourceFile && `"**/../*"`.length,
208                            reportsDeprecated: undefined,
209                            reportsUnnecessary: undefined
210                        }
211                    ]
212                },
213            ]);
214        });
215
216        describe("watch options extending passed in watch options", () => {
217            verifyWatchOptions(() => [
218                {
219                    json: { watchOptions: { watchFile: "UseFsEvents" } },
220                    expectedOptions: { watchFile: WatchFileKind.UseFsEvents, watchDirectory: WatchDirectoryKind.FixedPollingInterval },
221                    existingWatchOptions: { watchDirectory: WatchDirectoryKind.FixedPollingInterval }
222                },
223                {
224                    json: {},
225                    expectedOptions: { watchDirectory: WatchDirectoryKind.FixedPollingInterval },
226                    existingWatchOptions: { watchDirectory: WatchDirectoryKind.FixedPollingInterval }
227                },
228            ]);
229        });
230    });
231}
232