xref: /aosp_15_r20/external/go-cmp/cmp/options_test.go (revision 88d15eac089d7f20c739ff1001d56b91872b21a1)
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