github.com/jfrog/jfrog-cli-core/v2@v2.51.0/plugins/components/conversionlayer_test.go (about) 1 package components 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" 8 "github.com/stretchr/testify/assert" 9 ) 10 11 func TestCreateCommandUsages(t *testing.T) { 12 appNameSpace := "test-app" 13 cmdName := "test-command" 14 expectedPrefix := fmt.Sprintf("%s %s", appNameSpace, cmdName) 15 16 optFlag := NewBoolFlag("dummyFlag", "") 17 optStrFlag := NewStringFlag("optFlag", "", WithHelpValue("alias")) 18 strFlag := NewStringFlag("flag", "", SetMandatory()) 19 20 override := []string{"usage override", "usage override 2", "usage override 3"} 21 expectedOverride := []string{ 22 fmt.Sprintf("%s %s", coreutils.GetCliExecutableName(), "usage override"), 23 fmt.Sprintf("%s %s", coreutils.GetCliExecutableName(), "usage override 2"), 24 fmt.Sprintf("%s %s", coreutils.GetCliExecutableName(), "usage override 3"), 25 } 26 27 tests := []struct { 28 name string 29 cmd Command 30 stringFlags map[string]StringFlag 31 expected []string 32 expectErr bool 33 }{ 34 { 35 name: "no flags, no args", 36 cmd: Command{Name: cmdName}, 37 expected: []string{expectedPrefix}, 38 }, 39 { 40 name: "one optional flag, no args", 41 cmd: Command{Name: cmdName, Flags: []Flag{optFlag}}, 42 expected: []string{fmt.Sprintf("%s [command options]", expectedPrefix)}, 43 }, 44 { 45 name: "one mandatory flag, no args", 46 cmd: Command{Name: cmdName, Flags: []Flag{strFlag}}, 47 stringFlags: map[string]StringFlag{strFlag.Name: strFlag}, 48 expected: []string{fmt.Sprintf("%s --%s=<value>", expectedPrefix, strFlag.Name)}, 49 }, 50 { 51 name: "multiple flags, no args", 52 cmd: Command{Name: cmdName, Flags: []Flag{strFlag, optStrFlag, optFlag}}, 53 stringFlags: map[string]StringFlag{strFlag.Name: strFlag, optStrFlag.Name: optStrFlag}, 54 expected: []string{fmt.Sprintf("%s [command options] --%s=<value>", expectedPrefix, strFlag.Name)}, 55 }, 56 { 57 name: "no flags, mandatory args", 58 cmd: Command{Name: cmdName, Arguments: []Argument{{Name: "first argument"}, {Name: "second"}}}, 59 expected: []string{fmt.Sprintf("%s <%s> <%s>", expectedPrefix, "first argument", "second")}, 60 }, 61 { 62 name: "no flags, one optional arg", 63 cmd: Command{Name: cmdName, Arguments: []Argument{{Name: "first argument"}, {Name: "second", Optional: true}}}, 64 expected: []string{fmt.Sprintf("%s <%s> [%s]", expectedPrefix, "first argument", "second")}, 65 }, 66 { 67 name: "with flag and args with replace", 68 cmd: Command{ 69 Name: cmdName, 70 Flags: []Flag{optStrFlag}, 71 Arguments: []Argument{{Name: "first argument"}, {Name: "second", ReplaceWithFlag: optStrFlag.Name}, {Name: "third", Optional: true, ReplaceWithFlag: optStrFlag.Name}}, 72 }, 73 stringFlags: map[string]StringFlag{optStrFlag.Name: optStrFlag}, 74 expected: []string{ 75 fmt.Sprintf("%s [command options] <%s> <%s> [%s]", expectedPrefix, "first argument", "second", "third"), 76 fmt.Sprintf("%s --%s=<%s> <%s>", expectedPrefix, optStrFlag.Name, optStrFlag.HelpValue, "first argument"), 77 }, 78 }, 79 { 80 name: "replacement error", 81 cmd: Command{Name: cmdName, Arguments: []Argument{{Name: "first argument"}, {Name: "second", ReplaceWithFlag: "not-exist"}}}, 82 expected: []string{}, 83 expectErr: true, 84 }, 85 { 86 name: "with special usage cases", 87 cmd: Command{ 88 Name: cmdName, 89 Flags: []Flag{optStrFlag, optFlag}, 90 Arguments: []Argument{{Name: "first argument"}, {Name: "second", ReplaceWithFlag: optStrFlag.Name}}, 91 UsageOptions: &UsageOptions{Usage: override}, 92 }, 93 stringFlags: map[string]StringFlag{optStrFlag.Name: optStrFlag}, 94 expected: append(expectedOverride, 95 fmt.Sprintf("%s [command options] <%s> <%s>", expectedPrefix, "first argument", "second"), 96 fmt.Sprintf("%s [command options] --%s=<%s> <%s>", expectedPrefix, optStrFlag.Name, optStrFlag.HelpValue, "first argument"), 97 ), 98 }, 99 { 100 name: "with special usage cases, override", 101 cmd: Command{ 102 Name: "test-command", 103 Flags: []Flag{strFlag, optStrFlag, optFlag}, 104 Arguments: []Argument{{Name: "first argument"}, {Name: "second", ReplaceWithFlag: optStrFlag.Name}}, 105 UsageOptions: &UsageOptions{Usage: override, ReplaceAutoGeneratedUsage: true}, 106 }, 107 stringFlags: map[string]StringFlag{optStrFlag.Name: optStrFlag, strFlag.Name: strFlag}, 108 expected: expectedOverride, 109 }, 110 } 111 112 for _, test := range tests { 113 t.Run(test.name, func(t *testing.T) { 114 usage, err := createCommandUsages(test.cmd, test.stringFlags, appNameSpace) 115 if test.expectErr { 116 assert.Error(t, err) 117 } else { 118 assert.NoError(t, err) 119 assert.ElementsMatch(t, test.expected, usage) 120 } 121 }) 122 } 123 } 124 125 func TestCreateArgumentsSummary(t *testing.T) { 126 cmd := Command{ 127 Arguments: []Argument{ 128 { 129 Name: "first argument", 130 Description: "this is the first argument.", 131 }, 132 { 133 Name: "second", 134 Optional: true, 135 Description: "this is the second.", 136 }, 137 }, 138 } 139 expected := 140 ` first argument 141 this is the first argument. 142 143 second [Optional] 144 this is the second. 145 ` 146 assert.Equal(t, createArgumentsSummary(cmd), expected) 147 } 148 149 func TestCreateEnvVarsSummary(t *testing.T) { 150 cmd := Command{ 151 EnvVars: []EnvVar{ 152 { 153 Name: "FIRST_ENV", 154 Default: "15", 155 Description: "This is the first env.", 156 }, 157 { 158 Name: "NO_DEFAULT", 159 Description: "This flag has no default.", 160 }, 161 { 162 Name: "THIRD_ENV", 163 Default: "true", 164 Description: "This is the third env.", 165 }, 166 }, 167 } 168 expected := 169 ` FIRST_ENV 170 [Default: 15] 171 This is the first env. 172 173 NO_DEFAULT 174 This flag has no default. 175 176 THIRD_ENV 177 [Default: true] 178 This is the third env.` 179 assert.Equal(t, createEnvVarsSummary(cmd), expected) 180 } 181 182 type invalidFlag struct { 183 Name string 184 Usage string 185 } 186 187 func (f invalidFlag) GetName() string { 188 return f.Name 189 } 190 191 func (f invalidFlag) GetDescription() string { 192 return f.Usage 193 } 194 195 func (f invalidFlag) IsMandatory() bool { 196 return false 197 } 198 199 func TestConvertByTypeFailWithInvalidFlag(t *testing.T) { 200 invalid := invalidFlag{ 201 Name: "invalid", 202 Usage: "", 203 } 204 _, _, err := convertByType(invalid) 205 assert.Error(t, err) 206 } 207 208 func TestConvertStringFlagDefault(t *testing.T) { 209 f := NewStringFlag("string-flag", "This is how you use it.", WithStrDefaultValue("def")) 210 converted, pointerF, err := convertByType(f) 211 if assert.NoError(t, err) { 212 return 213 } 214 assert.Equal(t, pointerF, &f) 215 216 expected := "--string-flag \t[Default: def] This is how you use it." 217 assert.Equal(t, converted.String(), expected) 218 219 // Verify that when both Default and Mandatory are passed, only Default is shown. 220 f.Mandatory = true 221 converted, pointerF, err = convertByType(f) 222 if assert.NoError(t, err) { 223 return 224 } 225 assert.Equal(t, pointerF, &f) 226 assert.Equal(t, converted.String(), expected) 227 } 228 229 func TestConvertStringFlagMandatory(t *testing.T) { 230 f := NewStringFlag("string-flag", "This is how you use it.", SetMandatory()) 231 converted, pointerF, err := convertByType(f) 232 if assert.NoError(t, err) { 233 return 234 } 235 assert.Equal(t, pointerF, &f) 236 237 assert.Equal(t, converted.String(), "--string-flag \t[Mandatory] This is how you use it.") 238 239 // Test optional. 240 f.Mandatory = false 241 converted, pointerF, err = convertByType(f) 242 if assert.NoError(t, err) { 243 return 244 } 245 assert.Equal(t, pointerF, &f) 246 assert.Equal(t, converted.String(), "--string-flag \t[Optional] This is how you use it.") 247 } 248 249 func TestConvertBoolFlag(t *testing.T) { 250 f := NewBoolFlag("bool-flag", "This is how you use it.", WithBoolDefaultValue(true)) 251 converted, pointerF, err := convertByType(f) 252 if assert.NoError(t, err) { 253 return 254 } 255 assert.Nil(t, pointerF) 256 assert.Equal(t, converted.String(), "--bool-flag \t[Default: true] This is how you use it.") 257 258 // Test optional. 259 f.DefaultValue = false 260 converted, pointerF, err = convertByType(f) 261 if assert.NoError(t, err) { 262 return 263 } 264 assert.Nil(t, pointerF) 265 assert.Equal(t, converted.String(), "--bool-flag \t[Default: false] This is how you use it.") 266 } 267 268 func TestGetValueForStringFlag(t *testing.T) { 269 f := NewStringFlag("string-flag", "This is how you use it.") 270 271 // Not received, no default or mandatory. 272 finalValue, err := getValueForStringFlag(f, "") 273 assert.NoError(t, err) 274 assert.Empty(t, finalValue) 275 276 // Not received, no default but mandatory. 277 f.Mandatory = true 278 _, err = getValueForStringFlag(f, "") 279 assert.Error(t, err) 280 281 // Not received, verify default is taken. 282 f.DefaultValue = "default" 283 finalValue, err = getValueForStringFlag(f, "") 284 assert.NoError(t, err) 285 assert.Equal(t, finalValue, f.DefaultValue) 286 287 // Received, verify default is ignored. 288 expected := "value" 289 finalValue, err = getValueForStringFlag(f, expected) 290 assert.NoError(t, err) 291 assert.Equal(t, finalValue, expected) 292 }