github.com/grailbio/bigslice@v0.0.0-20230519005545-30c4c12152ad/typecheck/func_test.go (about) 1 // Copyright 2018 GRAIL, Inc. All rights reserved. 2 // Use of this source code is governed by the Apache 2.0 3 // license that can be found in the LICENSE file. 4 5 package typecheck 6 7 import ( 8 "fmt" 9 "reflect" 10 "testing" 11 12 "github.com/grailbio/bigslice/slicefunc" 13 "github.com/grailbio/bigslice/slicetype" 14 ) 15 16 type testStringer struct{} 17 18 func (testStringer) String() string { 19 return "testStringer" 20 } 21 22 var typeOfTestStringer = reflect.TypeOf(testStringer{}) 23 24 // TestCanApply verifies basic handling of function and argument types. 25 func TestCanApply(t *testing.T) { 26 fn, ok := slicefunc.Of(func(int, string) string { return "" }) 27 if !ok { 28 t.Fatal("not a func") 29 } 30 for _, c := range []struct { 31 args []reflect.Type 32 canApply bool 33 }{ 34 {[]reflect.Type{}, false}, 35 {[]reflect.Type{typeOfInt}, false}, 36 {[]reflect.Type{typeOfString}, false}, 37 {[]reflect.Type{typeOfInt, typeOfString}, true}, 38 {[]reflect.Type{typeOfInt, typeOfString, typeOfString}, false}, 39 {[]reflect.Type{typeOfInt, typeOfString, typeOfBool}, false}, 40 } { 41 argTyp := slicetype.New(c.args...) 42 if got, want := CanApply(fn, argTyp), c.canApply; got != want { 43 t.Errorf("got %v, want %v", got, want) 44 } 45 } 46 } 47 48 // TestCanApplyVariadic verifies the ability to apply a variadic function is 49 // properly evaluated. 50 func TestCanApplyVariadic(t *testing.T) { 51 fn, ok := slicefunc.Of(func(int, ...string) string { return "" }) 52 if !ok { 53 t.Fatal("not a func") 54 } 55 for _, c := range []struct { 56 args []reflect.Type 57 canApply bool 58 }{ 59 {[]reflect.Type{}, false}, 60 {[]reflect.Type{typeOfInt}, true}, 61 {[]reflect.Type{typeOfString}, false}, 62 {[]reflect.Type{typeOfInt, typeOfString}, true}, 63 {[]reflect.Type{typeOfInt, typeOfString, typeOfString}, true}, 64 {[]reflect.Type{typeOfInt, typeOfString, typeOfBool}, false}, 65 } { 66 argTyp := slicetype.New(c.args...) 67 if got, want := CanApply(fn, argTyp), c.canApply; got != want { 68 t.Errorf("got %v, want %v", got, want) 69 } 70 } 71 } 72 73 // TestCanApplyInterface verifies that types that implement interfaces can be 74 // passed as their interface types. 75 func TestCanApplyInterface(t *testing.T) { 76 fn, ok := slicefunc.Of(func(int, fmt.Stringer) string { return "" }) 77 if !ok { 78 t.Fatal("not a func") 79 } 80 for _, c := range []struct { 81 args []reflect.Type 82 canApply bool 83 }{ 84 {[]reflect.Type{}, false}, 85 {[]reflect.Type{typeOfInt}, false}, 86 {[]reflect.Type{typeOfString}, false}, 87 {[]reflect.Type{typeOfInt, typeOfString}, false}, 88 {[]reflect.Type{typeOfInt, typeOfTestStringer}, true}, 89 } { 90 argTyp := slicetype.New(c.args...) 91 if got, want := CanApply(fn, argTyp), c.canApply; got != want { 92 t.Logf("fn.In: %v, arg: %v", fn.In, argTyp) 93 t.Errorf("got %v, want %v", got, want) 94 } 95 } 96 }