package windsurf import ( "path/filepath" "reflect" "strings" "testing" ) func stubDataDirStat(t *testing.T, present map[string]dataDirStat) { t.Helper() orig := dataDirStatFn dataDirStatFn = func(path string) dataDirStat { return present[path] } t.Cleanup(func() { dataDirStatFn = orig }) } func stubUserConfigDir(t *testing.T, dir string) { t.Helper() orig := userConfigDirFn userConfigDirFn = func() string { return dir } t.Cleanup(func() { userConfigDirFn = orig }) } func TestResolveDataDir_ExplicitCfgWins(t *testing.T) { stubUserConfigDir(t, "/home/test/.config") got := resolveDataDirFor("/explicit/path", "", "linux") if got != "/explicit/path" { t.Errorf("explicit cfg should win, got %q", got) } } func TestResolveDataDir_EnvWinsOverDefaults(t *testing.T) { stubUserConfigDir(t, "/home/test/.config") got := resolveDataDirFor("", "/env/path", "linux") if got != "/env/path" { t.Errorf("env var should win over defaults, got %q", got) } } func TestResolveDataDir_LinuxLegacyKeptWhenWritable(t *testing.T) { stubDataDirStat(t, map[string]dataDirStat{ LegacyLinuxDataDir: {Exists: true, Writable: true}, }) stubUserConfigDir(t, "/home/test/.config") got := resolveDataDirFor("", "", "linux") if got != LegacyLinuxDataDir { t.Errorf("linux with writable /opt/windsurf/data should keep legacy path, got %q", got) } } func TestResolveDataDir_LinuxLegacyNotWritableFallsBack(t *testing.T) { stubDataDirStat(t, map[string]dataDirStat{ LegacyLinuxDataDir: {Exists: true, Writable: false}, // root-owned }) stubUserConfigDir(t, "/home/test/.config") got := resolveDataDirFor("", "", "linux") want := filepath.Join("/home/test/.config", "windsurf", "data") if got != want { t.Errorf("unwritable legacy should fall back to UserConfigDir, got %q want %q", got, want) } } func TestResolveDataDir_DarwinIgnoresLinuxLegacy(t *testing.T) { stubDataDirStat(t, map[string]dataDirStat{ LegacyLinuxDataDir: {Exists: true, Writable: true}, }) stubUserConfigDir(t, "/Users/test/Library/Application Support") got := resolveDataDirFor("", "", "darwin") want := filepath.Join("/Users/test/Library/Application Support", "windsurf", "data") if got != want { t.Errorf("darwin should ignore /opt/windsurf/data, got %q want %q", got, want) } } func TestResolveDataDir_WindowsUsesUserConfigDir(t *testing.T) { stubUserConfigDir(t, `C:\Users\test\AppData\Roaming`) got := resolveDataDirFor("", "", "windows") want := filepath.Join(`C:\Users\test\AppData\Roaming`, "windsurf", "data") if got != want { t.Errorf("windows should use UserConfigDir, got %q want %q", got, want) } } func TestResolveDataDir_EmptyUserConfigFallsBackToTemp(t *testing.T) { stubUserConfigDir(t, "") got := resolveDataDirFor("", "", "linux") if !strings.Contains(got, "windsurf-data") { t.Errorf("fallback should contain windsurf-data, got %q", got) } } func TestInstanceHomeDir(t *testing.T) { got := instanceHomeDir("/var/lib/windsurf/key1") want := filepath.Join("/var/lib/windsurf/key1", "home") if got != want { t.Errorf("got %q, want %q", got, want) } } func TestHomeEnvForPlatform(t *testing.T) { tests := []struct { goos string want []string }{ {"linux", []string{"HOME=/sandbox"}}, {"darwin", []string{"HOME=/sandbox"}}, {"windows", []string{"HOME=/sandbox", "USERPROFILE=/sandbox"}}, } for _, tt := range tests { t.Run(tt.goos, func(t *testing.T) { got := homeEnvForPlatform("/sandbox", tt.goos) if !reflect.DeepEqual(got, tt.want) { t.Errorf("goos=%s: got %v, want %v", tt.goos, got, tt.want) } }) } }