parser_main_test.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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 TestCommentParsing(t *testing.T) {
  15. // Comment parsing without statements
  16. input := `/* This is a comment*/ a := 1 + 1 # foo bar`
  17. expectedOutput := `
  18. :=
  19. identifier: a # This is a comment
  20. plus
  21. number: 1
  22. number: 1 # foo bar
  23. `[1:]
  24. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  25. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  26. return
  27. }
  28. }
  29. func TestSimpleExpressionParsing(t *testing.T) {
  30. // Test error output
  31. input := `"bl\*a"conversion`
  32. if _, err := UnitTestParse("mytest", input); err.Error() !=
  33. "Parse error in mytest: Lexical error (invalid syntax while parsing string) (Line:1 Pos:1)" {
  34. t.Error(err)
  35. return
  36. }
  37. // Test incomplete expression
  38. input = `a *`
  39. if _, err := UnitTestParse("mytest", input); err.Error() !=
  40. "Parse error in mytest: Unexpected end" {
  41. t.Error(err)
  42. return
  43. }
  44. input = `not ==`
  45. if _, err := UnitTestParse("mytest", input); err.Error() !=
  46. "Parse error in mytest: Term cannot start an expression (==) (Line:1 Pos:5)" {
  47. t.Error(err)
  48. return
  49. }
  50. input = `(==)`
  51. if _, err := UnitTestParse("mytest", input); err.Error() !=
  52. "Parse error in mytest: Term cannot start an expression (==) (Line:1 Pos:2)" {
  53. t.Error(err)
  54. return
  55. }
  56. input = "5 ( 5"
  57. if _, err := UnitTestParse("mytest", input); err.Error() !=
  58. "Parse error in mytest: Term can only start an expression (() (Line:1 Pos:3)" {
  59. t.Error(err)
  60. return
  61. }
  62. input = "5 + \""
  63. if _, err := UnitTestParse("mytest", input); err.Error() !=
  64. "Parse error in mytest: Lexical error (Unexpected end while reading string value (unclosed quotes)) (Line:1 Pos:5)" {
  65. t.Error(err)
  66. return
  67. }
  68. // Test prefix operator
  69. input = ` + a - -5`
  70. expectedOutput := `
  71. minus
  72. plus
  73. identifier: a
  74. minus
  75. number: 5
  76. `[1:]
  77. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  78. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  79. return
  80. }
  81. }
  82. func TestArithmeticParsing(t *testing.T) {
  83. input := "a + b * 5 /2"
  84. expectedOutput := `
  85. plus
  86. identifier: a
  87. div
  88. times
  89. identifier: b
  90. number: 5
  91. number: 2
  92. `[1:]
  93. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  94. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  95. return
  96. }
  97. // Test brackets
  98. input = "a + 1 * (5 + 6)"
  99. expectedOutput = `
  100. plus
  101. identifier: a
  102. times
  103. number: 1
  104. plus
  105. number: 5
  106. number: 6
  107. `[1:]
  108. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  109. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  110. return
  111. }
  112. // Test needless brackets
  113. input = "(a + 1) * (5 / (6 - 2))"
  114. expectedOutput = `
  115. times
  116. plus
  117. identifier: a
  118. number: 1
  119. div
  120. number: 5
  121. minus
  122. number: 6
  123. number: 2
  124. `[1:]
  125. // Pretty printer should get rid of the needless brackets
  126. res, err := UnitTestParseWithPPResult("mytest", input, "(a + 1) * 5 / (6 - 2)")
  127. if err != nil || fmt.Sprint(res) != expectedOutput {
  128. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  129. return
  130. }
  131. }
  132. func TestLogicParsing(t *testing.T) {
  133. input := "not (a + 1) * 5 and tRue == false or not 1 - 5 != test"
  134. expectedOutput := `
  135. or
  136. and
  137. not
  138. times
  139. plus
  140. identifier: a
  141. number: 1
  142. number: 5
  143. ==
  144. true
  145. false
  146. not
  147. !=
  148. minus
  149. number: 1
  150. number: 5
  151. identifier: test
  152. `[1:]
  153. res, err := UnitTestParseWithPPResult("mytest", input, "not (a + 1) * 5 and true == false or not 1 - 5 != test")
  154. if err != nil || fmt.Sprint(res) != expectedOutput {
  155. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  156. return
  157. }
  158. input = "a > b or a <= p or b hasSuffix 'test' or c hasPrefix 'test' and x < 4 or x >= 10"
  159. expectedOutput = `
  160. or
  161. or
  162. or
  163. or
  164. >
  165. identifier: a
  166. identifier: b
  167. <=
  168. identifier: a
  169. identifier: p
  170. hassuffix
  171. identifier: b
  172. string: 'test'
  173. and
  174. hasprefix
  175. identifier: c
  176. string: 'test'
  177. <
  178. identifier: x
  179. number: 4
  180. >=
  181. identifier: x
  182. number: 10
  183. `[1:]
  184. res, err = UnitTestParseWithPPResult("mytest", input, `a > b or a <= p or b hassuffix "test" or c hasprefix "test" and x < 4 or x >= 10`)
  185. if err != nil || fmt.Sprint(res) != expectedOutput {
  186. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  187. return
  188. }
  189. input = "(a in null or c notin d) and false like 9 or x // 6 > 2 % 1"
  190. expectedOutput = `
  191. or
  192. and
  193. or
  194. in
  195. identifier: a
  196. null
  197. notin
  198. identifier: c
  199. identifier: d
  200. like
  201. false
  202. number: 9
  203. >
  204. divint
  205. identifier: x
  206. number: 6
  207. modint
  208. number: 2
  209. number: 1
  210. `[1:]
  211. if res, err := UnitTestParse("mytest", input); err != nil || fmt.Sprint(res) != expectedOutput {
  212. t.Error("Unexpected parser output:\n", res, "expected was:\n", expectedOutput, "Error:", err)
  213. return
  214. }
  215. }