vendor tsgo
This commit is contained in:
291
tools/tsgo/internal/symlinks/knownsymlinks_test.go
Normal file
291
tools/tsgo/internal/symlinks/knownsymlinks_test.go
Normal file
@@ -0,0 +1,291 @@
|
||||
package symlinks
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/ast"
|
||||
"github.com/microsoft/typescript-go/internal/core"
|
||||
"github.com/microsoft/typescript-go/internal/module"
|
||||
"github.com/microsoft/typescript-go/internal/tspath"
|
||||
)
|
||||
|
||||
func TestNewKnownSymlink(t *testing.T) {
|
||||
t.Parallel()
|
||||
cache := NewKnownSymlink("/test/dir", true)
|
||||
if cache == nil {
|
||||
t.Fatal("Expected non-nil cache")
|
||||
}
|
||||
if cache.cwd != "/test/dir" {
|
||||
t.Errorf("Expected cwd to be '/test/dir', got '%s'", cache.cwd)
|
||||
}
|
||||
if !cache.useCaseSensitiveFileNames {
|
||||
t.Error("Expected useCaseSensitiveFileNames to be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetDirectory(t *testing.T) {
|
||||
t.Parallel()
|
||||
cache := NewKnownSymlink("/test/dir", true)
|
||||
symlinkPath := tspath.ToPath("/test/symlink", "/test/dir", true).EnsureTrailingDirectorySeparator()
|
||||
realDirectory := &KnownDirectoryLink{
|
||||
Real: "/real/path/",
|
||||
RealPath: tspath.ToPath("/real/path", "/test/dir", true).EnsureTrailingDirectorySeparator(),
|
||||
}
|
||||
|
||||
cache.SetDirectory("/test/symlink", symlinkPath, realDirectory)
|
||||
|
||||
// Check that directory was stored
|
||||
stored, ok := cache.Directories().Load(symlinkPath)
|
||||
if !ok {
|
||||
t.Fatal("Expected directory to be stored")
|
||||
}
|
||||
if stored.Real != realDirectory.Real {
|
||||
t.Errorf("Expected Real to be '%s', got '%s'", realDirectory.Real, stored.Real)
|
||||
}
|
||||
if stored.RealPath != realDirectory.RealPath {
|
||||
t.Errorf("Expected RealPath to be '%s', got '%s'", realDirectory.RealPath, stored.RealPath)
|
||||
}
|
||||
|
||||
// Check that realpath mapping was created
|
||||
set, ok := cache.DirectoriesByRealpath().Load(realDirectory.RealPath)
|
||||
if !ok || set.Size() == 0 {
|
||||
t.Fatal("Expected realpath mapping to be created")
|
||||
}
|
||||
if !set.Has("/test/symlink") {
|
||||
t.Error("Expected symlink '/test/symlink' to be in set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetFile(t *testing.T) {
|
||||
t.Parallel()
|
||||
cache := NewKnownSymlink("/test/dir", true)
|
||||
symlink := "/test/symlink/file.ts"
|
||||
symlinkPath := tspath.ToPath(symlink, "/test/dir", true)
|
||||
realpath := "/real/path/file.ts"
|
||||
|
||||
cache.SetFile(symlink, symlinkPath, realpath)
|
||||
|
||||
stored, ok := cache.Files().Load(symlinkPath)
|
||||
if !ok {
|
||||
t.Fatal("Expected file to be stored")
|
||||
}
|
||||
if stored != realpath {
|
||||
t.Errorf("Expected realpath to be '%s', got '%s'", realpath, stored)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessResolution(t *testing.T) {
|
||||
t.Parallel()
|
||||
cache := NewKnownSymlink("/test/dir", true)
|
||||
|
||||
// Test with empty paths
|
||||
cache.ProcessResolution("", "")
|
||||
cache.ProcessResolution("original", "")
|
||||
cache.ProcessResolution("", "resolved")
|
||||
|
||||
// Test with valid paths
|
||||
originalPath := "/test/original/file.ts"
|
||||
resolvedPath := "/test/resolved/file.ts"
|
||||
cache.ProcessResolution(originalPath, resolvedPath)
|
||||
|
||||
// Check that file was stored
|
||||
symlinkPath := tspath.ToPath(originalPath, "/test/dir", true)
|
||||
stored, ok := cache.Files().Load(symlinkPath)
|
||||
if !ok {
|
||||
t.Fatal("Expected file to be stored")
|
||||
}
|
||||
if stored != resolvedPath {
|
||||
t.Errorf("Expected resolved path to be '%s', got '%s'", resolvedPath, stored)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGuessDirectorySymlink(t *testing.T) {
|
||||
t.Parallel()
|
||||
cache := NewKnownSymlink("/test/dir", true)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
a string
|
||||
b string
|
||||
cwd string
|
||||
expected [2]string // [commonResolved, commonOriginal]
|
||||
}{
|
||||
{
|
||||
name: "identical paths",
|
||||
a: "/test/path/file.ts",
|
||||
b: "/test/path/file.ts",
|
||||
cwd: "/test/dir",
|
||||
expected: [2]string{"/", "/"},
|
||||
},
|
||||
{
|
||||
name: "different files same directory",
|
||||
a: "/test/path/file1.ts",
|
||||
b: "/test/path/file2.ts",
|
||||
cwd: "/test/dir",
|
||||
expected: [2]string{"", ""},
|
||||
},
|
||||
{
|
||||
name: "different directories",
|
||||
a: "/test/path1/file.ts",
|
||||
b: "/test/path2/file.ts",
|
||||
cwd: "/test/dir",
|
||||
expected: [2]string{"/test/path1", "/test/path2"},
|
||||
},
|
||||
{
|
||||
name: "node_modules paths",
|
||||
a: "/test/node_modules/pkg/file.ts",
|
||||
b: "/test/node_modules/pkg/file.ts",
|
||||
cwd: "/test/dir",
|
||||
expected: [2]string{"/test/node_modules/pkg", "/test/node_modules/pkg"},
|
||||
},
|
||||
{
|
||||
name: "scoped package paths",
|
||||
a: "/test/node_modules/@scope/pkg/file.ts",
|
||||
b: "/test/node_modules/@scope/pkg/file.ts",
|
||||
cwd: "/test/dir",
|
||||
expected: [2]string{"/test/node_modules/@scope/pkg", "/test/node_modules/@scope/pkg"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
commonResolved, commonOriginal := cache.guessDirectorySymlink(tt.a, tt.b, tt.cwd)
|
||||
if commonResolved != tt.expected[0] {
|
||||
t.Errorf("Expected commonResolved to be '%s', got '%s'", tt.expected[0], commonResolved)
|
||||
}
|
||||
if commonOriginal != tt.expected[1] {
|
||||
t.Errorf("Expected commonOriginal to be '%s', got '%s'", tt.expected[1], commonOriginal)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsNodeModulesOrScopedPackageDirectory(t *testing.T) {
|
||||
t.Parallel()
|
||||
cache := NewKnownSymlink("/test/dir", true)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
dir string
|
||||
expected bool
|
||||
}{
|
||||
{"node_modules", "node_modules", true},
|
||||
{"scoped package", "@scope", true},
|
||||
{"regular directory", "src", false},
|
||||
{"empty string", "", false},
|
||||
{"case insensitive node_modules", "NODE_MODULES", false}, // The function is case sensitive
|
||||
{"case insensitive scoped", "@SCOPE", true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
result := cache.isNodeModulesOrScopedPackageDirectory(tt.dir)
|
||||
if result != tt.expected {
|
||||
t.Errorf("Expected %v, got %v for directory '%s'", tt.expected, result, tt.dir)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetSymlinksFromResolutions(t *testing.T) {
|
||||
t.Parallel()
|
||||
cache := NewKnownSymlink("/test/dir", true)
|
||||
|
||||
// Mock resolution data
|
||||
resolvedModules := []struct {
|
||||
originalPath string
|
||||
resolvedPath string
|
||||
moduleName string
|
||||
mode core.ResolutionMode
|
||||
filePath tspath.Path
|
||||
}{
|
||||
{
|
||||
originalPath: "/test/original/file1.ts",
|
||||
resolvedPath: "/test/resolved/file1.ts",
|
||||
moduleName: "module1",
|
||||
mode: core.ResolutionModeNone,
|
||||
filePath: tspath.ToPath("/test/source.ts", "/test/dir", true),
|
||||
},
|
||||
{
|
||||
originalPath: "/test/original/file2.ts",
|
||||
resolvedPath: "/test/resolved/file2.ts",
|
||||
moduleName: "module2",
|
||||
mode: core.ResolutionModeNone,
|
||||
filePath: tspath.ToPath("/test/source.ts", "/test/dir", true),
|
||||
},
|
||||
}
|
||||
|
||||
// Mock callbacks
|
||||
forEachResolvedModule := func(callback func(resolution *module.ResolvedModule, moduleName string, mode core.ResolutionMode, filePath tspath.Path), file *ast.SourceFile) {
|
||||
for _, res := range resolvedModules {
|
||||
resolution := &module.ResolvedModule{
|
||||
OriginalPath: res.originalPath,
|
||||
ResolvedFileName: res.resolvedPath,
|
||||
}
|
||||
callback(resolution, res.moduleName, res.mode, res.filePath)
|
||||
}
|
||||
}
|
||||
|
||||
forEachResolvedTypeReferenceDirective := func(callback func(resolution *module.ResolvedTypeReferenceDirective, moduleName string, mode core.ResolutionMode, filePath tspath.Path), file *ast.SourceFile) {
|
||||
// No type reference directives for this test
|
||||
}
|
||||
|
||||
cache.SetSymlinksFromResolutions(forEachResolvedModule, forEachResolvedTypeReferenceDirective)
|
||||
|
||||
// Check that files were stored
|
||||
for _, res := range resolvedModules {
|
||||
symlinkPath := tspath.ToPath(res.originalPath, "/test/dir", true)
|
||||
stored, ok := cache.Files().Load(symlinkPath)
|
||||
if !ok {
|
||||
t.Errorf("Expected file '%s' to be stored", res.originalPath)
|
||||
continue
|
||||
}
|
||||
if stored != res.resolvedPath {
|
||||
t.Errorf("Expected resolved path to be '%s', got '%s'", res.resolvedPath, stored)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestKnownSymlinksThreadSafety(t *testing.T) {
|
||||
t.Parallel()
|
||||
cache := NewKnownSymlink("/test/dir", true)
|
||||
|
||||
// Test concurrent access
|
||||
done := make(chan bool, 10)
|
||||
|
||||
for i := range 10 {
|
||||
go func(id int) {
|
||||
defer func() { done <- true }()
|
||||
|
||||
symlinkPath := tspath.ToPath("/test/symlink"+string(rune(id)), "/test/dir", true).EnsureTrailingDirectorySeparator()
|
||||
realDirectory := &KnownDirectoryLink{
|
||||
Real: "/real/path" + string(rune(id)) + "/",
|
||||
RealPath: tspath.ToPath("/real/path"+string(rune(id)), "/test/dir", true).EnsureTrailingDirectorySeparator(),
|
||||
}
|
||||
|
||||
cache.SetDirectory("/test/symlink"+string(rune(id)), symlinkPath, realDirectory)
|
||||
|
||||
// Read back
|
||||
stored, ok := cache.Directories().Load(symlinkPath)
|
||||
if !ok {
|
||||
t.Errorf("Goroutine %d: Expected directory to be stored", id)
|
||||
return
|
||||
}
|
||||
if stored.Real != realDirectory.Real {
|
||||
t.Errorf("Goroutine %d: Expected Real to be '%s', got '%s'", id, realDirectory.Real, stored.Real)
|
||||
}
|
||||
}(i)
|
||||
}
|
||||
|
||||
// Wait for all goroutines to complete
|
||||
for range 10 {
|
||||
<-done
|
||||
}
|
||||
|
||||
// Verify all directories were stored
|
||||
if cache.Directories().Size() != 10 {
|
||||
t.Errorf("Expected 10 directories to be stored, got %d", cache.Directories().Size())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user