package git import ( "os" "os/exec" "strings" "testing" ) func TestIsRepo(t *testing.T) { // This test assumes we're running in a git repo result := IsRepo() if !result { t.Log("Warning: Not in a git repository, test may be running in unexpected environment") } } func TestRun(t *testing.T) { tests := []struct { name string args []string shouldErr bool }{ { name: "version command succeeds", args: []string{"--version"}, shouldErr: false, }, { name: "invalid command fails", args: []string{"invalid-command-xyz"}, shouldErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { output, err := Run(tt.args) if tt.shouldErr { if err == nil { t.Errorf("Run() expected error, got nil") } } else { if err != nil { t.Errorf("Run() unexpected error: %v", err) } if output == "" { t.Errorf("Run() expected output, got empty string") } } }) } } func TestGitRunner(t *testing.T) { runner := NewRunner() // Test Run output, err := runner.Run([]string{"--version"}) if err != nil { t.Errorf("GitRunner.Run() unexpected error: %v", err) } if output == "" { t.Errorf("GitRunner.Run() expected output, got empty string") } // Test IsRepo _ = runner.IsRepo() // Just ensure it doesn't panic } // initTaggedGitRepo creates a temp git repo with an initial commit and a tag. func initTaggedGitRepo(t *testing.T) string { t.Helper() tmpDir := t.TempDir() cmds := [][]string{ {"git", "init"}, {"git", "config", "user.email", "test@test.com"}, {"git", "config", "user.name", "Test"}, } for _, args := range cmds { cmd := exec.Command(args[0], args[1:]...) cmd.Dir = tmpDir if out, err := cmd.CombinedOutput(); err != nil { t.Fatalf("git setup failed (%v): %s", err, out) } } // Create initial commit and tag if err := os.WriteFile(tmpDir+"/init.txt", []byte("init"), 0644); err != nil { t.Fatal(err) } for _, args := range [][]string{ {"git", "add", "."}, {"git", "commit", "-m", "initial commit"}, {"git", "tag", "v0.1.0"}, } { cmd := exec.Command(args[0], args[1:]...) cmd.Dir = tmpDir if out, err := cmd.CombinedOutput(); err != nil { t.Fatalf("git setup (%v) failed: %s", args, out) } } return tmpDir } func TestLatestTag(t *testing.T) { tmpDir := initTaggedGitRepo(t) origDir, _ := os.Getwd() if err := os.Chdir(tmpDir); err != nil { t.Fatal(err) } defer func() { _ = os.Chdir(origDir) }() tag, err := LatestTag() if err != nil { t.Fatalf("LatestTag() failed: %v", err) } if tag != "v0.1.0" { t.Errorf("LatestTag() = %q, want 'v0.1.0'", tag) } } func TestLatestTagMultiple(t *testing.T) { tmpDir := initTaggedGitRepo(t) origDir, _ := os.Getwd() if err := os.Chdir(tmpDir); err != nil { t.Fatal(err) } defer func() { _ = os.Chdir(origDir) }() // Add a second commit and tag if err := os.WriteFile("second.txt", []byte("second"), 0644); err != nil { t.Fatal(err) } exec.Command("git", "add", ".").Run() exec.Command("git", "commit", "-m", "second commit").Run() exec.Command("git", "tag", "v0.2.0").Run() tag, err := LatestTag() if err != nil { t.Fatalf("LatestTag() failed: %v", err) } if tag != "v0.2.0" { t.Errorf("LatestTag() = %q, want 'v0.2.0'", tag) } } func TestPreviousTag(t *testing.T) { tmpDir := initTaggedGitRepo(t) origDir, _ := os.Getwd() if err := os.Chdir(tmpDir); err != nil { t.Fatal(err) } defer func() { _ = os.Chdir(origDir) }() // Add second commit and tag if err := os.WriteFile("second.txt", []byte("second"), 0644); err != nil { t.Fatal(err) } exec.Command("git", "add", ".").Run() exec.Command("git", "commit", "-m", "second commit").Run() exec.Command("git", "tag", "v0.2.0").Run() prev, err := PreviousTag("v0.2.0") if err != nil { t.Fatalf("PreviousTag() failed: %v", err) } if prev != "v0.1.0" { t.Errorf("PreviousTag('v0.2.0') = %q, want 'v0.1.0'", prev) } } func TestLogSince(t *testing.T) { tmpDir := initTaggedGitRepo(t) origDir, _ := os.Getwd() if err := os.Chdir(tmpDir); err != nil { t.Fatal(err) } defer func() { _ = os.Chdir(origDir) }() // Add commits after the tag if err := os.WriteFile("new.txt", []byte("new"), 0644); err != nil { t.Fatal(err) } exec.Command("git", "add", ".").Run() exec.Command("git", "commit", "-m", "feat: add new feature").Run() log, err := LogSince("v0.1.0") if err != nil { t.Fatalf("LogSince() failed: %v", err) } if !strings.Contains(log, "feat: add new feature") { t.Errorf("LogSince() missing expected commit message, got: %q", log) } } func TestDiff(t *testing.T) { tmpDir := initTaggedGitRepo(t) origDir, _ := os.Getwd() if err := os.Chdir(tmpDir); err != nil { t.Fatal(err) } defer func() { _ = os.Chdir(origDir) }() t.Run("no changes returns empty", func(t *testing.T) { out, err := Diff([]string{"diff"}) if err != nil { t.Fatalf("Diff() failed: %v", err) } if out != "" { t.Errorf("Diff() with no changes = %q, want empty", out) } }) t.Run("with unstaged changes returns diff", func(t *testing.T) { if err := os.WriteFile("init.txt", []byte("modified"), 0644); err != nil { t.Fatal(err) } out, err := Diff([]string{"diff"}) if err != nil { t.Fatalf("Diff() failed: %v", err) } if !strings.Contains(out, "modified") { t.Errorf("Diff() missing change content, got: %q", out) } }) }