genericfunc_test.go 4.5 KB

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