lexer_test.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. package parser
  2. import (
  3. "testing"
  4. "github.com/dop251/goja/file"
  5. "github.com/dop251/goja/token"
  6. "github.com/dop251/goja/unistring"
  7. )
  8. func TestLexer(t *testing.T) {
  9. tt(t, func() {
  10. setup := func(src string) *_parser {
  11. parser := newParser("", src)
  12. return parser
  13. }
  14. test := func(src string, test ...interface{}) {
  15. parser := setup(src)
  16. for len(test) > 0 {
  17. tkn, literal, _, idx := parser.scan()
  18. if len(test) > 0 {
  19. is(tkn, test[0].(token.Token))
  20. test = test[1:]
  21. }
  22. if len(test) > 0 {
  23. is(literal, unistring.String(test[0].(string)))
  24. test = test[1:]
  25. }
  26. if len(test) > 0 {
  27. // FIXME terst, Fix this so that cast to file.Idx is not necessary?
  28. is(idx, file.Idx(test[0].(int)))
  29. test = test[1:]
  30. }
  31. }
  32. }
  33. test("",
  34. token.EOF, "", 1,
  35. )
  36. test("1",
  37. token.NUMBER, "1", 1,
  38. token.EOF, "", 2,
  39. )
  40. test(".0",
  41. token.NUMBER, ".0", 1,
  42. token.EOF, "", 3,
  43. )
  44. test("abc",
  45. token.IDENTIFIER, "abc", 1,
  46. token.EOF, "", 4,
  47. )
  48. test("abc(1)",
  49. token.IDENTIFIER, "abc", 1,
  50. token.LEFT_PARENTHESIS, "", 4,
  51. token.NUMBER, "1", 5,
  52. token.RIGHT_PARENTHESIS, "", 6,
  53. token.EOF, "", 7,
  54. )
  55. test(".",
  56. token.PERIOD, "", 1,
  57. token.EOF, "", 2,
  58. )
  59. test("===.",
  60. token.STRICT_EQUAL, "", 1,
  61. token.PERIOD, "", 4,
  62. token.EOF, "", 5,
  63. )
  64. test(">>>=.0",
  65. token.UNSIGNED_SHIFT_RIGHT_ASSIGN, "", 1,
  66. token.NUMBER, ".0", 5,
  67. token.EOF, "", 7,
  68. )
  69. test(">>>=0.0.",
  70. token.UNSIGNED_SHIFT_RIGHT_ASSIGN, "", 1,
  71. token.NUMBER, "0.0", 5,
  72. token.PERIOD, "", 8,
  73. token.EOF, "", 9,
  74. )
  75. test("\"abc\"",
  76. token.STRING, "\"abc\"", 1,
  77. token.EOF, "", 6,
  78. )
  79. test("abc = //",
  80. token.IDENTIFIER, "abc", 1,
  81. token.ASSIGN, "", 5,
  82. token.EOF, "", 9,
  83. )
  84. test("abc = 1 / 2",
  85. token.IDENTIFIER, "abc", 1,
  86. token.ASSIGN, "", 5,
  87. token.NUMBER, "1", 7,
  88. token.SLASH, "", 9,
  89. token.NUMBER, "2", 11,
  90. token.EOF, "", 12,
  91. )
  92. test("abc = 1n / 2n",
  93. token.IDENTIFIER, "abc", 1,
  94. token.ASSIGN, "", 5,
  95. token.NUMBER, "1n", 7,
  96. token.SLASH, "", 10,
  97. token.NUMBER, "2n", 12,
  98. token.EOF, "", 14,
  99. )
  100. test("abc = 0x1n / 0x2n",
  101. token.IDENTIFIER, "abc", 1,
  102. token.ASSIGN, "", 5,
  103. token.NUMBER, "0x1n", 7,
  104. token.SLASH, "", 12,
  105. token.NUMBER, "0x2n", 14,
  106. token.EOF, "", 18,
  107. )
  108. test("xyzzy = 'Nothing happens.'",
  109. token.IDENTIFIER, "xyzzy", 1,
  110. token.ASSIGN, "", 7,
  111. token.STRING, "'Nothing happens.'", 9,
  112. token.EOF, "", 27,
  113. )
  114. test("abc = !false",
  115. token.IDENTIFIER, "abc", 1,
  116. token.ASSIGN, "", 5,
  117. token.NOT, "", 7,
  118. token.BOOLEAN, "false", 8,
  119. token.EOF, "", 13,
  120. )
  121. test("abc = !!true",
  122. token.IDENTIFIER, "abc", 1,
  123. token.ASSIGN, "", 5,
  124. token.NOT, "", 7,
  125. token.NOT, "", 8,
  126. token.BOOLEAN, "true", 9,
  127. token.EOF, "", 13,
  128. )
  129. test("abc *= 1",
  130. token.IDENTIFIER, "abc", 1,
  131. token.MULTIPLY_ASSIGN, "", 5,
  132. token.NUMBER, "1", 8,
  133. token.EOF, "", 9,
  134. )
  135. test("if 1 else",
  136. token.IF, "if", 1,
  137. token.NUMBER, "1", 4,
  138. token.ELSE, "else", 6,
  139. token.EOF, "", 10,
  140. )
  141. test("null",
  142. token.NULL, "null", 1,
  143. token.EOF, "", 5,
  144. )
  145. test(`"\u007a\x79\u000a\x78"`,
  146. token.STRING, "\"\\u007a\\x79\\u000a\\x78\"", 1,
  147. token.EOF, "", 23,
  148. )
  149. test(`"[First line \
  150. Second line \
  151. Third line\
  152. . ]"
  153. `,
  154. token.STRING, "\"[First line \\\nSecond line \\\n Third line\\\n. ]\"", 1,
  155. token.EOF, "", 53,
  156. )
  157. test("/",
  158. token.SLASH, "", 1,
  159. token.EOF, "", 2,
  160. )
  161. test("var abc = \"abc\uFFFFabc\"",
  162. token.VAR, "var", 1,
  163. token.IDENTIFIER, "abc", 5,
  164. token.ASSIGN, "", 9,
  165. token.STRING, "\"abc\uFFFFabc\"", 11,
  166. token.EOF, "", 22,
  167. )
  168. test(`'\t' === '\r'`,
  169. token.STRING, "'\\t'", 1,
  170. token.STRICT_EQUAL, "", 6,
  171. token.STRING, "'\\r'", 10,
  172. token.EOF, "", 14,
  173. )
  174. test(`var \u0024 = 1`,
  175. token.VAR, "var", 1,
  176. token.IDENTIFIER, "\\u0024", 5,
  177. token.ASSIGN, "", 12,
  178. token.NUMBER, "1", 14,
  179. token.EOF, "", 15,
  180. )
  181. test("10e10000",
  182. token.NUMBER, "10e10000", 1,
  183. token.EOF, "", 9,
  184. )
  185. test(`var if var class`,
  186. token.VAR, "var", 1,
  187. token.IF, "if", 5,
  188. token.VAR, "var", 8,
  189. token.KEYWORD, "class", 12,
  190. token.EOF, "", 17,
  191. )
  192. test(`-0`,
  193. token.MINUS, "", 1,
  194. token.NUMBER, "0", 2,
  195. token.EOF, "", 3,
  196. )
  197. test(`.01`,
  198. token.NUMBER, ".01", 1,
  199. token.EOF, "", 4,
  200. )
  201. test(`.01e+2`,
  202. token.NUMBER, ".01e+2", 1,
  203. token.EOF, "", 7,
  204. )
  205. test(";",
  206. token.SEMICOLON, "", 1,
  207. token.EOF, "", 2,
  208. )
  209. test(";;",
  210. token.SEMICOLON, "", 1,
  211. token.SEMICOLON, "", 2,
  212. token.EOF, "", 3,
  213. )
  214. test("//",
  215. token.EOF, "", 3,
  216. )
  217. test(";;//",
  218. token.SEMICOLON, "", 1,
  219. token.SEMICOLON, "", 2,
  220. token.EOF, "", 5,
  221. )
  222. test("1",
  223. token.NUMBER, "1", 1,
  224. )
  225. test("12 123",
  226. token.NUMBER, "12", 1,
  227. token.NUMBER, "123", 4,
  228. )
  229. test("1.2 12.3",
  230. token.NUMBER, "1.2", 1,
  231. token.NUMBER, "12.3", 5,
  232. )
  233. test("/ /=",
  234. token.SLASH, "", 1,
  235. token.QUOTIENT_ASSIGN, "", 3,
  236. )
  237. test(`"abc"`,
  238. token.STRING, `"abc"`, 1,
  239. )
  240. test(`'abc'`,
  241. token.STRING, `'abc'`, 1,
  242. )
  243. test("++",
  244. token.INCREMENT, "", 1,
  245. )
  246. test(">",
  247. token.GREATER, "", 1,
  248. )
  249. test(">=",
  250. token.GREATER_OR_EQUAL, "", 1,
  251. )
  252. test(">>",
  253. token.SHIFT_RIGHT, "", 1,
  254. )
  255. test(">>=",
  256. token.SHIFT_RIGHT_ASSIGN, "", 1,
  257. )
  258. test(">>>",
  259. token.UNSIGNED_SHIFT_RIGHT, "", 1,
  260. )
  261. test(">>>=",
  262. token.UNSIGNED_SHIFT_RIGHT_ASSIGN, "", 1,
  263. )
  264. test("1 \"abc\"",
  265. token.NUMBER, "1", 1,
  266. token.STRING, "\"abc\"", 3,
  267. )
  268. test(",",
  269. token.COMMA, "", 1,
  270. )
  271. test("1, \"abc\"",
  272. token.NUMBER, "1", 1,
  273. token.COMMA, "", 2,
  274. token.STRING, "\"abc\"", 4,
  275. )
  276. test("new abc(1, 3.14159);",
  277. token.NEW, "new", 1,
  278. token.IDENTIFIER, "abc", 5,
  279. token.LEFT_PARENTHESIS, "", 8,
  280. token.NUMBER, "1", 9,
  281. token.COMMA, "", 10,
  282. token.NUMBER, "3.14159", 12,
  283. token.RIGHT_PARENTHESIS, "", 19,
  284. token.SEMICOLON, "", 20,
  285. )
  286. test("1 == \"1\"",
  287. token.NUMBER, "1", 1,
  288. token.EQUAL, "", 3,
  289. token.STRING, "\"1\"", 6,
  290. )
  291. test("1\n[]\n",
  292. token.NUMBER, "1", 1,
  293. token.LEFT_BRACKET, "", 3,
  294. token.RIGHT_BRACKET, "", 4,
  295. )
  296. test("1\ufeff[]\ufeff",
  297. token.NUMBER, "1", 1,
  298. token.LEFT_BRACKET, "", 5,
  299. token.RIGHT_BRACKET, "", 6,
  300. )
  301. // ILLEGAL
  302. test(`3ea`,
  303. token.ILLEGAL, "3e", 1,
  304. token.IDENTIFIER, "a", 3,
  305. token.EOF, "", 4,
  306. )
  307. test(`3in`,
  308. token.ILLEGAL, "3", 1,
  309. token.IN, "in", 2,
  310. token.EOF, "", 4,
  311. )
  312. test("\"Hello\nWorld\"",
  313. token.ILLEGAL, "", 1,
  314. token.IDENTIFIER, "World", 8,
  315. token.ILLEGAL, "", 13,
  316. token.EOF, "", 14,
  317. )
  318. test("\u203f = 10",
  319. token.ILLEGAL, "", 1,
  320. token.ASSIGN, "", 5,
  321. token.NUMBER, "10", 7,
  322. token.EOF, "", 9,
  323. )
  324. test(`"\x0G"`,
  325. token.ILLEGAL, "\"\\x0G\"", 1,
  326. //token.STRING, "\"\\x0G\"", 1,
  327. token.EOF, "", 7,
  328. )
  329. })
  330. }