Return error when value is not specified and add more test cases
This commit is contained in:
parent
9456b4097b
commit
b8a7d72433
|
@ -9,6 +9,7 @@ import (
|
|||
var (
|
||||
ErrUnknownOption = errors.New("unknown option")
|
||||
ErrCannotChainOption = errors.New("cannot chain option")
|
||||
ErrOptionRequiresValue = errors.New("option requires value")
|
||||
)
|
||||
|
||||
type Parser struct {
|
||||
|
@ -76,12 +77,12 @@ func (p *Parser) peek() string {
|
|||
return p.args[p.curr+1]
|
||||
}
|
||||
|
||||
func (p *Parser) value() string {
|
||||
func (p *Parser) value() (string, bool) {
|
||||
if !p.hasNext() || (p.peek() != "-" && strings.HasPrefix(p.peek(), "-")) {
|
||||
return ""
|
||||
return "", false
|
||||
}
|
||||
|
||||
return p.next()
|
||||
return p.next(), true
|
||||
}
|
||||
|
||||
func (p *Parser) restArgs() []string {
|
||||
|
@ -109,7 +110,11 @@ func (p *Parser) parseLongOption(longName string) error {
|
|||
}
|
||||
|
||||
if value == "" && opt.TakesArg() {
|
||||
value = p.value()
|
||||
var ok bool
|
||||
value, ok = p.value()
|
||||
if !ok {
|
||||
return fmt.Errorf("%w: %s", ErrOptionRequiresValue, "--"+longName)
|
||||
}
|
||||
}
|
||||
|
||||
if err := opt.Parse(value); err != nil {
|
||||
|
@ -121,7 +126,7 @@ func (p *Parser) parseLongOption(longName string) error {
|
|||
|
||||
func (p *Parser) parseShortOption(shortNames string) error {
|
||||
if len(shortNames) == 1 {
|
||||
value := p.value()
|
||||
value, valOk := p.value()
|
||||
|
||||
opt, ok := p.opts.GetByShortName(shortNames)
|
||||
if !ok {
|
||||
|
@ -132,6 +137,10 @@ func (p *Parser) parseShortOption(shortNames string) error {
|
|||
return nil // Ignore unknown option. Continue parsing.
|
||||
}
|
||||
|
||||
if !valOk && opt.TakesArg() {
|
||||
return fmt.Errorf("%w: %s", ErrOptionRequiresValue, "-"+shortNames)
|
||||
}
|
||||
|
||||
if err := opt.Parse(value); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -156,9 +165,6 @@ func (p *Parser) parseShortOption(shortNames string) error {
|
|||
|
||||
value = shortNames[1:]
|
||||
value = strings.TrimPrefix(value, "=")
|
||||
if len(value) == 0 {
|
||||
value = p.value()
|
||||
}
|
||||
j = len(shortNames)
|
||||
}
|
||||
|
||||
|
|
|
@ -168,15 +168,15 @@ func TestParseLongOptionWithValueAndSpace(t *testing.T) {
|
|||
func TestParseOptionTerminator(t *testing.T) {
|
||||
opt := opts.String("fruit", "f", "banana", "")
|
||||
set := opts.Set{opt}
|
||||
args := []string{"--fruit", "--", "hello", "world"}
|
||||
args := []string{"--fruit", "apple", "--", "hello", "world"}
|
||||
parser := opts.NewParser(args, set, false)
|
||||
restArgs, err := parser.Parse()
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error, got: %s", err.Error())
|
||||
}
|
||||
|
||||
if opt.Value() != "banana" {
|
||||
t.Errorf("Expected fruit to be 'banana', got: %s", opt.Value())
|
||||
if opt.Value() != "apple" {
|
||||
t.Errorf("Expected fruit to be 'apple', got: %s", opt.Value())
|
||||
}
|
||||
|
||||
if len(restArgs) != 2 {
|
||||
|
@ -311,3 +311,25 @@ func TestParseShortOptionWithEqualBadValue(t *testing.T) {
|
|||
t.Error("Expected error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseLongOptionMissingValue(t *testing.T) {
|
||||
opt := opts.Int("fruit", "f", 0, "")
|
||||
set := opts.Set{opt}
|
||||
args := []string{"--fruit"}
|
||||
parser := opts.NewParser(args, set, false)
|
||||
_, err := parser.Parse()
|
||||
if err == nil {
|
||||
t.Error("Expected error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseShortOptionMissingValue(t *testing.T) {
|
||||
opt := opts.Int("fruit", "f", 0, "")
|
||||
set := opts.Set{opt}
|
||||
args := []string{"-f"}
|
||||
parser := opts.NewParser(args, set, false)
|
||||
_, err := parser.Parse()
|
||||
if err == nil {
|
||||
t.Error("Expected error")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue