1 // Copyright 2017, 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.md file.
13 ts "github.com/google/go-cmp/cmp/internal/teststructs"
16 // Test that the creation of Option values with non-sensible inputs produces
17 // a run-time panic with a decent error message
18 func TestOptionPanic(t *testing.T) {
21 label string // Test description
22 fnc interface{} // Option function to call
23 args []interface{} // Arguments to pass in
24 wantPanic string // Expected panic message
26 label: "AllowUnexported",
28 args: []interface{}{},
30 label: "AllowUnexported",
32 args: []interface{}{1},
33 wantPanic: "invalid struct type",
35 label: "AllowUnexported",
37 args: []interface{}{ts.StructA{}},
39 label: "AllowUnexported",
41 args: []interface{}{ts.StructA{}, ts.StructB{}, ts.StructA{}},
43 label: "AllowUnexported",
45 args: []interface{}{ts.StructA{}, &ts.StructB{}, ts.StructA{}},
46 wantPanic: "invalid struct type",
50 args: []interface{}{5},
51 wantPanic: "invalid comparer function",
55 args: []interface{}{func(x, y interface{}) bool { return true }},
59 args: []interface{}{func(x, y io.Reader) bool { return true }},
63 args: []interface{}{func(x, y io.Reader) myBool { return true }},
64 wantPanic: "invalid comparer function",
68 args: []interface{}{func(x string, y interface{}) bool { return true }},
69 wantPanic: "invalid comparer function",
73 args: []interface{}{(func(int, int) bool)(nil)},
74 wantPanic: "invalid comparer function",
78 args: []interface{}{"", 0},
79 wantPanic: "invalid transformer function",
83 args: []interface{}{"", func(int) int { return 0 }},
87 args: []interface{}{"", func(bool) bool { return true }},
91 args: []interface{}{"", func(int) bool { return true }},
95 args: []interface{}{"", func(int, int) bool { return true }},
96 wantPanic: "invalid transformer function",
100 args: []interface{}{"", (func(int) uint)(nil)},
101 wantPanic: "invalid transformer function",
103 label: "Transformer",
105 args: []interface{}{"Func", func(Path) Path { return nil }},
107 label: "Transformer",
109 args: []interface{}{"世界", func(int) bool { return true }},
111 label: "Transformer",
113 args: []interface{}{"/*", func(int) bool { return true }},
114 wantPanic: "invalid name",
116 label: "Transformer",
118 args: []interface{}{"_", func(int) bool { return true }},
122 args: []interface{}{(func(Path) bool)(nil), Ignore()},
123 wantPanic: "invalid path filter function",
127 args: []interface{}{func(Path) bool { return true }, Ignore()},
131 args: []interface{}{func(Path) bool { return true }, Reporter(&defaultReporter{})},
132 wantPanic: "invalid option type",
136 args: []interface{}{func(Path) bool { return true }, Options{Ignore(), Ignore()}},
140 args: []interface{}{func(Path) bool { return true }, Options{Ignore(), Reporter(&defaultReporter{})}},
141 wantPanic: "invalid option type",
143 label: "FilterValues",
145 args: []interface{}{0, Ignore()},
146 wantPanic: "invalid values filter function",
148 label: "FilterValues",
150 args: []interface{}{func(x, y int) bool { return true }, Ignore()},
152 label: "FilterValues",
154 args: []interface{}{func(x, y interface{}) bool { return true }, Ignore()},
156 label: "FilterValues",
158 args: []interface{}{func(x, y interface{}) myBool { return true }, Ignore()},
159 wantPanic: "invalid values filter function",
161 label: "FilterValues",
163 args: []interface{}{func(x io.Reader, y interface{}) bool { return true }, Ignore()},
164 wantPanic: "invalid values filter function",
166 label: "FilterValues",
168 args: []interface{}{(func(int, int) bool)(nil), Ignore()},
169 wantPanic: "invalid values filter function",
171 label: "FilterValues",
173 args: []interface{}{func(int, int) bool { return true }, Reporter(&defaultReporter{})},
174 wantPanic: "invalid option type",
176 label: "FilterValues",
178 args: []interface{}{func(int, int) bool { return true }, Options{Ignore(), Ignore()}},
180 label: "FilterValues",
182 args: []interface{}{func(int, int) bool { return true }, Options{Ignore(), Reporter(&defaultReporter{})}},
183 wantPanic: "invalid option type",
186 for _, tt := range tests {
187 t.Run(tt.label, func(t *testing.T) {
191 if ex := recover(); ex != nil {
192 if s, ok := ex.(string); ok {
199 var vargs []reflect.Value
200 for _, arg := range tt.args {
201 vargs = append(vargs, reflect.ValueOf(arg))
203 reflect.ValueOf(tt.fnc).Call(vargs)
205 if tt.wantPanic == "" {
207 t.Fatalf("unexpected panic message: %s", gotPanic)
210 if !strings.Contains(gotPanic, tt.wantPanic) {
211 t.Fatalf("panic message:\ngot: %s\nwant: %s", gotPanic, tt.wantPanic)