1
// Copyright Istio Authors
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
7
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
22
// TODO: add missing unit tests (istio/istio#17246).
24
// errToString returns the string representation of err and the empty string if
26
func errToString(err error) string {
33
// to ptr conversion utility functions
34
func toInt8Ptr(i int8) *int8 { return &i }
36
func TestIsValueNil(t *testing.T) {
38
t.Error("got IsValueNil(nil) false, want true")
40
if !IsValueNil((*int)(nil)) {
41
t.Error("got IsValueNil(ptr) false, want true")
43
if !IsValueNil(map[int]int(nil)) {
44
t.Error("got IsValueNil(map) false, want true")
46
if !IsValueNil([]int(nil)) {
47
t.Error("got IsValueNil(slice) false, want true")
49
if !IsValueNil(any(nil)) {
50
t.Error("got IsValueNil(interface) false, want true")
53
if IsValueNil(toInt8Ptr(42)) {
54
t.Error("got IsValueNil(ptr) true, want false")
56
if IsValueNil(map[int]int{42: 42}) {
57
t.Error("got IsValueNil(map) true, want false")
59
if IsValueNil([]int{1, 2, 3}) {
60
t.Error("got IsValueNil(slice) true, want false")
62
if IsValueNil(any(42)) {
63
t.Error("got IsValueNil(interface) true, want false")
67
func TestIsValueNilOrDefault(t *testing.T) {
68
if !IsValueNilOrDefault(nil) {
69
t.Error("got IsValueNilOrDefault(nil) false, want true")
71
if !IsValueNilOrDefault((*int)(nil)) {
72
t.Error("got IsValueNilOrDefault(ptr) false, want true")
74
if !IsValueNilOrDefault(map[int]int(nil)) {
75
t.Error("got IsValueNilOrDefault(map) false, want true")
77
if !IsValueNilOrDefault([]int(nil)) {
78
t.Error("got IsValueNilOrDefault(slice) false, want true")
80
if !IsValueNilOrDefault(any(nil)) {
81
t.Error("got IsValueNilOrDefault(interface) false, want true")
83
if !IsValueNilOrDefault(int(0)) {
84
t.Error("got IsValueNilOrDefault(int(0)) false, want true")
86
if !IsValueNilOrDefault("") {
87
t.Error("got IsValueNilOrDefault(\"\") false, want true")
89
if !IsValueNilOrDefault(false) {
90
t.Error("got IsValueNilOrDefault(false) false, want true")
94
if IsValueNilOrDefault(&ip) {
95
t.Error("got IsValueNilOrDefault(ptr to ptr) false, want true")
99
func TestIsValueFuncs(t *testing.T) {
101
testStruct := struct{}{}
102
testSlice := []bool{}
103
testMap := map[bool]bool{}
104
var testNilSlice []bool
105
var testNilMap map[bool]bool
107
allValues := []any{nil, testInt, &testInt, testStruct, &testStruct, testNilSlice, testSlice, &testSlice, testNilMap, testMap, &testMap}
111
function func(v reflect.Value) bool
116
function: IsValuePtr,
117
okValues: []any{&testInt, &testStruct, &testSlice, &testMap},
120
desc: "IsValueStruct",
121
function: IsValueStruct,
122
okValues: []any{testStruct},
125
desc: "IsValueInterface",
126
function: IsValueInterface,
130
desc: "IsValueStructPtr",
131
function: IsValueStructPtr,
132
okValues: []any{&testStruct},
136
function: IsValueMap,
137
okValues: []any{testNilMap, testMap},
140
desc: "IsValueSlice",
141
function: IsValueSlice,
142
okValues: []any{testNilSlice, testSlice},
145
desc: "IsValueScalar",
146
function: IsValueScalar,
147
okValues: []any{testInt, &testInt},
151
for _, tt := range tests {
152
for vidx, v := range allValues {
153
if got, want := tt.function(reflect.ValueOf(v)), isInListOfInterface(tt.okValues, v); got != want {
154
t.Errorf("%s with %s (#%d): got: %t, want: %t", tt.desc, reflect.TypeOf(v), vidx, got, want)
160
func TestValuesAreSameType(t *testing.T) {
170
inDesc: "success both are int32 types",
176
inDesc: "fail unmatching int types",
182
inDesc: "fail unmatching int and string type",
188
inDesc: "fail EnumType and int64 types",
195
for _, tt := range tests {
196
t.Run(tt.inDesc, func(t *testing.T) {
197
got := ValuesAreSameType(reflect.ValueOf(tt.inV1), reflect.ValueOf(tt.inV2))
199
t.Errorf("got %v, want %v for comparing %T against %T", got, tt.want, tt.inV1, tt.inV2)
205
func TestIsTypeFuncs(t *testing.T) {
207
testStruct := struct{}{}
208
testSlice := []bool{}
209
testSliceOfInterface := []any{}
210
testMap := map[bool]bool{}
211
var testNilSlice []bool
212
var testNilMap map[bool]bool
215
nil, testInt, &testInt, testStruct, &testStruct, testNilSlice,
216
testSlice, &testSlice, testSliceOfInterface, testNilMap, testMap, &testMap,
221
function func(v reflect.Type) bool
225
desc: "IsTypeStructPtr",
226
function: IsTypeStructPtr,
227
okTypes: []any{&testStruct},
230
desc: "IsTypeSlicePtr",
231
function: IsTypeSlicePtr,
232
okTypes: []any{&testSlice},
237
okTypes: []any{testNilMap, testMap},
240
desc: "IsTypeInterface",
241
function: IsTypeInterface,
245
desc: "IsTypeSliceOfInterface",
246
function: IsTypeSliceOfInterface,
247
okTypes: []any{testSliceOfInterface},
251
for _, tt := range tests {
252
for vidx, v := range allTypes {
253
if got, want := tt.function(reflect.TypeOf(v)), isInListOfInterface(tt.okTypes, v); got != want {
254
t.Errorf("%s with %s (#%d): got: %t, want: %t", tt.desc, reflect.TypeOf(v), vidx, got, want)
260
type interfaceContainer struct {
264
type anInterface interface {
268
type implementsInterface struct {
272
func (*implementsInterface) IsU() {}
274
func TestIsValueInterface(t *testing.T) {
275
intf := &interfaceContainer{
276
I: &implementsInterface{
280
iField := reflect.ValueOf(intf).Elem().FieldByName("I")
281
if !IsValueInterface(iField) {
282
t.Errorf("IsValueInterface(): got false, want true")
286
func TestIsTypeInterface(t *testing.T) {
287
intf := &interfaceContainer{
288
I: &implementsInterface{
292
testIfField := reflect.ValueOf(intf).Elem().Field(0)
294
if !IsTypeInterface(testIfField.Type()) {
295
t.Errorf("IsTypeInterface(): got false, want true")
299
func isInListOfInterface(lv []any, v any) bool {
300
for _, vv := range lv {
301
if reflect.DeepEqual(vv, v) {
308
func TestDeleteFromSlicePtr(t *testing.T) {
309
parentSlice := []int{42, 43, 44, 45}
310
var parentSliceI any = parentSlice
311
if err := DeleteFromSlicePtr(&parentSliceI, 1); err != nil {
312
t.Fatalf("got error: %s, want error: nil", err)
314
wantSlice := []int{42, 44, 45}
315
if got, want := parentSliceI, wantSlice; !reflect.DeepEqual(got, want) {
316
t.Errorf("got:\n%v\nwant:\n%v\n", got, want)
319
badParent := struct{}{}
320
wantErr := `deleteFromSlicePtr parent type is *struct {}, must be *[]interface{}`
321
if got, want := errToString(DeleteFromSlicePtr(&badParent, 1)), wantErr; got != want {
322
t.Fatalf("got error: %s, want error: %s", got, want)
326
func TestUpdateSlicePtr(t *testing.T) {
327
parentSlice := []int{42, 43, 44, 45}
328
var parentSliceI any = parentSlice
329
if err := UpdateSlicePtr(&parentSliceI, 1, 42); err != nil {
330
t.Fatalf("got error: %s, want error: nil", err)
332
wantSlice := []int{42, 42, 44, 45}
333
if got, want := parentSliceI, wantSlice; !reflect.DeepEqual(got, want) {
334
t.Errorf("got:\n%v\nwant:\n%v\n", got, want)
337
badParent := struct{}{}
338
wantErr := `updateSlicePtr parent type is *struct {}, must be *[]interface{}`
339
if got, want := errToString(UpdateSlicePtr(&badParent, 1, 42)), wantErr; got != want {
340
t.Fatalf("got error: %s, want error: %s", got, want)
344
func TestInsertIntoMap(t *testing.T) {
345
parentMap := map[int]string{42: "forty two", 43: "forty three"}
347
value := "forty four"
348
if err := InsertIntoMap(parentMap, key, value); err != nil {
349
t.Fatalf("got error: %s, want error: nil", err)
351
wantMap := map[int]string{42: "forty two", 43: "forty three", 44: "forty four"}
352
if got, want := parentMap, wantMap; !reflect.DeepEqual(got, want) {
353
t.Errorf("got:\n%v\nwant:\n%v\n", got, want)
356
badParent := struct{}{}
357
wantErr := `insertIntoMap parent type is *struct {}, must be map`
358
if got, want := errToString(InsertIntoMap(&badParent, key, value)), wantErr; got != want {
359
t.Fatalf("got error: %s, want error: %s", got, want)
364
allIntTypes = []any{int(-42), int8(-43), int16(-44), int32(-45), int64(-46)}
365
allUintTypes = []any{uint(42), uint8(43), uint16(44), uint32(45), uint64(46)}
366
allIntegerTypes = append(allIntTypes, allUintTypes...)
367
nonIntTypes = []any{nil, "", []int{}, map[string]bool{}}
368
allTypes = append(allIntegerTypes, nonIntTypes...)
371
func TestIsInteger(t *testing.T) {
374
function func(v reflect.Kind) bool
384
function: IsUintKind,
389
for _, tt := range tests {
391
for _, v := range allTypes {
392
if tt.function(reflect.ValueOf(v).Kind()) {
396
if !reflect.DeepEqual(got, tt.want) {
397
t.Errorf("%s: got %v, want %v", tt.desc, got, tt.want)
402
func TestToIntValue(t *testing.T) {
404
for _, v := range allTypes {
405
if i, ok := ToIntValue(v); ok {
409
want := []int{-42, -43, -44, -45, -46, 42, 43, 44, 45, 46}
410
if !reflect.DeepEqual(got, want) {
411
t.Errorf("got %v, want %v", got, want)