github.com/supragya/TendermintConnector@v0.0.0-20210619045051-113e32b84fb1/chains/tm34/libs/cli/setup_test.go (about) 1 package cli 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "strconv" 7 "strings" 8 "testing" 9 10 "github.com/spf13/cobra" 11 "github.com/spf13/viper" 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 ) 15 16 func TestSetupEnv(t *testing.T) { 17 cases := []struct { 18 args []string 19 env map[string]string 20 expected string 21 }{ 22 {nil, nil, ""}, 23 {[]string{"--foobar", "bang!"}, nil, "bang!"}, 24 // make sure reset is good 25 {nil, nil, ""}, 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"}, 32 } 33 34 for idx, tc := range cases { 35 i := strconv.Itoa(idx) 36 // test command that store value of foobar in local variable 37 var foo string 38 demo := &cobra.Command{ 39 Use: "demo", 40 RunE: func(cmd *cobra.Command, args []string) error { 41 foo = viper.GetString("foobar") 42 return nil 43 }, 44 } 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) {} 48 49 viper.Reset() 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) 54 } 55 } 56 57 func tempDir() string { 58 cdir, err := ioutil.TempDir("", "test-cli") 59 if err != nil { 60 panic(err) 61 } 62 return cdir 63 } 64 65 func TestSetupConfig(t *testing.T) { 66 // we pre-create two config files we can refer to in the rest of 67 // the test cases. 68 cval1 := "fubble" 69 conf1 := tempDir() 70 err := WriteConfigVals(conf1, map[string]string{"boo": cval1}) 71 require.Nil(t, err) 72 73 cases := []struct { 74 args []string 75 env map[string]string 76 expected string 77 expectedTwo string 78 }{ 79 {nil, nil, "", ""}, 80 // setting on the command line 81 {[]string{"--boo", "haha"}, nil, "haha", ""}, 82 {[]string{"--two-words", "rocks"}, nil, "", "rocks"}, 83 {[]string{"--home", conf1}, nil, cval1, ""}, 84 // test both variants of the prefix 85 {nil, map[string]string{"RD_BOO": "bang"}, "bang", ""}, 86 {nil, map[string]string{"RD_TWO_WORDS": "fly"}, "", "fly"}, 87 {nil, map[string]string{"RDTWO_WORDS": "fly"}, "", "fly"}, 88 {nil, map[string]string{"RD_HOME": conf1}, cval1, ""}, 89 {nil, map[string]string{"RDHOME": conf1}, cval1, ""}, 90 } 91 92 for idx, tc := range cases { 93 i := strconv.Itoa(idx) 94 // test command that store value of foobar in local variable 95 var foo, two string 96 boo := &cobra.Command{ 97 Use: "reader", 98 RunE: func(cmd *cobra.Command, args []string) error { 99 foo = viper.GetString("boo") 100 two = viper.GetString("two-words") 101 return nil 102 }, 103 } 104 boo.Flags().String("boo", "", "Some test value from config") 105 boo.Flags().String("two-words", "", "Check out env handling -") 106 cmd := PrepareBaseCmd(boo, "RD", "/qwerty/asdfgh") // some missing dir... 107 cmd.Exit = func(int) {} 108 109 viper.Reset() 110 args := append([]string{cmd.Use}, tc.args...) 111 err := RunWithArgs(cmd, args, tc.env) 112 require.Nil(t, err, i) 113 assert.Equal(t, tc.expected, foo, i) 114 assert.Equal(t, tc.expectedTwo, two, i) 115 } 116 } 117 118 type DemoConfig struct { 119 Name string `mapstructure:"name"` 120 Age int `mapstructure:"age"` 121 Unused int `mapstructure:"unused"` 122 } 123 124 func TestSetupUnmarshal(t *testing.T) { 125 // we pre-create two config files we can refer to in the rest of 126 // the test cases. 127 cval1, cval2 := "someone", "else" 128 conf1 := tempDir() 129 err := WriteConfigVals(conf1, map[string]string{"name": cval1}) 130 require.Nil(t, err) 131 // even with some ignored fields, should be no problem 132 conf2 := tempDir() 133 err = WriteConfigVals(conf2, map[string]string{"name": cval2, "foo": "bar"}) 134 require.Nil(t, err) 135 136 // unused is not declared on a flag and remains from base 137 base := DemoConfig{ 138 Name: "default", 139 Age: 42, 140 Unused: -7, 141 } 142 c := func(name string, age int) DemoConfig { 143 r := base 144 // anything set on the flags as a default is used over 145 // the default config object 146 r.Name = "from-flag" 147 if name != "" { 148 r.Name = name 149 } 150 if age != 0 { 151 r.Age = age 152 } 153 return r 154 } 155 156 cases := []struct { 157 args []string 158 env map[string]string 159 expected DemoConfig 160 }{ 161 {nil, nil, c("", 0)}, 162 // setting on the command line 163 {[]string{"--name", "haha"}, nil, c("haha", 0)}, 164 {[]string{"--home", conf1}, nil, c(cval1, 0)}, 165 // test both variants of the prefix 166 {nil, map[string]string{"MR_AGE": "56"}, c("", 56)}, 167 {nil, map[string]string{"MR_HOME": conf1}, c(cval1, 0)}, 168 {[]string{"--age", "17"}, map[string]string{"MRHOME": conf2}, c(cval2, 17)}, 169 } 170 171 for idx, tc := range cases { 172 i := strconv.Itoa(idx) 173 // test command that store value of foobar in local variable 174 cfg := base 175 marsh := &cobra.Command{ 176 Use: "marsh", 177 RunE: func(cmd *cobra.Command, args []string) error { 178 return viper.Unmarshal(&cfg) 179 }, 180 } 181 marsh.Flags().String("name", "from-flag", "Some test value from config") 182 // if we want a flag to use the proper default, then copy it 183 // from the default config here 184 marsh.Flags().Int("age", base.Age, "Some test value from config") 185 cmd := PrepareBaseCmd(marsh, "MR", "/qwerty/asdfgh") // some missing dir... 186 cmd.Exit = func(int) {} 187 188 viper.Reset() 189 args := append([]string{cmd.Use}, tc.args...) 190 err := RunWithArgs(cmd, args, tc.env) 191 require.Nil(t, err, i) 192 assert.Equal(t, tc.expected, cfg, i) 193 } 194 } 195 196 func TestSetupTrace(t *testing.T) { 197 cases := []struct { 198 args []string 199 env map[string]string 200 long bool 201 expected string 202 }{ 203 {nil, nil, false, "trace flag = false"}, 204 {[]string{"--trace"}, nil, true, "trace flag = true"}, 205 {[]string{"--no-such-flag"}, nil, false, "unknown flag: --no-such-flag"}, 206 {nil, map[string]string{"DBG_TRACE": "true"}, true, "trace flag = true"}, 207 } 208 209 for idx, tc := range cases { 210 i := strconv.Itoa(idx) 211 // test command that store value of foobar in local variable 212 trace := &cobra.Command{ 213 Use: "trace", 214 RunE: func(cmd *cobra.Command, args []string) error { 215 return fmt.Errorf("trace flag = %t", viper.GetBool(TraceFlag)) 216 }, 217 } 218 cmd := PrepareBaseCmd(trace, "DBG", "/qwerty/asdfgh") // some missing dir.. 219 cmd.Exit = func(int) {} 220 221 viper.Reset() 222 args := append([]string{cmd.Use}, tc.args...) 223 stdout, stderr, err := RunCaptureWithArgs(cmd, args, tc.env) 224 require.NotNil(t, err, i) 225 require.Equal(t, "", stdout, i) 226 require.NotEqual(t, "", stderr, i) 227 msg := strings.Split(stderr, "\n") 228 desired := fmt.Sprintf("ERROR: %s", tc.expected) 229 assert.Equal(t, desired, msg[0], i) 230 t.Log(msg) 231 if tc.long && assert.True(t, len(msg) > 2, i) { 232 // the next line starts the stack trace... 233 assert.Contains(t, stderr, "TestSetupTrace", i) 234 assert.Contains(t, stderr, "setup_test.go", i) 235 } 236 } 237 }