1
2
3
4
5 package cmp
6
7 import (
8 "io"
9 "reflect"
10 "strings"
11 "testing"
12
13 ts "github.com/google/go-cmp/cmp/internal/teststructs"
14 )
15
16
17
18 func TestOptionPanic(t *testing.T) {
19 type myBool bool
20 tests := []struct {
21 label string
22 fnc interface{}
23 args []interface{}
24 wantPanic string
25 }{{
26 label: "AllowUnexported",
27 fnc: AllowUnexported,
28 args: []interface{}{},
29 }, {
30 label: "AllowUnexported",
31 fnc: AllowUnexported,
32 args: []interface{}{1},
33 wantPanic: "invalid struct type",
34 }, {
35 label: "AllowUnexported",
36 fnc: AllowUnexported,
37 args: []interface{}{ts.StructA{}},
38 }, {
39 label: "AllowUnexported",
40 fnc: AllowUnexported,
41 args: []interface{}{ts.StructA{}, ts.StructB{}, ts.StructA{}},
42 }, {
43 label: "AllowUnexported",
44 fnc: AllowUnexported,
45 args: []interface{}{ts.StructA{}, &ts.StructB{}, ts.StructA{}},
46 wantPanic: "invalid struct type",
47 }, {
48 label: "Comparer",
49 fnc: Comparer,
50 args: []interface{}{5},
51 wantPanic: "invalid comparer function",
52 }, {
53 label: "Comparer",
54 fnc: Comparer,
55 args: []interface{}{func(x, y interface{}) bool { return true }},
56 }, {
57 label: "Comparer",
58 fnc: Comparer,
59 args: []interface{}{func(x, y io.Reader) bool { return true }},
60 }, {
61 label: "Comparer",
62 fnc: Comparer,
63 args: []interface{}{func(x, y io.Reader) myBool { return true }},
64 wantPanic: "invalid comparer function",
65 }, {
66 label: "Comparer",
67 fnc: Comparer,
68 args: []interface{}{func(x string, y interface{}) bool { return true }},
69 wantPanic: "invalid comparer function",
70 }, {
71 label: "Comparer",
72 fnc: Comparer,
73 args: []interface{}{(func(int, int) bool)(nil)},
74 wantPanic: "invalid comparer function",
75 }, {
76 label: "Transformer",
77 fnc: Transformer,
78 args: []interface{}{"", 0},
79 wantPanic: "invalid transformer function",
80 }, {
81 label: "Transformer",
82 fnc: Transformer,
83 args: []interface{}{"", func(int) int { return 0 }},
84 }, {
85 label: "Transformer",
86 fnc: Transformer,
87 args: []interface{}{"", func(bool) bool { return true }},
88 }, {
89 label: "Transformer",
90 fnc: Transformer,
91 args: []interface{}{"", func(int) bool { return true }},
92 }, {
93 label: "Transformer",
94 fnc: Transformer,
95 args: []interface{}{"", func(int, int) bool { return true }},
96 wantPanic: "invalid transformer function",
97 }, {
98 label: "Transformer",
99 fnc: Transformer,
100 args: []interface{}{"", (func(int) uint)(nil)},
101 wantPanic: "invalid transformer function",
102 }, {
103 label: "Transformer",
104 fnc: Transformer,
105 args: []interface{}{"Func", func(Path) Path { return nil }},
106 }, {
107 label: "Transformer",
108 fnc: Transformer,
109 args: []interface{}{"世界", func(int) bool { return true }},
110 }, {
111 label: "Transformer",
112 fnc: Transformer,
113 args: []interface{}{"/*", func(int) bool { return true }},
114 wantPanic: "invalid name",
115 }, {
116 label: "Transformer",
117 fnc: Transformer,
118 args: []interface{}{"_", func(int) bool { return true }},
119 }, {
120 label: "FilterPath",
121 fnc: FilterPath,
122 args: []interface{}{(func(Path) bool)(nil), Ignore()},
123 wantPanic: "invalid path filter function",
124 }, {
125 label: "FilterPath",
126 fnc: FilterPath,
127 args: []interface{}{func(Path) bool { return true }, Ignore()},
128 }, {
129 label: "FilterPath",
130 fnc: FilterPath,
131 args: []interface{}{func(Path) bool { return true }, Reporter(&defaultReporter{})},
132 wantPanic: "invalid option type",
133 }, {
134 label: "FilterPath",
135 fnc: FilterPath,
136 args: []interface{}{func(Path) bool { return true }, Options{Ignore(), Ignore()}},
137 }, {
138 label: "FilterPath",
139 fnc: FilterPath,
140 args: []interface{}{func(Path) bool { return true }, Options{Ignore(), Reporter(&defaultReporter{})}},
141 wantPanic: "invalid option type",
142 }, {
143 label: "FilterValues",
144 fnc: FilterValues,
145 args: []interface{}{0, Ignore()},
146 wantPanic: "invalid values filter function",
147 }, {
148 label: "FilterValues",
149 fnc: FilterValues,
150 args: []interface{}{func(x, y int) bool { return true }, Ignore()},
151 }, {
152 label: "FilterValues",
153 fnc: FilterValues,
154 args: []interface{}{func(x, y interface{}) bool { return true }, Ignore()},
155 }, {
156 label: "FilterValues",
157 fnc: FilterValues,
158 args: []interface{}{func(x, y interface{}) myBool { return true }, Ignore()},
159 wantPanic: "invalid values filter function",
160 }, {
161 label: "FilterValues",
162 fnc: FilterValues,
163 args: []interface{}{func(x io.Reader, y interface{}) bool { return true }, Ignore()},
164 wantPanic: "invalid values filter function",
165 }, {
166 label: "FilterValues",
167 fnc: FilterValues,
168 args: []interface{}{(func(int, int) bool)(nil), Ignore()},
169 wantPanic: "invalid values filter function",
170 }, {
171 label: "FilterValues",
172 fnc: FilterValues,
173 args: []interface{}{func(int, int) bool { return true }, Reporter(&defaultReporter{})},
174 wantPanic: "invalid option type",
175 }, {
176 label: "FilterValues",
177 fnc: FilterValues,
178 args: []interface{}{func(int, int) bool { return true }, Options{Ignore(), Ignore()}},
179 }, {
180 label: "FilterValues",
181 fnc: FilterValues,
182 args: []interface{}{func(int, int) bool { return true }, Options{Ignore(), Reporter(&defaultReporter{})}},
183 wantPanic: "invalid option type",
184 }}
185
186 for _, tt := range tests {
187 t.Run(tt.label, func(t *testing.T) {
188 var gotPanic string
189 func() {
190 defer func() {
191 if ex := recover(); ex != nil {
192 if s, ok := ex.(string); ok {
193 gotPanic = s
194 } else {
195 panic(ex)
196 }
197 }
198 }()
199 var vargs []reflect.Value
200 for _, arg := range tt.args {
201 vargs = append(vargs, reflect.ValueOf(arg))
202 }
203 reflect.ValueOf(tt.fnc).Call(vargs)
204 }()
205 if tt.wantPanic == "" {
206 if gotPanic != "" {
207 t.Fatalf("unexpected panic message: %s", gotPanic)
208 }
209 } else {
210 if !strings.Contains(gotPanic, tt.wantPanic) {
211 t.Fatalf("panic message:\ngot: %s\nwant: %s", gotPanic, tt.wantPanic)
212 }
213 }
214 })
215 }
216 }
217
View as plain text