func_provider_test.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  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 interpreter
  11. import (
  12. "fmt"
  13. "reflect"
  14. "testing"
  15. "devt.de/krotik/ecal/stdlib"
  16. )
  17. func TestStdlib(t *testing.T) {
  18. stdlib.AddStdlibPkg("fmt", "fmt package")
  19. stdlib.AddStdlibFunc("fmt", "Sprint",
  20. stdlib.NewECALFunctionAdapter(reflect.ValueOf(fmt.Sprint), "foo"))
  21. res, err := UnitTestEvalAndAST(
  22. `fmt.Sprint([1,2,3])`, nil,
  23. `
  24. identifier: fmt
  25. identifier: Sprint
  26. funccall
  27. list
  28. number: 1
  29. number: 2
  30. number: 3
  31. `[1:])
  32. if err != nil || res != "[1 2 3]" {
  33. t.Error("Unexpected result: ", res, err)
  34. return
  35. }
  36. res, err = UnitTestEvalAndAST(
  37. `fmt.Sprint(math.Pi)`, nil,
  38. `
  39. identifier: fmt
  40. identifier: Sprint
  41. funccall
  42. identifier: math
  43. identifier: Pi
  44. `[1:])
  45. if err != nil || res != "3.141592653589793" {
  46. t.Error("Unexpected result: ", res, err)
  47. return
  48. }
  49. // Negative case
  50. res, err = UnitTestEvalAndAST(
  51. `a.fmtSprint([1,2,3])`, nil,
  52. `
  53. identifier: a
  54. identifier: fmtSprint
  55. funccall
  56. list
  57. number: 1
  58. number: 2
  59. number: 3
  60. `[1:])
  61. if err == nil ||
  62. err.Error() != "ECAL error in ECALTestRuntime: Unknown construct (Unknown function: fmtSprint) (Line:1 Pos:3)" {
  63. t.Error("Unexpected result: ", res, err)
  64. return
  65. }
  66. }
  67. func TestSimpleFunctions(t *testing.T) {
  68. res, err := UnitTestEvalAndAST(
  69. `len([1,2,3])`, nil,
  70. `
  71. identifier: len
  72. funccall
  73. list
  74. number: 1
  75. number: 2
  76. number: 3
  77. `[1:])
  78. if err != nil || res != 3. {
  79. t.Error("Unexpected result: ", res, err)
  80. return
  81. }
  82. res, err = UnitTestEvalAndAST(
  83. `len({"a":1, 2:"b"})`, nil,
  84. `
  85. identifier: len
  86. funccall
  87. map
  88. kvp
  89. string: 'a'
  90. number: 1
  91. kvp
  92. number: 2
  93. string: 'b'
  94. `[1:])
  95. if err != nil || res != 2. {
  96. t.Error("Unexpected result: ", res, err)
  97. return
  98. }
  99. res, err = UnitTestEvalAndAST(
  100. `del([1,2,3], 1)`, nil,
  101. `
  102. identifier: del
  103. funccall
  104. list
  105. number: 1
  106. number: 2
  107. number: 3
  108. number: 1
  109. `[1:])
  110. if err != nil || fmt.Sprint(res) != "[1 3]" {
  111. t.Error("Unexpected result: ", res, err)
  112. return
  113. }
  114. res, err = UnitTestEvalAndAST(
  115. `del({
  116. "a" : 1
  117. "b" : 2
  118. "c" : 3
  119. }, "b")`, nil,
  120. `
  121. identifier: del
  122. funccall
  123. map
  124. kvp
  125. string: 'a'
  126. number: 1
  127. kvp
  128. string: 'b'
  129. number: 2
  130. kvp
  131. string: 'c'
  132. number: 3
  133. string: 'b'
  134. `[1:])
  135. if err != nil || fmt.Sprint(res) != "map[a:1 c:3]" {
  136. t.Error("Unexpected result: ", res, err)
  137. return
  138. }
  139. res, err = UnitTestEvalAndAST(
  140. `add([1,2,3], 4)`, nil,
  141. `
  142. identifier: add
  143. funccall
  144. list
  145. number: 1
  146. number: 2
  147. number: 3
  148. number: 4
  149. `[1:])
  150. if err != nil || fmt.Sprint(res) != "[1 2 3 4]" {
  151. t.Error("Unexpected result: ", res, err)
  152. return
  153. }
  154. res, err = UnitTestEvalAndAST(
  155. `add([1,2,3], 4, 0)`, nil,
  156. `
  157. identifier: add
  158. funccall
  159. list
  160. number: 1
  161. number: 2
  162. number: 3
  163. number: 4
  164. number: 0
  165. `[1:])
  166. if err != nil || fmt.Sprint(res) != "[4 1 2 3]" {
  167. t.Error("Unexpected result: ", res, err)
  168. return
  169. }
  170. res, err = UnitTestEvalAndAST(
  171. `add([1,2,3], 4, 1)`, nil,
  172. `
  173. identifier: add
  174. funccall
  175. list
  176. number: 1
  177. number: 2
  178. number: 3
  179. number: 4
  180. number: 1
  181. `[1:])
  182. if err != nil || fmt.Sprint(res) != "[1 4 2 3]" {
  183. t.Error("Unexpected result: ", res, err)
  184. return
  185. }
  186. res, err = UnitTestEvalAndAST(
  187. `concat([1,2,3], [4,5,6], [7,8,9])`, nil,
  188. `
  189. identifier: concat
  190. funccall
  191. list
  192. number: 1
  193. number: 2
  194. number: 3
  195. list
  196. number: 4
  197. number: 5
  198. number: 6
  199. list
  200. number: 7
  201. number: 8
  202. number: 9
  203. `[1:])
  204. if err != nil || fmt.Sprint(res) != "[1 2 3 4 5 6 7 8 9]" {
  205. t.Error("Unexpected result: ", res, err)
  206. return
  207. }
  208. res, err = UnitTestEvalAndAST(
  209. `dumpenv()`, nil,
  210. `
  211. identifier: dumpenv
  212. funccall
  213. `[1:])
  214. if err != nil || fmt.Sprint(res) != `GlobalScope {
  215. }` {
  216. t.Error("Unexpected result: ", res, err)
  217. return
  218. }
  219. res, err = UnitTestEval(
  220. `
  221. func foo() {
  222. log("hello")
  223. }
  224. doc(foo)`, nil)
  225. if err != nil || fmt.Sprint(res) != `Declared function: foo (Line 2, Pos 1)` {
  226. t.Error("Unexpected result: ", res, err)
  227. return
  228. }
  229. res, err = UnitTestEval(
  230. `doc(len)`, nil)
  231. if err != nil || fmt.Sprint(res) != `Len returns the size of a list or map.` {
  232. t.Error("Unexpected result: ", res, err)
  233. return
  234. }
  235. stdlib.AddStdlibPkg("fmt", "fmt package")
  236. stdlib.AddStdlibFunc("fmt", "Println",
  237. stdlib.NewECALFunctionAdapter(reflect.ValueOf(fmt.Sprint), "foo"))
  238. res, err = UnitTestEval(
  239. `doc(fmt.Println)`, nil)
  240. if err != nil || res != "foo" {
  241. t.Error("Unexpected result: ", res, err)
  242. return
  243. }
  244. res, err = UnitTestEval(
  245. `
  246. /*
  247. Foo is my custom function.
  248. */
  249. func foo() {
  250. log("hello")
  251. }
  252. doc(foo)`, nil)
  253. if err != nil || fmt.Sprint(res) != `Foo is my custom function.` {
  254. t.Error("Unexpected result: ", res, err)
  255. return
  256. }
  257. // Negative case
  258. res, err = UnitTestEvalAndAST(
  259. `a.len([1,2,3])`, nil,
  260. `
  261. identifier: a
  262. identifier: len
  263. funccall
  264. list
  265. number: 1
  266. number: 2
  267. number: 3
  268. `[1:])
  269. if err == nil ||
  270. err.Error() != "ECAL error in ECALTestRuntime: Unknown construct (Unknown function: len) (Line:1 Pos:3)" {
  271. t.Error("Unexpected result: ", res, err)
  272. return
  273. }
  274. }
  275. func TestDocstrings(t *testing.T) {
  276. for k, v := range InbuildFuncMap {
  277. if res, _ := v.DocString(); res == "" {
  278. t.Error("Docstring missing for ", k)
  279. return
  280. }
  281. }
  282. }
  283. func TestErrorConditions(t *testing.T) {
  284. ib := &inbuildBaseFunc{}
  285. if _, err := ib.AssertNumParam(1, "bob"); err == nil || err.Error() != "Parameter 1 should be a number" {
  286. t.Error("Unexpected result:", err)
  287. return
  288. }
  289. if _, err := ib.AssertMapParam(1, "bob"); err == nil || err.Error() != "Parameter 1 should be a map" {
  290. t.Error("Unexpected result:", err)
  291. return
  292. }
  293. if _, err := ib.AssertListParam(1, "bob"); err == nil || err.Error() != "Parameter 1 should be a list" {
  294. t.Error("Unexpected result:", err)
  295. return
  296. }
  297. rf := &rangeFunc{&inbuildBaseFunc{}}
  298. if _, err := rf.Run("", nil, nil, nil); err == nil || err.Error() != "Need at least an end range as first parameter" {
  299. t.Error("Unexpected result:", err)
  300. return
  301. }
  302. if _, err := rf.Run("", nil, nil, []interface{}{"bob"}); err == nil || err.Error() != "Parameter 1 should be a number" {
  303. t.Error("Unexpected result:", err)
  304. return
  305. }
  306. }