projects_test.go

  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}