• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1namespace ts.projectSystem {
2    describe("unittests:: tsserver:: with project references and compile on save", () => {
3        const dependecyLocation = `${tscWatch.projectRoot}/dependency`;
4        const usageLocation = `${tscWatch.projectRoot}/usage`;
5        const dependencyTs: File = {
6            path: `${dependecyLocation}/fns.ts`,
7            content: `export function fn1() { }
8export function fn2() { }
9`
10        };
11        const dependencyConfig: File = {
12            path: `${dependecyLocation}/tsconfig.json`,
13            content: JSON.stringify({
14                compilerOptions: { composite: true, declarationDir: "../decls" },
15                compileOnSave: true
16            })
17        };
18        const usageTs: File = {
19            path: `${usageLocation}/usage.ts`,
20            content: `import {
21    fn1,
22    fn2,
23} from '../decls/fns'
24fn1();
25fn2();
26`
27        };
28        const usageConfig: File = {
29            path: `${usageLocation}/tsconfig.json`,
30            content: JSON.stringify({
31                compileOnSave: true,
32                references: [{ path: "../dependency" }]
33            })
34        };
35
36        const localChange = "function fn3() { }";
37        const change = `export ${localChange}`;
38
39        describe("when dependency project is not open", () => {
40            describe("Of usageTs", () => {
41                it("with initial file open, without specifying project file", () => {
42                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
43                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
44                    openFilesForSession([usageTs], session);
45
46                    // Verify CompileOnSaveAffectedFileList
47                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
48                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
49                        arguments: { file: usageTs.path }
50                    });
51
52                    // Verify CompileOnSaveEmit
53                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
54                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
55                        arguments: { file: usageTs.path }
56                    });
57
58                    // Verify EmitOutput
59                    session.executeCommandSeq<protocol.EmitOutputRequest>({
60                        command: protocol.CommandTypes.EmitOutput,
61                        arguments: { file: usageTs.path }
62                    });
63                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage", session);
64                });
65                it("with initial file open, with specifying project file", () => {
66                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
67                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
68                    openFilesForSession([usageTs], session);
69
70                    // Verify CompileOnSaveAffectedFileList
71                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
72                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
73                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
74                    });
75
76                    // Verify CompileOnSaveEmit
77                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
78                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
79                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
80                    });
81
82                    // Verify EmitOutput
83                    session.executeCommandSeq<protocol.EmitOutputRequest>({
84                        command: protocol.CommandTypes.EmitOutput,
85                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
86                    });
87                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage with project", session);
88                });
89                it("with local change to dependency, without specifying project file", () => {
90                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
91                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
92                    openFilesForSession([usageTs], session);
93
94                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
95                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
96                        arguments: { file: dependencyTs.path }
97                    });
98                    host.writeFile(dependencyTs.path, `${dependencyTs.content}${localChange}`);
99
100                    // Verify CompileOnSaveAffectedFileList
101                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
102                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
103                        arguments: { file: usageTs.path }
104                    });
105
106                    // Verify CompileOnSaveEmit
107                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
108                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
109                        arguments: { file: usageTs.path }
110                    });
111
112                    // Verify EmitOutput
113                    session.executeCommandSeq<protocol.EmitOutputRequest>({
114                        command: protocol.CommandTypes.EmitOutput,
115                        arguments: { file: usageTs.path }
116                    });
117                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage and local change to dependency", session);
118                });
119                it("with local change to dependency, with specifying project file", () => {
120                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
121                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
122                    openFilesForSession([usageTs], session);
123
124                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
125                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
126                        arguments: { file: dependencyTs.path }
127                    });
128                    host.writeFile(dependencyTs.path, `${dependencyTs.content}${localChange}`);
129
130                    // Verify CompileOnSaveAffectedFileList
131                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
132                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
133                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
134                    });
135
136                    // Verify CompileOnSaveEmit
137                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
138                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
139                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
140                    });
141
142                    // Verify EmitOutput
143                    session.executeCommandSeq<protocol.EmitOutputRequest>({
144                        command: protocol.CommandTypes.EmitOutput,
145                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
146                    });
147                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage with project and local change to dependency", session);
148                });
149                it("with local change to usage, without specifying project file", () => {
150                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
151                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
152                    openFilesForSession([usageTs], session);
153
154                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
155                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
156                        arguments: { file: dependencyTs.path }
157                    });
158                    const toLocation = protocolToLocation(usageTs.content);
159                    const location = toLocation(usageTs.content.length);
160                    session.executeCommandSeq<protocol.ChangeRequest>({
161                        command: protocol.CommandTypes.Change,
162                        arguments: {
163                            file: usageTs.path,
164                            ...location,
165                            endLine: location.line,
166                            endOffset: location.offset,
167                            insertString: localChange
168                        }
169                    });
170
171                    // Verify CompileOnSaveAffectedFileList
172                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
173                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
174                        arguments: { file: usageTs.path }
175                    });
176
177                    // Verify CompileOnSaveEmit
178                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
179                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
180                        arguments: { file: usageTs.path }
181                    });
182
183                    // Verify EmitOutput
184                    session.executeCommandSeq<protocol.EmitOutputRequest>({
185                        command: protocol.CommandTypes.EmitOutput,
186                        arguments: { file: usageTs.path }
187                    });
188                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage and local change to usage", session);
189                });
190                it("with local change to usage, with specifying project file", () => {
191                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
192                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
193                    openFilesForSession([usageTs], session);
194
195                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
196                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
197                        arguments: { file: dependencyTs.path }
198                    });
199                    const toLocation = protocolToLocation(usageTs.content);
200                    const location = toLocation(usageTs.content.length);
201                    session.executeCommandSeq<protocol.ChangeRequest>({
202                        command: protocol.CommandTypes.Change,
203                        arguments: {
204                            file: usageTs.path,
205                            ...location,
206                            endLine: location.line,
207                            endOffset: location.offset,
208                            insertString: localChange
209                        }
210                    });
211
212                    // Verify CompileOnSaveAffectedFileList
213                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
214                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
215                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
216                    });
217
218                    // Verify CompileOnSaveEmit
219                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
220                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
221                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
222                    });
223
224                    // Verify EmitOutput
225                    session.executeCommandSeq<protocol.EmitOutputRequest>({
226                        command: protocol.CommandTypes.EmitOutput,
227                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
228                    });
229                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage with project and local change to usage", session);
230                });
231                it("with change to dependency, without specifying project file", () => {
232                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
233                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
234                    openFilesForSession([usageTs], session);
235
236                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
237                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
238                        arguments: { file: dependencyTs.path }
239                    });
240                    host.writeFile(dependencyTs.path, `${dependencyTs.content}${change}`);
241
242                    // Verify CompileOnSaveAffectedFileList
243                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
244                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
245                        arguments: { file: usageTs.path }
246                    });
247
248                    // Verify CompileOnSaveEmit
249                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
250                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
251                        arguments: { file: usageTs.path }
252                    });
253
254                    // Verify EmitOutput
255                    session.executeCommandSeq<protocol.EmitOutputRequest>({
256                        command: protocol.CommandTypes.EmitOutput,
257                        arguments: { file: usageTs.path }
258                    });
259                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage and change to depenedency", session);
260                });
261                it("with change to dependency, with specifying project file", () => {
262                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
263                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
264                    openFilesForSession([usageTs], session);
265
266                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
267                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
268                        arguments: { file: dependencyTs.path }
269                    });
270                    host.writeFile(dependencyTs.path, `${dependencyTs.content}${change}`);
271
272                    // Verify CompileOnSaveAffectedFileList
273                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
274                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
275                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
276                    });
277
278                    // Verify CompileOnSaveEmit
279                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
280                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
281                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
282                    });
283
284                    // Verify EmitOutput
285                    session.executeCommandSeq<protocol.EmitOutputRequest>({
286                        command: protocol.CommandTypes.EmitOutput,
287                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
288                    });
289                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage with project and change to depenedency", session);
290                });
291                it("with change to usage, without specifying project file", () => {
292                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
293                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
294                    openFilesForSession([usageTs], session);
295
296                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
297                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
298                        arguments: { file: dependencyTs.path }
299                    });
300                    const toLocation = protocolToLocation(usageTs.content);
301                    const location = toLocation(usageTs.content.length);
302                    session.executeCommandSeq<protocol.ChangeRequest>({
303                        command: protocol.CommandTypes.Change,
304                        arguments: {
305                            file: usageTs.path,
306                            ...location,
307                            endLine: location.line,
308                            endOffset: location.offset,
309                            insertString: change
310                        }
311                    });
312
313                    // Verify CompileOnSaveAffectedFileList
314                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
315                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
316                        arguments: { file: usageTs.path }
317                    });
318
319                    // Verify CompileOnSaveEmit
320                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
321                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
322                        arguments: { file: usageTs.path }
323                    });
324
325                    // Verify EmitOutput
326                    session.executeCommandSeq<protocol.EmitOutputRequest>({
327                        command: protocol.CommandTypes.EmitOutput,
328                        arguments: { file: usageTs.path }
329                    });
330                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage and change to usage", session);
331                });
332                it("with change to usage, with specifying project file", () => {
333                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
334                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
335                    openFilesForSession([usageTs], session);
336
337                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
338                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
339                        arguments: { file: dependencyTs.path }
340                    });
341                    const toLocation = protocolToLocation(usageTs.content);
342                    const location = toLocation(usageTs.content.length);
343                    session.executeCommandSeq<protocol.ChangeRequest>({
344                        command: protocol.CommandTypes.Change,
345                        arguments: {
346                            file: usageTs.path,
347                            ...location,
348                            endLine: location.line,
349                            endOffset: location.offset,
350                            insertString: change
351                        }
352                    });
353
354                    // Verify CompileOnSaveAffectedFileList
355                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
356                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
357                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
358                    });
359
360                    // Verify CompileOnSaveEmit
361                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
362                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
363                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
364                    });
365
366                    // Verify EmitOutput
367                    session.executeCommandSeq<protocol.EmitOutputRequest>({
368                        command: protocol.CommandTypes.EmitOutput,
369                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
370                    });
371                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage with project and change to usage", session);
372                });
373            });
374
375            describe("Of dependencyTs in usage project", () => {
376                it("with initial file open, without specifying project file", () => {
377                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
378                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
379                    openFilesForSession([usageTs], session);
380
381                    // Verify CompileOnSaveAffectedFileList
382                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
383                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
384                        arguments: { file: dependencyTs.path }
385                    });
386
387                    // Verify CompileOnSaveEmit
388                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
389                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
390                        arguments: { file: dependencyTs.path }
391                    });
392
393                    // Verify EmitOutput
394                    session.executeCommandSeq<protocol.EmitOutputRequest>({
395                        command: protocol.CommandTypes.EmitOutput,
396                        arguments: { file: dependencyTs.path }
397                    });
398                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency", session);
399                });
400                it("with initial file open, with specifying project file", () => {
401                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
402                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
403                    openFilesForSession([usageTs], session);
404
405                    // Verify CompileOnSaveAffectedFileList
406                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
407                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
408                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
409                    });
410
411                    // Verify CompileOnSaveEmit
412                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
413                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
414                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
415                    });
416
417                    // Verify EmitOutput
418                    session.executeCommandSeq<protocol.EmitOutputRequest>({
419                        command: protocol.CommandTypes.EmitOutput,
420                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
421                    });
422                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency with project", session);
423                });
424                it("with local change to dependency, without specifying project file", () => {
425                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
426                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
427                    openFilesForSession([usageTs], session);
428
429                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
430                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
431                        arguments: { file: dependencyTs.path }
432                    });
433                    host.writeFile(dependencyTs.path, `${dependencyTs.content}${localChange}`);
434
435                    // Verify CompileOnSaveAffectedFileList
436                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
437                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
438                        arguments: { file: dependencyTs.path }
439                    });
440
441                    // Verify CompileOnSaveEmit
442                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
443                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
444                        arguments: { file: dependencyTs.path }
445                    });
446
447                    // Verify EmitOutput
448                    session.executeCommandSeq<protocol.EmitOutputRequest>({
449                        command: protocol.CommandTypes.EmitOutput,
450                        arguments: { file: dependencyTs.path }
451                    });
452                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency and local change to dependency", session);
453                });
454                it("with local change to dependency, with specifying project file", () => {
455                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
456                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
457                    openFilesForSession([usageTs], session);
458
459                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
460                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
461                        arguments: { file: dependencyTs.path }
462                    });
463                    host.writeFile(dependencyTs.path, `${dependencyTs.content}${localChange}`);
464
465                    // Verify CompileOnSaveAffectedFileList
466                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
467                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
468                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
469                    });
470
471                    // Verify CompileOnSaveEmit
472                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
473                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
474                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
475                    });
476
477                    // Verify EmitOutput
478                    session.executeCommandSeq<protocol.EmitOutputRequest>({
479                        command: protocol.CommandTypes.EmitOutput,
480                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
481                    });
482                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency with project and local change to dependency", session);
483                });
484                it("with local change to usage, without specifying project file", () => {
485                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
486                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
487                    openFilesForSession([usageTs], session);
488
489                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
490                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
491                        arguments: { file: dependencyTs.path }
492                    });
493                    const toLocation = protocolToLocation(usageTs.content);
494                    const location = toLocation(usageTs.content.length);
495                    session.executeCommandSeq<protocol.ChangeRequest>({
496                        command: protocol.CommandTypes.Change,
497                        arguments: {
498                            file: usageTs.path,
499                            ...location,
500                            endLine: location.line,
501                            endOffset: location.offset,
502                            insertString: localChange
503                        }
504                    });
505
506                    // Verify CompileOnSaveAffectedFileList
507                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
508                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
509                        arguments: { file: dependencyTs.path }
510                    });
511
512                    // Verify CompileOnSaveEmit
513                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
514                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
515                        arguments: { file: dependencyTs.path }
516                    });
517
518                    // Verify EmitOutput
519                    session.executeCommandSeq<protocol.EmitOutputRequest>({
520                        command: protocol.CommandTypes.EmitOutput,
521                        arguments: { file: dependencyTs.path }
522                    });
523                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency and local change to usage", session);
524                });
525                it("with local change to usage, with specifying project file", () => {
526                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
527                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
528                    openFilesForSession([usageTs], session);
529
530                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
531                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
532                        arguments: { file: dependencyTs.path }
533                    });
534                    const toLocation = protocolToLocation(usageTs.content);
535                    const location = toLocation(usageTs.content.length);
536                    session.executeCommandSeq<protocol.ChangeRequest>({
537                        command: protocol.CommandTypes.Change,
538                        arguments: {
539                            file: usageTs.path,
540                            ...location,
541                            endLine: location.line,
542                            endOffset: location.offset,
543                            insertString: localChange
544                        }
545                    });
546
547                    // Verify CompileOnSaveAffectedFileList
548                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
549                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
550                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
551                    });
552
553                    // Verify CompileOnSaveEmit
554                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
555                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
556                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
557                    });
558
559                    // Verify EmitOutput
560                    session.executeCommandSeq<protocol.EmitOutputRequest>({
561                        command: protocol.CommandTypes.EmitOutput,
562                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
563                    });
564                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency with project and local change to usage", session);
565                });
566                it("with change to dependency, without specifying project file", () => {
567                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
568                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
569                    openFilesForSession([usageTs], session);
570
571                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
572                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
573                        arguments: { file: dependencyTs.path }
574                    });
575                    host.writeFile(dependencyTs.path, `${dependencyTs.content}${change}`);
576
577                    // Verify CompileOnSaveAffectedFileList
578                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
579                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
580                        arguments: { file: dependencyTs.path }
581                    });
582
583                    // Verify CompileOnSaveEmit
584                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
585                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
586                        arguments: { file: dependencyTs.path }
587                    });
588
589                    // Verify EmitOutput
590                    session.executeCommandSeq<protocol.EmitOutputRequest>({
591                        command: protocol.CommandTypes.EmitOutput,
592                        arguments: { file: dependencyTs.path }
593                    });
594                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency and change to dependency", session);
595                });
596                it("with change to dependency, with specifying project file", () => {
597                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
598                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
599                    openFilesForSession([usageTs], session);
600
601                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
602                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
603                        arguments: { file: dependencyTs.path }
604                    });
605                    host.writeFile(dependencyTs.path, `${dependencyTs.content}${change}`);
606
607                    // Verify CompileOnSaveAffectedFileList
608                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
609                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
610                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
611                    });
612
613                    // Verify CompileOnSaveEmit
614                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
615                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
616                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
617                    });
618
619                    // Verify EmitOutput
620                    session.executeCommandSeq<protocol.EmitOutputRequest>({
621                        command: protocol.CommandTypes.EmitOutput,
622                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
623                    });
624                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency with project and change to dependency", session);
625                });
626                it("with change to usage, without specifying project file", () => {
627                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
628                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
629                    openFilesForSession([usageTs], session);
630
631                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
632                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
633                        arguments: { file: dependencyTs.path }
634                    });
635                    const toLocation = protocolToLocation(usageTs.content);
636                    const location = toLocation(usageTs.content.length);
637                    session.executeCommandSeq<protocol.ChangeRequest>({
638                        command: protocol.CommandTypes.Change,
639                        arguments: {
640                            file: usageTs.path,
641                            ...location,
642                            endLine: location.line,
643                            endOffset: location.offset,
644                            insertString: change
645                        }
646                    });
647
648                    // Verify CompileOnSaveAffectedFileList
649                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
650                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
651                        arguments: { file: dependencyTs.path }
652                    });
653
654                    // Verify CompileOnSaveEmit
655                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
656                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
657                        arguments: { file: dependencyTs.path }
658                    });
659
660                    // Verify EmitOutput
661                    session.executeCommandSeq<protocol.EmitOutputRequest>({
662                        command: protocol.CommandTypes.EmitOutput,
663                        arguments: { file: dependencyTs.path }
664                    });
665                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency and change to usage", session);
666                });
667                it("with change to usage, with specifying project file", () => {
668                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
669                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
670                    openFilesForSession([usageTs], session);
671
672                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
673                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
674                        arguments: { file: dependencyTs.path }
675                    });
676                    const toLocation = protocolToLocation(usageTs.content);
677                    const location = toLocation(usageTs.content.length);
678                    session.executeCommandSeq<protocol.ChangeRequest>({
679                        command: protocol.CommandTypes.Change,
680                        arguments: {
681                            file: usageTs.path,
682                            ...location,
683                            endLine: location.line,
684                            endOffset: location.offset,
685                            insertString: change
686                        }
687                    });
688
689                    // Verify CompileOnSaveAffectedFileList
690                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
691                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
692                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
693                    });
694
695                    // Verify CompileOnSaveEmit
696                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
697                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
698                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
699                    });
700
701                    // Verify EmitOutput
702                    session.executeCommandSeq<protocol.EmitOutputRequest>({
703                        command: protocol.CommandTypes.EmitOutput,
704                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
705                    });
706                    baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency with project and change to usage", session);
707                });
708            });
709        });
710
711        describe("when the depedency file is open", () => {
712            describe("Of usageTs", () => {
713                it("with initial file open, without specifying project file", () => {
714                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
715                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
716                    openFilesForSession([usageTs, dependencyTs], session);
717
718                    // Verify CompileOnSaveAffectedFileList
719                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
720                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
721                        arguments: { file: usageTs.path }
722                    });
723
724                    // Verify CompileOnSaveEmit
725                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
726                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
727                        arguments: { file: usageTs.path }
728                    });
729
730                    // Verify EmitOutput
731                    session.executeCommandSeq<protocol.EmitOutputRequest>({
732                        command: protocol.CommandTypes.EmitOutput,
733                        arguments: { file: usageTs.path }
734                    });
735                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage", session);
736                });
737                it("with initial file open, with specifying project file", () => {
738                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
739                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
740                    openFilesForSession([usageTs, dependencyTs], session);
741
742                    // Verify CompileOnSaveAffectedFileList
743                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
744                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
745                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
746                    });
747
748                    // Verify CompileOnSaveEmit
749                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
750                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
751                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
752                    });
753
754                    // Verify EmitOutput
755                    session.executeCommandSeq<protocol.EmitOutputRequest>({
756                        command: protocol.CommandTypes.EmitOutput,
757                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
758                    });
759                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage with project", session);
760                });
761                it("with local change to dependency, without specifying project file", () => {
762                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
763                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
764                    openFilesForSession([usageTs, dependencyTs], session);
765
766                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
767                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
768                        arguments: { file: dependencyTs.path }
769                    });
770                    const toLocation = protocolToLocation(dependencyTs.content);
771                    const location = toLocation(dependencyTs.content.length);
772                    session.executeCommandSeq<protocol.ChangeRequest>({
773                        command: protocol.CommandTypes.Change,
774                        arguments: {
775                            file: dependencyTs.path,
776                            ...location,
777                            endLine: location.line,
778                            endOffset: location.offset,
779                            insertString: localChange
780                        }
781                    });
782
783                    // Verify CompileOnSaveAffectedFileList
784                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
785                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
786                        arguments: { file: usageTs.path }
787                    });
788
789                    // Verify CompileOnSaveEmit
790                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
791                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
792                        arguments: { file: usageTs.path }
793                    });
794
795                    // Verify EmitOutput
796                    session.executeCommandSeq<protocol.EmitOutputRequest>({
797                        command: protocol.CommandTypes.EmitOutput,
798                        arguments: { file: usageTs.path }
799                    });
800                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage and local change to dependency", session);
801                });
802                it("with local change to dependency, with specifying project file", () => {
803                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
804                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
805                    openFilesForSession([usageTs, dependencyTs], session);
806
807                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
808                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
809                        arguments: { file: dependencyTs.path }
810                    });
811                    const toLocation = protocolToLocation(dependencyTs.content);
812                    const location = toLocation(dependencyTs.content.length);
813                    session.executeCommandSeq<protocol.ChangeRequest>({
814                        command: protocol.CommandTypes.Change,
815                        arguments: {
816                            file: dependencyTs.path,
817                            ...location,
818                            endLine: location.line,
819                            endOffset: location.offset,
820                            insertString: localChange
821                        }
822                    });
823
824                    // Verify CompileOnSaveAffectedFileList
825                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
826                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
827                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
828                    });
829
830                    // Verify CompileOnSaveEmit
831                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
832                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
833                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
834                    });
835
836                    // Verify EmitOutput
837                    session.executeCommandSeq<protocol.EmitOutputRequest>({
838                        command: protocol.CommandTypes.EmitOutput,
839                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
840                    });
841                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage and local change to dependency with file", session);
842                });
843                it("with local change to usage, without specifying project file", () => {
844                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
845                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
846                    openFilesForSession([usageTs, dependencyTs], session);
847
848                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
849                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
850                        arguments: { file: dependencyTs.path }
851                    });
852                    const toLocation = protocolToLocation(usageTs.content);
853                    const location = toLocation(usageTs.content.length);
854                    session.executeCommandSeq<protocol.ChangeRequest>({
855                        command: protocol.CommandTypes.Change,
856                        arguments: {
857                            file: usageTs.path,
858                            ...location,
859                            endLine: location.line,
860                            endOffset: location.offset,
861                            insertString: localChange
862                        }
863                    });
864
865                    // Verify CompileOnSaveAffectedFileList
866                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
867                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
868                        arguments: { file: usageTs.path }
869                    });
870
871                    // Verify CompileOnSaveEmit
872                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
873                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
874                        arguments: { file: usageTs.path }
875                    });
876
877                    // Verify EmitOutput
878                    session.executeCommandSeq<protocol.EmitOutputRequest>({
879                        command: protocol.CommandTypes.EmitOutput,
880                        arguments: { file: usageTs.path }
881                    });
882                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage and local change to usage", session);
883                });
884                it("with local change to usage, with specifying project file", () => {
885                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
886                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
887                    openFilesForSession([usageTs, dependencyTs], session);
888
889                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
890                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
891                        arguments: { file: dependencyTs.path }
892                    });
893                    const toLocation = protocolToLocation(usageTs.content);
894                    const location = toLocation(usageTs.content.length);
895                    session.executeCommandSeq<protocol.ChangeRequest>({
896                        command: protocol.CommandTypes.Change,
897                        arguments: {
898                            file: usageTs.path,
899                            ...location,
900                            endLine: location.line,
901                            endOffset: location.offset,
902                            insertString: localChange
903                        }
904                    });
905
906                    // Verify CompileOnSaveAffectedFileList
907                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
908                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
909                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
910                    });
911
912                    // Verify CompileOnSaveEmit
913                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
914                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
915                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
916                    });
917
918                    // Verify EmitOutput
919                    session.executeCommandSeq<protocol.EmitOutputRequest>({
920                        command: protocol.CommandTypes.EmitOutput,
921                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
922                    });
923                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage and local change to usage with project", session);
924                });
925                it("with change to dependency, without specifying project file", () => {
926                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
927                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
928                    openFilesForSession([usageTs, dependencyTs], session);
929
930                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
931                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
932                        arguments: { file: dependencyTs.path }
933                    });
934                    const toLocation = protocolToLocation(dependencyTs.content);
935                    const location = toLocation(dependencyTs.content.length);
936                    session.executeCommandSeq<protocol.ChangeRequest>({
937                        command: protocol.CommandTypes.Change,
938                        arguments: {
939                            file: dependencyTs.path,
940                            ...location,
941                            endLine: location.line,
942                            endOffset: location.offset,
943                            insertString: change
944                        }
945                    });
946
947                    // Verify CompileOnSaveAffectedFileList
948                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
949                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
950                        arguments: { file: usageTs.path }
951                    });
952
953                    // Verify CompileOnSaveEmit
954                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
955                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
956                        arguments: { file: usageTs.path }
957                    });
958
959                    // Verify EmitOutput
960                    session.executeCommandSeq<protocol.EmitOutputRequest>({
961                        command: protocol.CommandTypes.EmitOutput,
962                        arguments: { file: usageTs.path }
963                    });
964                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage and change to dependency", session);
965                });
966                it("with change to dependency, with specifying project file", () => {
967                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
968                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
969                    openFilesForSession([usageTs, dependencyTs], session);
970
971                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
972                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
973                        arguments: { file: dependencyTs.path }
974                    });
975                    const toLocation = protocolToLocation(dependencyTs.content);
976                    const location = toLocation(dependencyTs.content.length);
977                    session.executeCommandSeq<protocol.ChangeRequest>({
978                        command: protocol.CommandTypes.Change,
979                        arguments: {
980                            file: dependencyTs.path,
981                            ...location,
982                            endLine: location.line,
983                            endOffset: location.offset,
984                            insertString: change
985                        }
986                    });
987
988                    // Verify CompileOnSaveAffectedFileList
989                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
990                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
991                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
992                    });
993
994                    // Verify CompileOnSaveEmit
995                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
996                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
997                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
998                    });
999
1000                    // Verify EmitOutput
1001                    session.executeCommandSeq<protocol.EmitOutputRequest>({
1002                        command: protocol.CommandTypes.EmitOutput,
1003                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
1004                    });
1005                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage with project and change to dependency", session);
1006                });
1007                it("with change to usage, without specifying project file", () => {
1008                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
1009                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
1010                    openFilesForSession([usageTs, dependencyTs], session);
1011
1012                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1013                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1014                        arguments: { file: dependencyTs.path }
1015                    });
1016                    const toLocation = protocolToLocation(usageTs.content);
1017                    const location = toLocation(usageTs.content.length);
1018                    session.executeCommandSeq<protocol.ChangeRequest>({
1019                        command: protocol.CommandTypes.Change,
1020                        arguments: {
1021                            file: usageTs.path,
1022                            ...location,
1023                            endLine: location.line,
1024                            endOffset: location.offset,
1025                            insertString: change
1026                        }
1027                    });
1028
1029                    // Verify CompileOnSaveAffectedFileList
1030                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1031                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1032                        arguments: { file: usageTs.path }
1033                    });
1034
1035                    // Verify CompileOnSaveEmit
1036                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
1037                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
1038                        arguments: { file: usageTs.path }
1039                    });
1040
1041                    // Verify EmitOutput
1042                    session.executeCommandSeq<protocol.EmitOutputRequest>({
1043                        command: protocol.CommandTypes.EmitOutput,
1044                        arguments: { file: usageTs.path }
1045                    });
1046                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage and change to usage", session);
1047                });
1048                it("with change to usage, with specifying project file", () => {
1049                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
1050                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
1051                    openFilesForSession([usageTs, dependencyTs], session);
1052
1053                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1054                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1055                        arguments: { file: dependencyTs.path }
1056                    });
1057                    const toLocation = protocolToLocation(usageTs.content);
1058                    const location = toLocation(usageTs.content.length);
1059                    session.executeCommandSeq<protocol.ChangeRequest>({
1060                        command: protocol.CommandTypes.Change,
1061                        arguments: {
1062                            file: usageTs.path,
1063                            ...location,
1064                            endLine: location.line,
1065                            endOffset: location.offset,
1066                            insertString: change
1067                        }
1068                    });
1069
1070                    // Verify CompileOnSaveAffectedFileList
1071                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1072                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1073                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
1074                    });
1075
1076                    // Verify CompileOnSaveEmit
1077                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
1078                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
1079                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
1080                    });
1081                    // Verify EmitOutput
1082                    session.executeCommandSeq<protocol.EmitOutputRequest>({
1083                        command: protocol.CommandTypes.EmitOutput,
1084                        arguments: { file: usageTs.path, projectFileName: usageConfig.path }
1085                    });
1086                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage with project and change to usage", session);
1087                });
1088            });
1089
1090            describe("Of dependencyTs in usage project", () => {
1091                it("with initial file open, with specifying project file", () => {
1092                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
1093                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
1094                    openFilesForSession([usageTs, dependencyTs], session);
1095
1096                    // Verify CompileOnSaveAffectedFileList
1097                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1098                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1099                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
1100                    });
1101
1102                    // Verify CompileOnSaveEmit
1103                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
1104                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
1105                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
1106                    });
1107
1108                    // Verify EmitOutput
1109                    session.executeCommandSeq<protocol.EmitOutputRequest>({
1110                        command: protocol.CommandTypes.EmitOutput,
1111                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
1112                    });
1113                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with usage project", session);
1114                });
1115                it("with local change to dependency, with specifying project file", () => {
1116                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
1117                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
1118                    openFilesForSession([usageTs, dependencyTs], session);
1119
1120                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1121                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1122                        arguments: { file: dependencyTs.path }
1123                    });
1124                    const toLocation = protocolToLocation(dependencyTs.content);
1125                    const location = toLocation(dependencyTs.content.length);
1126                    session.executeCommandSeq<protocol.ChangeRequest>({
1127                        command: protocol.CommandTypes.Change,
1128                        arguments: {
1129                            file: dependencyTs.path,
1130                            ...location,
1131                            endLine: location.line,
1132                            endOffset: location.offset,
1133                            insertString: localChange
1134                        }
1135                    });
1136
1137                    // Verify CompileOnSaveAffectedFileList
1138                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1139                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1140                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
1141                    });
1142
1143                    // Verify CompileOnSaveEmit
1144                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
1145                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
1146                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
1147                    });
1148
1149                    // Verify EmitOutput
1150                    session.executeCommandSeq<protocol.EmitOutputRequest>({
1151                        command: protocol.CommandTypes.EmitOutput,
1152                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
1153                    });
1154                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with usage project and local change to dependency", session);
1155                });
1156                it("with local change to usage, with specifying project file", () => {
1157                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
1158                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
1159                    openFilesForSession([usageTs, dependencyTs], session);
1160
1161                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1162                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1163                        arguments: { file: dependencyTs.path }
1164                    });
1165                    const toLocation = protocolToLocation(usageTs.content);
1166                    const location = toLocation(usageTs.content.length);
1167                    session.executeCommandSeq<protocol.ChangeRequest>({
1168                        command: protocol.CommandTypes.Change,
1169                        arguments: {
1170                            file: usageTs.path,
1171                            ...location,
1172                            endLine: location.line,
1173                            endOffset: location.offset,
1174                            insertString: localChange
1175                        }
1176                    });
1177
1178                    // Verify CompileOnSaveAffectedFileList
1179                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1180                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1181                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
1182                    });
1183
1184                    // Verify CompileOnSaveEmit
1185                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
1186                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
1187                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
1188                    });
1189
1190                    // Verify EmitOutput
1191                    session.executeCommandSeq<protocol.EmitOutputRequest>({
1192                        command: protocol.CommandTypes.EmitOutput,
1193                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
1194                    });
1195                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with usage project and local change to usage", session);
1196                });
1197                it("with change to dependency, with specifying project file", () => {
1198                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
1199                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
1200                    openFilesForSession([usageTs, dependencyTs], session);
1201
1202                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1203                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1204                        arguments: { file: dependencyTs.path }
1205                    });
1206                    const toLocation = protocolToLocation(dependencyTs.content);
1207                    const location = toLocation(dependencyTs.content.length);
1208                    session.executeCommandSeq<protocol.ChangeRequest>({
1209                        command: protocol.CommandTypes.Change,
1210                        arguments: {
1211                            file: dependencyTs.path,
1212                            ...location,
1213                            endLine: location.line,
1214                            endOffset: location.offset,
1215                            insertString: change
1216                        }
1217                    });
1218
1219                    // Verify CompileOnSaveAffectedFileList
1220                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1221                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1222                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
1223                    });
1224
1225                    // Verify CompileOnSaveEmit
1226                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
1227                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
1228                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
1229                    });
1230
1231                    // Verify EmitOutput
1232                    session.executeCommandSeq<protocol.EmitOutputRequest>({
1233                        command: protocol.CommandTypes.EmitOutput,
1234                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
1235                    });
1236                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with usage project and change to dependency", session);
1237                });
1238                it("with change to usage, with specifying project file", () => {
1239                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
1240                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
1241                    openFilesForSession([usageTs, dependencyTs], session);
1242
1243                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1244                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1245                        arguments: { file: dependencyTs.path }
1246                    });
1247                    const toLocation = protocolToLocation(usageTs.content);
1248                    const location = toLocation(usageTs.content.length);
1249                    session.executeCommandSeq<protocol.ChangeRequest>({
1250                        command: protocol.CommandTypes.Change,
1251                        arguments: {
1252                            file: usageTs.path,
1253                            ...location,
1254                            endLine: location.line,
1255                            endOffset: location.offset,
1256                            insertString: change
1257                        }
1258                    });
1259
1260                    // Verify CompileOnSaveAffectedFileList
1261                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1262                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1263                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
1264                    });
1265
1266                    // Verify CompileOnSaveEmit
1267                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
1268                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
1269                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
1270                    });
1271
1272                    // Verify EmitOutput
1273                    session.executeCommandSeq<protocol.EmitOutputRequest>({
1274                        command: protocol.CommandTypes.EmitOutput,
1275                        arguments: { file: dependencyTs.path, projectFileName: usageConfig.path }
1276                    });
1277                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with usage project and change to usage", session);
1278                });
1279            });
1280
1281            describe("Of dependencyTs", () => {
1282                it("with initial file open, without specifying project file", () => {
1283                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
1284                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
1285                    openFilesForSession([usageTs, dependencyTs], session);
1286
1287                    // Verify CompileOnSaveAffectedFileList
1288                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1289                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1290                        arguments: { file: dependencyTs.path }
1291                    });
1292
1293                    // Verify CompileOnSaveEmit
1294                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
1295                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
1296                        arguments: { file: dependencyTs.path }
1297                    });
1298
1299                    // Verify EmitOutput
1300                    session.executeCommandSeq<protocol.EmitOutputRequest>({
1301                        command: protocol.CommandTypes.EmitOutput,
1302                        arguments: { file: dependencyTs.path }
1303                    });
1304                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency", session);
1305                });
1306                it("with initial file open, with specifying project file", () => {
1307                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
1308                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
1309                    openFilesForSession([usageTs, dependencyTs], session);
1310
1311                    // Verify CompileOnSaveAffectedFileList
1312                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1313                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1314                        arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path }
1315                    });
1316
1317                    // Verify CompileOnSaveEmit
1318                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
1319                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
1320                        arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path }
1321                    });
1322
1323                    // Verify EmitOutput
1324                    session.executeCommandSeq<protocol.EmitOutputRequest>({
1325                        command: protocol.CommandTypes.EmitOutput,
1326                        arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path }
1327                    });
1328                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with project", session);
1329                });
1330                it("with local change to dependency, without specifying project file", () => {
1331                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
1332                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
1333                    openFilesForSession([usageTs, dependencyTs], session);
1334
1335                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1336                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1337                        arguments: { file: dependencyTs.path }
1338                    });
1339                    const toLocation = protocolToLocation(dependencyTs.content);
1340                    const location = toLocation(dependencyTs.content.length);
1341                    session.executeCommandSeq<protocol.ChangeRequest>({
1342                        command: protocol.CommandTypes.Change,
1343                        arguments: {
1344                            file: dependencyTs.path,
1345                            ...location,
1346                            endLine: location.line,
1347                            endOffset: location.offset,
1348                            insertString: localChange
1349                        }
1350                    });
1351
1352                    // Verify CompileOnSaveAffectedFileList
1353                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1354                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1355                        arguments: { file: dependencyTs.path }
1356                    });
1357
1358                    // Verify CompileOnSaveEmit
1359                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
1360                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
1361                        arguments: { file: dependencyTs.path }
1362                    });
1363
1364                    // Verify EmitOutput
1365                    session.executeCommandSeq<protocol.EmitOutputRequest>({
1366                        command: protocol.CommandTypes.EmitOutput,
1367                        arguments: { file: dependencyTs.path }
1368                    });
1369                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency and local change to dependency", session);
1370                });
1371                it("with local change to dependency, with specifying project file", () => {
1372                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
1373                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
1374                    openFilesForSession([usageTs, dependencyTs], session);
1375
1376                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1377                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1378                        arguments: { file: dependencyTs.path }
1379                    });
1380                    const toLocation = protocolToLocation(dependencyTs.content);
1381                    const location = toLocation(dependencyTs.content.length);
1382                    session.executeCommandSeq<protocol.ChangeRequest>({
1383                        command: protocol.CommandTypes.Change,
1384                        arguments: {
1385                            file: dependencyTs.path,
1386                            ...location,
1387                            endLine: location.line,
1388                            endOffset: location.offset,
1389                            insertString: localChange
1390                        }
1391                    });
1392
1393                    // Verify CompileOnSaveAffectedFileList
1394                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1395                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1396                        arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path }
1397                    });
1398
1399                    // Verify CompileOnSaveEmit
1400                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
1401                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
1402                        arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path }
1403                    });
1404
1405                    // Verify EmitOutput
1406                    session.executeCommandSeq<protocol.EmitOutputRequest>({
1407                        command: protocol.CommandTypes.EmitOutput,
1408                        arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path }
1409                    });
1410                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with project and local change to dependency", session);
1411                });
1412                it("with local change to usage, without specifying project file", () => {
1413                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
1414                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
1415                    openFilesForSession([usageTs, dependencyTs], session);
1416
1417                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1418                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1419                        arguments: { file: dependencyTs.path }
1420                    });
1421                    const toLocation = protocolToLocation(usageTs.content);
1422                    const location = toLocation(usageTs.content.length);
1423                    session.executeCommandSeq<protocol.ChangeRequest>({
1424                        command: protocol.CommandTypes.Change,
1425                        arguments: {
1426                            file: usageTs.path,
1427                            ...location,
1428                            endLine: location.line,
1429                            endOffset: location.offset,
1430                            insertString: localChange
1431                        }
1432                    });
1433
1434                    // Verify CompileOnSaveAffectedFileList
1435                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1436                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1437                        arguments: { file: dependencyTs.path }
1438                    });
1439
1440                    // Verify CompileOnSaveEmit
1441                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
1442                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
1443                        arguments: { file: dependencyTs.path }
1444                    });
1445
1446                    // Verify EmitOutput
1447                    session.executeCommandSeq<protocol.EmitOutputRequest>({
1448                        command: protocol.CommandTypes.EmitOutput,
1449                        arguments: { file: dependencyTs.path }
1450                    });
1451                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency and local change to usage", session);
1452                });
1453                it("with local change to usage, with specifying project file", () => {
1454                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
1455                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
1456                    openFilesForSession([usageTs, dependencyTs], session);
1457
1458                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1459                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1460                        arguments: { file: dependencyTs.path }
1461                    });
1462                    const toLocation = protocolToLocation(usageTs.content);
1463                    const location = toLocation(usageTs.content.length);
1464                    session.executeCommandSeq<protocol.ChangeRequest>({
1465                        command: protocol.CommandTypes.Change,
1466                        arguments: {
1467                            file: usageTs.path,
1468                            ...location,
1469                            endLine: location.line,
1470                            endOffset: location.offset,
1471                            insertString: localChange
1472                        }
1473                    });
1474
1475                    // Verify CompileOnSaveAffectedFileList
1476                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1477                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1478                        arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path }
1479                    });
1480
1481                    // Verify CompileOnSaveEmit
1482                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
1483                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
1484                        arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path }
1485                    });
1486
1487                    // Verify EmitOutput
1488                    session.executeCommandSeq<protocol.EmitOutputRequest>({
1489                        command: protocol.CommandTypes.EmitOutput,
1490                        arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path }
1491                    });
1492                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with project and local change to usage", session);
1493                });
1494                it("with change to dependency, without specifying project file", () => {
1495                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
1496                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
1497                    openFilesForSession([usageTs, dependencyTs], session);
1498
1499                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1500                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1501                        arguments: { file: dependencyTs.path }
1502                    });
1503                    const toLocation = protocolToLocation(dependencyTs.content);
1504                    const location = toLocation(dependencyTs.content.length);
1505                    session.executeCommandSeq<protocol.ChangeRequest>({
1506                        command: protocol.CommandTypes.Change,
1507                        arguments: {
1508                            file: dependencyTs.path,
1509                            ...location,
1510                            endLine: location.line,
1511                            endOffset: location.offset,
1512                            insertString: change
1513                        }
1514                    });
1515
1516                    // Verify CompileOnSaveAffectedFileList
1517                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1518                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1519                        arguments: { file: dependencyTs.path }
1520                    });
1521
1522                    // Verify CompileOnSaveEmit
1523                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
1524                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
1525                        arguments: { file: dependencyTs.path }
1526                    });
1527
1528                    // Verify EmitOutput
1529                    session.executeCommandSeq<protocol.EmitOutputRequest>({
1530                        command: protocol.CommandTypes.EmitOutput,
1531                        arguments: { file: dependencyTs.path }
1532                    });
1533                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency and change to dependency", session);
1534                });
1535                it("with change to dependency, with specifying project file", () => {
1536                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
1537                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
1538                    openFilesForSession([usageTs, dependencyTs], session);
1539
1540                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1541                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1542                        arguments: { file: dependencyTs.path }
1543                    });
1544                    const toLocation = protocolToLocation(dependencyTs.content);
1545                    const location = toLocation(dependencyTs.content.length);
1546                    session.executeCommandSeq<protocol.ChangeRequest>({
1547                        command: protocol.CommandTypes.Change,
1548                        arguments: {
1549                            file: dependencyTs.path,
1550                            ...location,
1551                            endLine: location.line,
1552                            endOffset: location.offset,
1553                            insertString: change
1554                        }
1555                    });
1556
1557                    // Verify CompileOnSaveAffectedFileList
1558                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1559                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1560                        arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path }
1561                    });
1562
1563                    // Verify CompileOnSaveEmit
1564                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
1565                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
1566                        arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path }
1567                    });
1568
1569                    // Verify EmitOutput
1570                    session.executeCommandSeq<protocol.EmitOutputRequest>({
1571                        command: protocol.CommandTypes.EmitOutput,
1572                        arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path }
1573                    });
1574                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with project and change to dependency", session);
1575                });
1576                it("with change to usage, without specifying project file", () => {
1577                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
1578                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
1579                    openFilesForSession([usageTs, dependencyTs], session);
1580
1581                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1582                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1583                        arguments: { file: dependencyTs.path }
1584                    });
1585                    const toLocation = protocolToLocation(usageTs.content);
1586                    const location = toLocation(usageTs.content.length);
1587                    session.executeCommandSeq<protocol.ChangeRequest>({
1588                        command: protocol.CommandTypes.Change,
1589                        arguments: {
1590                            file: usageTs.path,
1591                            ...location,
1592                            endLine: location.line,
1593                            endOffset: location.offset,
1594                            insertString: change
1595                        }
1596                    });
1597
1598                    // Verify CompileOnSaveAffectedFileList
1599                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1600                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1601                        arguments: { file: dependencyTs.path }
1602                    });
1603
1604                    // Verify CompileOnSaveEmit
1605                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
1606                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
1607                        arguments: { file: dependencyTs.path }
1608                    });
1609
1610                    // Verify EmitOutput
1611                    session.executeCommandSeq<protocol.EmitOutputRequest>({
1612                        command: protocol.CommandTypes.EmitOutput,
1613                        arguments: { file: dependencyTs.path }
1614                    });
1615                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency and change to usage", session);
1616                });
1617                it("with change to usage, with specifying project file", () => {
1618                    const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]);
1619                    const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
1620                    openFilesForSession([usageTs, dependencyTs], session);
1621
1622                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1623                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1624                        arguments: { file: dependencyTs.path }
1625                    });
1626                    const toLocation = protocolToLocation(usageTs.content);
1627                    const location = toLocation(usageTs.content.length);
1628                    session.executeCommandSeq<protocol.ChangeRequest>({
1629                        command: protocol.CommandTypes.Change,
1630                        arguments: {
1631                            file: usageTs.path,
1632                            ...location,
1633                            endLine: location.line,
1634                            endOffset: location.offset,
1635                            insertString: change
1636                        }
1637                    });
1638
1639                    // Verify CompileOnSaveAffectedFileList
1640                    session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
1641                        command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
1642                        arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path }
1643                    });
1644
1645                    // Verify CompileOnSaveEmit
1646                    session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
1647                        command: protocol.CommandTypes.CompileOnSaveEmitFile,
1648                        arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path }
1649                    });
1650
1651                    // Verify EmitOutput
1652                    session.executeCommandSeq<protocol.EmitOutputRequest>({
1653                        command: protocol.CommandTypes.EmitOutput,
1654                        arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path }
1655                    });
1656                    baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with project and change to usage", session);
1657                });
1658            });
1659        });
1660    });
1661
1662    describe("unittests:: tsserver:: with project references and compile on save with external projects", () => {
1663        it("compile on save emits same output as project build", () => {
1664            const tsbaseJson: File = {
1665                path: `${tscWatch.projectRoot}/tsbase.json`,
1666                content: JSON.stringify({
1667                    compileOnSave: true,
1668                    compilerOptions: {
1669                        module: "none",
1670                        composite: true
1671                    }
1672                })
1673            };
1674            const buttonClass = `${tscWatch.projectRoot}/buttonClass`;
1675            const buttonConfig: File = {
1676                path: `${buttonClass}/tsconfig.json`,
1677                content: JSON.stringify({
1678                    extends: "../tsbase.json",
1679                    compilerOptions: {
1680                        outFile: "Source.js"
1681                    },
1682                    files: ["Source.ts"]
1683                })
1684            };
1685            const buttonSource: File = {
1686                path: `${buttonClass}/Source.ts`,
1687                content: `module Hmi {
1688    export class Button {
1689        public static myStaticFunction() {
1690        }
1691    }
1692}`
1693            };
1694
1695            const siblingClass = `${tscWatch.projectRoot}/SiblingClass`;
1696            const siblingConfig: File = {
1697                path: `${siblingClass}/tsconfig.json`,
1698                content: JSON.stringify({
1699                    extends: "../tsbase.json",
1700                    references: [{
1701                        path: "../buttonClass/"
1702                    }],
1703                    compilerOptions: {
1704                        outFile: "Source.js"
1705                    },
1706                    files: ["Source.ts"]
1707                })
1708            };
1709            const siblingSource: File = {
1710                path: `${siblingClass}/Source.ts`,
1711                content: `module Hmi {
1712    export class Sibling {
1713        public mySiblingFunction() {
1714        }
1715    }
1716}`
1717            };
1718            const host = createServerHost([libFile, tsbaseJson, buttonConfig, buttonSource, siblingConfig, siblingSource], { useCaseSensitiveFileNames: true });
1719
1720            // ts build should succeed
1721            tscWatch.ensureErrorFreeBuild(host, [siblingConfig.path]);
1722
1723            const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) });
1724            openFilesForSession([siblingSource], session);
1725
1726            session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
1727                command: protocol.CommandTypes.CompileOnSaveEmitFile,
1728                arguments: {
1729                    file: siblingSource.path,
1730                    projectFileName: siblingConfig.path
1731                }
1732            });
1733            baselineTsserverLogs("projectReferenceCompileOnSave", "compile on save emits same output as project build with external project", session);
1734        });
1735    });
1736}