code-intelligence.com/cifuzz@v0.40.0/pkg/vcs/git_test.go (about)

     1  package vcs_test
     2  
     3  import (
     4  	"os"
     5  	"os/exec"
     6  	"path/filepath"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"code-intelligence.com/cifuzz/internal/testutil"
    12  	"code-intelligence.com/cifuzz/pkg/vcs"
    13  	"code-intelligence.com/cifuzz/util/fileutil"
    14  )
    15  
    16  // Tests can't run in parallel as they change the current working directory.
    17  
    18  func TestGitBranch(t *testing.T) {
    19  	repo := createGitRepoWithCommits(t)
    20  	defer os.RemoveAll(repo)
    21  	err := os.Chdir(repo)
    22  	require.NoError(t, err)
    23  
    24  	branch, err := vcs.GitBranch()
    25  	require.NoError(t, err)
    26  	require.Equal(t, "main", branch)
    27  
    28  	runGit(t, "", "checkout", "HEAD~")
    29  	branch, err = vcs.GitBranch()
    30  	require.NoError(t, err)
    31  	require.Equal(t, "HEAD", branch)
    32  }
    33  
    34  func TestGitCommit(t *testing.T) {
    35  	repo := createGitRepoWithCommits(t)
    36  	defer os.RemoveAll(repo)
    37  	err := os.Chdir(repo)
    38  	require.NoError(t, err)
    39  
    40  	commit1, err := vcs.GitCommit()
    41  	require.NoError(t, err)
    42  	// Verify that we obtain a full SHA-1 hash.
    43  	require.Equalf(t, 40, len(commit1), "Expected full commit SHA, got %q", commit1)
    44  
    45  	runGit(t, "", "checkout", "HEAD~")
    46  	commit2, err := vcs.GitCommit()
    47  	require.NoError(t, err)
    48  	require.Equalf(t, 40, len(commit2), "Expected full commit SHA, got %q", commit2)
    49  
    50  	require.NotEqual(t, commit1, commit2)
    51  }
    52  
    53  func TestGitIsDirty(t *testing.T) {
    54  	repo := createGitRepoWithCommits(t)
    55  	defer os.RemoveAll(repo)
    56  	err := os.Chdir(repo)
    57  	require.NoError(t, err)
    58  
    59  	require.False(t, vcs.GitIsDirty())
    60  
    61  	// Verify that modified files trigger a "dirty" state.
    62  	err = os.WriteFile("empty_file", []byte("changed"), 0644)
    63  	require.NoError(t, err)
    64  	require.True(t, vcs.GitIsDirty())
    65  
    66  	// Reset modifications.
    67  	runGit(t, "", "checkout", "--", ".")
    68  	require.False(t, vcs.GitIsDirty())
    69  
    70  	// Verify that untracked files trigger a "dirty" state.
    71  	err = fileutil.Touch("third_file")
    72  	require.NoError(t, err)
    73  	require.True(t, vcs.GitIsDirty())
    74  }
    75  
    76  func createGitRepoWithCommits(t *testing.T) string {
    77  	t.Helper()
    78  
    79  	repo := testutil.MkdirTemp(t, "", "git-test-*")
    80  
    81  	runGit(t, repo, "init")
    82  	runGit(t, repo, "config", "user.email", "you@example.com")
    83  	runGit(t, repo, "config", "user.name", "Your Name")
    84  
    85  	// Ensure that the main branch is called "main" even with older Git versions.
    86  	runGit(t, repo, "branch", "-M", "main")
    87  
    88  	err := fileutil.Touch(filepath.Join(repo, "empty_file"))
    89  	require.NoError(t, err)
    90  	runGit(t, repo, "add", "empty_file")
    91  	runGit(t, repo, "commit", "-m", "Initial commit")
    92  
    93  	err = fileutil.Touch(filepath.Join(repo, "other_file"))
    94  	require.NoError(t, err)
    95  	runGit(t, repo, "add", "other_file")
    96  	runGit(t, repo, "commit", "-m", "Second commit")
    97  
    98  	return repo
    99  }
   100  
   101  func runGit(t *testing.T, repo string, args ...string) {
   102  	cmd := exec.Command("git", args...)
   103  	cmd.Dir = repo
   104  	cmd.Stdout = os.Stdout
   105  	cmd.Stderr = os.Stderr
   106  	err := cmd.Run()
   107  	require.NoError(t, err)
   108  }