Skip to content

Commit 53a9bac

Browse files
committed
Use fake lib contents to make it deterministic for baselining as well as for better readability of baselines
1 parent fd9aa38 commit 53a9bac

File tree

43 files changed

+1333
-3014
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1333
-3014
lines changed

internal/execute/testfs_test.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package execute_test
2+
3+
import (
4+
"github.com/microsoft/typescript-go/internal/collections"
5+
"github.com/microsoft/typescript-go/internal/vfs"
6+
)
7+
8+
type testFsTrackingLibs struct {
9+
fs vfs.FS
10+
defaultLibs *collections.Set[string]
11+
}
12+
13+
var _ vfs.FS = (*testFsTrackingLibs)(nil)
14+
15+
func NewFSTrackingLibs(fs vfs.FS) *testFsTrackingLibs {
16+
return &testFsTrackingLibs{
17+
fs: fs,
18+
}
19+
}
20+
21+
func (f *testFsTrackingLibs) FS() vfs.FS {
22+
return f.fs
23+
}
24+
25+
func (f *testFsTrackingLibs) removeIgnoreLibPath(path string) {
26+
if f.defaultLibs != nil && f.defaultLibs.Has(path) {
27+
f.defaultLibs.Delete(path)
28+
}
29+
}
30+
31+
func (f *testFsTrackingLibs) UseCaseSensitiveFileNames() bool {
32+
return f.fs.UseCaseSensitiveFileNames()
33+
}
34+
35+
// FileExists returns true if the file exists.
36+
func (f *testFsTrackingLibs) FileExists(path string) bool {
37+
return f.fs.FileExists(path)
38+
}
39+
40+
// ReadFile reads the file specified by path and returns the content.
41+
// If the file fails to be read, ok will be false.
42+
func (f *testFsTrackingLibs) ReadFile(path string) (contents string, ok bool) {
43+
f.removeIgnoreLibPath(path)
44+
return f.fs.ReadFile(path)
45+
}
46+
47+
func (f *testFsTrackingLibs) WriteFile(path string, data string, writeByteOrderMark bool) error {
48+
f.removeIgnoreLibPath(path)
49+
return f.fs.WriteFile(path, data, writeByteOrderMark)
50+
}
51+
52+
// Removes `path` and all its contents. Will return the first error it encounters.
53+
func (f *testFsTrackingLibs) Remove(path string) error {
54+
f.removeIgnoreLibPath(path)
55+
return f.fs.Remove(path)
56+
}
57+
58+
// DirectoryExists returns true if the path is a directory.
59+
func (f *testFsTrackingLibs) DirectoryExists(path string) bool {
60+
return f.fs.DirectoryExists(path)
61+
}
62+
63+
// GetAccessibleEntries returns the files/directories in the specified directory.
64+
// If any entry is a symlink, it will be followed.
65+
func (f *testFsTrackingLibs) GetAccessibleEntries(path string) vfs.Entries {
66+
return f.fs.GetAccessibleEntries(path)
67+
}
68+
69+
func (f *testFsTrackingLibs) Stat(path string) vfs.FileInfo {
70+
return f.fs.Stat(path)
71+
}
72+
73+
// WalkDir walks the file tree rooted at root, calling walkFn for each file or directory in the tree.
74+
// It is has the same behavior as [fs.WalkDir], but with paths as [string].
75+
func (f *testFsTrackingLibs) WalkDir(root string, walkFn vfs.WalkDirFunc) error {
76+
return f.fs.WalkDir(root, walkFn)
77+
}
78+
79+
// Realpath returns the "real path" of the specified path,
80+
// following symlinks and correcting filename casing.
81+
func (f *testFsTrackingLibs) Realpath(path string) string {
82+
return f.fs.Realpath(path)
83+
}

internal/execute/testsys_test.go

Lines changed: 110 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,48 +10,90 @@ import (
1010
"strings"
1111
"time"
1212

13-
"github.com/microsoft/typescript-go/internal/bundled"
13+
"github.com/microsoft/typescript-go/internal/collections"
1414
"github.com/microsoft/typescript-go/internal/testutil/incrementaltestutil"
15+
"github.com/microsoft/typescript-go/internal/tsoptions"
1516
"github.com/microsoft/typescript-go/internal/vfs"
1617
"github.com/microsoft/typescript-go/internal/vfs/vfstest"
1718
)
1819

