1
1
namespace ts . projectSystem {
2
+ interface SetupHostOutput {
3
+ host : TestServerHost ;
4
+ openFiles : readonly File [ ] ;
5
+ config : File ;
6
+ }
7
+
8
+ function setupHostWithSavedResolutions < T extends SetupHostOutput > ( setupHost : ( ) => T ) : T {
9
+ const result = setupHost ( ) ;
10
+ const exit = result . host . exit ;
11
+ result . host . exit = noop ;
12
+ fakes . withTemporaryPatchingForBuildinfoReadWrite ( result . host , sys => executeCommandLine ( sys , noop , [ "--b" , result . config . path ] ) ) ;
13
+ result . host . clearOutput ( ) ;
14
+ result . host . exit = exit ;
15
+ return result ;
16
+ }
17
+
18
+ function setupHostWithClearedResolutions < T extends SetupHostOutput > ( setupHost : ( ) => T ) : T {
19
+ const result = setupHost ( ) ;
20
+ const exit = result . host . exit ;
21
+ result . host . exit = noop ;
22
+ fakes . withTemporaryPatchingForBuildinfoReadWrite ( result . host , sys => {
23
+ executeCommandLine ( sys , noop , [ "--b" , result . config . path ] ) ;
24
+ executeCommandLine ( sys , noop , [ "--b" , result . config . path , "--cleanPersistedProgram" ] ) ;
25
+ } ) ;
26
+ result . host . clearOutput ( ) ;
27
+ result . host . exit = exit ;
28
+ return result ;
29
+ }
30
+
31
+ function setup < T extends SetupHostOutput > ( { host, openFiles, config } : T ) {
32
+ fakes . patchHostForBuildInfoReadWrite ( host ) ;
33
+ const session = createSession ( host , { logger : createLoggerWithInMemoryLogs ( ) } ) ;
34
+ openFilesForSession ( openFiles , session ) ;
35
+ const project = session . getProjectService ( ) . configuredProjects . get ( config . path ) ! ;
36
+ return { session, project } ;
37
+ }
38
+
39
+ function persistResolutions ( file : File ) {
40
+ const content = JSON . parse ( file . content ) ;
41
+ content . compilerOptions = {
42
+ ...content . compilerOptions || { } ,
43
+ persistResolutions : false ,
44
+ traceResolution : true ,
45
+ } ;
46
+ file . content = JSON . stringify ( content , /*replacer*/ undefined , 4 ) ;
47
+ return file ;
48
+ }
49
+
2
50
describe ( "unittests:: tsserver:: persistResolutions" , ( ) => {
3
51
function setupHost ( ) {
4
52
const { main, anotherFileReusingResolution, filePresent, fileWithRef, types, globalMain, globalAnotherFileWithSameReferenes, globalFilePresent, externalThing, someType, config } = tscWatch . PersistentResolutionsTests . getFiles ( ) ;
5
53
const host = createServerHost (
6
54
[ main , anotherFileReusingResolution , filePresent , fileWithRef , types , globalMain , globalAnotherFileWithSameReferenes , globalFilePresent , externalThing , someType , config , libFile ] ,
7
55
{ currentDirectory : tscWatch . projectRoot , useCaseSensitiveFileNames : true }
8
56
) ;
9
- return { host, main, globalMain, config } ;
10
- }
11
-
12
- function setupHostWithSavedResolutions ( ) {
13
- const result = setupHost ( ) ;
14
- const exit = result . host . exit ;
15
- result . host . exit = noop ;
16
- fakes . withTemporaryPatchingForBuildinfoReadWrite ( result . host , sys => executeCommandLine ( sys , noop , [ "--p" , "." ] ) ) ;
17
- result . host . exit = exit ;
18
- result . host . clearOutput ( ) ;
19
- return result ;
20
- }
21
-
22
- function setupHostWithClearedResolutions ( ) {
23
- const result = setupHost ( ) ;
24
- const exit = result . host . exit ;
25
- result . host . exit = noop ;
26
- fakes . withTemporaryPatchingForBuildinfoReadWrite ( result . host , sys => {
27
- executeCommandLine ( sys , noop , [ "--p" , "." ] ) ;
28
- executeCommandLine ( sys , noop , [ "--p" , "." , "--cleanPersistedProgram" ] ) ;
29
- } ) ;
30
- result . host . exit = exit ;
31
- result . host . clearOutput ( ) ;
32
- return result ;
33
- }
34
-
35
- function setup ( { host, main, globalMain, config } : ReturnType < typeof setupHost > ) {
36
- fakes . patchHostForBuildInfoReadWrite ( host ) ;
37
- const session = createSession ( host , { logger : createLoggerWithInMemoryLogs ( ) } ) ;
38
- openFilesForSession ( [ main , globalMain ] , session ) ;
39
- const project = session . getProjectService ( ) . configuredProjects . get ( config . path ) ! ;
40
- return { session, project } ;
57
+ return { host, main, globalMain, config, openFiles : [ main , globalMain ] } ;
41
58
}
42
59
43
60
function modifyGlobalMain ( session : TestSession , project : server . ConfiguredProject , globalMain : File ) {
@@ -190,7 +207,7 @@ namespace ts.projectSystem {
190
207
}
191
208
192
209
it ( "uses saved resolution for program" , ( ) => {
193
- const result = setupHostWithSavedResolutions ( ) ;
210
+ const result = setupHostWithSavedResolutions ( setupHost ) ;
194
211
const { project, session } = setup ( result ) ;
195
212
const { host, main, globalMain } = result ;
196
213
appendProjectFileText ( project , session ) ;
@@ -236,7 +253,7 @@ namespace ts.projectSystem {
236
253
} ) ;
237
254
238
255
it ( "creates new resolutions for program if tsbuildinfo is present but program is not persisted" , ( ) => {
239
- const result = setupHostWithClearedResolutions ( ) ;
256
+ const result = setupHostWithClearedResolutions ( setupHost ) ;
240
257
const { project, session } = setup ( result ) ;
241
258
const { host, main, globalMain } = result ;
242
259
appendProjectFileText ( project , session ) ;
@@ -258,4 +275,117 @@ namespace ts.projectSystem {
258
275
baselineTsserverLogs ( "persistResolutions" , "creates new resolutions for program if tsbuildinfo is present but program is not persisted" , session ) ;
259
276
} ) ;
260
277
} ) ;
278
+
279
+ describe ( "unittests:: tsserver:: persistResolutions on sample project" , ( ) => {
280
+ function setupHost ( ) {
281
+ const coreConfig = persistResolutions ( TestFSWithWatch . getTsBuildProjectFile ( "sample1" , "core/tsconfig.json" ) ) ;
282
+ const coreIndex = TestFSWithWatch . getTsBuildProjectFile ( "sample1" , "core/index.ts" ) ;
283
+ const coreAnotherModule = TestFSWithWatch . getTsBuildProjectFile ( "sample1" , "core/anotherModule.ts" ) ;
284
+ const coreSomeDecl = TestFSWithWatch . getTsBuildProjectFile ( "sample1" , "core/some_decl.d.ts" ) ;
285
+ const logicConfig = persistResolutions ( TestFSWithWatch . getTsBuildProjectFile ( "sample1" , "logic/tsconfig.json" ) ) ;
286
+ const logicIndex = TestFSWithWatch . getTsBuildProjectFile ( "sample1" , "logic/index.ts" ) ;
287
+ const testsConfig = persistResolutions ( TestFSWithWatch . getTsBuildProjectFile ( "sample1" , "tests/tsconfig.json" ) ) ;
288
+ const testsIndex = TestFSWithWatch . getTsBuildProjectFile ( "sample1" , "tests/index.ts" ) ;
289
+ const host = createServerHost ( [ libFile , coreConfig , coreIndex , coreAnotherModule , coreSomeDecl , logicConfig , logicIndex , testsConfig , testsIndex ] ) ;
290
+ return { host, config : testsConfig , openFiles : [ testsIndex ] } ;
291
+ }
292
+
293
+
294
+ it ( "uses saved resolution for program" , ( ) => {
295
+ const result = setupHostWithSavedResolutions ( setupHost ) ;
296
+ const { project, session } = setup ( result ) ;
297
+ appendProjectFileText ( project , session ) ;
298
+ baselineTsserverLogs ( "persistResolutions" , "uses saved resolution for program with sample project" , session ) ;
299
+ } ) ;
300
+
301
+ it ( "creates new resolutions for program if tsbuildinfo is not present" , ( ) => {
302
+ const result = setupHost ( ) ;
303
+ const { project, session } = setup ( result ) ;
304
+ appendProjectFileText ( project , session ) ;
305
+ baselineTsserverLogs ( "persistResolutions" , "creates new resolutions for program if tsbuildinfo is not present with sample project" , session ) ;
306
+ } ) ;
307
+
308
+ it ( "creates new resolutions for program if tsbuildinfo is present but program is not persisted" , ( ) => {
309
+ const result = setupHostWithClearedResolutions ( setupHost ) ;
310
+ const { project, session } = setup ( result ) ;
311
+ appendProjectFileText ( project , session ) ;
312
+ baselineTsserverLogs ( "persistResolutions" , "creates new resolutions for program if tsbuildinfo is present but program is not persisted with sample project" , session ) ;
313
+ } ) ;
314
+ } ) ;
315
+
316
+ describe ( "unittests:: tsserver:: persistResolutions on project where d.ts file contains fewer modules than original file" , ( ) => {
317
+ function setupHost ( ) {
318
+ const coreConfig : File = {
319
+ path : `${ tscWatch . projectRoot } /core/tsconfig.json` ,
320
+ content : JSON . stringify ( { compilerOptions : { composite : true , persistResolutions : false , traceResolution : true } } )
321
+ } ;
322
+ const coreIndex : File = {
323
+ path : `${ tscWatch . projectRoot } /core/index.ts` ,
324
+ content : `export function bar() { return 10; }`
325
+ } ;
326
+ const coreMyClass : File = {
327
+ path : `${ tscWatch . projectRoot } /core/myClass.ts` ,
328
+ content : `export class myClass { }`
329
+ } ;
330
+ const coreAnotherClass : File = {
331
+ path : `${ tscWatch . projectRoot } /core/anotherClass.ts` ,
332
+ content : `export class anotherClass { }`
333
+ } ;
334
+ const logicConfig : File = {
335
+ path : `${ tscWatch . projectRoot } /logic/tsconfig.json` ,
336
+ content : JSON . stringify ( {
337
+ compilerOptions : { composite : true , persistResolutions : false , traceResolution : true } ,
338
+ references : [ { path : "../core" } ]
339
+ } )
340
+ } ;
341
+ const logicIndex : File = {
342
+ path : `${ tscWatch . projectRoot } /logic/index.ts` ,
343
+ content : `import { myClass } from "../core/myClass";
344
+ import { bar } from "../core";
345
+ import { anotherClass } from "../core/anotherClass";
346
+ export function returnMyClass() {
347
+ bar();
348
+ return new myClass();
349
+ }
350
+ export function returnAnotherClass() {
351
+ return new anotherClass();
352
+ }`
353
+ } ;
354
+ const testsConfig : File = {
355
+ path : `${ tscWatch . projectRoot } /tests/tsconfig.json` ,
356
+ content : JSON . stringify ( {
357
+ compilerOptions : { composite : true , persistResolutions : false , traceResolution : true } ,
358
+ references : [ { path : "../logic" } ]
359
+ } )
360
+ } ;
361
+ const testsIndex : File = {
362
+ path : `${ tscWatch . projectRoot } /tests/index.ts` ,
363
+ content : `import { returnMyClass } from "../logic";
364
+ returnMyClass();`
365
+ } ;
366
+ const host = createServerHost ( [ libFile , coreConfig , coreIndex , coreMyClass , coreAnotherClass , logicConfig , logicIndex , testsConfig , testsIndex ] ) ;
367
+ return { host, config : testsConfig , openFiles : [ testsIndex ] } ;
368
+ }
369
+
370
+ it ( "uses saved resolution for program" , ( ) => {
371
+ const result = setupHostWithSavedResolutions ( setupHost ) ;
372
+ const { project, session } = setup ( result ) ;
373
+ appendProjectFileText ( project , session ) ;
374
+ baselineTsserverLogs ( "persistResolutions" , "uses saved resolution for program with project where dts file contains fewer modules than original file" , session ) ;
375
+ } ) ;
376
+
377
+ it ( "creates new resolutions for program if tsbuildinfo is not present" , ( ) => {
378
+ const result = setupHost ( ) ;
379
+ const { project, session } = setup ( result ) ;
380
+ appendProjectFileText ( project , session ) ;
381
+ baselineTsserverLogs ( "persistResolutions" , "creates new resolutions for program if tsbuildinfo is not present with project where dts file contains fewer modules than original file" , session ) ;
382
+ } ) ;
383
+
384
+ it ( "creates new resolutions for program if tsbuildinfo is present but program is not persisted" , ( ) => {
385
+ const result = setupHostWithClearedResolutions ( setupHost ) ;
386
+ const { project, session } = setup ( result ) ;
387
+ appendProjectFileText ( project , session ) ;
388
+ baselineTsserverLogs ( "persistResolutions" , "creates new resolutions for program if tsbuildinfo is present but program is not persisted with project where dts file contains fewer modules than original file" , session ) ;
389
+ } ) ;
390
+ } ) ;
261
391
}
0 commit comments