-
Notifications
You must be signed in to change notification settings - Fork 225
/
genericfunc_test.go
130 lines (124 loc) · 4.5 KB
/
genericfunc_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package linq
import (
"errors"
"reflect"
"testing"
)
func TestNewGenericFunc(t *testing.T) {
tests := []struct {
methodName string
paramName string
function interface{}
validationFunc func(*functionCache) error
exception error
}{
{ // A valid function
"TestNewGenericFunc", "test1",
func(item int) bool { return item > 10 },
simpleParamValidator(newElemTypeSlice(new(int)), newElemTypeSlice(new(bool))),
nil,
},
{ // A valid generic function
"TestNewGenericFunc", "test1",
func(item int) bool { return item > 10 },
simpleParamValidator(newElemTypeSlice(new(genericType)), newElemTypeSlice(new(bool))),
nil,
},
{ //returns error when the function parameter has not the function kind
"TestNewGenericFunc", "test2",
"Not a function",
simpleParamValidator(nil, []reflect.Type{}),
errors.New("TestNewGenericFunc: parameter [test2] is not a function type. It is a 'string'"),
},
{ // Returns error when expected parameters number are not equal
"TestNewGenericFunc", "test3",
func(idx, item int) {},
simpleParamValidator(newElemTypeSlice(new(int)), []reflect.Type{}),
errors.New("TestNewGenericFunc: parameter [test3] has a invalid function signature. Expected: 'func(int)', actual: 'func(int,int)'"),
},
{ // Returns error when expected parameters types are not equal
"TestNewGenericFunc", "test4",
func(items ...int) bool { return false },
simpleParamValidator(newElemTypeSlice(new([]bool)), newElemTypeSlice(new(bool))),
errors.New("TestNewGenericFunc: parameter [test4] has a invalid function signature. Expected: 'func([]bool)bool', actual: 'func([]int)bool'"),
},
{ // Returns error when expected returns number are not equal
"TestNewGenericFunc", "test5",
func(item int) bool { return item > 10 },
simpleParamValidator(newElemTypeSlice(new(int)), []reflect.Type{}),
errors.New("TestNewGenericFunc: parameter [test5] has a invalid function signature. Expected: 'func(int)', actual: 'func(int)bool'"),
},
{ // Returns error when expected return types are not equal
"TestNewGenericFunc", "test6",
func(items ...int) bool { return false },
simpleParamValidator(newElemTypeSlice(new([]int)), newElemTypeSlice(new(int64))),
errors.New("TestNewGenericFunc: parameter [test6] has a invalid function signature. Expected: 'func([]int)int64', actual: 'func([]int)bool'"),
},
{ // Returns error when expected return types are not equal
"TestNewGenericFunc", "test7",
func(items ...int) bool { return false },
simpleParamValidator(newElemTypeSlice(new(genericType)), newElemTypeSlice(new(int64))),
errors.New("TestNewGenericFunc: parameter [test7] has a invalid function signature. Expected: 'func(T)int64', actual: 'func([]int)bool'"),
},
}
for _, test := range tests {
_, err := newGenericFunc(test.methodName, test.paramName, test.function, test.validationFunc)
if !(err == test.exception || err.Error() == test.exception.Error()) {
t.Errorf("Validate expect error: %s, actual: %s", test.exception, err)
}
}
}
func TestCall(t *testing.T) {
tests := []struct {
methodName string
paramName string
function interface{}
validationFunc func(*functionCache) error
fnParameter interface{}
result interface{}
exception error
}{
{ // A valid function and parameters
"TestCall", "test1",
func(i int) int { return i * 3 },
simpleParamValidator(newElemTypeSlice(new(genericType)), newElemTypeSlice(new(int))),
3,
9,
nil,
},
{ // Returns error when the required type doesn't match with the specification
"TestCall", "test2",
func(i int) int { return i * 3 },
simpleParamValidator(newElemTypeSlice(new(int)), newElemTypeSlice(new(int))),
"not a int",
9,
errors.New("reflect: Call using string as type int"),
},
{ // A valid function and parameters
"TestCall", "test3",
func(i int) {},
simpleParamValidator(newElemTypeSlice(new(genericType)), []reflect.Type{}),
3,
nil,
nil,
},
}
for _, test := range tests {
func() {
defer func() {
r := recover()
if !(r == test.exception || r == test.exception.Error()) {
t.Errorf("expect error: nil, actual: %s", r)
}
}()
dynaFunc, err := newGenericFunc(test.methodName, test.paramName, test.function, test.validationFunc)
if err != nil {
t.Errorf("expect error: nil, actual: %s", err)
}
result := dynaFunc.Call(test.fnParameter)
if result != nil && result != test.result {
t.Errorf("expect result: %d, actual: %d", test.result, result)
}
}()
}
}