1 package fftest
2
3 import (
4 "errors"
5 "flag"
6 "reflect"
7 "strings"
8 "testing"
9 "time"
10 )
11
12
13 func Pair() (*flag.FlagSet, *Vars) {
14 fs := flag.NewFlagSet("fftest", flag.ContinueOnError)
15 vars := DefaultVars(fs)
16 return fs, vars
17 }
18
19
20
21
22 func DefaultVars(fs *flag.FlagSet) *Vars {
23 var v Vars
24 fs.StringVar(&v.S, "s", "", "string")
25 fs.IntVar(&v.I, "i", 0, "int")
26 fs.Float64Var(&v.F, "f", 0., "float64")
27 fs.BoolVar(&v.B, "b", false, "bool")
28 fs.DurationVar(&v.D, "d", 0*time.Second, "time.Duration")
29 fs.Var(&v.X, "x", "collection of strings (repeatable)")
30 return &v
31 }
32
33
34
35
36 func NonzeroDefaultVars(fs *flag.FlagSet) *Vars {
37 var v Vars
38 fs.StringVar(&v.S, "s", "foo", "string")
39 fs.IntVar(&v.I, "i", 123, "int")
40 fs.Float64Var(&v.F, "f", 9.99, "float64")
41 fs.BoolVar(&v.B, "b", true, "bool")
42 fs.DurationVar(&v.D, "d", 3*time.Hour, "time.Duration")
43 fs.Var(&v.X, "x", "collection of strings (repeatable)")
44 return &v
45 }
46
47
48 type Vars struct {
49 S string
50 I int
51 F float64
52 B bool
53 D time.Duration
54 X StringSlice
55
56
57 ParseError error
58
59
60
61
62 WantParseErrorIs error
63
64
65
66
67 WantParseErrorString string
68 }
69
70
71
72 func Compare(t *testing.T, want, have *Vars) {
73 t.Helper()
74
75 if want.WantParseErrorIs != nil || want.WantParseErrorString != "" {
76 if want.WantParseErrorIs != nil && have.ParseError == nil {
77 t.Errorf("want error (%v), have none", want.WantParseErrorIs)
78 }
79 if want.WantParseErrorString != "" && have.ParseError == nil {
80 t.Errorf("want error (%q), have none", want.WantParseErrorString)
81 }
82 if want.WantParseErrorIs == nil && want.WantParseErrorString == "" && have.ParseError != nil {
83 t.Errorf("want clean parse, have error (%v)", have.ParseError)
84 }
85 if want.WantParseErrorIs != nil && have.ParseError != nil && !errors.Is(have.ParseError, want.WantParseErrorIs) {
86 t.Errorf("want wrapped error (%#+v), have error (%#+v)", want.WantParseErrorIs, have.ParseError)
87 }
88 if want.WantParseErrorString != "" && have.ParseError != nil && !strings.Contains(have.ParseError.Error(), want.WantParseErrorString) {
89 t.Errorf("want error string (%q), have error (%v)", want.WantParseErrorString, have.ParseError)
90 }
91 return
92 }
93
94 if have.ParseError != nil {
95 t.Errorf("error: %v", have.ParseError)
96 }
97
98 if want.S != have.S {
99 t.Errorf("var S: want %q, have %q", want.S, have.S)
100 }
101 if want.I != have.I {
102 t.Errorf("var I: want %d, have %d", want.I, have.I)
103 }
104 if want.F != have.F {
105 t.Errorf("var F: want %f, have %f", want.F, have.F)
106 }
107 if want.B != have.B {
108 t.Errorf("var B: want %v, have %v", want.B, have.B)
109 }
110 if want.D != have.D {
111 t.Errorf("var D: want %s, have %s", want.D, have.D)
112 }
113 if !reflect.DeepEqual(want.X, have.X) {
114 t.Errorf("var X: want %v, have %v", want.X, have.X)
115 }
116 }
117
118
119
120 type StringSlice []string
121
122
123 func (ss *StringSlice) Set(s string) error {
124 (*ss) = append(*ss, s)
125 return nil
126 }
127
128
129
130 func (ss *StringSlice) String() string {
131 if len(*ss) <= 0 {
132 return "..."
133 }
134 return strings.Join(*ss, ", ")
135 }
136
View as plain text