9 "github.com/pkg/errors"
10 "github.com/spf13/cobra"
11 "github.com/spf13/viper"
12 "github.com/stretchr/testify/assert"
13 "github.com/stretchr/testify/require"
16 func TestSetupEnv(t *testing.T) {
23 {[]string{"--foobar", "bang!"}, nil, "bang!"},
24 // make sure reset is good
26 // test both variants of the prefix
27 {nil, map[string]string{"DEMO_FOOBAR": "good"}, "good"},
28 {nil, map[string]string{"DEMOFOOBAR": "silly"}, "silly"},
29 // and that cli overrides env...
30 {[]string{"--foobar", "important"},
31 map[string]string{"DEMO_FOOBAR": "ignored"}, "important"},
34 for idx, tc := range cases {
35 i := strconv.Itoa(idx)
36 // test command that store value of foobar in local variable
38 demo := &cobra.Command{
40 RunE: func(cmd *cobra.Command, args []string) error {
41 foo = viper.GetString("foobar")
45 demo.Flags().String("foobar", "", "Some test value from config")
46 cmd := PrepareBaseCmd(demo, "DEMO", "/qwerty/asdfgh") // some missing dir..
47 cmd.Exit = func(int) {}
50 args := append([]string{cmd.Use}, tc.args...)
51 err := RunWithArgs(cmd, args, tc.env)
52 require.Nil(t, err, i)
53 assert.Equal(t, tc.expected, foo, i)
57 func TestSetupConfig(t *testing.T) {
58 // we pre-create two config files we can refer to in the rest of
60 cval1, cval2 := "fubble", "wubble"
61 conf1, err := WriteDemoConfig(map[string]string{"boo": cval1})
63 // make sure it handles dashed-words in the config, and ignores random info
64 conf2, err := WriteDemoConfig(map[string]string{"boo": cval2, "foo": "bar", "two-words": "WORD"})
74 // setting on the command line
75 {[]string{"--boo", "haha"}, nil, "haha", ""},
76 {[]string{"--two-words", "rocks"}, nil, "", "rocks"},
77 {[]string{"--root", conf1}, nil, cval1, ""},
78 // test both variants of the prefix
79 {nil, map[string]string{"RD_BOO": "bang"}, "bang", ""},
80 {nil, map[string]string{"RD_TWO_WORDS": "fly"}, "", "fly"},
81 {nil, map[string]string{"RDTWO_WORDS": "fly"}, "", "fly"},
82 {nil, map[string]string{"RD_ROOT": conf1}, cval1, ""},
83 {nil, map[string]string{"RDROOT": conf2}, cval2, "WORD"},
84 {nil, map[string]string{"RDHOME": conf1}, cval1, ""},
85 // and when both are set??? HOME wins every time!
86 {[]string{"--root", conf1}, map[string]string{"RDHOME": conf2}, cval2, "WORD"},
89 for idx, tc := range cases {
90 i := strconv.Itoa(idx)
91 // test command that store value of foobar in local variable
93 boo := &cobra.Command{
95 RunE: func(cmd *cobra.Command, args []string) error {
96 foo = viper.GetString("boo")
97 two = viper.GetString("two-words")
101 boo.Flags().String("boo", "", "Some test value from config")
102 boo.Flags().String("two-words", "", "Check out env handling -")
103 cmd := PrepareBaseCmd(boo, "RD", "/qwerty/asdfgh") // some missing dir...
104 cmd.Exit = func(int) {}
107 args := append([]string{cmd.Use}, tc.args...)
108 err := RunWithArgs(cmd, args, tc.env)
109 require.Nil(t, err, i)
110 assert.Equal(t, tc.expected, foo, i)
111 assert.Equal(t, tc.expectedTwo, two, i)
115 type DemoConfig struct {
116 Name string `mapstructure:"name"`
117 Age int `mapstructure:"age"`
118 Unused int `mapstructure:"unused"`
121 func TestSetupUnmarshal(t *testing.T) {
122 // we pre-create two config files we can refer to in the rest of
124 cval1, cval2 := "someone", "else"
125 conf1, err := WriteDemoConfig(map[string]string{"name": cval1})
127 // even with some ignored fields, should be no problem
128 conf2, err := WriteDemoConfig(map[string]string{"name": cval2, "foo": "bar"})
131 // unused is not declared on a flag and remains from base
137 c := func(name string, age int) DemoConfig {
139 // anything set on the flags as a default is used over
140 // the default config object
153 env map[string]string
156 {nil, nil, c("", 0)},
157 // setting on the command line
158 {[]string{"--name", "haha"}, nil, c("haha", 0)},
159 {[]string{"--root", conf1}, nil, c(cval1, 0)},
160 // test both variants of the prefix
161 {nil, map[string]string{"MR_AGE": "56"}, c("", 56)},
162 {nil, map[string]string{"MR_ROOT": conf1}, c(cval1, 0)},
163 {[]string{"--age", "17"}, map[string]string{"MRHOME": conf2}, c(cval2, 17)},
166 for idx, tc := range cases {
167 i := strconv.Itoa(idx)
168 // test command that store value of foobar in local variable
170 marsh := &cobra.Command{
172 RunE: func(cmd *cobra.Command, args []string) error {
173 return viper.Unmarshal(&cfg)
176 marsh.Flags().String("name", "from-flag", "Some test value from config")
177 // if we want a flag to use the proper default, then copy it
178 // from the default config here
179 marsh.Flags().Int("age", base.Age, "Some test value from config")
180 cmd := PrepareBaseCmd(marsh, "MR", "/qwerty/asdfgh") // some missing dir...
181 cmd.Exit = func(int) {}
184 args := append([]string{cmd.Use}, tc.args...)
185 err := RunWithArgs(cmd, args, tc.env)
186 require.Nil(t, err, i)
187 assert.Equal(t, tc.expected, cfg, i)
191 func TestSetupTrace(t *testing.T) {
194 env map[string]string
198 {nil, nil, false, "Trace flag = false"},
199 {[]string{"--trace"}, nil, true, "Trace flag = true"},
200 {[]string{"--no-such-flag"}, nil, false, "unknown flag: --no-such-flag"},
201 {nil, map[string]string{"DBG_TRACE": "true"}, true, "Trace flag = true"},
204 for idx, tc := range cases {
205 i := strconv.Itoa(idx)
206 // test command that store value of foobar in local variable
207 trace := &cobra.Command{
209 RunE: func(cmd *cobra.Command, args []string) error {
210 return errors.Errorf("Trace flag = %t", viper.GetBool(TraceFlag))
213 cmd := PrepareBaseCmd(trace, "DBG", "/qwerty/asdfgh") // some missing dir..
214 cmd.Exit = func(int) {}
217 args := append([]string{cmd.Use}, tc.args...)
218 stdout, stderr, err := RunCaptureWithArgs(cmd, args, tc.env)
219 require.NotNil(t, err, i)
220 require.Equal(t, "", stdout, i)
221 require.NotEqual(t, "", stderr, i)
222 msg := strings.Split(stderr, "\n")
223 desired := fmt.Sprintf("ERROR: %s", tc.expected)
224 assert.Equal(t, desired, msg[0], i)
225 if tc.long && assert.True(t, len(msg) > 2, i) {
226 // the next line starts the stack trace...
227 assert.Contains(t, msg[1], "TestSetupTrace", i)
228 assert.Contains(t, msg[2], "setup_test.go", i)