@@ -3,9 +3,7 @@ package tsctests
33import (
44 "fmt"
55 "io"
6- "io/fs"
76 "maps"
8- "slices"
97 "strconv"
108 "strings"
119 "sync"
@@ -14,8 +12,10 @@ import (
1412 "github.com/microsoft/typescript-go/internal/collections"
1513 "github.com/microsoft/typescript-go/internal/compiler"
1614 "github.com/microsoft/typescript-go/internal/core"
15+ "github.com/microsoft/typescript-go/internal/execute"
1716 "github.com/microsoft/typescript-go/internal/execute/incremental"
1817 "github.com/microsoft/typescript-go/internal/execute/tsc"
18+ "github.com/microsoft/typescript-go/internal/testutil/fsbaselineutil"
1919 "github.com/microsoft/typescript-go/internal/testutil/harnessutil"
2020 "github.com/microsoft/typescript-go/internal/testutil/stringtestutil"
2121 "github.com/microsoft/typescript-go/internal/tsoptions"
@@ -95,6 +95,20 @@ func NewTscSystem(files FileMap, useCaseSensitiveFileNames bool, cwd string) *Te
9595 }
9696}
9797
98+ func GetFileMapWithBuild (files FileMap , commandLineArgs []string ) FileMap {
99+ sys := newTestSys (& tscInput {
100+ files : maps .Clone (files ),
101+ }, false )
102+ execute .CommandLine (sys , commandLineArgs , sys )
103+ sys .fs .writtenFiles .Range (func (key string ) bool {
104+ if text , ok := sys .fsFromFileMap ().ReadFile (key ); ok {
105+ files [key ] = text
106+ }
107+ return true
108+ })
109+ return files
110+ }
111+
98112func newTestSys (tscInput * tscInput , forIncrementalCorrectness bool ) * TestSys {
99113 cwd := tscInput .cwd
100114 if cwd == "" {
@@ -114,6 +128,11 @@ func newTestSys(tscInput *tscInput, forIncrementalCorrectness bool) *TestSys {
114128 }, currentWrite )
115129 sys .env = tscInput .env
116130 sys .forIncrementalCorrectness = forIncrementalCorrectness
131+ sys .fsDiffer = & fsbaselineutil.FSDiffer {
132+ FS : sys .fs .FS .(iovfs.FsWithSys ),
133+ DefaultLibs : func () * collections.SyncSet [string ] { return sys .fs .defaultLibs },
134+ WrittenFiles : & sys .fs .writtenFiles ,
135+ }
117136
118137 // Ensure the default library file is present
119138 sys .ensureLibPathExists ("lib.d.ts" )
@@ -126,24 +145,12 @@ func newTestSys(tscInput *tscInput, forIncrementalCorrectness bool) *TestSys {
126145 return sys
127146}
128147
129- type diffEntry struct {
130- content string
131- mTime time.Time
132- isWritten bool
133- symlinkTarget string
134- }
135-
136- type snapshot struct {
137- snap map [string ]* diffEntry
138- defaultLibs * collections.SyncSet [string ]
139- }
140-
141148type TestSys struct {
142149 currentWrite * strings.Builder
143150 programBaselines strings.Builder
144151 programIncludeBaselines strings.Builder
145152 tracer * harnessutil.TracerForBaselining
146- serializedDiff * snapshot
153+ fsDiffer * fsbaselineutil. FSDiffer
147154 forIncrementalCorrectness bool
148155
149156 fs * testFs
@@ -171,11 +178,11 @@ func (s *TestSys) FS() vfs.FS {
171178}
172179
173180func (s * TestSys ) fsFromFileMap () iovfs.FsWithSys {
174- return s .fs .FS .(iovfs. FsWithSys )
181+ return s .fsDiffer .FS
175182}
176183
177184func (s * TestSys ) mapFs () * vfstest.MapFS {
178- return s .fsFromFileMap (). FSys ().( * vfstest. MapFS )
185+ return s .fsDiffer . MapFs ( )
179186}
180187
181188func (s * TestSys ) ensureLibPathExists (path string ) {
@@ -223,8 +230,8 @@ func (s *TestSys) OnEmittedFiles(result *compiler.EmitResult, mTimesCache *colle
223230 if result != nil {
224231 for _ , file := range result .EmittedFiles {
225232 modTime := s .mapFs ().GetModTime (file )
226- if s . serializedDiff != nil {
227- if diff , ok := s . serializedDiff .snap [file ]; ok && diff .mTime .Equal (modTime ) {
233+ if serializedDiff := s . fsDiffer . SerializedDiff (); serializedDiff != nil {
234+ if diff , ok := serializedDiff .Snap [file ]; ok && diff .MTime .Equal (modTime ) {
228235 // Even though written, timestamp was reverted
229236 continue
230237 }
@@ -500,83 +507,7 @@ func (s *TestSys) clearOutput() {
500507}
501508
502509func (s * TestSys ) baselineFSwithDiff (baseline io.Writer ) {
503- // todo: baselines the entire fs, possibly doesn't correctly diff all cases of emitted files, since emit isn't fully implemented and doesn't always emit the same way as strada
504- snap := map [string ]* diffEntry {}
505-
506- diffs := map [string ]string {}
507-
508- for path , file := range s .mapFs ().Entries () {
509- if file .Mode & fs .ModeSymlink != 0 {
510- target , ok := s .mapFs ().GetTargetOfSymlink (path )
511- if ! ok {
512- panic ("Failed to resolve symlink target: " + path )
513- }
514- newEntry := & diffEntry {symlinkTarget : target }
515- snap [path ] = newEntry
516- s .addFsEntryDiff (diffs , newEntry , path )
517- continue
518- } else if file .Mode .IsRegular () {
519- newEntry := & diffEntry {content : string (file .Data ), mTime : file .ModTime , isWritten : s .fs .writtenFiles .Has (path )}
520- snap [path ] = newEntry
521- s .addFsEntryDiff (diffs , newEntry , path )
522- }
523- }
524- if s .serializedDiff != nil {
525- for path := range s .serializedDiff .snap {
526- if fileInfo := s .mapFs ().GetFileInfo (path ); fileInfo == nil {
527- // report deleted
528- s .addFsEntryDiff (diffs , nil , path )
529- }
530- }
531- }
532- var defaultLibs collections.SyncSet [string ]
533- if s .fs .defaultLibs != nil {
534- s .fs .defaultLibs .Range (func (libPath string ) bool {
535- defaultLibs .Add (libPath )
536- return true
537- })
538- }
539- s .serializedDiff = & snapshot {
540- snap : snap ,
541- defaultLibs : & defaultLibs ,
542- }
543- diffKeys := slices .Collect (maps .Keys (diffs ))
544- slices .Sort (diffKeys )
545- for _ , path := range diffKeys {
546- fmt .Fprint (baseline , "//// [" + path + "] " , diffs [path ], "\n " )
547- }
548- fmt .Fprintln (baseline )
549- s .fs .writtenFiles = collections.SyncSet [string ]{} // Reset written files after baseline
550- }
551-
552- func (s * TestSys ) addFsEntryDiff (diffs map [string ]string , newDirContent * diffEntry , path string ) {
553- var oldDirContent * diffEntry
554- var defaultLibs * collections.SyncSet [string ]
555- if s .serializedDiff != nil {
556- oldDirContent = s .serializedDiff .snap [path ]
557- defaultLibs = s .serializedDiff .defaultLibs
558- }
559- // todo handle more cases of fs changes
560- if oldDirContent == nil {
561- if s .fs .defaultLibs == nil || ! s .fs .defaultLibs .Has (path ) {
562- if newDirContent .symlinkTarget != "" {
563- diffs [path ] = "-> " + newDirContent .symlinkTarget + " *new*"
564- } else {
565- diffs [path ] = "*new* \n " + newDirContent .content
566- }
567- }
568- } else if newDirContent == nil {
569- diffs [path ] = "*deleted*"
570- } else if newDirContent .content != oldDirContent .content {
571- diffs [path ] = "*modified* \n " + newDirContent .content
572- } else if newDirContent .isWritten {
573- diffs [path ] = "*rewrite with same content*"
574- } else if newDirContent .mTime != oldDirContent .mTime {
575- diffs [path ] = "*mTime changed*"
576- } else if defaultLibs != nil && defaultLibs .Has (path ) && s .fs .defaultLibs != nil && ! s .fs .defaultLibs .Has (path ) {
577- // Lib file that was read
578- diffs [path ] = "*Lib*\n " + newDirContent .content
579- }
510+ s .fsDiffer .BaselineFSwithDiff (baseline )
580511}
581512
582513func (s * TestSys ) writeFileNoError (path string , content string , writeByteOrderMark bool ) {
0 commit comments