@@ -16,17 +16,17 @@ namespace ts.tscWatch {
16
16
expectedIncrementalEmit ?: ReadonlyArray < File > ;
17
17
expectedIncrementalErrors ?: ReadonlyArray < string > ;
18
18
}
19
- function verifyIncrementalWatchEmit ( input : VerifyIncrementalWatchEmitInput ) {
19
+ function verifyIncrementalWatchEmit ( input : ( ) => VerifyIncrementalWatchEmitInput ) {
20
20
it ( "with tsc --w" , ( ) => {
21
21
verifyIncrementalWatchEmitWorker ( {
22
- input,
22
+ input : input ( ) ,
23
23
emitAndReportErrors : createWatchOfConfigFile ,
24
24
verifyErrors : checkOutputErrorsInitial
25
25
} ) ;
26
26
} ) ;
27
27
it ( "with tsc" , ( ) => {
28
28
verifyIncrementalWatchEmitWorker ( {
29
- input,
29
+ input : input ( ) ,
30
30
emitAndReportErrors : incrementalBuild ,
31
31
verifyErrors : checkNormalBuildErrors
32
32
} ) ;
@@ -122,15 +122,15 @@ namespace ts.tscWatch {
122
122
123
123
function checkFileEmit ( actual : Map < string > , expected : ReadonlyArray < File > ) {
124
124
assert . equal ( actual . size , expected . length , `Actual: ${ JSON . stringify ( arrayFrom ( actual . entries ( ) ) , /*replacer*/ undefined , " " ) } \nExpected: ${ JSON . stringify ( expected , /*replacer*/ undefined , " " ) } ` ) ;
125
- expected . forEach ( file => {
125
+ for ( const file of expected ) {
126
126
let expectedContent = file . content ;
127
127
let actualContent = actual . get ( file . path ) ;
128
128
if ( isBuildInfoFile ( file . path ) ) {
129
129
actualContent = actualContent && sanitizeBuildInfo ( actualContent ) ;
130
130
expectedContent = sanitizeBuildInfo ( expectedContent ) ;
131
131
}
132
132
assert . equal ( actualContent , expectedContent , `Emit for ${ file . path } ` ) ;
133
- } ) ;
133
+ }
134
134
}
135
135
136
136
const libFileInfo : BuilderState . FileInfo = {
@@ -170,7 +170,7 @@ namespace ts.tscWatch {
170
170
describe ( "own file emit without errors" , ( ) => {
171
171
function verify ( optionsToExtend ?: CompilerOptions , expectedBuildinfoOptions ?: CompilerOptions ) {
172
172
const modifiedFile2Content = file2 . content . replace ( "y" , "z" ) . replace ( "20" , "10" ) ;
173
- verifyIncrementalWatchEmit ( {
173
+ verifyIncrementalWatchEmit ( ( ) => ( {
174
174
files : [ libFile , file1 , file2 , configFile ] ,
175
175
optionsToExtend,
176
176
expectedInitialEmit : [
@@ -226,7 +226,7 @@ namespace ts.tscWatch {
226
226
}
227
227
] ,
228
228
expectedIncrementalErrors : emptyArray ,
229
- } ) ;
229
+ } ) ) ;
230
230
}
231
231
verify ( ) ;
232
232
describe ( "with commandline parameters that are not relative" , ( ) => {
@@ -259,7 +259,7 @@ namespace ts.tscWatch {
259
259
"file2.ts(1,7): error TS2322: Type '20' is not assignable to type 'string'.\n"
260
260
] ;
261
261
const modifiedFile1Content = file1 . content . replace ( "x" , "z" ) ;
262
- verifyIncrementalWatchEmit ( {
262
+ verifyIncrementalWatchEmit ( ( ) => ( {
263
263
files : [ libFile , file1 , fileModified , configFile ] ,
264
264
expectedInitialEmit : [
265
265
file1Js ,
@@ -320,7 +320,7 @@ namespace ts.tscWatch {
320
320
}
321
321
] ,
322
322
expectedIncrementalErrors : file2Errors ,
323
- } ) ;
323
+ } ) ) ;
324
324
} ) ;
325
325
326
326
describe ( "with --out" , ( ) => {
@@ -332,7 +332,7 @@ namespace ts.tscWatch {
332
332
path : `${ project } /out.js` ,
333
333
content : "var x = 10;\nvar y = 20;\n"
334
334
} ;
335
- verifyIncrementalWatchEmit ( {
335
+ verifyIncrementalWatchEmit ( ( ) => ( {
336
336
files : [ libFile , file1 , file2 , config ] ,
337
337
expectedInitialEmit : [
338
338
outFile ,
@@ -353,7 +353,7 @@ namespace ts.tscWatch {
353
353
}
354
354
] ,
355
355
expectedInitialErrors : emptyArray
356
- } ) ;
356
+ } ) ) ;
357
357
} ) ;
358
358
359
359
} ) ;
@@ -397,7 +397,7 @@ namespace ts.tscWatch {
397
397
398
398
describe ( "own file emit without errors" , ( ) => {
399
399
const modifiedFile2Content = file2 . content . replace ( "y" , "z" ) . replace ( "20" , "10" ) ;
400
- verifyIncrementalWatchEmit ( {
400
+ verifyIncrementalWatchEmit ( ( ) => ( {
401
401
files : [ libFile , file1 , file2 , config ] ,
402
402
expectedInitialEmit : [
403
403
file1Js ,
@@ -451,7 +451,7 @@ namespace ts.tscWatch {
451
451
}
452
452
] ,
453
453
expectedIncrementalErrors : emptyArray ,
454
- } ) ;
454
+ } ) ) ;
455
455
} ) ;
456
456
457
457
describe ( "own file emit with errors" , ( ) => {
@@ -479,7 +479,7 @@ namespace ts.tscWatch {
479
479
"file2.ts(1,14): error TS2322: Type '20' is not assignable to type 'string'.\n"
480
480
] ;
481
481
const modifiedFile1Content = file1 . content . replace ( "x = 10" , "z = 10" ) ;
482
- verifyIncrementalWatchEmit ( {
482
+ verifyIncrementalWatchEmit ( ( ) => ( {
483
483
files : [ libFile , file1 , fileModified , config ] ,
484
484
expectedInitialEmit : [
485
485
file1Js ,
@@ -541,7 +541,7 @@ namespace ts.tscWatch {
541
541
}
542
542
] ,
543
543
expectedIncrementalErrors : file2Errors ,
544
- } ) ;
544
+ } ) ) ;
545
545
546
546
it ( "verify that state is read correctly" , ( ) => {
547
547
const system = createWatchedSystem ( [ libFile , file1 , fileModified , config ] , { currentDirectory : project } ) ;
@@ -604,7 +604,7 @@ namespace ts.tscWatch {
604
604
});
605
605
` ;
606
606
}
607
- verifyIncrementalWatchEmit ( {
607
+ verifyIncrementalWatchEmit ( ( ) => ( {
608
608
files : [ libFile , file1 , file2 , config ] ,
609
609
expectedInitialEmit : [
610
610
outFile ,
@@ -625,7 +625,140 @@ namespace ts.tscWatch {
625
625
}
626
626
] ,
627
627
expectedInitialErrors : emptyArray
628
- } ) ;
628
+ } ) ) ;
629
+ } ) ;
630
+ } ) ;
631
+
632
+ describe ( "incremental with circular references" , ( ) => {
633
+ function getFileInfo ( content : string ) : BuilderState . FileInfo {
634
+ const signature = Harness . mockHash ( content ) ;
635
+ return { version : signature , signature } ;
636
+ }
637
+ const config : File = {
638
+ path : configFile . path ,
639
+ content : JSON . stringify ( {
640
+ compilerOptions : {
641
+ incremental : true ,
642
+ target : "es5" ,
643
+ module : "commonjs" ,
644
+ declaration : true ,
645
+ emitDeclarationOnly : true
646
+ }
647
+ } )
648
+ } ;
649
+ const aTs : File = {
650
+ path : `${ project } /a.ts` ,
651
+ content : `import { B } from "./b";
652
+ export interface A {
653
+ b: B;
654
+ }
655
+ `
656
+ } ;
657
+ const bTs : File = {
658
+ path : `${ project } /b.ts` ,
659
+ content : `import { C } from "./c";
660
+ export interface B {
661
+ b: C;
662
+ }
663
+ `
664
+ } ;
665
+ const cTs : File = {
666
+ path : `${ project } /c.ts` ,
667
+ content : `import { A } from "./a";
668
+ export interface C {
669
+ a: A;
670
+ }
671
+ `
672
+ } ;
673
+ const indexTs : File = {
674
+ path : `${ project } /index.ts` ,
675
+ content : `export { A } from "./a";
676
+ export { B } from "./b";
677
+ export { C } from "./c";
678
+ `
679
+ } ;
680
+
681
+ verifyIncrementalWatchEmit ( ( ) => {
682
+ const referencedMap : MapLike < string [ ] > = {
683
+ "./a.ts" : [ "./b.ts" ] ,
684
+ "./b.ts" : [ "./c.ts" ] ,
685
+ "./c.ts" : [ "./a.ts" ] ,
686
+ "./index.ts" : [ "./a.ts" , "./b.ts" , "./c.ts" ] ,
687
+ } ;
688
+ const initialProgram : ProgramBuildInfo = {
689
+ fileInfos : {
690
+ [ libFilePath ] : libFileInfo ,
691
+ "./c.ts" : getFileInfo ( cTs . content ) ,
692
+ "./b.ts" : getFileInfo ( bTs . content ) ,
693
+ "./a.ts" : getFileInfo ( aTs . content ) ,
694
+ "./index.ts" : getFileInfo ( indexTs . content )
695
+ } ,
696
+ options : {
697
+ incremental : true ,
698
+ target : ScriptTarget . ES5 ,
699
+ module : ModuleKind . CommonJS ,
700
+ declaration : true ,
701
+ emitDeclarationOnly : true ,
702
+ configFilePath : "./tsconfig.json"
703
+ } ,
704
+ referencedMap,
705
+ exportedModulesMap : referencedMap ,
706
+ semanticDiagnosticsPerFile : [
707
+ libFilePath ,
708
+ "./a.ts" ,
709
+ "./b.ts" ,
710
+ "./c.ts" ,
711
+ "./index.ts" ,
712
+ ]
713
+ } ;
714
+ const { fileInfos, ...rest } = initialProgram ;
715
+ const expectedADts : File = { path : `${ project } /a.d.ts` , content : aTs . content } ;
716
+ const expectedBDts : File = { path : `${ project } /b.d.ts` , content : bTs . content } ;
717
+ const expectedCDts : File = { path : `${ project } /c.d.ts` , content : cTs . content } ;
718
+ const expectedIndexDts : File = { path : `${ project } /index.d.ts` , content : indexTs . content } ;
719
+ const modifiedATsContent = aTs . content . replace ( "b: B;" , `b: B;
720
+ foo: any;` ) ;
721
+ return {
722
+ files : [ libFile , aTs , bTs , cTs , indexTs , config ] ,
723
+ expectedInitialEmit : [
724
+ expectedADts ,
725
+ expectedBDts ,
726
+ expectedCDts ,
727
+ expectedIndexDts ,
728
+ {
729
+ path : `${ project } /tsconfig.tsbuildinfo` ,
730
+ content : getBuildInfoText ( {
731
+ program : initialProgram ,
732
+ version
733
+ } )
734
+ }
735
+ ] ,
736
+ expectedInitialErrors : emptyArray ,
737
+ modifyFs : host => host . writeFile ( aTs . path , modifiedATsContent ) ,
738
+ expectedIncrementalEmit : [
739
+ { path : expectedADts . path , content : modifiedATsContent } ,
740
+ expectedBDts ,
741
+ expectedCDts ,
742
+ expectedIndexDts ,
743
+ {
744
+ path : `${ project } /tsconfig.tsbuildinfo` ,
745
+ content : getBuildInfoText ( {
746
+ program : {
747
+ fileInfos : {
748
+ [ libFilePath ] : libFileInfo ,
749
+ "./c.ts" : getFileInfo ( cTs . content ) ,
750
+ "./b.ts" : getFileInfo ( bTs . content ) ,
751
+ "./a.ts" : getFileInfo ( modifiedATsContent ) ,
752
+ "./index.ts" : getFileInfo ( indexTs . content )
753
+ } ,
754
+ ...rest
755
+ } ,
756
+ version
757
+ } )
758
+ }
759
+ ] ,
760
+ expectedIncrementalErrors : emptyArray
761
+ } ;
629
762
} ) ;
630
763
} ) ;
631
764
} ) ;
0 commit comments