1// Copyright 2009 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package pflag 6 7import ( 8 "bytes" 9 "strconv" 10 "testing" 11) 12 13// This value can be a boolean ("true", "false") or "maybe" 14type triStateValue int 15 16const ( 17 triStateFalse triStateValue = 0 18 triStateTrue triStateValue = 1 19 triStateMaybe triStateValue = 2 20) 21 22const strTriStateMaybe = "maybe" 23 24func (v *triStateValue) IsBoolFlag() bool { 25 return true 26} 27 28func (v *triStateValue) Get() interface{} { 29 return triStateValue(*v) 30} 31 32func (v *triStateValue) Set(s string) error { 33 if s == strTriStateMaybe { 34 *v = triStateMaybe 35 return nil 36 } 37 boolVal, err := strconv.ParseBool(s) 38 if boolVal { 39 *v = triStateTrue 40 } else { 41 *v = triStateFalse 42 } 43 return err 44} 45 46func (v *triStateValue) String() string { 47 if *v == triStateMaybe { 48 return strTriStateMaybe 49 } 50 return strconv.FormatBool(*v == triStateTrue) 51} 52 53// The type of the flag as required by the pflag.Value interface 54func (v *triStateValue) Type() string { 55 return "version" 56} 57 58func setUpFlagSet(tristate *triStateValue) *FlagSet { 59 f := NewFlagSet("test", ContinueOnError) 60 *tristate = triStateFalse 61 flag := f.VarPF(tristate, "tristate", "t", "tristate value (true, maybe or false)") 62 flag.NoOptDefVal = "true" 63 return f 64} 65 66func TestExplicitTrue(t *testing.T) { 67 var tristate triStateValue 68 f := setUpFlagSet(&tristate) 69 err := f.Parse([]string{"--tristate=true"}) 70 if err != nil { 71 t.Fatal("expected no error; got", err) 72 } 73 if tristate != triStateTrue { 74 t.Fatal("expected", triStateTrue, "(triStateTrue) but got", tristate, "instead") 75 } 76} 77 78func TestImplicitTrue(t *testing.T) { 79 var tristate triStateValue 80 f := setUpFlagSet(&tristate) 81 err := f.Parse([]string{"--tristate"}) 82 if err != nil { 83 t.Fatal("expected no error; got", err) 84 } 85 if tristate != triStateTrue { 86 t.Fatal("expected", triStateTrue, "(triStateTrue) but got", tristate, "instead") 87 } 88} 89 90func TestShortFlag(t *testing.T) { 91 var tristate triStateValue 92 f := setUpFlagSet(&tristate) 93 err := f.Parse([]string{"-t"}) 94 if err != nil { 95 t.Fatal("expected no error; got", err) 96 } 97 if tristate != triStateTrue { 98 t.Fatal("expected", triStateTrue, "(triStateTrue) but got", tristate, "instead") 99 } 100} 101 102func TestShortFlagExtraArgument(t *testing.T) { 103 var tristate triStateValue 104 f := setUpFlagSet(&tristate) 105 // The"maybe"turns into an arg, since short boolean options will only do true/false 106 err := f.Parse([]string{"-t", "maybe"}) 107 if err != nil { 108 t.Fatal("expected no error; got", err) 109 } 110 if tristate != triStateTrue { 111 t.Fatal("expected", triStateTrue, "(triStateTrue) but got", tristate, "instead") 112 } 113 args := f.Args() 114 if len(args) != 1 || args[0] != "maybe" { 115 t.Fatal("expected an extra 'maybe' argument to stick around") 116 } 117} 118 119func TestExplicitMaybe(t *testing.T) { 120 var tristate triStateValue 121 f := setUpFlagSet(&tristate) 122 err := f.Parse([]string{"--tristate=maybe"}) 123 if err != nil { 124 t.Fatal("expected no error; got", err) 125 } 126 if tristate != triStateMaybe { 127 t.Fatal("expected", triStateMaybe, "(triStateMaybe) but got", tristate, "instead") 128 } 129} 130 131func TestExplicitFalse(t *testing.T) { 132 var tristate triStateValue 133 f := setUpFlagSet(&tristate) 134 err := f.Parse([]string{"--tristate=false"}) 135 if err != nil { 136 t.Fatal("expected no error; got", err) 137 } 138 if tristate != triStateFalse { 139 t.Fatal("expected", triStateFalse, "(triStateFalse) but got", tristate, "instead") 140 } 141} 142 143func TestImplicitFalse(t *testing.T) { 144 var tristate triStateValue 145 f := setUpFlagSet(&tristate) 146 err := f.Parse([]string{}) 147 if err != nil { 148 t.Fatal("expected no error; got", err) 149 } 150 if tristate != triStateFalse { 151 t.Fatal("expected", triStateFalse, "(triStateFalse) but got", tristate, "instead") 152 } 153} 154 155func TestInvalidValue(t *testing.T) { 156 var tristate triStateValue 157 f := setUpFlagSet(&tristate) 158 var buf bytes.Buffer 159 f.SetOutput(&buf) 160 err := f.Parse([]string{"--tristate=invalid"}) 161 if err == nil { 162 t.Fatal("expected an error but did not get any, tristate has value", tristate) 163 } 164} 165 166func TestBoolP(t *testing.T) { 167 b := BoolP("bool", "b", false, "bool value in CommandLine") 168 c := BoolP("c", "c", false, "other bool value") 169 args := []string{"--bool"} 170 if err := CommandLine.Parse(args); err != nil { 171 t.Error("expected no error, got ", err) 172 } 173 if *b != true { 174 t.Errorf("expected b=true got b=%v", *b) 175 } 176 if *c != false { 177 t.Errorf("expect c=false got c=%v", *c) 178 } 179} 180