package filetree import ( "testing" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/stretchr/testify/assert" ) func TestGetVisualDepthAtIndex(t *testing.T) { scenarios := []struct { name string files []*models.File showRootItem bool collapsedPaths []string expectedDepths []int // one per visible node, skipping root }{ { name: "flat files with root item", files: []*models.File{ {Path: "a"}, {Path: "b"}, }, showRootItem: true, // Displayed as: // index 0: ▼ / (depth 0, the "." root dir) // index 1: a (depth 1) // index 2: b (depth 1) expectedDepths: []int{0, 1, 1}, }, { name: "flat files without root item", files: []*models.File{ {Path: "a"}, {Path: "b"}, }, showRootItem: false, // Displayed as: // index 0: a (depth 0) // index 1: b (depth 0) expectedDepths: []int{0, 0}, }, { name: "nested directories with root item", files: []*models.File{ {Path: "dir/a"}, {Path: "dir/b"}, {Path: "c"}, }, showRootItem: true, // Displayed as: // index 0: ▼ / (depth 0) // index 4: c (depth 1) // index 1: ▼ dir (depth 1) // index 2: a (depth 2) // index 3: b (depth 2) expectedDepths: []int{0, 1, 1, 2, 2}, }, { name: "compressed paths with root item", files: []*models.File{ {Path: "dir1/dir3/a"}, {Path: "dir2/dir4/b"}, }, showRootItem: true, // Tree compresses dir1/dir3 and dir2/dir4 into single nodes. // Displayed as: // index 0: ▼ / (depth 0) // index 1: ▼ dir1/dir3 (depth 1, compressed) // index 2: a (depth 2) // index 3: ▼ dir2/dir4 (depth 1, compressed) // index 4: b (depth 2) expectedDepths: []int{0, 1, 2, 1, 2}, }, { name: "compressed paths without root item", files: []*models.File{ {Path: "dir1/dir3/a"}, {Path: "dir2/dir4/b"}, }, showRootItem: false, // Displayed as: // index 0: ▼ dir1/dir3 (depth 0, compressed) // index 1: a (depth 1) // index 2: ▼ dir2/dir4 (depth 0, compressed) // index 3: b (depth 1) expectedDepths: []int{0, 1, 0, 1}, }, { name: "collapsed directory hides children", files: []*models.File{ {Path: "dir/a"}, {Path: "dir/b"}, {Path: "c"}, }, showRootItem: true, collapsedPaths: []string{"./dir"}, // Displayed as: // index 0: ▼ / (depth 0) // index 1: ▶ dir (depth 1, collapsed) // index 2: c (depth 1) expectedDepths: []int{0, 1, 1}, }, { name: "out of range returns -1", files: []*models.File{ {Path: "a"}, }, showRootItem: false, expectedDepths: []int{0}, }, } for _, s := range scenarios { t.Run(s.name, func(t *testing.T) { tree := BuildTreeFromFiles(s.files, s.showRootItem, NodeSortComparator[models.File]("mixed", false)) collapsedPaths := NewCollapsedPaths() for _, p := range s.collapsedPaths { collapsedPaths.Collapse(p) } for i, expectedDepth := range s.expectedDepths { // +1 to skip the invisible root node, matching what FileTree.GetVisualDepth does actualDepth := tree.GetVisualDepthAtIndex(i+1, collapsedPaths) assert.Equal(t, expectedDepth, actualDepth, "index %d: expected depth %d, got %d", i, expectedDepth, actualDepth) } // Verify out-of-range returns -1 outOfRange := tree.GetVisualDepthAtIndex(len(s.expectedDepths)+1, collapsedPaths) assert.Equal(t, -1, outOfRange, "out of range index should return -1") }) } }