mirror of
https://github.com/jesseduffield/lazygit.git
synced 2024-12-14 11:23:09 +02:00
7b302d8c29
Afero is a package that lets you mock out a filesystem with an in-memory filesystem. It allows us to easily create the files required for a given test without worrying about a cleanup step or different tests tripping on eachother when run in parallel. Later on I'll standardise on using afero over the vanilla os package
239 lines
6.0 KiB
Go
239 lines
6.0 KiB
Go
package git_commands
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/go-errors/errors"
|
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
|
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
|
"github.com/spf13/afero"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestGetWorktrees(t *testing.T) {
|
|
type scenario struct {
|
|
testName string
|
|
repoPaths *RepoPaths
|
|
before func(runner *oscommands.FakeCmdObjRunner, fs afero.Fs)
|
|
expectedWorktrees []*models.Worktree
|
|
expectedErr string
|
|
}
|
|
|
|
scenarios := []scenario{
|
|
{
|
|
testName: "Single worktree (main)",
|
|
repoPaths: &RepoPaths{
|
|
repoPath: "/path/to/repo",
|
|
worktreePath: "/path/to/repo",
|
|
},
|
|
before: func(runner *oscommands.FakeCmdObjRunner, fs afero.Fs) {
|
|
runner.ExpectGitArgs([]string{"worktree", "list", "--porcelain"},
|
|
`worktree /path/to/repo
|
|
HEAD d85cc9d281fa6ae1665c68365fc70e75e82a042d
|
|
branch refs/heads/mybranch
|
|
`,
|
|
nil)
|
|
|
|
_ = fs.MkdirAll("/path/to/repo/.git", 0o755)
|
|
},
|
|
expectedWorktrees: []*models.Worktree{
|
|
{
|
|
IsMain: true,
|
|
IsCurrent: true,
|
|
Path: "/path/to/repo",
|
|
IsPathMissing: false,
|
|
GitDir: "/path/to/repo/.git",
|
|
Branch: "mybranch",
|
|
Name: "repo",
|
|
},
|
|
},
|
|
expectedErr: "",
|
|
},
|
|
{
|
|
testName: "Multiple worktrees (main + linked)",
|
|
repoPaths: &RepoPaths{
|
|
repoPath: "/path/to/repo",
|
|
worktreePath: "/path/to/repo",
|
|
},
|
|
before: func(runner *oscommands.FakeCmdObjRunner, fs afero.Fs) {
|
|
runner.ExpectGitArgs([]string{"worktree", "list", "--porcelain"},
|
|
`worktree /path/to/repo
|
|
HEAD d85cc9d281fa6ae1665c68365fc70e75e82a042d
|
|
branch refs/heads/mybranch
|
|
|
|
worktree /path/to/repo-worktree
|
|
HEAD 775955775e79b8f5b4c4b56f82fbf657e2d5e4de
|
|
branch refs/heads/mybranch-worktree
|
|
`,
|
|
nil)
|
|
|
|
_ = fs.MkdirAll("/path/to/repo/.git", 0o755)
|
|
_ = fs.MkdirAll("/path/to/repo-worktree", 0o755)
|
|
_ = fs.MkdirAll("/path/to/repo/.git/worktrees/repo-worktree", 0o755)
|
|
_ = afero.WriteFile(fs, "/path/to/repo-worktree/.git", []byte("gitdir: /path/to/repo/.git/worktrees/repo-worktree"), 0o755)
|
|
},
|
|
expectedWorktrees: []*models.Worktree{
|
|
{
|
|
IsMain: true,
|
|
IsCurrent: true,
|
|
Path: "/path/to/repo",
|
|
IsPathMissing: false,
|
|
GitDir: "/path/to/repo/.git",
|
|
Branch: "mybranch",
|
|
Name: "repo",
|
|
},
|
|
{
|
|
IsMain: false,
|
|
IsCurrent: false,
|
|
Path: "/path/to/repo-worktree",
|
|
IsPathMissing: false,
|
|
GitDir: "/path/to/repo/.git/worktrees/repo-worktree",
|
|
Branch: "mybranch-worktree",
|
|
Name: "repo-worktree",
|
|
},
|
|
},
|
|
expectedErr: "",
|
|
},
|
|
{
|
|
testName: "Worktree missing path",
|
|
repoPaths: &RepoPaths{
|
|
repoPath: "/path/to/repo",
|
|
worktreePath: "/path/to/repo",
|
|
},
|
|
before: func(runner *oscommands.FakeCmdObjRunner, fs afero.Fs) {
|
|
runner.ExpectGitArgs([]string{"worktree", "list", "--porcelain"},
|
|
`worktree /path/to/worktree
|
|
HEAD 775955775e79b8f5b4c4b56f82fbf657e2d5e4de
|
|
branch refs/heads/missingbranch
|
|
`,
|
|
nil)
|
|
|
|
_ = fs.MkdirAll("/path/to/repo/.git", 0o755)
|
|
},
|
|
expectedWorktrees: []*models.Worktree{
|
|
{
|
|
IsMain: false,
|
|
IsCurrent: false,
|
|
Path: "/path/to/worktree",
|
|
IsPathMissing: true,
|
|
GitDir: "",
|
|
Branch: "missingbranch",
|
|
Name: "worktree",
|
|
},
|
|
},
|
|
expectedErr: "",
|
|
},
|
|
{
|
|
testName: "In linked worktree",
|
|
repoPaths: &RepoPaths{
|
|
repoPath: "/path/to/repo",
|
|
worktreePath: "/path/to/repo-worktree",
|
|
},
|
|
before: func(runner *oscommands.FakeCmdObjRunner, fs afero.Fs) {
|
|
runner.ExpectGitArgs([]string{"worktree", "list", "--porcelain"},
|
|
`worktree /path/to/repo
|
|
HEAD d85cc9d281fa6ae1665c68365fc70e75e82a042d
|
|
branch refs/heads/mybranch
|
|
|
|
worktree /path/to/repo-worktree
|
|
HEAD 775955775e79b8f5b4c4b56f82fbf657e2d5e4de
|
|
branch refs/heads/mybranch-worktree
|
|
`,
|
|
nil)
|
|
|
|
_ = fs.MkdirAll("/path/to/repo/.git", 0o755)
|
|
_ = fs.MkdirAll("/path/to/repo-worktree", 0o755)
|
|
_ = fs.MkdirAll("/path/to/repo/.git/worktrees/repo-worktree", 0o755)
|
|
_ = afero.WriteFile(fs, "/path/to/repo-worktree/.git", []byte("gitdir: /path/to/repo/.git/worktrees/repo-worktree"), 0o755)
|
|
},
|
|
expectedWorktrees: []*models.Worktree{
|
|
{
|
|
IsMain: false,
|
|
IsCurrent: true,
|
|
Path: "/path/to/repo-worktree",
|
|
IsPathMissing: false,
|
|
GitDir: "/path/to/repo/.git/worktrees/repo-worktree",
|
|
Branch: "mybranch-worktree",
|
|
Name: "repo-worktree",
|
|
},
|
|
{
|
|
IsMain: true,
|
|
IsCurrent: false,
|
|
Path: "/path/to/repo",
|
|
IsPathMissing: false,
|
|
GitDir: "/path/to/repo/.git",
|
|
Branch: "mybranch",
|
|
Name: "repo",
|
|
},
|
|
},
|
|
expectedErr: "",
|
|
},
|
|
}
|
|
|
|
for _, s := range scenarios {
|
|
s := s
|
|
t.Run(s.testName, func(t *testing.T) {
|
|
runner := oscommands.NewFakeRunner(t)
|
|
fs := afero.NewMemMapFs()
|
|
s.before(runner, fs)
|
|
|
|
loader := &WorktreeLoader{
|
|
GitCommon: buildGitCommon(commonDeps{runner: runner, fs: fs, repoPaths: s.repoPaths}),
|
|
}
|
|
|
|
worktrees, err := loader.GetWorktrees()
|
|
if s.expectedErr != "" {
|
|
assert.EqualError(t, errors.New(s.expectedErr), err.Error())
|
|
} else {
|
|
assert.NoError(t, err)
|
|
assert.EqualValues(t, worktrees, s.expectedWorktrees)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetUniqueNamesFromPaths(t *testing.T) {
|
|
for _, scenario := range []struct {
|
|
input []string
|
|
expected []string
|
|
}{
|
|
{
|
|
input: []string{},
|
|
expected: []string{},
|
|
},
|
|
{
|
|
input: []string{
|
|
"/my/path/feature/one",
|
|
},
|
|
expected: []string{
|
|
"one",
|
|
},
|
|
},
|
|
{
|
|
input: []string{
|
|
"/my/path/feature/one/",
|
|
},
|
|
expected: []string{
|
|
"one",
|
|
},
|
|
},
|
|
{
|
|
input: []string{
|
|
"/a/b/c/d",
|
|
"/a/b/c/e",
|
|
"/a/b/f/d",
|
|
"/a/e/c/d",
|
|
},
|
|
expected: []string{
|
|
"b/c/d",
|
|
"e",
|
|
"f/d",
|
|
"e/c/d",
|
|
},
|
|
},
|
|
} {
|
|
actual := getUniqueNamesFromPaths(scenario.input)
|
|
assert.EqualValues(t, scenario.expected, actual)
|
|
}
|
|
}
|