v2.31.0-dev10 f49cffc

tree_test.go RawHistoryFolder

1package components
2
3import (
4	"strings"
5	"testing"
6
7	"github.com/stretchr/testify/assert"
8	"github.com/stretchr/testify/require"
9)
10
11// NOTE: stripANSI is already defined in table_test.go (same package).
12// Use it directly — do NOT redefine it here.
13
14func TestTree_SingleNodeNoChildren(t *testing.T) {
15	tree := NewTree()
16	tree.AddNode("my-app.dev", "myapp:latest")
17
18	rendered := stripANSI(tree.Render())
19
20	assert.Contains(t, rendered, "my-app.dev")
21	assert.Contains(t, rendered, "myapp:latest")
22}
23
24func TestTree_NodeWithOneChild(t *testing.T) {
25	tree := NewTree()
26	node := tree.AddNode("my-app.dev", "myapp:latest")
27	node.AddChild("my-postgres", "postgres:16")
28
29	rendered := stripANSI(tree.Render())
30
31	assert.Contains(t, rendered, "my-app.dev")
32	assert.Contains(t, rendered, "myapp:latest")
33	assert.Contains(t, rendered, "└─")
34	assert.Contains(t, rendered, "my-postgres")
35	assert.Contains(t, rendered, "postgres:16")
36}
37
38func TestTree_NodeWithMultipleChildren(t *testing.T) {
39	tree := NewTree()
40	node := tree.AddNode("my-app.dev", "myapp:latest")
41	node.AddChild("my-postgres", "postgres:16")
42	node.AddChild("my-redis", "redis:7")
43
44	rendered := stripANSI(tree.Render())
45
46	assert.Contains(t, rendered, "├─")
47	assert.Contains(t, rendered, "└─")
48	assert.Contains(t, rendered, "my-postgres")
49	assert.Contains(t, rendered, "my-redis")
50}
51
52func TestTree_GroupWithNodes(t *testing.T) {
53	tree := NewTree()
54	group := tree.AddGroup("shared-services")
55	group.AddNode("app-a.dev", "app-a:latest")
56	group.AddNode("app-b.dev", "app-b:latest")
57
58	rendered := stripANSI(tree.Render())
59
60	assert.Contains(t, rendered, "shared-services")
61	assert.Contains(t, rendered, "◆")
62	assert.Contains(t, rendered, "│")
63	assert.Contains(t, rendered, "app-a.dev")
64	assert.Contains(t, rendered, "app-b.dev")
65}
66
67func TestTree_MixedNodesAndGroups(t *testing.T) {
68	tree := NewTree()
69	tree.AddNode("alpha.dev", "alpha:latest")
70
71	group := tree.AddGroup("my-group")
72	group.AddNode("beta.dev", "beta:latest")
73	group.AddNode("gamma.dev", "gamma:latest")
74
75	tree.AddNode("delta.dev", "delta:latest")
76
77	rendered := stripANSI(tree.Render())
78
79	assert.Contains(t, rendered, "alpha.dev")
80	assert.Contains(t, rendered, "my-group")
81	assert.Contains(t, rendered, "beta.dev")
82	assert.Contains(t, rendered, "gamma.dev")
83	assert.Contains(t, rendered, "delta.dev")
84}
85
86func TestTree_EmptyTreeRendersEmpty(t *testing.T) {
87	tree := NewTree()
88	rendered := tree.Render()
89	assert.Empty(t, rendered)
90}
91
92func TestTree_NodeWithChildSubtitleIndented(t *testing.T) {
93	tree := NewTree()
94	node := tree.AddNode("my-app.dev", "myapp:latest")
95	node.AddChild("my-postgres", "postgres:16")
96
97	rendered := stripANSI(tree.Render())
98	lines := strings.Split(rendered, "\n")
99
100	var childSubtitleLine string
101	for _, line := range lines {
102		if strings.Contains(line, "postgres:16") {
103			childSubtitleLine = line
104			break
105		}
106	}
107	require.NotEmpty(t, childSubtitleLine, "child subtitle line should exist")
108}
109
110func TestTree_GroupNodeWithChild(t *testing.T) {
111	tree := NewTree()
112	group := tree.AddGroup("shared")
113	node := group.AddNode("app.dev", "app:latest")
114	node.AddChild("app-db", "postgres:16")
115
116	rendered := stripANSI(tree.Render())
117
118	assert.Contains(t, rendered, "shared")
119	assert.Contains(t, rendered, "app.dev")
120	assert.Contains(t, rendered, "app-db")
121	assert.Contains(t, rendered, "postgres:16")
122}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close