package platform import ( "context" "strings" "testing" ) type aurFakeRunner struct { runCalls [][]string outCalls [][]string // yayInstalled toggles what `pacman -Q yay` returns. yayInstalled bool } func (f *aurFakeRunner) Run(_ context.Context, name string, args ...string) error { f.runCalls = append(f.runCalls, append([]string{name}, args...)) return nil } func (f *aurFakeRunner) Output(_ context.Context, name string, args ...string) ([]byte, error) { f.outCalls = append(f.outCalls, append([]string{name}, args...)) if name == "pacman" && len(args) == 2 && args[0] == "-Q" && args[1] == "yay" { if f.yayInstalled { return []byte("yay 12.0-1\n"), nil } return nil, &fakeExitErr{} } return nil, nil } type fakeExitErr struct{} func (fakeExitErr) Error() string { return "exit 1" } func TestAUREnsureInstalledSkipsWhenYayPresent(t *testing.T) { r := &aurFakeRunner{yayInstalled: true} y := NewYay(r) if err := y.EnsureInstalled(context.Background()); err != nil { t.Fatal(err) } if len(r.runCalls) != 0 { t.Fatalf("no installs expected, got %v", r.runCalls) } } func TestAUREnsureInstalledBootstrapsYay(t *testing.T) { r := &aurFakeRunner{yayInstalled: false} y := NewYay(r) if err := y.EnsureInstalled(context.Background()); err != nil { t.Fatal(err) } // Expect: pacman install base-devel+git, git clone yay, makepkg -si in that dir. sawPacman := false sawClone := false sawMakepkg := false for _, c := range r.runCalls { if len(c) >= 2 && c[0] == "sudo" && c[1] == "pacman" { sawPacman = true } if len(c) >= 2 && c[0] == "git" && c[1] == "clone" { sawClone = true } if len(c) >= 3 && c[0] == "sh" && c[1] == "-c" && strings.Contains(c[2], "makepkg") { sawMakepkg = true } } if !sawPacman || !sawClone || !sawMakepkg { t.Fatalf("missing bootstrap step; calls=%v", r.runCalls) } } func TestAURInstall(t *testing.T) { r := &aurFakeRunner{yayInstalled: true} y := NewYay(r) if err := y.Install(context.Background(), []string{"ttf-jetbrains-mono-nerd"}); err != nil { t.Fatal(err) } if len(r.runCalls) == 0 { t.Fatal("expected yay install call") } c := r.runCalls[len(r.runCalls)-1] want := []string{"yay", "-S", "--needed", "--noconfirm", "ttf-jetbrains-mono-nerd"} for i, w := range want { if i >= len(c) || c[i] != w { t.Fatalf("call = %v, want %v", c, want) } } }