adapter_test.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*
  2. * ECAL
  3. *
  4. * Copyright 2020 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the MIT
  7. * License, If a copy of the MIT License was not distributed with this
  8. * file, You can obtain one at https://opensource.org/licenses/MIT.
  9. */
  10. package stdlib
  11. import (
  12. "fmt"
  13. "math"
  14. "reflect"
  15. "strconv"
  16. "testing"
  17. "devt.de/krotik/common/errorutil"
  18. "devt.de/krotik/ecal/scope"
  19. )
  20. func TestECALFunctionAdapterSimple(t *testing.T) {
  21. res, err := runAdapterTest(
  22. reflect.ValueOf(strconv.Atoi),
  23. []interface{}{"1"},
  24. )
  25. if errorutil.AssertOk(err); res != float64(1) {
  26. t.Error("Unexpected result: ", res, err)
  27. return
  28. }
  29. res, err = runAdapterTest(
  30. reflect.ValueOf(strconv.ParseUint),
  31. []interface{}{"123", float64(0), float64(0)},
  32. )
  33. if errorutil.AssertOk(err); res != float64(123) {
  34. t.Error("Unexpected result: ", res, err)
  35. return
  36. }
  37. res, err = runAdapterTest(
  38. reflect.ValueOf(strconv.ParseFloat),
  39. []interface{}{"123.123", float64(0)},
  40. )
  41. if errorutil.AssertOk(err); res != float64(123.123) {
  42. t.Error("Unexpected result: ", res, err)
  43. return
  44. }
  45. res, err = runAdapterTest(
  46. reflect.ValueOf(fmt.Sprintf),
  47. []interface{}{"foo %v", "bar"},
  48. )
  49. if errorutil.AssertOk(err); res != "foo bar" {
  50. t.Error("Unexpected result: ", res, err)
  51. return
  52. }
  53. res, err = runAdapterTest(
  54. reflect.ValueOf(math.Float32bits),
  55. []interface{}{float64(11)},
  56. )
  57. errorutil.AssertOk(err)
  58. if r := fmt.Sprintf("%X", uint32(res.(float64))); r != fmt.Sprintf("%X", math.Float32bits(11)) {
  59. t.Error("Unexpected result: ", r, err)
  60. return
  61. }
  62. res, err = runAdapterTest(
  63. reflect.ValueOf(math.Float32frombits),
  64. []interface{}{float64(math.Float32bits(11))},
  65. )
  66. errorutil.AssertOk(err)
  67. if r := fmt.Sprintf("%v", res.(float64)); r != "11" {
  68. t.Error("Unexpected result: ", r, err)
  69. return
  70. }
  71. res, err = runAdapterTest(
  72. reflect.ValueOf(math.Float32frombits),
  73. []interface{}{math.Float32bits(11)}, // Giving the correct type also works
  74. )
  75. errorutil.AssertOk(err)
  76. if r := fmt.Sprintf("%v", res.(float64)); r != "11" {
  77. t.Error("Unexpected result: ", r, err)
  78. return
  79. }
  80. }
  81. func TestECALFunctionAdapterSimple2(t *testing.T) {
  82. res, err := runAdapterTest(
  83. reflect.ValueOf(math.Float64bits),
  84. []interface{}{float64(11)},
  85. )
  86. errorutil.AssertOk(err)
  87. if r := fmt.Sprintf("%X", uint64(res.(float64))); r != fmt.Sprintf("%X", math.Float64bits(11)) {
  88. t.Error("Unexpected result: ", r, err)
  89. return
  90. }
  91. res, err = runAdapterTest(
  92. reflect.ValueOf(math.Float64frombits),
  93. []interface{}{float64(math.Float64bits(11))},
  94. )
  95. errorutil.AssertOk(err)
  96. if r := fmt.Sprintf("%v", res.(float64)); r != "11" {
  97. t.Error("Unexpected result: ", r, err)
  98. return
  99. }
  100. res, err = runAdapterTest(
  101. reflect.ValueOf(dummyUint),
  102. []interface{}{float64(1)},
  103. )
  104. if errorutil.AssertOk(err); res != "1" {
  105. t.Error("Unexpected result: ", res, err)
  106. return
  107. }
  108. res, err = runAdapterTest(
  109. reflect.ValueOf(dummyUint8),
  110. []interface{}{float64(1)},
  111. )
  112. if errorutil.AssertOk(err); res != "1" {
  113. t.Error("Unexpected result: ", res, err)
  114. return
  115. }
  116. res, err = runAdapterTest(
  117. reflect.ValueOf(dummyUint16),
  118. []interface{}{float64(1)},
  119. )
  120. if errorutil.AssertOk(err); res != "1" {
  121. t.Error("Unexpected result: ", res, err)
  122. return
  123. }
  124. res, err = runAdapterTest(
  125. reflect.ValueOf(dummyUintptr),
  126. []interface{}{float64(1)},
  127. )
  128. if errorutil.AssertOk(err); res != "1" {
  129. t.Error("Unexpected result: ", res, err)
  130. return
  131. }
  132. res, err = runAdapterTest(
  133. reflect.ValueOf(dummyInt8),
  134. []interface{}{float64(1)},
  135. )
  136. if errorutil.AssertOk(err); res != "1" {
  137. t.Error("Unexpected result: ", res, err)
  138. return
  139. }
  140. res, err = runAdapterTest(
  141. reflect.ValueOf(dummyInt16),
  142. []interface{}{float64(1)},
  143. )
  144. if errorutil.AssertOk(err); res != "1" {
  145. t.Error("Unexpected result: ", res, err)
  146. return
  147. }
  148. res, err = runAdapterTest(
  149. reflect.ValueOf(dummyInt32),
  150. []interface{}{float64(1)},
  151. )
  152. if errorutil.AssertOk(err); res != "1" {
  153. t.Error("Unexpected result: ", res, err)
  154. return
  155. }
  156. res, err = runAdapterTest(
  157. reflect.ValueOf(dummyInt64),
  158. []interface{}{float64(1)},
  159. )
  160. if errorutil.AssertOk(err); res != "1" {
  161. t.Error("Unexpected result: ", res, err)
  162. return
  163. }
  164. }
  165. func TestECALFunctionAdapterErrors(t *testing.T) {
  166. // Test Error cases
  167. res, err := runAdapterTest(
  168. reflect.ValueOf(strconv.ParseFloat),
  169. []interface{}{"123.123", 0, 0},
  170. )
  171. if err == nil || err.Error() != "Too many parameters - got 3 expected 2" {
  172. t.Error("Unexpected result: ", res, err)
  173. return
  174. }
  175. res, err = runAdapterTest(
  176. reflect.ValueOf(strconv.ParseFloat),
  177. []interface{}{"Hans", 0},
  178. )
  179. if err == nil || err.Error() != `strconv.ParseFloat: parsing "Hans": invalid syntax` {
  180. t.Error("Unexpected result: ", res, err)
  181. return
  182. }
  183. res, err = runAdapterTest(
  184. reflect.ValueOf(strconv.ParseFloat),
  185. []interface{}{123, 0},
  186. )
  187. if err == nil || err.Error() != `Parameter 1 should be of type string but is of type int` {
  188. t.Error("Unexpected result: ", res, err)
  189. return
  190. }
  191. // Make sure we are never panicing but just returning an error
  192. res, err = runAdapterTest(
  193. reflect.ValueOf(errorutil.AssertTrue),
  194. []interface{}{false, "Some Panic Description"},
  195. )
  196. if err == nil || err.Error() != `Error: Some Panic Description` {
  197. t.Error("Unexpected result: ", res, err)
  198. return
  199. }
  200. // Get documentation
  201. afuncEcal := NewECALFunctionAdapter(reflect.ValueOf(fmt.Sprint), "test123")
  202. if s, err := afuncEcal.DocString(); s == "" || err != nil {
  203. t.Error("Docstring should return something")
  204. return
  205. }
  206. }
  207. func runAdapterTest(afunc reflect.Value, args []interface{}) (interface{}, error) {
  208. afuncEcal := &ECALFunctionAdapter{afunc, ""}
  209. return afuncEcal.Run("test", scope.NewScope(""), make(map[string]interface{}), 0, args)
  210. }
  211. func dummyUint(v uint) string {
  212. return fmt.Sprint(v)
  213. }
  214. func dummyUint8(v uint8) string {
  215. return fmt.Sprint(v)
  216. }
  217. func dummyUint16(v uint16) string {
  218. return fmt.Sprint(v)
  219. }
  220. func dummyUintptr(v uintptr) string {
  221. return fmt.Sprint(v)
  222. }
  223. func dummyInt8(v int8) string {
  224. return fmt.Sprint(v)
  225. }
  226. func dummyInt16(v int16) string {
  227. return fmt.Sprint(v)
  228. }
  229. func dummyInt32(v int32) string {
  230. return fmt.Sprint(v)
  231. }
  232. func dummyInt64(v int64) string {
  233. return fmt.Sprint(v)
  234. }