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 }