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  }