package platform import ( "context" "errors" "reflect" "testing" ) type fakeRunner struct { runCalls [][]string outputCalls [][]string outputErr error output []byte } func (f *fakeRunner) Run(_ context.Context, name string, args ...string) error { f.runCalls = append(f.runCalls, append([]string{name}, args...)) return nil } func (f *fakeRunner) Output(_ context.Context, name string, args ...string) ([]byte, error) { f.outputCalls = append(f.outputCalls, append([]string{name}, args...)) return f.output, f.outputErr } func TestPacmanInstallShellsOutCorrectly(t *testing.T) { r := &fakeRunner{} p := NewPacman(r) if err := p.Install(context.Background(), []string{"tio", "git"}); err != nil { t.Fatal(err) } if len(r.runCalls) != 1 { t.Fatalf("run calls = %d", len(r.runCalls)) } want := []string{"sudo", "pacman", "-S", "--needed", "--noconfirm", "tio", "git"} if !reflect.DeepEqual(r.runCalls[0], want) { t.Fatalf("args = %v, want %v", r.runCalls[0], want) } } func TestPacmanInstallEmptyIsNoop(t *testing.T) { r := &fakeRunner{} p := NewPacman(r) if err := p.Install(context.Background(), nil); err != nil { t.Fatal(err) } if len(r.runCalls) != 0 { t.Fatalf("expected no calls, got %v", r.runCalls) } } func TestPacmanIsInstalledTrue(t *testing.T) { r := &fakeRunner{output: []byte("tio 3.2-1")} p := NewPacman(r) ok, err := p.IsInstalled(context.Background(), "tio") if err != nil { t.Fatal(err) } if !ok { t.Fatal("want installed=true") } } func TestPacmanIsInstalledFalseOnError(t *testing.T) { r := &fakeRunner{outputErr: errors.New("not found")} p := NewPacman(r) ok, err := p.IsInstalled(context.Background(), "ghost") if err != nil { t.Fatal(err) } if ok { t.Fatal("want installed=false") } } func TestPacmanUpdate(t *testing.T) { r := &fakeRunner{} p := NewPacman(r) if err := p.Update(context.Background()); err != nil { t.Fatal(err) } want := []string{"sudo", "pacman", "-Sy"} if !reflect.DeepEqual(r.runCalls[0], want) { t.Fatalf("args = %v, want %v", r.runCalls[0], want) } }