Files

189 lines
5.4 KiB
Go
Raw Permalink Normal View History

package cursor
import (
"database/sql"
"encoding/json"
"os"
"path/filepath"
"testing"
_ "modernc.org/sqlite"
)
func TestProjectPathFromURI(t *testing.T) {
cases := []struct {
name string
uri string
want string
}{
{"windows 盘符", "file:///d:/Project/x", "d:/Project/x"},
{"编码盘符", "file:///d%3A/Project/x", "d:/Project/x"},
{"带空格编码", "file:///d:/My%20Projects/x", "d:/My Projects/x"},
{"posix 路径", "file:///home/user/x", "/home/user/x"},
{"非 file URI", "vscode-remote://ssh-remote/home/x", ""},
{"普通路径", "d:/Project/x", ""},
{"空串", "", ""},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
if got := projectPathFromURI(tc.uri); got != tc.want {
t.Fatalf("projectPathFromURI(%q) = %q, want %q", tc.uri, got, tc.want)
}
})
}
}
// createStateDB 在 userDir/globalStorage 下创建含最近打开列表的 state.vscdb。
func createStateDB(t *testing.T, userDir string, uris []string) {
t.Helper()
if err := os.MkdirAll(filepath.Join(userDir, "globalStorage"), 0o755); err != nil {
t.Fatal(err)
}
db, err := sql.Open("sqlite", filepath.Join(userDir, "globalStorage", "state.vscdb"))
if err != nil {
t.Fatal(err)
}
defer db.Close()
if _, err := db.Exec("CREATE TABLE ItemTable (key TEXT UNIQUE, value TEXT)"); err != nil {
t.Fatal(err)
}
entries := make([]map[string]string, 0, len(uris))
for _, uri := range uris {
entries = append(entries, map[string]string{"folderUri": uri})
}
raw, _ := json.Marshal(map[string]any{"entries": entries})
if _, err := db.Exec(
"INSERT INTO ItemTable (key, value) VALUES ('history.recentlyOpenedPathsList', ?)", string(raw),
); err != nil {
t.Fatal(err)
}
}
func readRecentlyOpened(t *testing.T, userDir string) []string {
t.Helper()
db, err := sql.Open("sqlite", filepath.Join(userDir, "globalStorage", "state.vscdb"))
if err != nil {
t.Fatal(err)
}
defer db.Close()
var raw string
if err := db.QueryRow(
"SELECT value FROM ItemTable WHERE key = 'history.recentlyOpenedPathsList'",
).Scan(&raw); err != nil {
t.Fatal(err)
}
var payload struct {
Entries []struct {
FolderURI string `json:"folderUri"`
} `json:"entries"`
}
if err := json.Unmarshal([]byte(raw), &payload); err != nil {
t.Fatal(err)
}
result := make([]string, 0, len(payload.Entries))
for _, item := range payload.Entries {
result = append(result, item.FolderURI)
}
return result
}
func TestRemoveRecentlyOpenedEntry(t *testing.T) {
t.Run("命中条目被移除", func(t *testing.T) {
userDir := t.TempDir()
createStateDB(t, userDir, []string{"file:///d:/Proj/A", "file:///d:/Proj/B"})
removed, err := removeRecentlyOpenedEntry(userDir, "d:/Proj/A")
if err != nil {
t.Fatal(err)
}
if removed != 1 {
t.Fatalf("removed = %d, want 1", removed)
}
remaining := readRecentlyOpened(t, userDir)
if len(remaining) != 1 || remaining[0] != "file:///d:/Proj/B" {
t.Fatalf("remaining = %v, want [file:///d:/Proj/B]", remaining)
}
})
t.Run("未命中不写库", func(t *testing.T) {
userDir := t.TempDir()
createStateDB(t, userDir, []string{"file:///d:/Proj/A"})
removed, err := removeRecentlyOpenedEntry(userDir, "d:/Proj/Other")
if err != nil {
t.Fatal(err)
}
if removed != 0 {
t.Fatalf("removed = %d, want 0", removed)
}
if got := readRecentlyOpened(t, userDir); len(got) != 1 {
t.Fatalf("remaining = %v, want 1 entry", got)
}
})
t.Run("缺失数据库返回零值无错误", func(t *testing.T) {
removed, err := removeRecentlyOpenedEntry(t.TempDir(), "d:/Proj/A")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if removed != 0 {
t.Fatalf("removed = %d, want 0", removed)
}
})
t.Run("损坏数据库返回错误", func(t *testing.T) {
userDir := t.TempDir()
if err := os.MkdirAll(filepath.Join(userDir, "globalStorage"), 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(
filepath.Join(userDir, "globalStorage", "state.vscdb"), []byte("not a db"), 0o644,
); err != nil {
t.Fatal(err)
}
if _, err := removeRecentlyOpenedEntry(userDir, "d:/Proj/A"); err == nil {
t.Fatal("want error for corrupt db, got nil")
}
})
}
func TestRemoveWorkspaceStorageEntries(t *testing.T) {
t.Run("命中目录被整目录删除", func(t *testing.T) {
userDir := t.TempDir()
target := filepath.Join(userDir, "workspaceStorage", "hash-a")
other := filepath.Join(userDir, "workspaceStorage", "hash-b")
for dir, folder := range map[string]string{
target: "file:///d:/Proj/A",
other: "file:///d:/Proj/B",
} {
if err := os.MkdirAll(dir, 0o755); err != nil {
t.Fatal(err)
}
raw, _ := json.Marshal(map[string]string{"folder": folder})
if err := os.WriteFile(filepath.Join(dir, "workspace.json"), raw, 0o644); err != nil {
t.Fatal(err)
}
}
removed, err := removeWorkspaceStorageEntries(userDir, "d:/Proj/A")
if err != nil {
t.Fatal(err)
}
if removed != 1 {
t.Fatalf("removed = %d, want 1", removed)
}
if _, err := os.Stat(target); !os.IsNotExist(err) {
t.Fatalf("target dir should be removed, stat err = %v", err)
}
if _, err := os.Stat(other); err != nil {
t.Fatalf("other dir should remain: %v", err)
}
})
t.Run("缺失 workspaceStorage 返回零值无错误", func(t *testing.T) {
removed, err := removeWorkspaceStorageEntries(t.TempDir(), "d:/Proj/A")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if removed != 0 {
t.Fatalf("removed = %d, want 0", removed)
}
})
}