lazygit/pkg/gui/presentation/files_test.go
Stefan Haller e27bc15bbd Store Commit.Hash by pointer (kept in a pool of hashes)
This in itself is not an improvement, because hashes are unique (they are shared
between real commits and rebase todos, but there are so few of those that it
doesn't matter). However, it becomes an improvement once we also store parent
hashes in the same pool; but the real motivation for this change is to also
reuse the hash pointers in Pipe objects later in the branch. This will be a big
win because in a merge-heavy git repo there are many more Pipe instances than
commits.
2025-04-29 14:57:15 +02:00

171 lines
4.6 KiB
Go

package presentation
import (
"strings"
"testing"
"github.com/gookit/color"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/patch"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/stretchr/testify/assert"
"github.com/xo/terminfo"
)
func toStringSlice(str string) []string {
return strings.Split(strings.TrimSpace(str), "\n")
}
func TestRenderFileTree(t *testing.T) {
scenarios := []struct {
name string
root *filetree.FileNode
files []*models.File
collapsedPaths []string
showLineChanges bool
expected []string
}{
{
name: "nil node",
files: nil,
expected: []string{},
},
{
name: "leaf node",
files: []*models.File{
{Path: "test", ShortStatus: " M", HasStagedChanges: true},
},
expected: []string{" M test"},
},
{
name: "numstat",
files: []*models.File{
{Path: "test", ShortStatus: " M", HasStagedChanges: true, LinesAdded: 1, LinesDeleted: 1},
{Path: "test2", ShortStatus: " M", HasStagedChanges: true, LinesAdded: 1},
{Path: "test3", ShortStatus: " M", HasStagedChanges: true, LinesDeleted: 1},
{Path: "test4", ShortStatus: " M", HasStagedChanges: true, LinesAdded: 0, LinesDeleted: 0},
},
showLineChanges: true,
expected: []string{
"▼ /",
" M test +1 -1",
" M test2 +1",
" M test3 -1",
" M test4",
},
},
{
name: "big example",
files: []*models.File{
{Path: "dir1/file2", ShortStatus: "M ", HasUnstagedChanges: true},
{Path: "dir1/file3", ShortStatus: "M ", HasUnstagedChanges: true},
{Path: "dir2/dir2/file3", ShortStatus: " M", HasStagedChanges: true},
{Path: "dir2/dir2/file4", ShortStatus: "M ", HasUnstagedChanges: true},
{Path: "dir2/file5", ShortStatus: "M ", HasUnstagedChanges: true},
{Path: "file1", ShortStatus: "M ", HasUnstagedChanges: true},
},
expected: toStringSlice(
`
▼ /
▶ dir1
▼ dir2
▼ dir2
M file3
M file4
M file5
M file1
`,
),
collapsedPaths: []string{"./dir1"},
},
}
oldColorLevel := color.ForceSetColorLevel(terminfo.ColorLevelNone)
defer color.ForceSetColorLevel(oldColorLevel)
for _, s := range scenarios {
t.Run(s.name, func(t *testing.T) {
viewModel := filetree.NewFileTree(func() []*models.File { return s.files }, utils.NewDummyLog(), true)
viewModel.SetTree()
for _, path := range s.collapsedPaths {
viewModel.ToggleCollapsed(path)
}
result := RenderFileTree(viewModel, nil, false, s.showLineChanges, &config.CustomIconsConfig{})
assert.EqualValues(t, s.expected, result)
})
}
}
func TestRenderCommitFileTree(t *testing.T) {
scenarios := []struct {
name string
root *filetree.FileNode
files []*models.CommitFile
collapsedPaths []string
expected []string
}{
{
name: "nil node",
files: nil,
expected: []string{},
},
{
name: "leaf node",
files: []*models.CommitFile{
{Path: "test", ChangeStatus: "A"},
},
expected: []string{"A test"},
},
{
name: "big example",
files: []*models.CommitFile{
{Path: "dir1/file2", ChangeStatus: "M"},
{Path: "dir1/file3", ChangeStatus: "A"},
{Path: "dir2/dir2/file3", ChangeStatus: "D"},
{Path: "dir2/dir2/file4", ChangeStatus: "M"},
{Path: "dir2/file5", ChangeStatus: "M"},
{Path: "file1", ChangeStatus: "M"},
},
expected: toStringSlice(
`
▼ /
▶ dir1
▼ dir2
▼ dir2
D file3
M file4
M file5
M file1
`,
),
collapsedPaths: []string{"./dir1"},
},
}
oldColorLevel := color.ForceSetColorLevel(terminfo.ColorLevelNone)
defer color.ForceSetColorLevel(oldColorLevel)
for _, s := range scenarios {
t.Run(s.name, func(t *testing.T) {
hashPool := &utils.StringPool{}
viewModel := filetree.NewCommitFileTreeViewModel(func() []*models.CommitFile { return s.files }, utils.NewDummyLog(), true)
viewModel.SetRef(models.NewCommit(hashPool, models.NewCommitOpts{Hash: "1234"}))
viewModel.SetTree()
for _, path := range s.collapsedPaths {
viewModel.ToggleCollapsed(path)
}
patchBuilder := patch.NewPatchBuilder(
utils.NewDummyLog(),
func(from string, to string, reverse bool, filename string, plain bool) (string, error) {
return "", nil
},
)
patchBuilder.Start("from", "to", false, false)
result := RenderCommitFileTree(viewModel, patchBuilder, false, &config.CustomIconsConfig{})
assert.EqualValues(t, s.expected, result)
})
}
}