vendor tsgo
This commit is contained in:
342
tools/tsgo/internal/modulespecifiers/specifiers_test.go
Normal file
342
tools/tsgo/internal/modulespecifiers/specifiers_test.go
Normal file
@@ -0,0 +1,342 @@
|
||||
package modulespecifiers
|
||||
|
||||
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/packagejson"
|
||||
"github.com/microsoft/typescript-go/internal/symlinks"
|
||||
"github.com/microsoft/typescript-go/internal/tsoptions"
|
||||
"github.com/microsoft/typescript-go/internal/tspath"
|
||||
)
|
||||
|
||||
// Mock host for testing
|
||||
type mockModuleSpecifierGenerationHost struct {
|
||||
currentDir string
|
||||
useCaseSensitiveFileNames bool
|
||||
symlinkCache *symlinks.KnownSymlinks
|
||||
}
|
||||
|
||||
func (h *mockModuleSpecifierGenerationHost) GetCurrentDirectory() string {
|
||||
return h.currentDir
|
||||
}
|
||||
|
||||
func (h *mockModuleSpecifierGenerationHost) UseCaseSensitiveFileNames() bool {
|
||||
return h.useCaseSensitiveFileNames
|
||||
}
|
||||
|
||||
func (h *mockModuleSpecifierGenerationHost) GetSymlinkCache() *symlinks.KnownSymlinks {
|
||||
return h.symlinkCache
|
||||
}
|
||||
|
||||
func (h *mockModuleSpecifierGenerationHost) ResolveModuleName(moduleName string, containingFile string, resolutionMode core.ResolutionMode) *module.ResolvedModule {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *mockModuleSpecifierGenerationHost) GetGlobalTypingsCacheLocation() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (h *mockModuleSpecifierGenerationHost) CommonSourceDirectory() string {
|
||||
return h.currentDir
|
||||
}
|
||||
|
||||
func (h *mockModuleSpecifierGenerationHost) GetProjectReferenceFromSource(path tspath.Path) *tsoptions.SourceOutputAndProjectReference {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *mockModuleSpecifierGenerationHost) GetRedirectTargets(path tspath.Path) []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *mockModuleSpecifierGenerationHost) GetSourceOfProjectReferenceIfOutputIncluded(file ast.HasFileName) string {
|
||||
return file.FileName()
|
||||
}
|
||||
|
||||
func (h *mockModuleSpecifierGenerationHost) FileExists(path string) bool {
|
||||
return true // Mock implementation
|
||||
}
|
||||
|
||||
func (h *mockModuleSpecifierGenerationHost) GetNearestAncestorDirectoryWithPackageJson(dirname string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (h *mockModuleSpecifierGenerationHost) GetPackageJsonInfo(pkgJsonPath string) *packagejson.InfoCacheEntry {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *mockModuleSpecifierGenerationHost) GetDefaultResolutionModeForFile(file ast.HasFileName) core.ResolutionMode {
|
||||
return core.ResolutionModeNone
|
||||
}
|
||||
|
||||
func (h *mockModuleSpecifierGenerationHost) GetResolvedModuleFromModuleSpecifier(file ast.HasFileName, moduleSpecifier *ast.StringLiteralLike) *module.ResolvedModule {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *mockModuleSpecifierGenerationHost) GetModeForUsageLocation(file ast.HasFileName, moduleSpecifier *ast.StringLiteralLike) core.ResolutionMode {
|
||||
return core.ResolutionModeNone
|
||||
}
|
||||
|
||||
func TestGetEachFileNameOfModule(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
importingFile string
|
||||
importedFile string
|
||||
preferSymlinks bool
|
||||
expectedCount int
|
||||
expectedPaths []string
|
||||
}{
|
||||
{
|
||||
name: "basic file path",
|
||||
importingFile: "/project/src/main.ts",
|
||||
importedFile: "/project/lib/utils.ts",
|
||||
preferSymlinks: false,
|
||||
expectedCount: 1,
|
||||
expectedPaths: []string{"/project/lib/utils.ts"},
|
||||
},
|
||||
{
|
||||
name: "symlink preference false",
|
||||
importingFile: "/project/src/main.ts",
|
||||
importedFile: "/project/lib/utils.ts",
|
||||
preferSymlinks: false,
|
||||
expectedCount: 1,
|
||||
},
|
||||
{
|
||||
name: "symlink preference true",
|
||||
importingFile: "/project/src/main.ts",
|
||||
importedFile: "/project/lib/utils.ts",
|
||||
preferSymlinks: true,
|
||||
expectedCount: 1,
|
||||
},
|
||||
{
|
||||
name: "ignored path with no alternatives",
|
||||
importingFile: "/project/src/main.ts",
|
||||
importedFile: "/project/node_modules/.pnpm/file.ts",
|
||||
preferSymlinks: false,
|
||||
expectedCount: 1, // Should return 1 because there's no better option (all paths are ignored)
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
host := &mockModuleSpecifierGenerationHost{
|
||||
currentDir: "/project",
|
||||
useCaseSensitiveFileNames: true,
|
||||
symlinkCache: symlinks.NewKnownSymlink("/project", true),
|
||||
}
|
||||
|
||||
result := GetEachFileNameOfModule(tt.importingFile, tt.importedFile, host, tt.preferSymlinks)
|
||||
|
||||
if len(result) != tt.expectedCount {
|
||||
t.Errorf("Expected %d paths, got %d", tt.expectedCount, len(result))
|
||||
}
|
||||
|
||||
if tt.expectedPaths != nil {
|
||||
for i, expectedPath := range tt.expectedPaths {
|
||||
if i >= len(result) {
|
||||
t.Errorf("Expected path %d: %s, but result has only %d paths", i, expectedPath, len(result))
|
||||
continue
|
||||
}
|
||||
if result[i].FileName != expectedPath {
|
||||
t.Errorf("Expected path %d to be %s, got %s", i, expectedPath, result[i].FileName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i, path := range result {
|
||||
if path.FileName == "" {
|
||||
t.Errorf("Path %d has empty FileName", i)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetEachFileNameOfModuleWithSymlinks(t *testing.T) {
|
||||
t.Parallel()
|
||||
host := &mockModuleSpecifierGenerationHost{
|
||||
currentDir: "/project",
|
||||
useCaseSensitiveFileNames: true,
|
||||
symlinkCache: symlinks.NewKnownSymlink("/project", true),
|
||||
}
|
||||
|
||||
symlinkPath := tspath.ToPath("/project/symlink", "/project", true).EnsureTrailingDirectorySeparator()
|
||||
realDirectory := &symlinks.KnownDirectoryLink{
|
||||
Real: "/real/path/",
|
||||
RealPath: tspath.ToPath("/real/path", "/project", true).EnsureTrailingDirectorySeparator(),
|
||||
}
|
||||
host.symlinkCache.SetDirectory("/project/symlink", symlinkPath, realDirectory)
|
||||
|
||||
result := GetEachFileNameOfModule("/project/src/main.ts", "/real/path/file.ts", host, true)
|
||||
|
||||
// Should find the symlink path
|
||||
found := false
|
||||
for _, path := range result {
|
||||
if path.FileName == "/project/symlink/file.ts" {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
t.Error("Expected to find symlink path /project/symlink/file.ts")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainsNodeModules(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "contains node_modules",
|
||||
path: "/project/node_modules/lodash/index.js",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "does not contain node_modules",
|
||||
path: "/project/src/utils.ts",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "node_modules in middle",
|
||||
path: "/project/packages/node_modules/pkg/file.js",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "empty path",
|
||||
path: "",
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
result := ContainsNodeModules(tt.path)
|
||||
if result != tt.expected {
|
||||
t.Errorf("ContainsNodeModules(%q) = %v, expected %v", tt.path, result, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainsIgnoredPath(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "ignored path",
|
||||
path: "/project/node_modules/.pnpm/file.ts",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "not ignored path",
|
||||
path: "/project/src/file.ts",
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
result := containsIgnoredPath(tt.path)
|
||||
if result != tt.expected {
|
||||
t.Errorf("containsIgnoredPath(%q) = %v, expected %v", tt.path, result, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestTryGetRealFileNameForNonJSDeclarationFileName(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
fileName string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "json declaration file",
|
||||
fileName: "/project/foo.d.json.ts",
|
||||
expected: "/project/foo.json",
|
||||
},
|
||||
{
|
||||
name: "multi-dot source extension declaration file",
|
||||
fileName: "/project/foo.module.d.css.ts",
|
||||
expected: "/project/foo.module.css",
|
||||
},
|
||||
{
|
||||
name: "plain dts file ignored",
|
||||
fileName: "/project/foo.d.ts",
|
||||
expected: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
if got := TryGetRealFileNameForNonJSDeclarationFileName(tt.fileName); got != tt.expected {
|
||||
t.Errorf("TryGetRealFileNameForNonJSDeclarationFileName(%q) = %q, expected %q", tt.fileName, got, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestTryGetModuleNameFromExportsOrImports(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("with exports pattern", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
targetFilePath string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "match",
|
||||
targetFilePath: "/pkg/src/things/thing1/index.ts",
|
||||
expected: "./src/things/thing1",
|
||||
},
|
||||
{
|
||||
name: "mismatch with matching leading and trailing strings",
|
||||
targetFilePath: "/pkg/src/things/index.ts",
|
||||
expected: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
result := tryGetModuleNameFromExportsOrImports(
|
||||
&core.CompilerOptions{},
|
||||
&mockModuleSpecifierGenerationHost{},
|
||||
tt.targetFilePath,
|
||||
"/pkg",
|
||||
"./src/things/*",
|
||||
packagejson.ExportsOrImports{
|
||||
JSONValue: packagejson.JSONValue{
|
||||
Type: packagejson.JSONValueTypeString,
|
||||
Value: "./src/things/*/index.js",
|
||||
},
|
||||
},
|
||||
[]string{},
|
||||
MatchingModePattern,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
if result != tt.expected {
|
||||
t.Errorf("tryGetModuleNameFromExportsOrImports(targetFilePath = %q) = %v, expected %v", tt.targetFilePath, result, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user