error_test.go 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  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 util
  11. import (
  12. "encoding/json"
  13. "fmt"
  14. "strings"
  15. "sync"
  16. "testing"
  17. "devt.de/krotik/ecal/parser"
  18. "devt.de/krotik/ecal/scope"
  19. )
  20. func TestRuntimeError(t *testing.T) {
  21. ast, _ := parser.Parse("foo", "a")
  22. err1 := NewRuntimeError("foo", fmt.Errorf("foo"), "bar", ast)
  23. if err1.Error() != "ECAL error in foo: foo (bar) (Line:1 Pos:1)" {
  24. t.Error("Unexpected result:", err1)
  25. return
  26. }
  27. ast.Token = nil
  28. err2 := NewRuntimeError("foo", fmt.Errorf("foo"), "bar", ast)
  29. if err2.Error() != "ECAL error in foo: foo (bar)" {
  30. t.Error("Unexpected result:", err2)
  31. return
  32. }
  33. ast, _ = parser.Parse("foo", "a:=1")
  34. err3 := NewRuntimeError("foo", fmt.Errorf("foo"), "bar", ast)
  35. ast, _ = parser.Parse("bar1", "print(b)")
  36. err3.(TraceableRuntimeError).AddTrace(ast)
  37. ast, _ = parser.Parse("bar2", "raise(c)")
  38. err3.(TraceableRuntimeError).AddTrace(ast)
  39. ast, _ = parser.Parse("bar3", "1 + d")
  40. err3.(TraceableRuntimeError).AddTrace(ast)
  41. trace := strings.Join(err3.(TraceableRuntimeError).GetTraceString(), "\n")
  42. if trace != `print(b) (bar1:1)
  43. raise(c) (bar2:1)
  44. 1 + d (bar3:1)` {
  45. t.Error("Unexpected result:", trace)
  46. return
  47. }
  48. err4 := &RuntimeErrorWithDetail{err3.(*RuntimeError), nil, nil}
  49. res, _ := json.MarshalIndent(err4.RuntimeError, "", " ")
  50. if string(res) != `{
  51. "Detail": "bar",
  52. "Node": {
  53. "Name": ":=",
  54. "Token": {
  55. "ID": 39,
  56. "Pos": 1,
  57. "Val": ":=",
  58. "Identifier": false,
  59. "AllowEscapes": false,
  60. "Lsource": "foo",
  61. "Lline": 1,
  62. "Lpos": 2
  63. },
  64. "Meta": null,
  65. "Children": [
  66. {
  67. "Name": "identifier",
  68. "Token": {
  69. "ID": 7,
  70. "Pos": 0,
  71. "Val": "a",
  72. "Identifier": true,
  73. "AllowEscapes": false,
  74. "Lsource": "foo",
  75. "Lline": 1,
  76. "Lpos": 1
  77. },
  78. "Meta": null,
  79. "Children": [],
  80. "Runtime": null
  81. },
  82. {
  83. "Name": "number",
  84. "Token": {
  85. "ID": 6,
  86. "Pos": 3,
  87. "Val": "1",
  88. "Identifier": false,
  89. "AllowEscapes": false,
  90. "Lsource": "foo",
  91. "Lline": 1,
  92. "Lpos": 4
  93. },
  94. "Meta": null,
  95. "Children": [],
  96. "Runtime": null
  97. }
  98. ],
  99. "Runtime": null
  100. },
  101. "Source": "foo",
  102. "Trace": [
  103. {
  104. "Name": "identifier",
  105. "Token": {
  106. "ID": 7,
  107. "Pos": 0,
  108. "Val": "print",
  109. "Identifier": true,
  110. "AllowEscapes": false,
  111. "Lsource": "bar1",
  112. "Lline": 1,
  113. "Lpos": 1
  114. },
  115. "Meta": null,
  116. "Children": [
  117. {
  118. "Name": "funccall",
  119. "Token": null,
  120. "Meta": null,
  121. "Children": [
  122. {
  123. "Name": "identifier",
  124. "Token": {
  125. "ID": 7,
  126. "Pos": 6,
  127. "Val": "b",
  128. "Identifier": true,
  129. "AllowEscapes": false,
  130. "Lsource": "bar1",
  131. "Lline": 1,
  132. "Lpos": 7
  133. },
  134. "Meta": null,
  135. "Children": [],
  136. "Runtime": null
  137. }
  138. ],
  139. "Runtime": null
  140. }
  141. ],
  142. "Runtime": null
  143. },
  144. {
  145. "Name": "identifier",
  146. "Token": {
  147. "ID": 7,
  148. "Pos": 0,
  149. "Val": "raise",
  150. "Identifier": true,
  151. "AllowEscapes": false,
  152. "Lsource": "bar2",
  153. "Lline": 1,
  154. "Lpos": 1
  155. },
  156. "Meta": null,
  157. "Children": [
  158. {
  159. "Name": "funccall",
  160. "Token": null,
  161. "Meta": null,
  162. "Children": [
  163. {
  164. "Name": "identifier",
  165. "Token": {
  166. "ID": 7,
  167. "Pos": 6,
  168. "Val": "c",
  169. "Identifier": true,
  170. "AllowEscapes": false,
  171. "Lsource": "bar2",
  172. "Lline": 1,
  173. "Lpos": 7
  174. },
  175. "Meta": null,
  176. "Children": [],
  177. "Runtime": null
  178. }
  179. ],
  180. "Runtime": null
  181. }
  182. ],
  183. "Runtime": null
  184. },
  185. {
  186. "Name": "plus",
  187. "Token": {
  188. "ID": 33,
  189. "Pos": 2,
  190. "Val": "+",
  191. "Identifier": false,
  192. "AllowEscapes": false,
  193. "Lsource": "bar3",
  194. "Lline": 1,
  195. "Lpos": 3
  196. },
  197. "Meta": null,
  198. "Children": [
  199. {
  200. "Name": "number",
  201. "Token": {
  202. "ID": 6,
  203. "Pos": 0,
  204. "Val": "1",
  205. "Identifier": false,
  206. "AllowEscapes": false,
  207. "Lsource": "bar3",
  208. "Lline": 1,
  209. "Lpos": 1
  210. },
  211. "Meta": null,
  212. "Children": [],
  213. "Runtime": null
  214. },
  215. {
  216. "Name": "identifier",
  217. "Token": {
  218. "ID": 7,
  219. "Pos": 4,
  220. "Val": "d",
  221. "Identifier": true,
  222. "AllowEscapes": false,
  223. "Lsource": "bar3",
  224. "Lline": 1,
  225. "Lpos": 5
  226. },
  227. "Meta": null,
  228. "Children": [],
  229. "Runtime": null
  230. }
  231. ],
  232. "Runtime": null
  233. }
  234. ],
  235. "Type": "foo"
  236. }` {
  237. t.Error("Unexpected result:", string(res))
  238. return
  239. }
  240. s := scope.NewScope("aa")
  241. s.SetValue("xx", 123)
  242. err4 = &RuntimeErrorWithDetail{err3.(*RuntimeError), s, sync.Mutex{}}
  243. res, _ = json.MarshalIndent(err4, "", " ")
  244. if string(res) != `{
  245. "Data": {},
  246. "Detail": "bar",
  247. "Environment": {
  248. "xx": 123
  249. },
  250. "Node": {
  251. "Name": ":=",
  252. "Token": {
  253. "ID": 39,
  254. "Pos": 1,
  255. "Val": ":=",
  256. "Identifier": false,
  257. "AllowEscapes": false,
  258. "Lsource": "foo",
  259. "Lline": 1,
  260. "Lpos": 2
  261. },
  262. "Meta": null,
  263. "Children": [
  264. {
  265. "Name": "identifier",
  266. "Token": {
  267. "ID": 7,
  268. "Pos": 0,
  269. "Val": "a",
  270. "Identifier": true,
  271. "AllowEscapes": false,
  272. "Lsource": "foo",
  273. "Lline": 1,
  274. "Lpos": 1
  275. },
  276. "Meta": null,
  277. "Children": [],
  278. "Runtime": null
  279. },
  280. {
  281. "Name": "number",
  282. "Token": {
  283. "ID": 6,
  284. "Pos": 3,
  285. "Val": "1",
  286. "Identifier": false,
  287. "AllowEscapes": false,
  288. "Lsource": "foo",
  289. "Lline": 1,
  290. "Lpos": 4
  291. },
  292. "Meta": null,
  293. "Children": [],
  294. "Runtime": null
  295. }
  296. ],
  297. "Runtime": null
  298. },
  299. "Source": "foo",
  300. "Trace": [
  301. {
  302. "Name": "identifier",
  303. "Token": {
  304. "ID": 7,
  305. "Pos": 0,
  306. "Val": "print",
  307. "Identifier": true,
  308. "AllowEscapes": false,
  309. "Lsource": "bar1",
  310. "Lline": 1,
  311. "Lpos": 1
  312. },
  313. "Meta": null,
  314. "Children": [
  315. {
  316. "Name": "funccall",
  317. "Token": null,
  318. "Meta": null,
  319. "Children": [
  320. {
  321. "Name": "identifier",
  322. "Token": {
  323. "ID": 7,
  324. "Pos": 6,
  325. "Val": "b",
  326. "Identifier": true,
  327. "AllowEscapes": false,
  328. "Lsource": "bar1",
  329. "Lline": 1,
  330. "Lpos": 7
  331. },
  332. "Meta": null,
  333. "Children": [],
  334. "Runtime": null
  335. }
  336. ],
  337. "Runtime": null
  338. }
  339. ],
  340. "Runtime": null
  341. },
  342. {
  343. "Name": "identifier",
  344. "Token": {
  345. "ID": 7,
  346. "Pos": 0,
  347. "Val": "raise",
  348. "Identifier": true,
  349. "AllowEscapes": false,
  350. "Lsource": "bar2",
  351. "Lline": 1,
  352. "Lpos": 1
  353. },
  354. "Meta": null,
  355. "Children": [
  356. {
  357. "Name": "funccall",
  358. "Token": null,
  359. "Meta": null,
  360. "Children": [
  361. {
  362. "Name": "identifier",
  363. "Token": {
  364. "ID": 7,
  365. "Pos": 6,
  366. "Val": "c",
  367. "Identifier": true,
  368. "AllowEscapes": false,
  369. "Lsource": "bar2",
  370. "Lline": 1,
  371. "Lpos": 7
  372. },
  373. "Meta": null,
  374. "Children": [],
  375. "Runtime": null
  376. }
  377. ],
  378. "Runtime": null
  379. }
  380. ],
  381. "Runtime": null
  382. },
  383. {
  384. "Name": "plus",
  385. "Token": {
  386. "ID": 33,
  387. "Pos": 2,
  388. "Val": "+",
  389. "Identifier": false,
  390. "AllowEscapes": false,
  391. "Lsource": "bar3",
  392. "Lline": 1,
  393. "Lpos": 3
  394. },
  395. "Meta": null,
  396. "Children": [
  397. {
  398. "Name": "number",
  399. "Token": {
  400. "ID": 6,
  401. "Pos": 0,
  402. "Val": "1",
  403. "Identifier": false,
  404. "AllowEscapes": false,
  405. "Lsource": "bar3",
  406. "Lline": 1,
  407. "Lpos": 1
  408. },
  409. "Meta": null,
  410. "Children": [],
  411. "Runtime": null
  412. },
  413. {
  414. "Name": "identifier",
  415. "Token": {
  416. "ID": 7,
  417. "Pos": 4,
  418. "Val": "d",
  419. "Identifier": true,
  420. "AllowEscapes": false,
  421. "Lsource": "bar3",
  422. "Lline": 1,
  423. "Lpos": 5
  424. },
  425. "Meta": null,
  426. "Children": [],
  427. "Runtime": null
  428. }
  429. ],
  430. "Runtime": null
  431. }
  432. ],
  433. "Type": "foo"
  434. }` {
  435. t.Error("Unexpected result:", string(res))
  436. return
  437. }
  438. }