Do some retarded shit idk what claude did here hopefully something good this will probably get dropped
This commit is contained in:
432
utils/path_test.go
Normal file
432
utils/path_test.go
Normal file
@@ -0,0 +1,432 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestResolvePath(t *testing.T) {
|
||||
// Save original working directory
|
||||
origDir, _ := os.Getwd()
|
||||
defer os.Chdir(origDir)
|
||||
|
||||
// Create a temporary directory for testing
|
||||
tmpDir, err := os.MkdirTemp("", "path_test")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
expected string
|
||||
setup func() // Optional setup function
|
||||
}{
|
||||
{
|
||||
name: "Empty path",
|
||||
input: "",
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "Already absolute path",
|
||||
input: func() string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return "C:/absolute/path/file.txt"
|
||||
}
|
||||
return "/absolute/path/file.txt"
|
||||
}(),
|
||||
expected: func() string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return "C:/absolute/path/file.txt"
|
||||
}
|
||||
return "/absolute/path/file.txt"
|
||||
}(),
|
||||
},
|
||||
{
|
||||
name: "Relative path",
|
||||
input: "relative/file.txt",
|
||||
expected: func() string {
|
||||
abs, _ := filepath.Abs("relative/file.txt")
|
||||
return strings.ReplaceAll(abs, "\\", "/")
|
||||
}(),
|
||||
},
|
||||
{
|
||||
name: "Tilde expansion - home only",
|
||||
input: "~",
|
||||
expected: func() string {
|
||||
home := os.Getenv("HOME")
|
||||
if home == "" && runtime.GOOS == "windows" {
|
||||
home = os.Getenv("USERPROFILE")
|
||||
}
|
||||
return strings.ReplaceAll(filepath.Clean(home), "\\", "/")
|
||||
}(),
|
||||
},
|
||||
{
|
||||
name: "Tilde expansion - with subpath",
|
||||
input: "~/Documents/file.txt",
|
||||
expected: func() string {
|
||||
home := os.Getenv("HOME")
|
||||
if home == "" && runtime.GOOS == "windows" {
|
||||
home = os.Getenv("USERPROFILE")
|
||||
}
|
||||
expected := filepath.Join(home, "Documents", "file.txt")
|
||||
return strings.ReplaceAll(filepath.Clean(expected), "\\", "/")
|
||||
}(),
|
||||
},
|
||||
{
|
||||
name: "Path normalization - double slashes",
|
||||
input: "path//to//file.txt",
|
||||
expected: func() string {
|
||||
abs, _ := filepath.Abs("path/to/file.txt")
|
||||
return strings.ReplaceAll(abs, "\\", "/")
|
||||
}(),
|
||||
},
|
||||
{
|
||||
name: "Path normalization - . and ..",
|
||||
input: "path/./to/../file.txt",
|
||||
expected: func() string {
|
||||
abs, _ := filepath.Abs("path/file.txt")
|
||||
return strings.ReplaceAll(abs, "\\", "/")
|
||||
}(),
|
||||
},
|
||||
{
|
||||
name: "Windows backslash normalization",
|
||||
input: "path\\to\\file.txt",
|
||||
expected: func() string {
|
||||
abs, _ := filepath.Abs("path/to/file.txt")
|
||||
return strings.ReplaceAll(abs, "\\", "/")
|
||||
}(),
|
||||
},
|
||||
{
|
||||
name: "Mixed separators with tilde",
|
||||
input: "~/Documents\\file.txt",
|
||||
expected: func() string {
|
||||
home := os.Getenv("HOME")
|
||||
if home == "" && runtime.GOOS == "windows" {
|
||||
home = os.Getenv("USERPROFILE")
|
||||
}
|
||||
expected := filepath.Join(home, "Documents", "file.txt")
|
||||
return strings.ReplaceAll(filepath.Clean(expected), "\\", "/")
|
||||
}(),
|
||||
},
|
||||
{
|
||||
name: "Relative path from current directory",
|
||||
input: "./file.txt",
|
||||
expected: func() string {
|
||||
abs, _ := filepath.Abs("file.txt")
|
||||
return strings.ReplaceAll(abs, "\\", "/")
|
||||
}(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.setup != nil {
|
||||
tt.setup()
|
||||
}
|
||||
|
||||
result := ResolvePath(tt.input)
|
||||
assert.Equal(t, tt.expected, result, "ResolvePath(%q) = %q, want %q", tt.input, result, tt.expected)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolvePathWithWorkingDirectoryChange(t *testing.T) {
|
||||
// Save original working directory
|
||||
origDir, _ := os.Getwd()
|
||||
defer os.Chdir(origDir)
|
||||
|
||||
// Create temporary directories
|
||||
tmpDir, err := os.MkdirTemp("", "path_test")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
subDir := filepath.Join(tmpDir, "subdir")
|
||||
err = os.MkdirAll(subDir, 0755)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Change to subdirectory
|
||||
err = os.Chdir(subDir)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Test relative path resolution from new working directory
|
||||
result := ResolvePath("../test.txt")
|
||||
expected := filepath.Join(tmpDir, "test.txt")
|
||||
expected = strings.ReplaceAll(filepath.Clean(expected), "\\", "/")
|
||||
|
||||
assert.Equal(t, expected, result)
|
||||
}
|
||||
|
||||
func TestResolvePathComplexTilde(t *testing.T) {
|
||||
// Test complex tilde patterns
|
||||
home := os.Getenv("HOME")
|
||||
if home == "" && runtime.GOOS == "windows" {
|
||||
home = os.Getenv("USERPROFILE")
|
||||
}
|
||||
|
||||
if home == "" {
|
||||
t.Skip("Cannot determine home directory for tilde expansion tests")
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
input: "~",
|
||||
expected: strings.ReplaceAll(filepath.Clean(home), "\\", "/"),
|
||||
},
|
||||
{
|
||||
input: "~/",
|
||||
expected: strings.ReplaceAll(filepath.Clean(home), "\\", "/"),
|
||||
},
|
||||
{
|
||||
input: "~~",
|
||||
expected: func() string {
|
||||
// ~~ should be treated as ~ followed by ~ (tilde expansion)
|
||||
home := os.Getenv("HOME")
|
||||
if home == "" && runtime.GOOS == "windows" {
|
||||
home = os.Getenv("USERPROFILE")
|
||||
}
|
||||
if home != "" {
|
||||
// First ~ gets expanded, second ~ remains
|
||||
return strings.ReplaceAll(filepath.Clean(home+"~"), "\\", "/")
|
||||
}
|
||||
abs, _ := filepath.Abs("~~")
|
||||
return strings.ReplaceAll(abs, "\\", "/")
|
||||
}(),
|
||||
},
|
||||
{
|
||||
input: func() string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return "C:/not/tilde/path"
|
||||
}
|
||||
return "/not/tilde/path"
|
||||
}(),
|
||||
expected: func() string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return "C:/not/tilde/path"
|
||||
}
|
||||
return "/not/tilde/path"
|
||||
}(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run("Complex tilde: "+tt.input, func(t *testing.T) {
|
||||
result := ResolvePath(tt.input)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsAbsolutePath(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "Empty path",
|
||||
input: "",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "Absolute Unix path",
|
||||
input: "/absolute/path",
|
||||
expected: func() bool {
|
||||
if runtime.GOOS == "windows" {
|
||||
// On Windows, paths starting with / are not considered absolute
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}(),
|
||||
},
|
||||
{
|
||||
name: "Relative path",
|
||||
input: "relative/path",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "Tilde expansion (becomes absolute)",
|
||||
input: "~/path",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "Windows absolute path",
|
||||
input: "C:\\Windows\\System32",
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := IsAbsolutePath(tt.input)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRelativePath(t *testing.T) {
|
||||
// Create temporary directories for testing
|
||||
tmpDir, err := os.MkdirTemp("", "relative_path_test")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
baseDir := filepath.Join(tmpDir, "base")
|
||||
targetDir := filepath.Join(tmpDir, "target")
|
||||
subDir := filepath.Join(targetDir, "subdir")
|
||||
|
||||
err = os.MkdirAll(baseDir, 0755)
|
||||
assert.NoError(t, err)
|
||||
err = os.MkdirAll(subDir, 0755)
|
||||
assert.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
base string
|
||||
target string
|
||||
expected string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "Target is subdirectory of base",
|
||||
base: baseDir,
|
||||
target: filepath.Join(baseDir, "subdir"),
|
||||
expected: "subdir",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Target is parent of base",
|
||||
base: filepath.Join(baseDir, "subdir"),
|
||||
target: baseDir,
|
||||
expected: "..",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Target is sibling directory",
|
||||
base: baseDir,
|
||||
target: targetDir,
|
||||
expected: "../target",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Same directory",
|
||||
base: baseDir,
|
||||
target: baseDir,
|
||||
expected: ".",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "With tilde expansion",
|
||||
base: baseDir,
|
||||
target: filepath.Join(baseDir, "file.txt"),
|
||||
expected: "file.txt",
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result, err := GetRelativePath(tt.base, tt.target)
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolvePathRegression(t *testing.T) {
|
||||
// This test specifically addresses the original bug:
|
||||
// "~ is NOT BEING FUCKING RESOLVED"
|
||||
|
||||
home := os.Getenv("HOME")
|
||||
if home == "" && runtime.GOOS == "windows" {
|
||||
home = os.Getenv("USERPROFILE")
|
||||
}
|
||||
|
||||
if home == "" {
|
||||
t.Skip("Cannot determine home directory for regression test")
|
||||
}
|
||||
|
||||
// Test the exact pattern from the bug report
|
||||
testPath := "~/Seafile/activitywatch/sync.yml"
|
||||
result := ResolvePath(testPath)
|
||||
expected := filepath.Join(home, "Seafile", "activitywatch", "sync.yml")
|
||||
expected = strings.ReplaceAll(filepath.Clean(expected), "\\", "/")
|
||||
|
||||
assert.Equal(t, expected, result, "Tilde expansion bug not fixed!")
|
||||
assert.NotContains(t, result, "~", "Tilde still present in resolved path!")
|
||||
// Convert both to forward slashes for comparison
|
||||
homeForwardSlash := strings.ReplaceAll(home, "\\", "/")
|
||||
assert.Contains(t, result, homeForwardSlash, "Home directory not found in resolved path!")
|
||||
}
|
||||
|
||||
func TestResolvePathEdgeCases(t *testing.T) {
|
||||
// Save original working directory
|
||||
origDir, _ := os.Getwd()
|
||||
defer os.Chdir(origDir)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
setup func()
|
||||
shouldPanic bool
|
||||
}{
|
||||
{
|
||||
name: "Just dot",
|
||||
input: ".",
|
||||
},
|
||||
{
|
||||
name: "Just double dot",
|
||||
input: "..",
|
||||
},
|
||||
{
|
||||
name: "Triple dot",
|
||||
input: "...",
|
||||
},
|
||||
{
|
||||
name: "Multiple leading dots",
|
||||
input: "./.././../file.txt",
|
||||
},
|
||||
{
|
||||
name: "Path with spaces",
|
||||
input: "path with spaces/file.txt",
|
||||
},
|
||||
{
|
||||
name: "Very long relative path",
|
||||
input: strings.Repeat("../", 10) + "file.txt",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.setup != nil {
|
||||
tt.setup()
|
||||
}
|
||||
|
||||
if tt.shouldPanic {
|
||||
assert.Panics(t, func() {
|
||||
ResolvePath(tt.input)
|
||||
})
|
||||
} else {
|
||||
// Should not panic
|
||||
assert.NotPanics(t, func() {
|
||||
ResolvePath(tt.input)
|
||||
})
|
||||
// Result should be a valid absolute path
|
||||
result := ResolvePath(tt.input)
|
||||
if tt.input != "" {
|
||||
assert.True(t, filepath.IsAbs(result) || result == "", "Result should be absolute or empty")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user