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