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}