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  }