1package projects
2
3import (
4 "path/filepath"
5 "testing"
6 "time"
7)
8
9func TestRegisterAndList(t *testing.T) {
10 // Create a temporary directory for the test
11 tmpDir := t.TempDir()
12
13 // Override the projects file path for testing
14 t.Setenv("XDG_DATA_HOME", tmpDir)
15 t.Setenv("CRUSH_GLOBAL_DATA", filepath.Join(tmpDir, "crush"))
16
17 // Test registering a project
18 err := Register("/home/user/project1", "/home/user/project1/.crush")
19 if err != nil {
20 t.Fatalf("Register failed: %v", err)
21 }
22
23 // List projects
24 projects, err := List()
25 if err != nil {
26 t.Fatalf("List failed: %v", err)
27 }
28
29 if len(projects) != 1 {
30 t.Fatalf("Expected 1 project, got %d", len(projects))
31 }
32
33 if projects[0].Path != "/home/user/project1" {
34 t.Errorf("Expected path /home/user/project1, got %s", projects[0].Path)
35 }
36
37 if projects[0].DataDir != "/home/user/project1/.crush" {
38 t.Errorf("Expected data_dir /home/user/project1/.crush, got %s", projects[0].DataDir)
39 }
40
41 // Register another project
42 err = Register("/home/user/project2", "/home/user/project2/.crush")
43 if err != nil {
44 t.Fatalf("Register failed: %v", err)
45 }
46
47 projects, err = List()
48 if err != nil {
49 t.Fatalf("List failed: %v", err)
50 }
51
52 if len(projects) != 2 {
53 t.Fatalf("Expected 2 projects, got %d", len(projects))
54 }
55
56 // Most recent should be first
57 if projects[0].Path != "/home/user/project2" {
58 t.Errorf("Expected most recent project first, got %s", projects[0].Path)
59 }
60}
61
62func TestRegisterUpdatesExisting(t *testing.T) {
63 tmpDir := t.TempDir()
64 t.Setenv("XDG_DATA_HOME", tmpDir)
65 t.Setenv("CRUSH_GLOBAL_DATA", filepath.Join(tmpDir, "crush"))
66
67 // Register a project
68 err := Register("/home/user/project1", "/home/user/project1/.crush")
69 if err != nil {
70 t.Fatalf("Register failed: %v", err)
71 }
72
73 projects, _ := List()
74 firstAccess := projects[0].LastAccessed
75
76 // Wait a bit and re-register
77 time.Sleep(10 * time.Millisecond)
78
79 err = Register("/home/user/project1", "/home/user/project1/.crush-new")
80 if err != nil {
81 t.Fatalf("Register failed: %v", err)
82 }
83
84 projects, _ = List()
85
86 if len(projects) != 1 {
87 t.Fatalf("Expected 1 project after update, got %d", len(projects))
88 }
89
90 if projects[0].DataDir != "/home/user/project1/.crush-new" {
91 t.Errorf("Expected updated data_dir, got %s", projects[0].DataDir)
92 }
93
94 if !projects[0].LastAccessed.After(firstAccess) {
95 t.Error("Expected LastAccessed to be updated")
96 }
97}
98
99func TestLoadEmptyFile(t *testing.T) {
100 tmpDir := t.TempDir()
101 t.Setenv("XDG_DATA_HOME", tmpDir)
102 t.Setenv("CRUSH_GLOBAL_DATA", filepath.Join(tmpDir, "crush"))
103
104 // List before any projects exist
105 projects, err := List()
106 if err != nil {
107 t.Fatalf("List failed: %v", err)
108 }
109
110 if len(projects) != 0 {
111 t.Errorf("Expected 0 projects, got %d", len(projects))
112 }
113}
114
115func TestProjectsFilePath(t *testing.T) {
116 tmpDir := t.TempDir()
117 t.Setenv("XDG_DATA_HOME", tmpDir)
118 t.Setenv("CRUSH_GLOBAL_DATA", filepath.Join(tmpDir, "crush"))
119
120 expected := filepath.Join(tmpDir, "crush", "projects.json")
121 actual := projectsFilePath()
122
123 if actual != expected {
124 t.Errorf("Expected %s, got %s", expected, actual)
125 }
126}
127
128func TestRegisterWithParentDataDir(t *testing.T) {
129 tmpDir := t.TempDir()
130 t.Setenv("XDG_DATA_HOME", tmpDir)
131 t.Setenv("CRUSH_GLOBAL_DATA", filepath.Join(tmpDir, "crush"))
132
133 // Register a project where .crush is in a parent directory.
134 // e.g., working in /home/user/monorepo/packages/app but .crush is at /home/user/monorepo/.crush
135 err := Register("/home/user/monorepo/packages/app", "/home/user/monorepo/.crush")
136 if err != nil {
137 t.Fatalf("Register failed: %v", err)
138 }
139
140 projects, err := List()
141 if err != nil {
142 t.Fatalf("List failed: %v", err)
143 }
144
145 if len(projects) != 1 {
146 t.Fatalf("Expected 1 project, got %d", len(projects))
147 }
148
149 if projects[0].Path != "/home/user/monorepo/packages/app" {
150 t.Errorf("Expected path /home/user/monorepo/packages/app, got %s", projects[0].Path)
151 }
152
153 if projects[0].DataDir != "/home/user/monorepo/.crush" {
154 t.Errorf("Expected data_dir /home/user/monorepo/.crush, got %s", projects[0].DataDir)
155 }
156}
157
158func TestRegisterWithExternalDataDir(t *testing.T) {
159 tmpDir := t.TempDir()
160 t.Setenv("XDG_DATA_HOME", tmpDir)
161 t.Setenv("CRUSH_GLOBAL_DATA", filepath.Join(tmpDir, "crush"))
162
163 // Register a project where .crush is in a completely different location.
164 // e.g., project at /home/user/project but data stored at /var/data/crush/myproject
165 err := Register("/home/user/project", "/var/data/crush/myproject")
166 if err != nil {
167 t.Fatalf("Register failed: %v", err)
168 }
169
170 projects, err := List()
171 if err != nil {
172 t.Fatalf("List failed: %v", err)
173 }
174
175 if len(projects) != 1 {
176 t.Fatalf("Expected 1 project, got %d", len(projects))
177 }
178
179 if projects[0].Path != "/home/user/project" {
180 t.Errorf("Expected path /home/user/project, got %s", projects[0].Path)
181 }
182
183 if projects[0].DataDir != "/var/data/crush/myproject" {
184 t.Errorf("Expected data_dir /var/data/crush/myproject, got %s", projects[0].DataDir)
185 }
186}