github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/app/utils/sanity/type_test.go (about)

     1  package sanity
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/spf13/cobra"
     8  	"github.com/spf13/viper"
     9  )
    10  
    11  // universeFlag used to build command
    12  type universeFlag interface {
    13  	// add flag to cmd
    14  	add(cmd *cobra.Command)
    15  	// args get formatted flags
    16  	args() string
    17  	// changed If the user set the value (or if left to default)
    18  	changed() bool
    19  }
    20  
    21  // boolFlag bool type flag
    22  type boolFlag struct {
    23  	Name    string
    24  	Default bool
    25  	Changed bool
    26  	Value   bool
    27  }
    28  
    29  func (bf *boolFlag) add(cmd *cobra.Command) {
    30  	cmd.Flags().Bool(bf.Name, bf.Default, "")
    31  	viper.BindPFlag(bf.Name, cmd.Flags().Lookup(bf.Name))
    32  }
    33  
    34  func (bf *boolFlag) args() string {
    35  	return fmt.Sprintf("--%v=%v", bf.Name, bf.Value)
    36  }
    37  
    38  func (bf *boolFlag) changed() bool {
    39  	return bf.Changed
    40  }
    41  
    42  // stringFlag string type flag
    43  type stringFlag struct {
    44  	Name    string
    45  	Default string
    46  	Changed bool
    47  	Value   string
    48  }
    49  
    50  func (sf *stringFlag) add(cmd *cobra.Command) {
    51  	cmd.Flags().String(sf.Name, sf.Default, "")
    52  	viper.BindPFlag(sf.Name, cmd.Flags().Lookup(sf.Name))
    53  }
    54  
    55  func (sf *stringFlag) args() string {
    56  	return fmt.Sprintf("--%v=%v", sf.Name, sf.Value)
    57  }
    58  
    59  func (sf *stringFlag) changed() bool {
    60  	return sf.Changed
    61  }
    62  
    63  // intFlag string type flag
    64  type intFlag struct {
    65  	Name    string
    66  	Default int
    67  	Changed bool
    68  	Value   int
    69  }
    70  
    71  func (sf *intFlag) add(cmd *cobra.Command) {
    72  	cmd.Flags().Int(sf.Name, sf.Default, "")
    73  	viper.BindPFlag(sf.Name, cmd.Flags().Lookup(sf.Name))
    74  }
    75  
    76  func (sf *intFlag) args() string {
    77  	return fmt.Sprintf("--%v=%v", sf.Name, sf.Value)
    78  }
    79  
    80  func (sf *intFlag) changed() bool {
    81  	return sf.Changed
    82  }
    83  
    84  // getCommand build command by flags
    85  func getCommand(flags []universeFlag) *cobra.Command {
    86  	cmd := &cobra.Command{}
    87  	var args []string
    88  	for _, v := range flags {
    89  		v.add(cmd)
    90  		if v.changed() {
    91  			args = append(args, v.args())
    92  		}
    93  	}
    94  	cmd.ParseFlags(args)
    95  
    96  	cmd.Execute()
    97  	return cmd
    98  }
    99  
   100  func getCommandBool() *cobra.Command {
   101  	return getCommand([]universeFlag{
   102  		&boolFlag{
   103  			Name:    "b1",
   104  			Default: false,
   105  			Changed: true,
   106  			Value:   true,
   107  		},
   108  		&boolFlag{
   109  			Name:    "b2",
   110  			Default: false,
   111  			Changed: true,
   112  			Value:   true,
   113  		},
   114  	})
   115  }
   116  
   117  func getCommandBoolDiff() *cobra.Command {
   118  	return getCommand([]universeFlag{
   119  		&boolFlag{
   120  			Name:    "b1",
   121  			Default: false,
   122  			Changed: true,
   123  			Value:   true,
   124  		},
   125  		&boolFlag{
   126  			Name:    "b3",
   127  			Default: false,
   128  			Changed: true,
   129  			Value:   false,
   130  		},
   131  	})
   132  }
   133  
   134  func getCommandBoolString() *cobra.Command {
   135  	return getCommand([]universeFlag{
   136  		&boolFlag{
   137  			Name:    "b1",
   138  			Default: false,
   139  			Changed: true,
   140  			Value:   true,
   141  		},
   142  		&stringFlag{
   143  			Name:    "s1",
   144  			Default: "none",
   145  			Changed: true,
   146  			Value:   "conflict",
   147  		},
   148  	})
   149  }
   150  
   151  func Test_conflictPair_checkConflict(t *testing.T) {
   152  	type fields struct {
   153  		configA item
   154  		configB item
   155  	}
   156  	type args struct {
   157  		cmd *cobra.Command
   158  	}
   159  	tests := []struct {
   160  		name    string
   161  		fields  fields
   162  		args    args
   163  		wantErr bool
   164  	}{
   165  		{name: "1. bool item and bool item both true",
   166  			fields: fields{configA: boolItem{name: "b1", expect: true}, configB: boolItem{name: "b2", expect: true}},
   167  			args:   args{cmd: getCommandBool()}, wantErr: true},
   168  		{name: "2. bool item and bool item true vs false",
   169  			fields: fields{configA: boolItem{name: "b1", expect: true}, configB: boolItem{name: "b3", expect: false}},
   170  			args:   args{cmd: getCommandBoolDiff()}, wantErr: true},
   171  		{name: "3. bool item and string item",
   172  			fields: fields{configA: boolItem{name: "b1", expect: true}, configB: stringItem{name: "s1", expect: "conflict"}},
   173  			args:   args{cmd: getCommandBoolString()}, wantErr: true},
   174  	}
   175  	for _, tt := range tests {
   176  		t.Run(tt.name, func(t *testing.T) {
   177  			cp := &conflictPair{
   178  				configA: tt.fields.configA,
   179  				configB: tt.fields.configB,
   180  			}
   181  			var err error
   182  			if err = cp.check(); (err != nil) != tt.wantErr {
   183  				t.Errorf("checkConflict() error = %v, wantErr %v", err, tt.wantErr)
   184  			}
   185  			t.Log(err)
   186  		})
   187  	}
   188  }
   189  
   190  func Test_dependentPair_check(t *testing.T) {
   191  	type args struct {
   192  		cmd *cobra.Command
   193  	}
   194  	tests := []struct {
   195  		name    string
   196  		fields  dependentPair
   197  		args    args
   198  		wantErr bool
   199  	}{
   200  		{name: "1. b1=true, b2=true, correct",
   201  			fields: dependentPair{config: boolItem{name: "b1", expect: true}, reliedConfig: boolItem{name: "b2", expect: true}},
   202  			args:   args{cmd: getCommandBool()}, wantErr: false},
   203  		{name: "2. b1=true,b2=false, need error",
   204  			fields: dependentPair{config: boolItem{name: "b1", expect: true}, reliedConfig: boolItem{name: "b2", expect: false}},
   205  			args:   args{cmd: getCommandBool()}, wantErr: true},
   206  		{name: "2. b1=false, no error",
   207  			fields: dependentPair{config: boolItem{name: "b1", expect: false}, reliedConfig: boolItem{name: "b2", expect: false}},
   208  			args:   args{cmd: getCommandBool()}, wantErr: false},
   209  	}
   210  	for _, tt := range tests {
   211  		t.Run(tt.name, func(t *testing.T) {
   212  			var err error
   213  			if err = tt.fields.check(); (err != nil) != tt.wantErr {
   214  				t.Errorf("checkConflict() error = %v, wantErr %v", err, tt.wantErr)
   215  			}
   216  			t.Log(err)
   217  		})
   218  	}
   219  }