1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
package opt_test
import (
"fmt"
"testing"
"git.sr.ht/~rjarry/go-opt/v2"
"github.com/stretchr/testify/assert"
)
type OptionStruct struct {
Jobs int `opt:"-j,--jobs" required:"true"`
Delay float64 `opt:"--delay" default:"0.5"`
Zero bool `opt:"-z" aliases:"baz"`
Backoff bool `opt:"-B,--backoff"`
Name string `opt:"name" aliases:"bar" action:"ParseName"`
}
func (o *OptionStruct) ParseName(arg string) error {
if arg == "invalid" {
return fmt.Errorf("%q invalid value", arg)
}
o.Name = arg
return nil
}
func TestArgsToStructErrors(t *testing.T) {
vectors := []struct {
cmdline string
err string
}{
{"foo", "-j is required"},
{"foo -j", "-j takes a value"},
{"foo --delay -B", "--delay takes a value"},
{"bar -j4", "<name> is required"},
{"foo -j f", `strconv.ParseInt: parsing "f": invalid syntax.`},
{"foo --delay=m", `strconv.ParseFloat: parsing "m": invalid syntax.`},
{"foo --jobs 8 baz", `"baz" unexpected argument`},
{"foo -u8 hop", `"-u8" unexpected argument`},
{"foo -z", `"-z" unexpected argument`},
{"bar -j4 foo baz", `"baz" unexpected argument`},
{"bar -j4 invalid", `invalid value`},
}
for _, v := range vectors {
t.Run(v.cmdline, func(t *testing.T) {
err := opt.CmdlineToStruct(v.cmdline, new(OptionStruct))
assert.ErrorContains(t, err, v.err)
})
}
spec := opt.NewCmdSpec("bar", new(OptionStruct))
assert.Equal(t, spec.Usage(), "bar -j <jobs> [--delay <delay>] [-B] <name>")
}
func TestArgsToStruct(t *testing.T) {
vectors := []struct {
cmdline string
expected OptionStruct
}{
{
cmdline: `bar -j4 'f o o \(°</ f o o'`,
expected: OptionStruct{
Jobs: 4,
Delay: 0.5,
Name: `f o o \(°</ f o o`,
},
},
{
cmdline: "foo --delay 0.1 -Bj 8",
expected: OptionStruct{
Jobs: 8,
Delay: 0.1,
Backoff: true,
},
},
{
cmdline: `baz -Bz --delay=0.1 -j8`,
expected: OptionStruct{
Jobs: 8,
Delay: 0.1,
Zero: true,
Backoff: true,
},
},
{
cmdline: `bar 'n a m e' -j7 --backoff`,
expected: OptionStruct{
Jobs: 7,
Delay: 0.5,
Backoff: true,
Name: "n a m e",
},
},
{
cmdline: `bar -j3 -- -j7`,
expected: OptionStruct{
Jobs: 3,
Delay: 0.5,
Name: "-j7",
},
},
}
for _, v := range vectors {
t.Run(v.cmdline, func(t *testing.T) {
var s OptionStruct
assert.Nil(t, opt.CmdlineToStruct(v.cmdline, &s))
assert.Equal(t, v.expected, s)
})
}
}
|