Skip to content

Commit 6b941e9

Browse files
committed
test(cli): add tests for Init, Output, and Prompter
- Init adds completion, reference, version commands - Version command not added without option - Output/Prompter return fallback when context not set - Fix nil context panic in Output/Prompter extractors
1 parent a38dd1b commit 6b941e9

2 files changed

Lines changed: 119 additions & 4 deletions

File tree

cli/cli.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,20 @@ func versionCmd(name, ver, repo string) *cobra.Command {
9191

9292
// Output extracts the shared printer from a command's context.
9393
func Output(cmd *cobra.Command) *printer.Output {
94-
if ctx, ok := cmd.Context().Value(contextKey{}).(*cliContext); ok {
95-
return ctx.output
94+
if ctx := cmd.Context(); ctx != nil {
95+
if cc, ok := ctx.Value(contextKey{}).(*cliContext); ok {
96+
return cc.output
97+
}
9698
}
9799
return printer.NewOutput(os.Stdout)
98100
}
99101

100102
// Prompter extracts the shared prompter from a command's context.
101103
func Prompter(cmd *cobra.Command) prompt.Prompter {
102-
if ctx, ok := cmd.Context().Value(contextKey{}).(*cliContext); ok {
103-
return ctx.prompter
104+
if ctx := cmd.Context(); ctx != nil {
105+
if cc, ok := ctx.Value(contextKey{}).(*cliContext); ok {
106+
return cc.prompter
107+
}
104108
}
105109
return prompt.New()
106110
}

cli/cli_test.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package cli_test
2+
3+
import (
4+
"bytes"
5+
"testing"
6+
7+
"github.com/raystack/salt/cli"
8+
"github.com/spf13/cobra"
9+
"github.com/stretchr/testify/assert"
10+
"github.com/stretchr/testify/require"
11+
)
12+
13+
func newTestRoot() *cobra.Command {
14+
return &cobra.Command{Use: "testcli", Short: "test app"}
15+
}
16+
17+
func TestInit(t *testing.T) {
18+
t.Run("adds completion command", func(t *testing.T) {
19+
root := newTestRoot()
20+
cli.Init(root)
21+
22+
found := false
23+
for _, cmd := range root.Commands() {
24+
if cmd.Name() == "completion" {
25+
found = true
26+
}
27+
}
28+
assert.True(t, found, "completion command should be added")
29+
})
30+
31+
t.Run("adds reference command", func(t *testing.T) {
32+
root := newTestRoot()
33+
cli.Init(root)
34+
35+
found := false
36+
for _, cmd := range root.Commands() {
37+
if cmd.Name() == "reference" {
38+
found = true
39+
}
40+
}
41+
assert.True(t, found, "reference command should be added")
42+
})
43+
44+
t.Run("adds version command when configured", func(t *testing.T) {
45+
root := newTestRoot()
46+
cli.Init(root, cli.Version("1.0.0", "raystack/test"))
47+
48+
found := false
49+
for _, cmd := range root.Commands() {
50+
if cmd.Name() == "version" {
51+
found = true
52+
}
53+
}
54+
assert.True(t, found, "version command should be added")
55+
})
56+
57+
t.Run("no version command without option", func(t *testing.T) {
58+
root := newTestRoot()
59+
cli.Init(root)
60+
61+
for _, cmd := range root.Commands() {
62+
assert.NotEqual(t, "version", cmd.Name(), "version command should not be added without option")
63+
}
64+
})
65+
66+
t.Run("version command prints version", func(t *testing.T) {
67+
root := newTestRoot()
68+
cli.Init(root, cli.Version("2.5.0", ""))
69+
70+
var buf bytes.Buffer
71+
root.SetOut(&buf)
72+
root.SetArgs([]string{"version"})
73+
err := root.Execute()
74+
require.NoError(t, err)
75+
})
76+
}
77+
78+
func TestOutput(t *testing.T) {
79+
t.Run("returns output from context after Init", func(t *testing.T) {
80+
root := newTestRoot()
81+
cli.Init(root)
82+
83+
var out *bytes.Buffer
84+
child := &cobra.Command{
85+
Use: "child",
86+
Run: func(cmd *cobra.Command, _ []string) {
87+
o := cli.Output(cmd)
88+
assert.NotNil(t, o)
89+
out = &bytes.Buffer{}
90+
},
91+
}
92+
root.AddCommand(child)
93+
root.SetArgs([]string{"child"})
94+
root.Execute()
95+
assert.NotNil(t, out)
96+
})
97+
98+
t.Run("returns fallback when no context", func(t *testing.T) {
99+
cmd := &cobra.Command{Use: "bare"}
100+
out := cli.Output(cmd)
101+
assert.NotNil(t, out, "should return fallback output")
102+
})
103+
}
104+
105+
func TestPrompter(t *testing.T) {
106+
t.Run("returns fallback when no context", func(t *testing.T) {
107+
cmd := &cobra.Command{Use: "bare"}
108+
p := cli.Prompter(cmd)
109+
assert.NotNil(t, p, "should return fallback prompter")
110+
})
111+
}

0 commit comments

Comments
 (0)