package commands
import (
"fmt"
"io/ioutil"
"regexp"
"testing"
"github.com/go-errors/errors"
"github.com/jesseduffield/lazygit/pkg/commands/git_config"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/stretchr/testify/assert"
)
func TestGitCommandStageFile(t *testing.T) {
runner := oscommands.NewFakeRunner(t).
ExpectArgs([]string{"git", "add", "--", "test.txt"}, "", nil)
gitCmd := NewDummyGitCommandWithRunner(runner)
assert.NoError(t, gitCmd.StageFile("test.txt"))
runner.CheckForMissingCalls()
}
func TestGitCommandUnstageFile(t *testing.T) {
type scenario struct {
testName string
reset bool
runner *oscommands.FakeCmdObjRunner
test func(error)
}
scenarios := []scenario{
{
testName: "Remove an untracked file from staging",
reset: false,
runner: oscommands.NewFakeRunner(t).
ExpectArgs([]string{"git", "rm", "--cached", "--force", "--", "test.txt"}, "", nil),
test: func(err error) {
assert.NoError(t, err)
},
},
{
testName: "Remove a tracked file from staging",
reset: true,
runner: oscommands.NewFakeRunner(t).
ExpectArgs([]string{"git", "reset", "HEAD", "--", "test.txt"}, "", nil),
test: func(err error) {
assert.NoError(t, err)
},
},
}
for _, s := range scenarios {
t.Run(s.testName, func(t *testing.T) {
gitCmd := NewDummyGitCommandWithRunner(s.runner)
s.test(gitCmd.UnStageFile([]string{"test.txt"}, s.reset))
})
}
}
// these tests don't cover everything, in part because we already have an integration
// test which does cover everything. I don't want to unnecessarily assert on the 'how'
// when the 'what' is what matters
func TestGitCommandDiscardAllFileChanges(t *testing.T) {
type scenario struct {
testName string
file *models.File
removeFile func(string) error
runner *oscommands.FakeCmdObjRunner
expectedError string
}
scenarios := []scenario{
{
testName: "An error occurred when resetting",
file: &models.File{
Name: "test",
HasStagedChanges: true,
},
removeFile: func(string) error { return nil },
runner: oscommands.NewFakeRunner(t).
ExpectArgs([]string{"git", "reset", "--", "test"}, "", errors.New("error")),
expectedError: "error",
},
{
testName: "An error occurred when removing file",
file: &models.File{
Name: "test",
Tracked: false,
Added: true,
},
removeFile: func(string) error {
return fmt.Errorf("an error occurred when removing file")
},
runner: oscommands.NewFakeRunner(t),
expectedError: "an error occurred when removing file",
},
{
testName: "An error occurred with checkout",
file: &models.File{
Name: "test",
Tracked: true,
HasStagedChanges: false,
},
removeFile: func(string) error { return nil },
runner: oscommands.NewFakeRunner(t).
ExpectArgs([]string{"git", "checkout", "--", "test"}, "", errors.New("error")),
expectedError: "error",
},
{
testName: "Checkout only",
file: &models.File{
Name: "test",
Tracked: true,
HasStagedChanges: false,
},
removeFile: func(string) error { return nil },
runner: oscommands.NewFakeRunner(t).
ExpectArgs([]string{"git", "checkout", "--", "test"}, "", nil),
expectedError: "",
},
{
testName: "Reset and checkout staged changes",
file: &models.File{
Name: "test",
Tracked: true,
HasStagedChanges: true,
},
removeFile: func(string) error { return nil },
runner: oscommands.NewFakeRunner(t).
ExpectArgs([]string{"git", "reset", "--", "test"}, "", nil).
ExpectArgs([]string{"git", "checkout", "--", "test"}, "", nil),
expectedError: "",
},
{
testName: "Reset and checkout merge conflicts",
file: &models.File{
Name: "test",
Tracked: true