From c1984528c8b8ee2d6d9ffdc50f31c1f81c7b97a3 Mon Sep 17 00:00:00 2001 From: Anthony HAMON Date: Wed, 29 Aug 2018 22:55:57 +0200 Subject: [PATCH] pkg/git : add tests for SetupGit --- pkg/commands/git.go | 117 ++++++++++++++++++++++----------------- pkg/commands/git_test.go | 70 +++++++++++++++++++++++ 2 files changed, 135 insertions(+), 52 deletions(-) diff --git a/pkg/commands/git.go b/pkg/commands/git.go index 68571769e..101a45515 100644 --- a/pkg/commands/git.go +++ b/pkg/commands/git.go @@ -19,21 +19,39 @@ import ( // to check if we have a valid git repository and we get an error instead var ErrGitRepositoryInvalid = fmt.Errorf("can't find a valid git repository in current directory") +func openGitRepositoryAndWorktree() (*gogit.Repository, *gogit.Worktree, error) { + r, err := gogit.PlainOpen(".") + + if err != nil { + return nil, nil, err + } + + w, err := r.Worktree() + + if err != nil { + return nil, nil, err + } + + return r, w, nil +} + // GitCommand is our main git interface type GitCommand struct { - Log *logrus.Entry - OSCommand *OSCommand - Worktree *gogit.Worktree - Repo *gogit.Repository - Tr *i18n.Localizer + Log *logrus.Entry + OSCommand *OSCommand + Worktree *gogit.Worktree + Repo *gogit.Repository + Tr *i18n.Localizer + openGitRepositoryAndWorktree func() (*gogit.Repository, *gogit.Worktree, error) } // NewGitCommand it runs git commands func NewGitCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Localizer) (*GitCommand, error) { gitCommand := &GitCommand{ - Log: log, - OSCommand: osCommand, - Tr: tr, + Log: log, + OSCommand: osCommand, + Tr: tr, + openGitRepositoryAndWorktree: openGitRepositoryAndWorktree, } return gitCommand, nil } @@ -43,7 +61,7 @@ func (c *GitCommand) SetupGit() error { fs := []func() error{ c.verifyInGitRepo, c.navigateToRepoRootDirectory, - c.setupWorktree, + c.setupRepositoryAndWorktree, } for _, f := range fs { @@ -55,6 +73,44 @@ func (c *GitCommand) SetupGit() error { return nil } +func (c *GitCommand) verifyInGitRepo() error { + if _, err := c.OSCommand.RunCommandWithOutput("git status"); err != nil { + return ErrGitRepositoryInvalid + } + + return nil +} + +func (c *GitCommand) navigateToRepoRootDirectory() error { + for { + f, err := os.Stat(".git") + + if err == nil && f.IsDir() { + return nil + } + + c.Log.Debug("going up a directory to find the root") + + if err = os.Chdir(".."); err != nil { + return err + } + } +} + +func (c *GitCommand) setupRepositoryAndWorktree() (err error) { + c.Repo, c.Worktree, err = c.openGitRepositoryAndWorktree() + + if err == nil { + return + } + + if strings.Contains(err.Error(), `unquoted '\' must be followed by new line`) { + return errors.New(c.Tr.SLocalize("GitconfigParseErr")) + } + + return +} + // GetStashEntries stash entryies func (c *GitCommand) GetStashEntries() []StashEntry { rawString, _ := c.OSCommand.RunCommandWithOutput("git stash list --pretty='%gs'") @@ -156,54 +212,11 @@ func (c *GitCommand) MergeStatusFiles(oldFiles, newFiles []File) []File { return append(headResults, tailResults...) } -func (c *GitCommand) verifyInGitRepo() error { - if _, err := c.OSCommand.RunCommandWithOutput("git status"); err != nil { - return ErrGitRepositoryInvalid - } - - return nil -} - // GetBranchName branch name func (c *GitCommand) GetBranchName() (string, error) { return c.OSCommand.RunCommandWithOutput("git symbolic-ref --short HEAD") } -func (c *GitCommand) navigateToRepoRootDirectory() error { - for { - f, err := os.Stat(".git") - - if err == nil && f.IsDir() { - return nil - } - - c.Log.Debug("going up a directory to find the root") - - if err = os.Chdir(".."); err != nil { - return err - } - } -} - -func (c *GitCommand) setupWorktree() error { - r, err := gogit.PlainOpen(".") - if err != nil { - if strings.Contains(err.Error(), `unquoted '\' must be followed by new line`) { - errorMessage := c.Tr.SLocalize("GitconfigParseErr") - return errors.New(errorMessage) - } - return err - } - c.Repo = r - - w, err := r.Worktree() - if err != nil { - return err - } - c.Worktree = w - return nil -} - // ResetHard does the equivalent of `git reset --hard HEAD` func (c *GitCommand) ResetHard() error { return c.Worktree.Reset(&gogit.ResetOptions{Mode: gogit.HardReset}) diff --git a/pkg/commands/git_test.go b/pkg/commands/git_test.go index fb3bafe6c..062e8ee3d 100644 --- a/pkg/commands/git_test.go +++ b/pkg/commands/git_test.go @@ -1,13 +1,16 @@ package commands import ( + "fmt" "io/ioutil" "os/exec" "testing" + "github.com/jesseduffield/lazygit/pkg/i18n" "github.com/jesseduffield/lazygit/pkg/test" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" + gogit "gopkg.in/src-d/go-git.v4" ) func newDummyLog() *logrus.Entry { @@ -20,6 +23,73 @@ func newDummyGitCommand() *GitCommand { return &GitCommand{ Log: newDummyLog(), OSCommand: newDummyOSCommand(), + Tr: i18n.NewLocalizer(newDummyLog()), + } +} + +func TestGitCommandSetupGit(t *testing.T) { + type scenario struct { + command func(string, ...string) *exec.Cmd + openGitRepositoryAndWorktree func() (*gogit.Repository, *gogit.Worktree, error) + test func(error) + } + + scenarios := []scenario{ + { + func(string, ...string) *exec.Cmd { + return exec.Command("exit", "1") + }, + func() (*gogit.Repository, *gogit.Worktree, error) { + return nil, nil, nil + }, + func(err error) { + assert.Error(t, err) + assert.Equal(t, ErrGitRepositoryInvalid, err) + }, + }, + { + func(string, ...string) *exec.Cmd { + return exec.Command("echo") + }, + func() (*gogit.Repository, *gogit.Worktree, error) { + return nil, nil, fmt.Errorf(`unquoted '\' must be followed by new line`) + }, + func(err error) { + assert.Error(t, err) + assert.Contains(t, err.Error(), "gitconfig") + }, + }, + { + func(string, ...string) *exec.Cmd { + return exec.Command("echo") + }, + func() (*gogit.Repository, *gogit.Worktree, error) { + return nil, nil, fmt.Errorf("Error from inside gogit") + }, + func(err error) { + assert.Error(t, err) + assert.EqualError(t, err, "Error from inside gogit") + }, + }, + { + func(string, ...string) *exec.Cmd { + return exec.Command("echo") + }, + func() (*gogit.Repository, *gogit.Worktree, error) { + return &gogit.Repository{}, &gogit.Worktree{}, nil + }, + func(err error) { + assert.NoError(t, err) + }, + }, + } + + for _, s := range scenarios { + gitCmd := newDummyGitCommand() + gitCmd.OSCommand.command = s.command + gitCmd.openGitRepositoryAndWorktree = s.openGitRepositoryAndWorktree + + s.test(gitCmd.SetupGit()) } }