lexer_test.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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 TestNextAndPeek(t *testing.T) {
  15. l := &lexer{"", "Test", 0, 0, 0, 0, 0, make(chan LexToken)}
  16. if res := fmt.Sprintf("%c", l.next(0)); res != "T" {
  17. t.Error("Unexpected result:", res)
  18. }
  19. if res := fmt.Sprintf("%c", l.next(1)); res != "e" {
  20. t.Error("Unexpected result:", res)
  21. }
  22. if res := fmt.Sprintf("%c", l.next(2)); res != "s" {
  23. t.Error("Unexpected result:", res)
  24. }
  25. if res := fmt.Sprintf("%c", l.next(3)); res != "t" {
  26. t.Error("Unexpected result:", res)
  27. }
  28. if l.pos != 0 {
  29. t.Error("Lexer moved forward when it shouldn't: ", l.pos)
  30. return
  31. }
  32. if res := fmt.Sprintf("%c", l.next(-1)); res != "T" {
  33. t.Error("Unexpected result:", res)
  34. }
  35. if l.pos != 1 {
  36. t.Error("Lexer moved forward when it shouldn't: ", l.pos)
  37. return
  38. }
  39. if res := fmt.Sprintf("%c", l.next(-1)); res != "e" {
  40. t.Error("Unexpected result:", res)
  41. }
  42. if l.pos != 2 {
  43. t.Error("Lexer moved forward when it shouldn't: ", l.pos)
  44. return
  45. }
  46. }
  47. func TestSimpleLexing(t *testing.T) {
  48. if res := fmt.Sprint(LexToList("test", "\ufeff1!23")); res != `[int(1) ! int(23) EOF]` {
  49. t.Error("Unexpected result:", res)
  50. return
  51. }
  52. if res := fmt.Sprint(LexToList("test", "1!23.4e+11 3E-5 11.1 .4$")); res !=
  53. `[int(1) ! flt(23.4e+11) flt(3e-5) flt(11.1) flt(.4) $ EOF]` {
  54. t.Error("Unexpected result:", res)
  55. return
  56. }
  57. if res := fmt.Sprint(LexToList("test", "12!foo...bar99")); res !=
  58. `[int(12) ! <foo> ... <bar99> EOF]` {
  59. t.Error("Unexpected result:", res)
  60. return
  61. }
  62. if res := fmt.Sprint(LexToList("test", "-0 0 1230 0123")); res !=
  63. `[int(-0) int(0) int(1230) Error: 0123 (Line 1, Pos 11) EOF]` {
  64. t.Error("Unexpected result:", res)
  65. return
  66. }
  67. }
  68. func TestLexingErrors(t *testing.T) {
  69. if res := fmt.Sprint(LexToList("test", `"te`)); res != `[Error: EOF inside quotes (Line 1, Pos 1) EOF]` {
  70. t.Error("Unexpected result:", res)
  71. return
  72. }
  73. }
  74. func TestMultilineLexing(t *testing.T) {
  75. if res := fmt.Sprint(LexToList("test", `1!23#...4e+11
  76. 123
  77. true
  78. `)); res != `[int(1) ! int(23) int(123) <true> EOF]` {
  79. t.Error("Unexpected result:", res)
  80. return
  81. }
  82. if res := fmt.Sprint(LexToList("test", `"""
  83. 123
  84. """
  85. "["
  86. [
  87. "123"
  88. "123\u2318"
  89. """123\u2318"""
  90. """
  91. bla
  92. """
  93. `)); res != `["123" "[" [ "123" "123⌘" "123\u2318" "bla" EOF]` {
  94. t.Error("Unexpected result:", res)
  95. return
  96. }
  97. if res := fmt.Sprint(LexToList("test", `"""
  98. Hello,
  99. World!
  100. Yours,
  101. GraphQL.
  102. """
  103. `)); res != `["Hello,
  104. World!
  105. Yours,
  106. GraphQL." EOF]` {
  107. t.Error("Unexpected result:", res)
  108. return
  109. }
  110. if res := fmt.Sprint(LexToList("test", `"Hello,\n World!\n\nYours,\n GraphQL."
  111. `)); res != `["Hello,
  112. World!
  113. Yours,
  114. GraphQL." EOF]` {
  115. t.Error("Unexpected result:", res)
  116. return
  117. }
  118. ll := LexToList("test", `"Hello,\n World!\n\nYours,\n GraphQL."
  119. `)
  120. if res := ll[len(ll)-1].PosString(); res != "Line 2, Pos 1" {
  121. t.Error("Unexpected result:", res)
  122. return
  123. }
  124. }
  125. func TestIgnoredLexing(t *testing.T) {
  126. res := fmt.Sprint(LexToList("test", "1,2,3...abc\t\r\n#123\n"))
  127. if res != `[int(1) int(2) int(3) ... <abc> EOF]` {
  128. t.Error("Unexpected result:", res)
  129. return
  130. }
  131. res = fmt.Sprint(LexToList("test", "1,2,3 .. x abc\r\n#123\n"))
  132. if res != `[int(1) int(2) int(3) Error: .. (Line 1, Pos 7) <x> <abc> EOF]` {
  133. t.Error("Unexpected result:", res)
  134. return
  135. }
  136. res = fmt.Sprint(LexToList("test", "1,2,3 .. x abc\r\n#123"))
  137. if res != `[int(1) int(2) int(3) Error: .. (Line 1, Pos 7) <x> <abc> EOF]` {
  138. t.Error("Unexpected result:", res)
  139. return
  140. }
  141. }
  142. func TestSampleQueries(t *testing.T) {
  143. sampleQueries := [][]string{{`
  144. query StudentsNormal {
  145. allStudents(pagination: {offset: 0, limit: 10}, sort: {fields: [{field: "studentNumber", order: ASC}]},
  146. filter: {fields: [{op: NIN, value: "[Harry]", field: "name"}]}) {
  147. result {
  148. ...studentFields
  149. subjects {
  150. name
  151. classroom
  152. }
  153. }
  154. pagination {
  155. offset
  156. limit
  157. total
  158. }
  159. }
  160. }
  161. `, `[<query> <StudentsNormal> { <allStudents> ( <pagination> : { <offset> : int(0) <limit> : int(10) } <sort> : { <fields> : [ { <field> : "studentNumber" <order> : <ASC> } ] } <filter> : { <fields> : [ { <op> : <NIN> <value> : "[Harry]" <field> : "name" } ] } ) { <result> { ... <studentFields> <subjects> { <name> <classroom> } } <pagination> { <offset> <limit> <total> } } } EOF]`},
  162. {`
  163. query StudentsJPA {
  164. allStudentsJPA(pagination: {offset: 0, limit: 10}, sort: {fields: [{field: "studentNumber", order: ASC}]}, filter: {fields: [{op: NIN, value: "[Harry]", field: "name"}]}) {
  165. ... on PaginationWrapper_Student {
  166. result {
  167. name
  168. }
  169. }
  170. result {
  171. ...studentFields
  172. ... on Student {
  173. enrolled
  174. }
  175. subjects {
  176. name
  177. classroom
  178. }
  179. }
  180. pagination {
  181. offset
  182. limit
  183. total
  184. }
  185. }
  186. }
  187. `, `[<query> <StudentsJPA> { <allStudentsJPA> ( <pagination> : { <offset> : int(0) <limit> : int(10) } <sort> : { <fields> : [ { <field> : "studentNumber" <order> : <ASC> } ] } <filter> : { <fields> : [ { <op> : <NIN> <value> : "[Harry]" <field> : "name" } ] } ) { ... <on> <PaginationWrapper_Student> { <result> { <name> } } <result> { ... <studentFields> ... <on> <Student> { <enrolled> } <subjects> { <name> <classroom> } } <pagination> { <offset> <limit> <total> } } } EOF]`},
  188. {`
  189. # query variables
  190. {
  191. "st": {
  192. "studentNumber": 63170004,
  193. "studentLoan": 631700.04,
  194. "name": "Latest",
  195. "surname": "Greatest"
  196. }
  197. `, `[{ "st" : { "studentNumber" : int(63170004) "studentLoan" : flt(631700.04) "name" : "Latest" "surname" : "Greatest" } EOF]`}}
  198. for _, sampleQuery := range sampleQueries {
  199. if res := fmt.Sprint(LexToList("test", sampleQuery[0])); res != sampleQuery[1] {
  200. t.Error("Unexpected result\nGiven:\n", sampleQuery[0], "\nGot:\n", res, "\nExpected:\n", sampleQuery[1])
  201. return
  202. }
  203. }
  204. }