func_provider_test.go 6.2 KB

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