package cache import ( "sync" "testing" ) // TestNew tests cache initialization func TestNew(t *testing.T) { tests := []struct { name string languages []string wantErr bool }{ { name: "English and Spanish", languages: []string{"en", "es"}, wantErr: false, }, { name: "English only", languages: []string{"en"}, wantErr: false, }, { name: "Invalid language", languages: []string{"fr"}, wantErr: true, }, { name: "Empty languages", languages: []string{}, wantErr: false, // Empty is valid, just no data loaded }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { cache, err := New(tt.languages) if tt.wantErr { if err == nil { t.Error("Expected error but got nil") } return } if err != nil { t.Errorf("Unexpected error: %v", err) return } if cache == nil { t.Error("Expected cache but got nil") } }) } } // TestGetCV tests CV data retrieval func TestGetCV(t *testing.T) { cache, err := New([]string{"en", "es"}) if err != nil { t.Fatalf("Failed to create cache: %v", err) } tests := []struct { name string lang string wantNil bool }{ { name: "English CV", lang: "en", wantNil: false, }, { name: "Spanish CV", lang: "es", wantNil: false, }, { name: "French CV (not loaded)", lang: "fr", wantNil: true, }, { name: "Empty language", lang: "", wantNil: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { cv := cache.GetCV(tt.lang) if tt.wantNil && cv != nil { t.Error("Expected nil but got CV") } if !tt.wantNil && cv == nil { t.Error("Expected CV but got nil") } }) } } // TestGetUI tests UI data retrieval func TestGetUI(t *testing.T) { cache, err := New([]string{"en", "es"}) if err != nil { t.Fatalf("Failed to create cache: %v", err) } tests := []struct { name string lang string wantNil bool }{ { name: "English UI", lang: "en", wantNil: false, }, { name: "Spanish UI", lang: "es", wantNil: false, }, { name: "French UI (not loaded)", lang: "fr", wantNil: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ui := cache.GetUI(tt.lang) if tt.wantNil && ui != nil { t.Error("Expected nil but got UI") } if !tt.wantNil && ui == nil { t.Error("Expected UI but got nil") } }) } } // TestLanguages tests language list retrieval func TestLanguages(t *testing.T) { cache, err := New([]string{"en", "es"}) if err != nil { t.Fatalf("Failed to create cache: %v", err) } langs := cache.Languages() if len(langs) != 2 { t.Errorf("Expected 2 languages, got %d", len(langs)) } // Check both languages are present (order may vary) hasEn, hasEs := false, false for _, l := range langs { if l == "en" { hasEn = true } if l == "es" { hasEs = true } } if !hasEn || !hasEs { t.Errorf("Expected en and es, got %v", langs) } } // TestConcurrentAccess tests thread safety func TestConcurrentAccess(t *testing.T) { cache, err := New([]string{"en", "es"}) if err != nil { t.Fatalf("Failed to create cache: %v", err) } var wg sync.WaitGroup errors := make(chan error, 100) // Simulate 100 concurrent reads for i := 0; i < 100; i++ { wg.Add(1) go func(i int) { defer wg.Done() lang := "en" if i%2 == 0 { lang = "es" } cv := cache.GetCV(lang) if cv == nil { errors <- nil // Should not happen } ui := cache.GetUI(lang) if ui == nil { errors <- nil // Should not happen } }(i) } wg.Wait() close(errors) // Check for any errors for err := range errors { if err != nil { t.Errorf("Concurrent access error: %v", err) } } } // TestDataIntegrity tests that cached data is complete func TestDataIntegrity(t *testing.T) { cache, err := New([]string{"en", "es"}) if err != nil { t.Fatalf("Failed to create cache: %v", err) } for _, lang := range []string{"en", "es"} { t.Run(lang, func(t *testing.T) { cv := cache.GetCV(lang) if cv == nil { t.Fatal("CV is nil") } // Check CV has essential fields if cv.Personal.Name == "" { t.Error("CV name is empty") } if len(cv.Experience) == 0 { t.Error("CV has no experiences") } if len(cv.Projects) == 0 { t.Error("CV has no projects") } ui := cache.GetUI(lang) if ui == nil { t.Fatal("UI is nil") } // Check UI has essential fields if ui.Navigation.Experience == "" { t.Error("UI navigation experience is empty") } }) } }