Files
kjol/tools/tsgo/internal/vfs/osvfs/realpath_test.go
2026-07-09 16:50:43 -04:00

153 lines
4.4 KiB
Go

package osvfs
import (
"os"
"os/exec"
"path/filepath"
"testing"
"github.com/microsoft/typescript-go/internal/tspath"
"gotest.tools/v3/assert"
)
func TestSymlinkRealpath(t *testing.T) {
t.Parallel()
targetFile, linkFile := setupSymlinks(t)
gotContents, err := os.ReadFile(linkFile)
assert.NilError(t, err)
assert.Equal(t, string(gotContents), "hello")
fs := FS()
targetRealpath := fs.Realpath(tspath.NormalizePath(targetFile))
linkRealpath := fs.Realpath(tspath.NormalizePath(linkFile))
if targetRealpath != linkRealpath {
t.Errorf("expected realpath of target and link to be equal, got %q and %q", targetRealpath, linkRealpath)
cmd := exec.Command("node", "-e", `console.log({ native: fs.realpathSync.native(process.argv[1]), node: fs.realpathSync(process.argv[1]) })`, linkFile)
out, err := cmd.CombinedOutput()
assert.NilError(t, err)
t.Logf("node: %s", out)
}
}
func setupSymlinks(tb testing.TB) (targetFile, linkFile string) {
tb.Helper()
tmp := tb.TempDir()
target := filepath.Join(tmp, "target")
targetFile = filepath.Join(target, "file")
link := filepath.Join(tmp, "link")
linkFile = filepath.Join(link, "file")
assert.NilError(tb, os.MkdirAll(target, 0o777))
assert.NilError(tb, os.WriteFile(targetFile, []byte("hello"), 0o666))
mklink(tb, target, link, true)
return targetFile, linkFile
}
func BenchmarkRealpath(b *testing.B) {
targetFile, linkFile := setupSymlinks(b)
fs := FS()
normalizedTargetFile := tspath.NormalizePath(targetFile)
normalizedLinkFile := tspath.NormalizePath(linkFile)
b.Run("target", func(b *testing.B) {
b.ReportAllocs()
for b.Loop() {
fs.Realpath(normalizedTargetFile)
}
})
b.Run("link", func(b *testing.B) {
b.ReportAllocs()
for b.Loop() {
fs.Realpath(normalizedLinkFile)
}
})
// Simulate a deep node_modules path to show scaling with depth.
deepDir := b.TempDir()
for _, seg := range []string{"project", "node_modules", "@scope", "package", "node_modules", "dep", "lib", "dist", "esm", "internal", "utils"} {
deepDir = filepath.Join(deepDir, seg)
}
assert.NilError(b, os.MkdirAll(deepDir, 0o777))
deepFile := filepath.Join(deepDir, "index.js")
assert.NilError(b, os.WriteFile(deepFile, []byte("module.exports = {}"), 0o666))
normalizedDeepFile := tspath.NormalizePath(deepFile)
b.Run("deep", func(b *testing.B) {
b.ReportAllocs()
for b.Loop() {
fs.Realpath(normalizedDeepFile)
}
})
b.Run("deep_evalSymlinks", func(b *testing.B) {
b.ReportAllocs()
deepNative := filepath.FromSlash(normalizedDeepFile)
for b.Loop() {
filepath.EvalSymlinks(deepNative) //nolint:errcheck
}
})
}
func TestGetAccessibleEntries(t *testing.T) {
t.Parallel()
tmp := t.TempDir()
target := filepath.Join(tmp, "target")
link := filepath.Join(tmp, "link")
assert.NilError(t, os.MkdirAll(target, 0o777))
assert.NilError(t, os.MkdirAll(link, 0o777))
targetFile1 := filepath.Join(target, "file1")
targetFile2 := filepath.Join(target, "file2")
assert.NilError(t, os.WriteFile(targetFile1, []byte("hello"), 0o666))
assert.NilError(t, os.WriteFile(targetFile2, []byte("world"), 0o666))
targetDir1 := filepath.Join(target, "dir1")
targetDir2 := filepath.Join(target, "dir2")
assert.NilError(t, os.MkdirAll(targetDir1, 0o777))
assert.NilError(t, os.MkdirAll(targetDir2, 0o777))
mklink(t, targetFile1, filepath.Join(link, "file1"), false)
mklink(t, targetFile2, filepath.Join(link, "file2"), false)
mklink(t, targetDir1, filepath.Join(link, "dir1"), true)
mklink(t, targetDir2, filepath.Join(link, "dir2"), true)
fs := FS()
entries := fs.GetAccessibleEntries(tspath.NormalizePath(link))
assert.DeepEqual(t, entries.Directories, []string{"dir1", "dir2"})
assert.DeepEqual(t, entries.Files, []string{"file1", "file2"})
assert.Check(t, entries.Symlinks != nil, "expected Symlinks to be set for directory with symlinks")
assert.Equal(t, len(entries.Symlinks), 4)
for _, name := range []string{"file1", "file2", "dir1", "dir2"} {
_, ok := entries.Symlinks[name]
assert.Check(t, ok, "expected %q to be in Symlinks", name)
}
// Non-symlink directory should have empty Symlinks.
entries = fs.GetAccessibleEntries(tspath.NormalizePath(target))
assert.DeepEqual(t, entries.Directories, []string{"dir1", "dir2"})
assert.DeepEqual(t, entries.Files, []string{"file1", "file2"})
assert.Check(t, entries.Symlinks != nil, "expected Symlinks to be non-nil for directory without symlinks")
assert.Equal(t, len(entries.Symlinks), 0)
}