package providers import ( "os" "path/filepath" "testing" ) func TestNewHyprlandProvider(t *testing.T) { tests := []struct { name string configPath string wantPath string }{ { name: "custom path", configPath: "/custom/path", wantPath: "/custom/path", }, { name: "empty path defaults", configPath: "", wantPath: "$HOME/.config/hypr", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { p := NewHyprlandProvider(tt.configPath) if p == nil { t.Fatal("NewHyprlandProvider returned nil") } if p.configPath != tt.wantPath { t.Errorf("configPath = %q, want %q", p.configPath, tt.wantPath) } }) } } func TestHyprlandProviderName(t *testing.T) { p := NewHyprlandProvider("") if p.Name() != "hyprland" { t.Errorf("Name() = %q, want %q", p.Name(), "hyprland") } } func TestHyprlandProviderGetCheatSheet(t *testing.T) { tmpDir := t.TempDir() configFile := filepath.Join(tmpDir, "hyprland.conf") content := `##! Window Management bind = SUPER, Q, killactive bind = SUPER, F, fullscreen, 0 ###! Movement bind = SUPER, left, movefocus, l bind = SUPER, right, movefocus, r ##! Applications bind = SUPER, T, exec, kitty # Terminal bind = SUPER, 1, workspace, 1 ` if err := os.WriteFile(configFile, []byte(content), 0644); err != nil { t.Fatalf("Failed to write test config: %v", err) } p := NewHyprlandProvider(tmpDir) sheet, err := p.GetCheatSheet() if err != nil { t.Fatalf("GetCheatSheet failed: %v", err) } if sheet.Title != "Hyprland Keybinds" { t.Errorf("Title = %q, want %q", sheet.Title, "Hyprland Keybinds") } if sheet.Provider != "hyprland" { t.Errorf("Provider = %q, want %q", sheet.Provider, "hyprland") } if len(sheet.Binds) == 0 { t.Error("expected categorized bindings, got none") } if windowBinds, ok := sheet.Binds["Window"]; !ok || len(windowBinds) == 0 { t.Error("expected Window category with bindings") } if execBinds, ok := sheet.Binds["Execute"]; !ok || len(execBinds) == 0 { t.Error("expected Execute category with bindings") } if wsBinds, ok := sheet.Binds["Workspace"]; !ok || len(wsBinds) == 0 { t.Error("expected Workspace category with bindings") } } func TestHyprlandProviderGetCheatSheetError(t *testing.T) { p := NewHyprlandProvider("/nonexistent/path") _, err := p.GetCheatSheet() if err == nil { t.Error("expected error for nonexistent path, got nil") } } func TestFormatKey(t *testing.T) { tmpDir := t.TempDir() configFile := filepath.Join(tmpDir, "test.conf") tests := []struct { name string content string expected string category string }{ { name: "single mod", content: "bind = SUPER, Q, killactive", expected: "SUPER+Q", category: "Window", }, { name: "multiple mods", content: "bind = SUPER+SHIFT, F, fullscreen, 0", expected: "SUPER+SHIFT+F", category: "Window", }, { name: "no mods", content: "bind = , Print, exec, screenshot", expected: "Print", category: "Execute", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := os.WriteFile(configFile, []byte(tt.content), 0644); err != nil { t.Fatalf("Failed to write test config: %v", err) } p := NewHyprlandProvider(tmpDir) sheet, err := p.GetCheatSheet() if err != nil { t.Fatalf("GetCheatSheet failed: %v", err) } categoryBinds, ok := sheet.Binds[tt.category] if !ok || len(categoryBinds) == 0 { t.Fatalf("expected binds in category %q", tt.category) } if categoryBinds[0].Key != tt.expected { t.Errorf("Key = %q, want %q", categoryBinds[0].Key, tt.expected) } }) } } func TestDescriptionFallback(t *testing.T) { tmpDir := t.TempDir() configFile := filepath.Join(tmpDir, "test.conf") tests := []struct { name string content string wantDesc string }{ { name: "autogenerated description for known dispatcher", content: "bind = SUPER, Q, killactive", wantDesc: "Close window", }, { name: "custom comment overrides autogeneration", content: "bind = SUPER, T, exec, kitty # Open terminal", wantDesc: "Open terminal", }, { name: "fallback for unknown dispatcher without params", content: "bind = SUPER, W, unknowndispatcher", wantDesc: "unknowndispatcher", }, { name: "fallback for unknown dispatcher with params", content: "bind = SUPER, X, customdispatcher, arg1", wantDesc: "customdispatcher arg1", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := os.WriteFile(configFile, []byte(tt.content), 0644); err != nil { t.Fatalf("Failed to write test config: %v", err) } p := NewHyprlandProvider(tmpDir) sheet, err := p.GetCheatSheet() if err != nil { t.Fatalf("GetCheatSheet failed: %v", err) } found := false for _, binds := range sheet.Binds { for _, bind := range binds { if bind.Description == tt.wantDesc { found = true break } } if found { break } } if !found { t.Errorf("expected description %q not found in any bind", tt.wantDesc) } }) } }