automation-tests/common/pkg/flag/flag_test.go

223 lines
7.2 KiB
Go

package flag
import (
"testing"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestOptionalBoolSet(t *testing.T) {
for _, c := range []struct {
input string
accepted bool
value bool
}{
// Valid inputs documented for strconv.ParseBool == flag.BoolVar
{"1", true, true},
{"t", true, true},
{"T", true, true},
{"TRUE", true, true},
{"true", true, true},
{"True", true, true},
{"0", true, false},
{"f", true, false},
{"F", true, false},
{"FALSE", true, false},
{"false", true, false},
{"False", true, false},
// A few invalid inputs
{"", false, false},
{"yes", false, false},
{"no", false, false},
{"2", false, false},
} {
var ob OptionalBool
v := internalNewOptionalBoolValue(&ob)
require.False(t, ob.Present())
err := v.Set(c.input)
if c.accepted {
assert.NoError(t, err, c.input)
assert.Equal(t, c.value, ob.Value())
} else {
assert.Error(t, err, c.input)
assert.False(t, ob.Present()) // Just to be extra paranoid.
}
}
// Nothing actually explicitly says that .Set() is never called when the flag is not present on the command line;
// so, check that it is not being called, at least in the straightforward case (it's not possible to test that it
// is not called in any possible situation).
var globalOB, commandOB OptionalBool
actionRun := false
app := &cobra.Command{
Use: "app",
}
OptionalBoolFlag(app.PersistentFlags(), &globalOB, "global-OB", "")
cmd := &cobra.Command{
Use: "cmd",
RunE: func(_ *cobra.Command, args []string) error {
assert.False(t, globalOB.Present())
assert.False(t, commandOB.Present())
actionRun = true
return nil
},
}
OptionalBoolFlag(cmd.Flags(), &commandOB, "command-OB", "")
app.AddCommand(cmd)
app.SetArgs([]string{"cmd"})
err := app.Execute()
require.NoError(t, err)
assert.True(t, actionRun)
}
func TestOptionalBoolString(t *testing.T) {
for _, c := range []struct {
input OptionalBool
expected string
}{
{OptionalBool{present: true, value: true}, "true"},
{OptionalBool{present: true, value: false}, "false"},
{OptionalBool{present: false, value: true}, ""},
{OptionalBool{present: false, value: false}, ""},
} {
var ob OptionalBool
v := internalNewOptionalBoolValue(&ob)
ob = c.input
res := v.String()
assert.Equal(t, c.expected, res)
}
}
func TestOptionalBoolIsBoolFlag(t *testing.T) {
// IsBoolFlag means that the argument value must either be part of the same argument, with =;
// if there is no =, the value is set to true.
// This differs form other flags, where the argument is required and may be either separated with = or supplied in the next argument.
for _, c := range []struct {
input []string
expectedOB OptionalBool
expectedArgs []string
}{
{[]string{"1", "2"}, OptionalBool{present: false}, []string{"1", "2"}}, // Flag not present
{[]string{"--OB=true", "1", "2"}, OptionalBool{present: true, value: true}, []string{"1", "2"}}, // --OB=true
{[]string{"--OB=false", "1", "2"}, OptionalBool{present: true, value: false}, []string{"1", "2"}}, // --OB=false
{[]string{"--OB", "true", "1", "2"}, OptionalBool{present: true, value: true}, []string{"true", "1", "2"}}, // --OB true
{[]string{"--OB", "false", "1", "2"}, OptionalBool{present: true, value: true}, []string{"false", "1", "2"}}, // --OB false
} {
var ob OptionalBool
actionRun := false
app := &cobra.Command{Use: "app"}
cmd := &cobra.Command{
Use: "cmd",
RunE: func(_ *cobra.Command, args []string) error {
assert.Equal(t, c.expectedOB, ob) // nolint
assert.Equal(t, c.expectedArgs, args) //nolint
actionRun = true
return nil
},
}
OptionalBoolFlag(cmd.Flags(), &ob, "OB", "")
app.AddCommand(cmd)
app.SetArgs(append([]string{"cmd"}, c.input...))
err := app.Execute()
require.NoError(t, err)
assert.True(t, actionRun)
}
}
func TestOptionalStringSet(t *testing.T) {
// Really just a smoke test, but differentiating between not present and empty.
for _, c := range []string{"", "hello"} {
var os OptionalString
v := NewOptionalStringValue(&os)
require.False(t, os.Present())
err := v.Set(c)
assert.NoError(t, err, c)
assert.Equal(t, c, os.Value())
}
// Nothing actually explicitly says that .Set() is never called when the flag is not present on the command line;
// so, check that it is not being called, at least in the straightforward case (it's not possible to test that it
// is not called in any possible situation).
var globalOS, commandOS OptionalString
actionRun := false
app := &cobra.Command{
Use: "app",
}
app.PersistentFlags().Var(NewOptionalStringValue(&globalOS), "global-OS", "")
cmd := &cobra.Command{
Use: "cmd",
RunE: func(_ *cobra.Command, args []string) error {
assert.False(t, globalOS.Present())
assert.False(t, commandOS.Present())
actionRun = true
return nil
},
}
cmd.Flags().Var(NewOptionalStringValue(&commandOS), "command-OS", "")
app.AddCommand(cmd)
app.SetArgs([]string{"cmd"})
err := app.Execute()
require.NoError(t, err)
assert.True(t, actionRun)
}
func TestOptionalStringString(t *testing.T) {
for _, c := range []struct {
input OptionalString
expected string
}{
{OptionalString{present: true, value: "hello"}, "hello"},
{OptionalString{present: true, value: ""}, ""},
{OptionalString{present: false, value: "hello"}, ""},
{OptionalString{present: false, value: ""}, ""},
} {
var os OptionalString
v := NewOptionalStringValue(&os)
os = c.input
res := v.String()
assert.Equal(t, c.expected, res)
}
}
func TestOptionalStringIsBoolFlag(t *testing.T) {
// NOTE: OptionalStringValue does not implement IsBoolFlag!
// IsBoolFlag means that the argument value must either be part of the same argument, with =;
// if there is no =, the value is set to true.
// This differs form other flags, where the argument is required and may be either separated with = or supplied in the next argument.
for _, c := range []struct {
input []string
expectedOS OptionalString
expectedArgs []string
}{
{[]string{"1", "2"}, OptionalString{present: false}, []string{"1", "2"}}, // Flag not present
{[]string{"--OS=hello", "1", "2"}, OptionalString{present: true, value: "hello"}, []string{"1", "2"}}, // --OS=true
{[]string{"--OS=", "1", "2"}, OptionalString{present: true, value: ""}, []string{"1", "2"}}, // --OS=false
{[]string{"--OS", "hello", "1", "2"}, OptionalString{present: true, value: "hello"}, []string{"1", "2"}}, // --OS true
{[]string{"--OS", "", "1", "2"}, OptionalString{present: true, value: ""}, []string{"1", "2"}}, // --OS false
} {
var os OptionalString
actionRun := false
app := &cobra.Command{
Use: "app",
}
cmd := &cobra.Command{
Use: "cmd",
RunE: func(cmd *cobra.Command, args []string) error {
assert.Equal(t, c.expectedOS, os) // nolint
assert.Equal(t, c.expectedArgs, args) // nolint
actionRun = true
return nil
},
}
cmd.Flags().Var(NewOptionalStringValue(&os), "OS", "")
app.AddCommand(cmd)
app.SetArgs(append([]string{"cmd"}, c.input...))
err := app.Execute()
require.NoError(t, err)
assert.True(t, actionRun)
}
}