parser_main_test.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. /*
  2. * Public Domain Software
  3. *
  4. * I (Matthias Ladkau) am the author of the source code in this file.
  5. * I have placed the source code in this file in the public domain.
  6. *
  7. * For further information see: http://creativecommons.org/publicdomain/zero/1.0/
  8. */
  9. package parser
  10. import (
  11. "fmt"
  12. "testing"
  13. )
  14. func TestStatementParsing(t *testing.T) {
  15. // Comment parsing without statements
  16. input := `a := 1
  17. b := 2; c:= 3`
  18. expectedOutput := `
  19. statements
  20. :=
  21. identifier: a
  22. number: 1
  23. :=
  24. identifier: b
  25. number: 2
  26. :=
  27. identifier: c
  28. number: 3
  29. `[1:]
  30. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  31. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  32. return
  33. }
  34. }
  35. func TestIdentifierParsing(t *testing.T) {
  36. input := `a := 1
  37. a.foo := 2
  38. a.b.c.foo := a.b
  39. `
  40. expectedOutput := `
  41. statements
  42. :=
  43. identifier: a
  44. number: 1
  45. :=
  46. identifier: a
  47. identifier: foo
  48. number: 2
  49. :=
  50. identifier: a
  51. identifier: b
  52. identifier: c
  53. identifier: foo
  54. identifier: a
  55. identifier: b
  56. `[1:]
  57. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  58. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  59. return
  60. }
  61. input = `a := b[1 + 1]
  62. a[4].foo["aaa"] := c[i]
  63. `
  64. expectedOutput = `
  65. statements
  66. :=
  67. identifier: a
  68. identifier: b
  69. compaccess
  70. plus
  71. number: 1
  72. number: 1
  73. :=
  74. identifier: a
  75. compaccess
  76. number: 4
  77. identifier: foo
  78. compaccess
  79. string: 'aaa'
  80. identifier: c
  81. compaccess
  82. identifier: i
  83. `[1:]
  84. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  85. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  86. return
  87. }
  88. }
  89. func TestCommentParsing(t *testing.T) {
  90. // Comment parsing without statements
  91. input := `/* This is a comment*/ a := 1 + 1 # foo bar`
  92. expectedOutput := `
  93. :=
  94. identifier: a # This is a comment
  95. plus
  96. number: 1
  97. number: 1 # foo bar
  98. `[1:]
  99. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  100. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  101. return
  102. }
  103. input = `/* foo */ 1 # foo bar`
  104. expectedOutput = `
  105. number: 1 # foo foo bar
  106. `[1:]
  107. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  108. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  109. return
  110. }
  111. }
  112. func TestSimpleExpressionParsing(t *testing.T) {
  113. // Test error output
  114. input := `"bl\*a"conversion`
  115. if _, err := UnitTestParse("mytest", input); err.Error() !=
  116. "Parse error in mytest: Lexical error (invalid syntax while parsing string) (Line:1 Pos:1)" {
  117. t.Error(err)
  118. return
  119. }
  120. // Test incomplete expression
  121. input = `a *`
  122. if _, err := UnitTestParse("mytest", input); err.Error() !=
  123. "Parse error in mytest: Unexpected end" {
  124. t.Error(err)
  125. return
  126. }
  127. input = `not ==`
  128. if _, err := UnitTestParse("mytest", input); err.Error() !=
  129. "Parse error in mytest: Term cannot start an expression (==) (Line:1 Pos:5)" {
  130. t.Error(err)
  131. return
  132. }
  133. input = `(==)`
  134. if _, err := UnitTestParse("mytest", input); err.Error() !=
  135. "Parse error in mytest: Term cannot start an expression (==) (Line:1 Pos:2)" {
  136. t.Error(err)
  137. return
  138. }
  139. input = "5 ( 5"
  140. if _, err := UnitTestParse("mytest", input); err.Error() !=
  141. "Parse error in mytest: Term can only start an expression (() (Line:1 Pos:3)" {
  142. t.Error(err)
  143. return
  144. }
  145. input = "5 + \""
  146. if _, err := UnitTestParse("mytest", input); err.Error() !=
  147. "Parse error in mytest: Lexical error (Unexpected end while reading string value (unclosed quotes)) (Line:1 Pos:5)" {
  148. t.Error(err)
  149. return
  150. }
  151. // Test prefix operator
  152. input = ` + a - -5`
  153. expectedOutput := `
  154. minus
  155. plus
  156. identifier: a
  157. minus
  158. number: 5
  159. `[1:]
  160. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  161. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  162. return
  163. }
  164. }
  165. func TestArithmeticParsing(t *testing.T) {
  166. input := "a + b * 5 /2"
  167. expectedOutput := `
  168. plus
  169. identifier: a
  170. div
  171. times
  172. identifier: b
  173. number: 5
  174. number: 2
  175. `[1:]
  176. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  177. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  178. return
  179. }
  180. // Test brackets
  181. input = "a + 1 * (5 + 6)"
  182. expectedOutput = `
  183. plus
  184. identifier: a
  185. times
  186. number: 1
  187. plus
  188. number: 5
  189. number: 6
  190. `[1:]
  191. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  192. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  193. return
  194. }
  195. // Test needless brackets
  196. input = "(a + 1) * (5 / (6 - 2))"
  197. expectedOutput = `
  198. times
  199. plus
  200. identifier: a
  201. number: 1
  202. div
  203. number: 5
  204. minus
  205. number: 6
  206. number: 2
  207. `[1:]
  208. // Pretty printer should get rid of the needless brackets
  209. res, err := UnitTestParseWithPPResult("mytest", input, "(a + 1) * 5 / (6 - 2)")
  210. if err != nil || fmt.Sprint(res) != expectedOutput {
  211. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  212. return
  213. }
  214. }
  215. func TestLogicParsing(t *testing.T) {
  216. input := "not (a + 1) * 5 and tRue == false or not 1 - 5 != test"
  217. expectedOutput := `
  218. or
  219. and
  220. not
  221. times
  222. plus
  223. identifier: a
  224. number: 1
  225. number: 5
  226. ==
  227. true
  228. false
  229. not
  230. !=
  231. minus
  232. number: 1
  233. number: 5
  234. identifier: test
  235. `[1:]
  236. res, err := UnitTestParseWithPPResult("mytest", input, "not (a + 1) * 5 and true == false or not 1 - 5 != test")
  237. if err != nil || fmt.Sprint(res) != expectedOutput {
  238. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  239. return
  240. }
  241. input = "a > b or a <= p or b hasSuffix 'test' or c hasPrefix 'test' and x < 4 or x >= 10"
  242. expectedOutput = `
  243. or
  244. or
  245. or
  246. or
  247. >
  248. identifier: a
  249. identifier: b
  250. <=
  251. identifier: a
  252. identifier: p
  253. hassuffix
  254. identifier: b
  255. string: 'test'
  256. and
  257. hasprefix
  258. identifier: c
  259. string: 'test'
  260. <
  261. identifier: x
  262. number: 4
  263. >=
  264. identifier: x
  265. number: 10
  266. `[1:]
  267. res, err = UnitTestParseWithPPResult("mytest", input, `a > b or a <= p or b hassuffix "test" or c hasprefix "test" and x < 4 or x >= 10`)
  268. if err != nil || fmt.Sprint(res) != expectedOutput {
  269. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  270. return
  271. }
  272. input = "(a in null or c notin d) and false like 9 or x // 6 > 2 % 1"
  273. expectedOutput = `
  274. or
  275. and
  276. or
  277. in
  278. identifier: a
  279. null
  280. notin
  281. identifier: c
  282. identifier: d
  283. like
  284. false
  285. number: 9
  286. >
  287. divint
  288. identifier: x
  289. number: 6
  290. modint
  291. number: 2
  292. number: 1
  293. `[1:]
  294. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  295. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  296. return
  297. }
  298. }