19-
type FileMap map[string]string
20+
type FileMap map[string]any
21+
22+
var (
23+
tscLibPath = "/home/src/tslibs/TS/Lib"
24+
tscDefaultLibContent = `/// <reference no-default-lib="true"/>
25+
interface Boolean {}
26+
interface Function {}
27+
interface CallableFunction {}
28+
interface NewableFunction {}
29+
interface IArguments {}
30+
interface Number { toExponential: any; }
31+
interface Object {}
32+
interface RegExp {}
33+
interface String { charAt: any; }
34+
interface Array<T> { length: number; [n: number]: T; }
35+
interface ReadonlyArray<T> {}
36+
interface SymbolConstructor {
37+
(desc?: string | number): symbol;
38+
for(name: string): symbol;
39+
readonly toStringTag: symbol;
40+
}
41+
declare var Symbol: SymbolConstructor;
42+
interface Symbol {
43+
readonly [Symbol.toStringTag]: string;
44+
}
45+
declare const console: { log(msg: any): void; };`
46+
)
2047

2148
func newTestSys(fileOrFolderList FileMap, cwd string) *testSys {
2249
if cwd == "" {
2350
cwd = "/home/src/workspaces/project"
2451
}
25-
return &testSys{
26-
fs: incrementaltestutil.NewFsHandlingBuildInfo(bundled.WrapFS(vfstest.FromMap(fileOrFolderList, true /*useCaseSensitiveFileNames*/))),
27-
defaultLibraryPath: bundled.LibPath(),
52+
sys := &testSys{
53+
fs: NewFSTrackingLibs(incrementaltestutil.NewFsHandlingBuildInfo(vfstest.FromMap(fileOrFolderList, true /*useCaseSensitiveFileNames*/))),
54+
defaultLibraryPath: tscLibPath,
2855
cwd: cwd,
2956
files: slices.Collect(maps.Keys(fileOrFolderList)),
3057
output: []string{},
3158
currentWrite: &strings.Builder{},
3259
start: time.Now(),
3360
}
61+
62+
// Ensure the default library file is present
63+
sys.ensureLibPathExists("lib.d.ts")
64+
for _, libFile := range tsoptions.TargetToLibMap() {
65+
sys.ensureLibPathExists(libFile)
66+
}
67+
for libFile := range tsoptions.LibFilesSet.Keys() {
68+
sys.ensureLibPathExists(libFile)
69+
}
70+
return sys
71+
}
72+
73+
type diffEntry struct {
74+
content string
75+
fileInfo fs.FileInfo
76+
}
77+
78+
type snapshot struct {
79+
snap map[string]*diffEntry
80+
defaultLibs *collections.Set[string]
3481
}
3582

3683
type testSys struct {
3784
// todo: original has write to output as a string[] because the separations are needed for baselining
3885
output []string
3986
currentWrite *strings.Builder
40-
serializedDiff map[string]string
87+
serializedDiff *snapshot
4188

42-
fs *incrementaltestutil.FsHandlingBuildInfo
89+
fs *testFsTrackingLibs
4390
defaultLibraryPath string
4491
cwd string
4592
files []string
4693

4794
start time.Time
4895
}
4996

50-
func (s *testSys) IsTestDone() bool {
51-
// todo: test is done if there are no edits left. Edits are not yet implemented
52-
return true
53-
}
54-
5597
func (s *testSys) Now() time.Time {
5698
// todo: make a "test time" structure
5799
return time.Now()
@@ -66,7 +108,18 @@ func (s *testSys) FS() vfs.FS {
66108
}
67109

68110
func (s *testSys) TestFS() *incrementaltestutil.FsHandlingBuildInfo {
69-
return s.fs
111+
return s.fs.fs.(*incrementaltestutil.FsHandlingBuildInfo)
112+
}
113+
114+
func (s *testSys) ensureLibPathExists(path string) {
115+
path = tscLibPath + "/" + path
116+
if _, ok := s.TestFS().ReadFile(path); !ok {
117+
if s.fs.defaultLibs == nil {
118+
s.fs.defaultLibs = collections.NewSetWithSizeHint[string](tsoptions.LibFilesSet.Len() + len(tsoptions.TargetToLibMap()) + 1)
119+
}
120+
s.fs.defaultLibs.Add(path)
121+
s.TestFS().WriteFile(path, tscDefaultLibContent, false)
122+
}
70123
}
71124

72125
func (s *testSys) DefaultLibraryPath() string {
@@ -115,7 +168,7 @@ func (s *testSys) baselineOutput(baseline io.Writer) {
115168

116169
func (s *testSys) baselineFSwithDiff(baseline io.Writer) {
117170
// 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
118-
snap := map[string]string{}
171+
snap := map[string]*diffEntry{}
119172

120173
err := s.FS().WalkDir("/", func(path string, d vfs.DirEntry, e error) error {
121174
if e != nil {
@@ -130,37 +183,62 @@ func (s *testSys) baselineFSwithDiff(baseline io.Writer) {
130183
if !ok {
131184
return nil
132185
}
133-
snap[path] = newContents
134-
reportFSEntryDiff(baseline, s.serializedDiff[path], newContents, path)
186+
fileInfo, err := d.Info()
187+
if err != nil {
188+
return nil
189+
}
190+
newEntry := &diffEntry{content: newContents, fileInfo: fileInfo}
191+
snap[path] = newEntry
192+
s.reportFSEntryDiff(baseline, newEntry, path)
135193

136194
return nil
137195
})
138196
if err != nil && !errors.Is(err, fs.ErrNotExist) {
139197
panic("walkdir error during diff: " + err.Error())
140198
}
141-
for path, oldDirContents := range s.serializedDiff {
142-
if s.FS().FileExists(path) {
143-
_, ok := s.FS().ReadFile(path)
144-
if !ok {
145-
// report deleted
146-
reportFSEntryDiff(baseline, oldDirContents, "", path)
199+
if s.serializedDiff != nil {
200+
for path := range s.serializedDiff.snap {
201+
if s.FS().FileExists(path) {
202+
_, ok := s.TestFS().FS().ReadFile(path)
203+
if !ok {
204+
// report deleted
205+
s.reportFSEntryDiff(baseline, nil, path)
206+
}
147207
}
148208
}
149209
}
150-
s.serializedDiff = snap
210+
var defaultLibs *collections.Set[string]
211+
if s.fs.defaultLibs != nil {
212+
defaultLibs = s.fs.defaultLibs.Clone()
213+
}
214+
s.serializedDiff = &snapshot{
215+
snap: snap,
216+
defaultLibs: defaultLibs,
217+
}
151218
fmt.Fprintln(baseline)
152219
}
153220

154-
func reportFSEntryDiff(baseline io.Writer, oldDirContent string, newDirContent string, path string) {
221+
func (s *testSys) reportFSEntryDiff(baseline io.Writer, newDirContent *diffEntry, path string) {
222+
var oldDirContent *diffEntry
223+
var defaultLibs *collections.Set[string]
224+
if s.serializedDiff != nil {
225+
oldDirContent = s.serializedDiff.snap[path]
226+
defaultLibs = s.serializedDiff.defaultLibs
227+
}
155228
// todo handle more cases of fs changes
156-
if oldDirContent == "" {
157-
fmt.Fprint(baseline, "//// [", path, "] new file\n", newDirContent, "\n")
158-
} else if newDirContent == "" {
159-
fmt.Fprint(baseline, "//// [", path, "] deleted\n")
160-
} else if newDirContent == oldDirContent {
161-
fmt.Fprint(baseline, "//// [", path, "] no change\n")
162-
} else {
163-
fmt.Fprint(baseline, "//// [", path, "] modified. new content:\n", newDirContent, "\n")
229+
if oldDirContent == nil {
230+
if s.fs.defaultLibs == nil || !s.fs.defaultLibs.Has(path) {
231+
fmt.Fprint(baseline, "//// [", path, "] *new* \n", newDirContent.content, "\n")
232+
}
233+
} else if newDirContent == nil {
234+
fmt.Fprint(baseline, "//// [", path, "] *deleted*\n")
235+
} else if newDirContent.content != oldDirContent.content {
236+
fmt.Fprint(baseline, "//// [", path, "] *modified* \n", newDirContent, "\n")
237+
} else if newDirContent.fileInfo.ModTime() != oldDirContent.fileInfo.ModTime() {
238+
fmt.Fprint(baseline, "//// [", path, "] *modified time*\n")
239+
} else if defaultLibs != nil && defaultLibs.Has(path) && s.fs.defaultLibs != nil && !s.fs.defaultLibs.Has(path) {
240+
// Lib file that was read
241+
fmt.Fprint(baseline, "//// [", path, "] *Lib*\n", newDirContent.content, "\n")
164242
}
165243
}
166244

internal/execute/tsc_test.go

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,6 @@ import (
88

99
func TestTsc(t *testing.T) {
1010
t.Parallel()
11-
if !bundled.Embedded {
12-
// Without embedding, we'd need to read all of the lib files out from disk into the MapFS.
13-
// Just skip this for now.
14-
t.Skip("bundled files are not embedded")
15-
}
16-
1711
testCases := []*tscInput{
1812
{
1913
subScenario: "show help with ExitStatus.DiagnosticsPresent_OutputsSkipped",
@@ -124,12 +118,6 @@ func TestTsc(t *testing.T) {
124118

125119
func TestNoEmit(t *testing.T) {
126120
t.Parallel()
127-
if !bundled.Embedded {
128-
// Without embedding, we'd need to read all of the lib files out from disk into the MapFS.
129-
// Just skip this for now.
130-
t.Skip("bundled files are not embedded")
131-
}
132-
133121
(&tscInput{
134122
subScenario: "when project has strict true",
135123
sys: newTestSys(FileMap{
@@ -147,12 +135,6 @@ func TestNoEmit(t *testing.T) {
147135

148136
func TestExtends(t *testing.T) {
149137
t.Parallel()
150-
if !bundled.Embedded {
151-
// Without embedding, we'd need to read all of the lib files out from disk into the MapFS.
152-
// Just skip this for now.
153-
t.Skip("bundled files are not embedded")
154-
}
155-
156138
extendsSysFiles := FileMap{
157139
"/home/src/projects/configs/first/tsconfig.json": `{
158140
"extends": "../second/tsconfig.json",

internal/execute/tscincremental_test.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,10 @@ package execute_test
22

33
import (
44
"testing"
5-
6-
"github.com/microsoft/typescript-go/internal/bundled"
75
)
86

97
func TestIncremental(t *testing.T) {
108
t.Parallel()
11-
if !bundled.Embedded {
12-
// Without embedding, we'd need to read all of the lib files out from disk into the MapFS.
13-
// Just skip this for now.
14-
t.Skip("bundled files are not embedded")
15-
}
16-
179
testCases := []*tscInput{
1810
{
1911
subScenario: "serializing error chain",
@@ -60,6 +52,9 @@ func TestIncremental(t *testing.T) {
6052
const wrapper = () => Messageable();
6153
type MessageablePerson = InstanceType<ReturnType<typeof wrapper>>;
6254
export default MessageablePerson;`,
55+
tscLibPath + "/lib.d.ts": tscDefaultLibContent + `
56+
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
57+
type InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any;`,
6358
}, "/home/src/workspaces/project"),
6459
commandLineArgs: []string{"--incremental"},
6560
// edits: [
@@ -94,6 +89,9 @@ func TestIncremental(t *testing.T) {
9489
const wrapper = () => Messageable();
9590
type MessageablePerson = InstanceType<ReturnType<typeof wrapper>>;
9691
export default MessageablePerson;`,
92+
tscLibPath + "/lib.d.ts": tscDefaultLibContent + `
93+
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
94+
type InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any;`,
9795
}, "/home/src/workspaces/project"),
9896
commandLineArgs: []string{"--incremental"},
9997
// edits: [

internal/execute/tscprojectreferences_test.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,10 @@ package execute_test
22

33
import (
44
"testing"
5-
6-
"github.com/microsoft/typescript-go/internal/bundled"
75
)
86

97
func TestProjectReferences(t *testing.T) {
108
t.Parallel()
11-
if !bundled.Embedded {
12-
// Without embedding, we'd need to read all of the lib files out from disk into the MapFS.
13-
// Just skip this for now.
14-
t.Skip("bundled files are not embedded")
15-
}
16-
179
cases := []tscInput{
1810
// !!! sheetal todo verifyCompilerOptions - check for noEmit
1911
{

0 commit comments

Comments
 (0)