Files
beads/cmd/bd/version_test.go
matt wilkie 0423fc689f fix: Add commit and branch to bd version output (github #503)
- Update Makefile install target to extract and pass git commit/branch via ldflags
- Add -X main.Commit and -X main.Branch to all build configurations in .goreleaser.yml
- Create scripts/install.sh helper for explicit version control during installation
- Add comprehensive tests for commit/branch resolution and output formatting

Fixes github #503: 'bd version' now reports as-built commit hash and branch
information regardless of installation method (make install, go install, or
released binaries from goreleaser).
2025-12-13 10:04:01 +11:00

266 lines
6.4 KiB
Go

package main
import (
"bytes"
"encoding/json"
"os"
"strings"
"testing"
)
func TestVersionCommand(t *testing.T) {
// Save original stdout
oldStdout := os.Stdout
defer func() { os.Stdout = oldStdout }()
t.Run("plain text version output", func(t *testing.T) {
// Create a pipe to capture output
r, w, err := os.Pipe()
if err != nil {
t.Fatalf("Failed to create pipe: %v", err)
}
os.Stdout = w
jsonOutput = false
// Run version command
versionCmd.Run(versionCmd, []string{})
// Close writer and read output
w.Close()
var buf bytes.Buffer
buf.ReadFrom(r)
output := buf.String()
// Verify output contains version info
if !strings.Contains(output, "bd version") {
t.Errorf("Expected output to contain 'bd version', got: %s", output)
}
if !strings.Contains(output, Version) {
t.Errorf("Expected output to contain version %s, got: %s", Version, output)
}
})
t.Run("json version output", func(t *testing.T) {
// Create a pipe to capture output
r, w, err := os.Pipe()
if err != nil {
t.Fatalf("Failed to create pipe: %v", err)
}
os.Stdout = w
jsonOutput = true
// Run version command
versionCmd.Run(versionCmd, []string{})
// Close writer and read output
w.Close()
var buf bytes.Buffer
buf.ReadFrom(r)
output := buf.String()
// Parse JSON output
var result map[string]string
if err := json.Unmarshal([]byte(output), &result); err != nil {
t.Fatalf("Failed to parse JSON output: %v", err)
}
// Verify JSON contains version and build
if result["version"] != Version {
t.Errorf("Expected version %s, got %s", Version, result["version"])
}
if result["build"] == "" {
t.Error("Expected build field to be non-empty")
}
})
// Restore default
jsonOutput = false
}
func TestResolveCommitHash(t *testing.T) {
// Save original Commit value
origCommit := Commit
defer func() { Commit = origCommit }()
t.Run("returns ldflag value when set", func(t *testing.T) {
testCommit := "abc123def456"
Commit = testCommit
result := resolveCommitHash()
if result != testCommit {
t.Errorf("Expected %q, got %q", testCommit, result)
}
})
t.Run("returns empty string when not set", func(t *testing.T) {
Commit = ""
result := resolveCommitHash()
// Result could be from git or empty - just verify it doesn't panic
if result == "" || len(result) >= 7 {
// Either empty or looks like a git hash
return
}
t.Errorf("Unexpected result format: %q", result)
})
}
func TestResolveBranch(t *testing.T) {
// Save original Branch value
origBranch := Branch
defer func() { Branch = origBranch }()
t.Run("returns ldflag value when set", func(t *testing.T) {
testBranch := "main"
Branch = testBranch
result := resolveBranch()
if result != testBranch {
t.Errorf("Expected %q, got %q", testBranch, result)
}
})
t.Run("returns empty string or git branch when not set", func(t *testing.T) {
Branch = ""
result := resolveBranch()
// Result could be from git or empty - just verify it doesn't panic
if result == "" || result == "main" || strings.Contains(result, "detached") {
return
}
t.Logf("Got branch: %q", result)
})
}
func TestVersionOutputWithCommitAndBranch(t *testing.T) {
// Save original values
oldStdout := os.Stdout
origCommit := Commit
origBranch := Branch
defer func() {
os.Stdout = oldStdout
Commit = origCommit
Branch = origBranch
}()
t.Run("text output includes commit and branch when available", func(t *testing.T) {
Commit = "7e709405b38c472d8cbc996c7cd26df7e3b438d0"
Branch = "main"
r, w, err := os.Pipe()
if err != nil {
t.Fatalf("Failed to create pipe: %v", err)
}
os.Stdout = w
jsonOutput = false
versionCmd.Run(versionCmd, []string{})
w.Close()
var buf bytes.Buffer
buf.ReadFrom(r)
output := buf.String()
// Should contain both branch and commit
if !strings.Contains(output, "main@") {
t.Errorf("Expected output to contain 'main@', got: %s", output)
}
if !strings.Contains(output, "7e70940") { // first 7 chars of commit
t.Errorf("Expected output to contain commit hash, got: %s", output)
}
})
t.Run("json output includes commit and branch when available", func(t *testing.T) {
Commit = "7e709405b38c472d8cbc996c7cd26df7e3b438d0"
Branch = "main"
r, w, err := os.Pipe()
if err != nil {
t.Fatalf("Failed to create pipe: %v", err)
}
os.Stdout = w
jsonOutput = true
versionCmd.Run(versionCmd, []string{})
w.Close()
var buf bytes.Buffer
buf.ReadFrom(r)
output := buf.String()
var result map[string]string
if err := json.Unmarshal([]byte(output), &result); err != nil {
t.Fatalf("Failed to parse JSON output: %v", err)
}
if result["commit"] != Commit {
t.Errorf("Expected commit %q, got %q", Commit, result["commit"])
}
if result["branch"] != Branch {
t.Errorf("Expected branch %q, got %q", Branch, result["branch"])
}
})
}
func TestVersionFlag(t *testing.T) {
// Save original stdout
oldStdout := os.Stdout
defer func() { os.Stdout = oldStdout }()
t.Run("--version flag", func(t *testing.T) {
// Create a pipe to capture output
r, w, err := os.Pipe()
if err != nil {
t.Fatalf("Failed to create pipe: %v", err)
}
os.Stdout = w
// Set version flag and run root command
rootCmd.SetArgs([]string{"--version"})
rootCmd.Execute()
// Close writer and read output
w.Close()
var buf bytes.Buffer
buf.ReadFrom(r)
output := buf.String()
// Verify output contains version info
if !strings.Contains(output, "bd version") {
t.Errorf("Expected output to contain 'bd version', got: %s", output)
}
if !strings.Contains(output, Version) {
t.Errorf("Expected output to contain version %s, got: %s", Version, output)
}
// Reset args
rootCmd.SetArgs(nil)
})
t.Run("-v shorthand", func(t *testing.T) {
// Create a pipe to capture output
r, w, err := os.Pipe()
if err != nil {
t.Fatalf("Failed to create pipe: %v", err)
}
os.Stdout = w
// Set version flag and run root command
rootCmd.SetArgs([]string{"-v"})
rootCmd.Execute()
// Close writer and read output
w.Close()
var buf bytes.Buffer
buf.ReadFrom(r)
output := buf.String()
// Verify output contains version info
if !strings.Contains(output, "bd version") {
t.Errorf("Expected output to contain 'bd version', got: %s", output)
}
if !strings.Contains(output, Version) {
t.Errorf("Expected output to contain version %s, got: %s", Version, output)
}
// Reset args
rootCmd.SetArgs(nil)
})
}