• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1namespace ts.projectSystem {
2    describe("unittests:: tsserver:: with project references and error reporting", () => {
3        const dependecyLocation = `${tscWatch.projectRoot}/dependency`;
4        const usageLocation = `${tscWatch.projectRoot}/usage`;
5
6
7        interface VerifyUsageAndDependency {
8            allFiles: readonly [File, File, File, File]; // dependencyTs, dependencyConfig, usageTs, usageConfig
9            usageDiagnostics(): GetErrDiagnostics;
10            dependencyDiagnostics(): GetErrDiagnostics;
11
12        }
13        function verifyUsageAndDependency({ allFiles, usageDiagnostics, dependencyDiagnostics }: VerifyUsageAndDependency) {
14            const [dependencyTs, dependencyConfig, usageTs, usageConfig] = allFiles;
15            function usageProjectDiagnostics(): GetErrForProjectDiagnostics {
16                return {
17                    project: usageTs.path,
18                    errors: [
19                        usageDiagnostics(),
20                        emptyDiagnostics(dependencyTs)
21                    ]
22                };
23            }
24
25            function dependencyProjectDiagnostics(): GetErrForProjectDiagnostics {
26                return {
27                    project: dependencyTs.path,
28                    errors: [
29                        dependencyDiagnostics()
30                    ]
31                };
32            }
33
34            function usageConfigDiag(): server.ConfigFileDiagEvent["data"] {
35                return {
36                    triggerFile: usageTs.path,
37                    configFileName: usageConfig.path,
38                    diagnostics: emptyArray
39                };
40            }
41
42            function dependencyConfigDiag(): server.ConfigFileDiagEvent["data"] {
43                return {
44                    triggerFile: dependencyTs.path,
45                    configFileName: dependencyConfig.path,
46                    diagnostics: emptyArray
47                };
48            }
49
50            describe("when dependency project is not open", () => {
51                verifyGetErrScenario({
52                    allFiles: () => allFiles,
53                    openFiles: () => [usageTs],
54                    expectedGetErr: () => [
55                        usageDiagnostics()
56                    ],
57                    expectedGetErrForProject: () => [
58                        usageProjectDiagnostics(),
59                        {
60                            project: dependencyTs.path,
61                            errors: [
62                                emptyDiagnostics(dependencyTs),
63                                usageDiagnostics()
64                            ]
65                        }
66                    ],
67                    expectedSyncDiagnostics: () => [
68                        // Without project
69                        usageDiagnostics(),
70                        emptyDiagnostics(dependencyTs),
71                        // With project
72                        syncDiagnostics(usageDiagnostics(), usageConfig.path),
73                        syncDiagnostics(emptyDiagnostics(dependencyTs), usageConfig.path),
74                    ],
75                    expectedConfigFileDiagEvents: () => [
76                        usageConfigDiag()
77                    ],
78                });
79            });
80
81            describe("when the depedency file is open", () => {
82                verifyGetErrScenario({
83                    allFiles: () => allFiles,
84                    openFiles: () => [usageTs, dependencyTs],
85                    expectedGetErr: () => [
86                        usageDiagnostics(),
87                        dependencyDiagnostics(),
88                    ],
89                    expectedGetErrForProject: () => [
90                        usageProjectDiagnostics(),
91                        dependencyProjectDiagnostics()
92                    ],
93                    expectedSyncDiagnostics: () => [
94                        // Without project
95                        usageDiagnostics(),
96                        dependencyDiagnostics(),
97                        // With project
98                        syncDiagnostics(usageDiagnostics(), usageConfig.path),
99                        syncDiagnostics(emptyDiagnostics(dependencyTs), usageConfig.path),
100                        syncDiagnostics(dependencyDiagnostics(), dependencyConfig.path),
101                    ],
102                    expectedConfigFileDiagEvents: () => [
103                        usageConfigDiag(),
104                        dependencyConfigDiag()
105                    ],
106                });
107            });
108        }
109
110        describe("with module scenario", () => {
111            const dependencyTs: File = {
112                path: `${dependecyLocation}/fns.ts`,
113                content: `export function fn1() { }
114export function fn2() { }
115// Introduce error for fnErr import in main
116// export function fnErr() { }
117// Error in dependency ts file
118export let x: string = 10;`
119            };
120            const dependencyConfig: File = {
121                path: `${dependecyLocation}/tsconfig.json`,
122                content: JSON.stringify({ compilerOptions: { composite: true, declarationDir: "../decls" } })
123            };
124            const usageTs: File = {
125                path: `${usageLocation}/usage.ts`,
126                content: `import {
127    fn1,
128    fn2,
129    fnErr
130} from '../decls/fns'
131fn1();
132fn2();
133fnErr();
134`
135            };
136            const usageConfig: File = {
137                path: `${usageLocation}/tsconfig.json`,
138                content: JSON.stringify({
139                    compilerOptions: { composite: true },
140                    references: [{ path: "../dependency" }]
141                })
142            };
143            function usageDiagnostics(): GetErrDiagnostics {
144                return {
145                    file: usageTs,
146                    syntax: emptyArray,
147                    semantic: [
148                        createDiagnostic(
149                            { line: 4, offset: 5 },
150                            { line: 4, offset: 10 },
151                            Diagnostics.Module_0_has_no_exported_member_1,
152                            [`"../decls/fns"`, "fnErr"],
153                            "error",
154                        )
155                    ],
156                    suggestion: emptyArray
157                };
158            }
159
160            function dependencyDiagnostics(): GetErrDiagnostics {
161                return {
162                    file: dependencyTs,
163                    syntax: emptyArray,
164                    semantic: [
165                        createDiagnostic(
166                            { line: 6, offset: 12 },
167                            { line: 6, offset: 13 },
168                            Diagnostics.Type_0_is_not_assignable_to_type_1,
169                            ["number", "string"],
170                            "error",
171                        )
172                    ],
173                    suggestion: emptyArray
174                };
175            }
176
177            verifyUsageAndDependency({
178                allFiles: [dependencyTs, dependencyConfig, usageTs, usageConfig],
179                usageDiagnostics,
180                dependencyDiagnostics
181            });
182        });
183
184        describe("with non module --out", () => {
185            const dependencyTs: File = {
186                path: `${dependecyLocation}/fns.ts`,
187                content: `function fn1() { }
188function fn2() { }
189// Introduce error for fnErr import in main
190// function fnErr() { }
191// Error in dependency ts file
192let x: string = 10;`
193            };
194            const dependencyConfig: File = {
195                path: `${dependecyLocation}/tsconfig.json`,
196                content: JSON.stringify({ compilerOptions: { composite: true, outFile: "../dependency.js" } })
197            };
198            const usageTs: File = {
199                path: `${usageLocation}/usage.ts`,
200                content: `fn1();
201fn2();
202fnErr();
203`
204            };
205            const usageConfig: File = {
206                path: `${usageLocation}/tsconfig.json`,
207                content: JSON.stringify({
208                    compilerOptions: { composite: true, outFile: "../usage.js" },
209                    references: [{ path: "../dependency" }]
210                })
211            };
212            function usageDiagnostics(): GetErrDiagnostics {
213                return {
214                    file: usageTs,
215                    syntax: emptyArray,
216                    semantic: [
217                        createDiagnostic(
218                            { line: 3, offset: 1 },
219                            { line: 3, offset: 6 },
220                            Diagnostics.Cannot_find_name_0,
221                            ["fnErr"],
222                            "error",
223                        )
224                    ],
225                    suggestion: emptyArray
226                };
227            }
228
229            function dependencyDiagnostics(): GetErrDiagnostics {
230                return {
231                    file: dependencyTs,
232                    syntax: emptyArray,
233                    semantic: [
234                        createDiagnostic(
235                            { line: 6, offset: 5 },
236                            { line: 6, offset: 6 },
237                            Diagnostics.Type_0_is_not_assignable_to_type_1,
238                            ["number", "string"],
239                            "error",
240                        )
241                    ],
242                    suggestion: emptyArray
243                };
244            }
245
246            verifyUsageAndDependency({
247                allFiles: [dependencyTs, dependencyConfig, usageTs, usageConfig],
248                usageDiagnostics,
249                dependencyDiagnostics
250            });
251        });
252    });
253}
254