xfa_formcalc_spec.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. /* Copyright 2020 Mozilla Foundation
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. import { Errors, Parser } from "../../src/core/xfa/formcalc_parser.js";
  16. import { Lexer, Token, TOKEN } from "../../src/core/xfa/formcalc_lexer.js";
  17. describe("FormCalc expression parser", function () {
  18. const EOF = new Token(TOKEN.eof);
  19. describe("FormCalc lexer", function () {
  20. it("should lex numbers", function () {
  21. const lexer = new Lexer(
  22. "1 7 12 1.2345 .7 .12345 1e-2 1.2E+3 1e2 1.2E3 nan 12. 2.e3 infinity 99999999999999999 123456789.012345678 9e99999"
  23. );
  24. expect(lexer.next()).toEqual(new Token(TOKEN.number, 1));
  25. expect(lexer.next()).toEqual(new Token(TOKEN.number, 7));
  26. expect(lexer.next()).toEqual(new Token(TOKEN.number, 12));
  27. expect(lexer.next()).toEqual(new Token(TOKEN.number, 1.2345));
  28. expect(lexer.next()).toEqual(new Token(TOKEN.number, 0.7));
  29. expect(lexer.next()).toEqual(new Token(TOKEN.number, 0.12345));
  30. expect(lexer.next()).toEqual(new Token(TOKEN.number, 1e-2));
  31. expect(lexer.next()).toEqual(new Token(TOKEN.number, 1.2e3));
  32. expect(lexer.next()).toEqual(new Token(TOKEN.number, 1e2));
  33. expect(lexer.next()).toEqual(new Token(TOKEN.number, 1.2e3));
  34. expect(lexer.next()).toEqual(new Token(TOKEN.number, NaN));
  35. expect(lexer.next()).toEqual(new Token(TOKEN.number, 12));
  36. expect(lexer.next()).toEqual(new Token(TOKEN.number, 2e3));
  37. expect(lexer.next()).toEqual(new Token(TOKEN.number, Infinity));
  38. expect(lexer.next()).toEqual(new Token(TOKEN.number, 100000000000000000));
  39. expect(lexer.next()).toEqual(new Token(TOKEN.number, 123456789.01234567));
  40. expect(lexer.next()).toEqual(new Token(TOKEN.number, Infinity));
  41. expect(lexer.next()).toEqual(EOF);
  42. });
  43. it("should lex strings", function () {
  44. const lexer = new Lexer(
  45. `"hello world" "hello ""world" "hello ""world"" ""world""""hello""" "hello \\uabcdeh \\Uabcd \\u00000123abc" "a \\a \\ub \\Uc \\b"`
  46. );
  47. expect(lexer.next()).toEqual(new Token(TOKEN.string, `hello world`));
  48. expect(lexer.next()).toEqual(new Token(TOKEN.string, `hello "world`));
  49. expect(lexer.next()).toEqual(
  50. new Token(TOKEN.string, `hello "world" "world""hello"`)
  51. );
  52. expect(lexer.next()).toEqual(
  53. new Token(TOKEN.string, `hello \uabcdeh \uabcd \u0123abc`)
  54. );
  55. expect(lexer.next()).toEqual(
  56. new Token(TOKEN.string, `a \\a \\ub \\Uc \\b`)
  57. );
  58. expect(lexer.next()).toEqual(EOF);
  59. });
  60. it("should lex operators", function () {
  61. const lexer = new Lexer("( , ) <= <> = == >= < > / * . .* .# [ ] & |");
  62. expect(lexer.next()).toEqual(new Token(TOKEN.leftParen));
  63. expect(lexer.next()).toEqual(new Token(TOKEN.comma));
  64. expect(lexer.next()).toEqual(new Token(TOKEN.rightParen));
  65. expect(lexer.next()).toEqual(new Token(TOKEN.le));
  66. expect(lexer.next()).toEqual(new Token(TOKEN.ne));
  67. expect(lexer.next()).toEqual(new Token(TOKEN.assign));
  68. expect(lexer.next()).toEqual(new Token(TOKEN.eq));
  69. expect(lexer.next()).toEqual(new Token(TOKEN.ge));
  70. expect(lexer.next()).toEqual(new Token(TOKEN.lt));
  71. expect(lexer.next()).toEqual(new Token(TOKEN.gt));
  72. expect(lexer.next()).toEqual(new Token(TOKEN.divide));
  73. expect(lexer.next()).toEqual(new Token(TOKEN.times));
  74. expect(lexer.next()).toEqual(new Token(TOKEN.dot));
  75. expect(lexer.next()).toEqual(new Token(TOKEN.dotStar));
  76. expect(lexer.next()).toEqual(new Token(TOKEN.dotHash));
  77. expect(lexer.next()).toEqual(new Token(TOKEN.leftBracket));
  78. expect(lexer.next()).toEqual(new Token(TOKEN.rightBracket));
  79. expect(lexer.next()).toEqual(new Token(TOKEN.and));
  80. expect(lexer.next()).toEqual(new Token(TOKEN.or));
  81. expect(lexer.next()).toEqual(EOF);
  82. });
  83. it("should skip comments", function () {
  84. const lexer = new Lexer(`
  85. \t\t 1 \r\n\r\n
  86. ; blah blah blah
  87. 2
  88. // blah blah blah blah blah
  89. 3
  90. `);
  91. expect(lexer.next()).toEqual(new Token(TOKEN.number, 1));
  92. expect(lexer.next()).toEqual(new Token(TOKEN.number, 2));
  93. expect(lexer.next()).toEqual(new Token(TOKEN.number, 3));
  94. expect(lexer.next()).toEqual(EOF);
  95. });
  96. it("should lex identifiers", function () {
  97. const lexer = new Lexer(
  98. "eq for fore while continue hello こんにちは世界 $!hello今日は12今日は"
  99. );
  100. expect(lexer.next()).toEqual(new Token(TOKEN.eq));
  101. expect(lexer.next()).toEqual(new Token(TOKEN.for));
  102. expect(lexer.next()).toEqual(new Token(TOKEN.identifier, "fore"));
  103. expect(lexer.next()).toEqual(new Token(TOKEN.while));
  104. expect(lexer.next()).toEqual(new Token(TOKEN.continue));
  105. expect(lexer.next()).toEqual(new Token(TOKEN.identifier, "hello"));
  106. expect(lexer.next()).toEqual(
  107. new Token(TOKEN.identifier, "こんにちは世界")
  108. );
  109. expect(lexer.next()).toEqual(new Token(TOKEN.identifier, "$"));
  110. expect(lexer.next()).toEqual(
  111. new Token(TOKEN.identifier, "!hello今日は12今日は")
  112. );
  113. expect(lexer.next()).toEqual(EOF);
  114. });
  115. });
  116. describe("FormCalc parser", function () {
  117. it("should parse basic arithmetic expression", function () {
  118. const parser = new Parser("1 + 2 * 3");
  119. expect(parser.parse().dump()[0]).toEqual(7);
  120. });
  121. it("should parse basic arithmetic expression with the same operator", function () {
  122. const parser = new Parser("1 + a + 3");
  123. expect(parser.parse().dump()[0]).toEqual({
  124. operator: "+",
  125. left: {
  126. operator: "+",
  127. left: 1,
  128. right: { id: "a" },
  129. },
  130. right: 3,
  131. });
  132. });
  133. it("should parse expressions with unary operators", function () {
  134. const parser = new Parser(`
  135. s = +x + 1
  136. t = -+u * 2
  137. t = +-u * 2
  138. u = -foo()
  139. `);
  140. expect(parser.parse().dump()).toEqual([
  141. {
  142. assignment: "s",
  143. expr: {
  144. operator: "+",
  145. left: { operator: "+", arg: { id: "x" } },
  146. right: 1,
  147. },
  148. },
  149. {
  150. assignment: "t",
  151. expr: {
  152. operator: "*",
  153. left: {
  154. operator: "-",
  155. arg: {
  156. operator: "+",
  157. arg: { id: "u" },
  158. },
  159. },
  160. right: 2,
  161. },
  162. },
  163. {
  164. assignment: "t",
  165. expr: {
  166. operator: "*",
  167. left: {
  168. operator: "+",
  169. arg: {
  170. operator: "-",
  171. arg: { id: "u" },
  172. },
  173. },
  174. right: 2,
  175. },
  176. },
  177. {
  178. assignment: "u",
  179. expr: {
  180. operator: "-",
  181. arg: {
  182. callee: { id: "foo" },
  183. params: [],
  184. },
  185. },
  186. },
  187. ]);
  188. });
  189. it("should parse basic expression with a string", function () {
  190. const parser = new Parser(`(5 - "abc") * 3`);
  191. expect(parser.parse().dump()[0]).toEqual(15);
  192. });
  193. it("should parse basic expression with a calls", function () {
  194. const parser = new Parser(`foo(2, 3, a & b) or c * d + 1.234 / e`);
  195. expect(parser.parse().dump()[0]).toEqual({
  196. operator: "||",
  197. left: {
  198. callee: { id: "foo" },
  199. params: [
  200. 2,
  201. 3,
  202. {
  203. operator: "&&",
  204. left: { id: "a" },
  205. right: { id: "b" },
  206. },
  207. ],
  208. },
  209. right: {
  210. operator: "+",
  211. left: {
  212. operator: "*",
  213. left: { id: "c" },
  214. right: { id: "d" },
  215. },
  216. right: {
  217. operator: "/",
  218. left: 1.234,
  219. right: { id: "e" },
  220. },
  221. },
  222. });
  223. });
  224. it("should parse basic expression with a subscript", function () {
  225. let parser = new Parser(`こんにちは世界[-0]`);
  226. let dump = parser.parse().dump()[0];
  227. expect(dump).toEqual({
  228. operand: { id: "こんにちは世界" },
  229. index: -0,
  230. });
  231. expect(Object.is(-0, dump.index)).toBe(true);
  232. parser = new Parser(`こんにちは世界[+0]`);
  233. dump = parser.parse().dump()[0];
  234. expect(dump).toEqual({
  235. operand: { id: "こんにちは世界" },
  236. index: +0,
  237. });
  238. expect(Object.is(+0, dump.index)).toBe(true);
  239. parser = new Parser(`こんにちは世界[*]`);
  240. expect(parser.parse().dump()[0]).toEqual({
  241. operand: { id: "こんにちは世界" },
  242. index: { special: "*" },
  243. });
  244. });
  245. it("should parse basic expression with dots", function () {
  246. const parser = new Parser("a.b.c.#d..e.f..g.*");
  247. const exprlist = parser.parse();
  248. expect(exprlist.expressions[0].isDotExpression()).toEqual(true);
  249. expect(exprlist.dump()[0]).toEqual({
  250. operator: ".",
  251. left: { id: "a" },
  252. right: {
  253. operator: ".",
  254. left: { id: "b" },
  255. right: {
  256. operator: ".#",
  257. left: { id: "c" },
  258. right: {
  259. operator: "..",
  260. left: { id: "d" },
  261. right: {
  262. operator: ".",
  263. left: { id: "e" },
  264. right: {
  265. operator: "..",
  266. left: { id: "f" },
  267. right: {
  268. operator: ".",
  269. left: { id: "g" },
  270. right: { special: "*" },
  271. },
  272. },
  273. },
  274. },
  275. },
  276. },
  277. });
  278. });
  279. it("should parse var declaration with error", function () {
  280. let parser = new Parser("var 123 = a");
  281. expect(() => parser.parse()).toThrow(new Error(Errors.var));
  282. parser = new Parser(`var "123" = a`);
  283. expect(() => parser.parse()).toThrow(new Error(Errors.var));
  284. parser = new Parser(`var for var a`);
  285. expect(() => parser.parse()).toThrow(new Error(Errors.var));
  286. });
  287. it("should parse for declaration with a step", function () {
  288. const parser = new Parser(`
  289. var s = 0
  290. for var i = 1 upto 10 + x step 1 do
  291. s = s + i * 2
  292. endfor`);
  293. expect(parser.parse().dump()).toEqual([
  294. {
  295. var: "s",
  296. expr: 0,
  297. },
  298. {
  299. decl: "for",
  300. assignment: {
  301. var: "i",
  302. expr: 1,
  303. },
  304. type: "upto",
  305. end: {
  306. operator: "+",
  307. left: 10,
  308. right: { id: "x" },
  309. },
  310. step: 1,
  311. body: [
  312. {
  313. assignment: "s",
  314. expr: {
  315. operator: "+",
  316. left: { id: "s" },
  317. right: {
  318. operator: "*",
  319. left: { id: "i" },
  320. right: 2,
  321. },
  322. },
  323. },
  324. ],
  325. },
  326. ]);
  327. });
  328. it("should parse for declaration without a step", function () {
  329. const parser = new Parser(`
  330. for i = 1 + 2 downto 10 do
  331. s = foo()
  332. endfor`);
  333. expect(parser.parse().dump()).toEqual([
  334. {
  335. decl: "for",
  336. assignment: {
  337. assignment: "i",
  338. expr: 3,
  339. },
  340. type: "downto",
  341. end: 10,
  342. step: null,
  343. body: [
  344. {
  345. assignment: "s",
  346. expr: {
  347. callee: { id: "foo" },
  348. params: [],
  349. },
  350. },
  351. ],
  352. },
  353. ]);
  354. });
  355. it("should parse for declaration with error", function () {
  356. let parser = new Parser("for 123 = i upto 1 do a = 1 endfor");
  357. expect(() => parser.parse()).toThrow(new Error(Errors.assignment));
  358. parser = new Parser("for var 123 = i upto 1 do a = 1 endfor");
  359. expect(() => parser.parse()).toThrow(new Error(Errors.assignment));
  360. parser = new Parser("for var i = 123 upt 1 do a = 1 endfor");
  361. expect(() => parser.parse()).toThrow(new Error(Errors.for));
  362. parser = new Parser("for var i = 123 var 1 do a = 1 endfor");
  363. expect(() => parser.parse()).toThrow(new Error(Errors.for));
  364. parser = new Parser(
  365. "for var i = 123 upto 1 step for var j = 1 do endfor do a = 1 endfor"
  366. );
  367. expect(() => parser.parse()).toThrow(new Error(Errors.for));
  368. parser = new Parser("for var i = 123 downto 1 do a = 1 endfunc");
  369. expect(() => parser.parse()).toThrow(new Error(Errors.for));
  370. parser = new Parser("for var i = 123 downto 1 do a = 1");
  371. expect(() => parser.parse()).toThrow(new Error(Errors.for));
  372. });
  373. it("should parse foreach declaration", function () {
  374. const parser = new Parser(`
  375. foreach i in (a, b, c, d) do
  376. s = foo()[i]
  377. endfor`);
  378. expect(parser.parse().dump()).toEqual([
  379. {
  380. decl: "foreach",
  381. id: "i",
  382. params: [{ id: "a" }, { id: "b" }, { id: "c" }, { id: "d" }],
  383. body: [
  384. {
  385. assignment: "s",
  386. expr: {
  387. operand: {
  388. callee: { id: "foo" },
  389. params: [],
  390. },
  391. index: { id: "i" },
  392. },
  393. },
  394. ],
  395. },
  396. ]);
  397. });
  398. it("should parse foreach declaration with error", function () {
  399. let parser = new Parser("foreach 123 in (1, 2, 3) do a = 1 endfor");
  400. expect(() => parser.parse()).toThrow(new Error(Errors.foreach));
  401. parser = new Parser("foreach foo in 1, 2, 3) do a = 1 endfor");
  402. expect(() => parser.parse()).toThrow(new Error(Errors.foreach));
  403. parser = new Parser("foreach foo in (1, 2, 3 do a = 1 endfor");
  404. expect(() => parser.parse()).toThrow(new Error(Errors.params));
  405. parser = new Parser("foreach foo in (1, 2 3) do a = 1 endfor");
  406. expect(() => parser.parse()).toThrow(new Error(Errors.params));
  407. parser = new Parser("foreach foo in (1, 2, 3) od a = 1 endfor");
  408. expect(() => parser.parse()).toThrow(new Error(Errors.foreach));
  409. parser = new Parser("foreach foo in (1, 2, 3) do a = 1 endforeach");
  410. expect(() => parser.parse()).toThrow(new Error(Errors.foreach));
  411. parser = new Parser("foreach foo in (1, 2, 3) do a = 1 123");
  412. expect(() => parser.parse()).toThrow(new Error(Errors.foreach));
  413. });
  414. it("should parse while declaration", function () {
  415. const parser = new Parser(`
  416. while (1) do
  417. if (0) then
  418. break
  419. else
  420. continue
  421. endif
  422. endwhile
  423. `);
  424. expect(parser.parse().dump()).toEqual([
  425. {
  426. decl: "while",
  427. condition: 1,
  428. body: [
  429. {
  430. decl: "if",
  431. condition: 0,
  432. then: [{ special: "break" }],
  433. elseif: null,
  434. else: [{ special: "continue" }],
  435. },
  436. ],
  437. },
  438. ]);
  439. });
  440. it("should parse while declaration with error", function () {
  441. let parser = new Parser("while a == 1 do a = 2 endwhile");
  442. expect(() => parser.parse()).toThrow(new Error(Errors.while));
  443. parser = new Parser("while (a == 1 do a = 2 endwhile");
  444. expect(() => parser.parse()).toThrow(new Error(Errors.while));
  445. parser = new Parser("while (a == 1) var a = 2 endwhile");
  446. expect(() => parser.parse()).toThrow(new Error(Errors.while));
  447. parser = new Parser("while (a == 1) do var a = 2 end");
  448. expect(() => parser.parse()).toThrow(new Error(Errors.while));
  449. });
  450. it("should parse do declaration", function () {
  451. const parser = new Parser(`
  452. do
  453. x = 1
  454. ; a comment in the middle of the block
  455. y = 2
  456. end
  457. `);
  458. expect(parser.parse().dump()).toEqual([
  459. {
  460. decl: "block",
  461. body: [
  462. {
  463. assignment: "x",
  464. expr: 1,
  465. },
  466. {
  467. assignment: "y",
  468. expr: 2,
  469. },
  470. ],
  471. },
  472. ]);
  473. });
  474. it("should parse do declaration with error", function () {
  475. const parser = new Parser(`
  476. do
  477. x = 1
  478. y = 2
  479. endfunc
  480. `);
  481. expect(() => parser.parse()).toThrow(new Error(Errors.block));
  482. });
  483. it("should parse func declaration", function () {
  484. const parser = new Parser(`
  485. func こんにちは世界123(a, b) do
  486. a + b
  487. endfunc
  488. `);
  489. expect(parser.parse().dump()).toEqual([
  490. {
  491. func: "こんにちは世界123",
  492. params: ["a", "b"],
  493. body: [
  494. {
  495. operator: "+",
  496. left: { id: "a" },
  497. right: { id: "b" },
  498. },
  499. ],
  500. },
  501. ]);
  502. });
  503. it("should parse func declaration with error", function () {
  504. let parser = new Parser("func 123(a, b) do a = 1 endfunc");
  505. expect(() => parser.parse()).toThrow(new Error(Errors.func));
  506. parser = new Parser("func foo(a, b) for a = 1 endfunc");
  507. expect(() => parser.parse()).toThrow(new Error(Errors.func));
  508. parser = new Parser("func foo(a, b) do a = 1 endfun");
  509. expect(() => parser.parse()).toThrow(new Error(Errors.func));
  510. parser = new Parser("func foo(a, b, c do a = 1 endfunc");
  511. expect(() => parser.parse()).toThrow(new Error(Errors.func));
  512. parser = new Parser("func foo(a, b, 123) do a = 1 endfunc");
  513. expect(() => parser.parse()).toThrow(new Error(Errors.func));
  514. });
  515. it("should parse if declaration", function () {
  516. const parser = new Parser(`
  517. if (a & b) then
  518. var s = 1
  519. endif
  520. if (a or b) then
  521. var s = 1
  522. else
  523. var x = 2
  524. endif
  525. if (0) then
  526. s = 1
  527. elseif (1) then
  528. s = 2
  529. elseif (2) then
  530. s = 3
  531. elseif (3) then
  532. s = 4
  533. else
  534. s = 5
  535. endif
  536. // a comment
  537. if (0) then
  538. s = 1
  539. elseif (1) then
  540. s = 2
  541. endif
  542. `);
  543. expect(parser.parse().dump()).toEqual([
  544. {
  545. decl: "if",
  546. condition: {
  547. operator: "&&",
  548. left: { id: "a" },
  549. right: { id: "b" },
  550. },
  551. then: [
  552. {
  553. var: "s",
  554. expr: 1,
  555. },
  556. ],
  557. elseif: null,
  558. else: null,
  559. },
  560. {
  561. decl: "if",
  562. condition: {
  563. operator: "||",
  564. left: { id: "a" },
  565. right: { id: "b" },
  566. },
  567. then: [
  568. {
  569. var: "s",
  570. expr: 1,
  571. },
  572. ],
  573. elseif: null,
  574. else: [
  575. {
  576. var: "x",
  577. expr: 2,
  578. },
  579. ],
  580. },
  581. {
  582. decl: "if",
  583. condition: 0,
  584. then: [
  585. {
  586. assignment: "s",
  587. expr: 1,
  588. },
  589. ],
  590. elseif: [
  591. {
  592. decl: "elseif",
  593. condition: 1,
  594. then: [
  595. {
  596. assignment: "s",
  597. expr: 2,
  598. },
  599. ],
  600. },
  601. {
  602. decl: "elseif",
  603. condition: 2,
  604. then: [
  605. {
  606. assignment: "s",
  607. expr: 3,
  608. },
  609. ],
  610. },
  611. {
  612. decl: "elseif",
  613. condition: 3,
  614. then: [
  615. {
  616. assignment: "s",
  617. expr: 4,
  618. },
  619. ],
  620. },
  621. ],
  622. else: [
  623. {
  624. assignment: "s",
  625. expr: 5,
  626. },
  627. ],
  628. },
  629. {
  630. decl: "if",
  631. condition: 0,
  632. then: [
  633. {
  634. assignment: "s",
  635. expr: 1,
  636. },
  637. ],
  638. elseif: [
  639. {
  640. decl: "elseif",
  641. condition: 1,
  642. then: [
  643. {
  644. assignment: "s",
  645. expr: 2,
  646. },
  647. ],
  648. },
  649. ],
  650. else: null,
  651. },
  652. ]);
  653. });
  654. it("should parse if declaration with error", function () {
  655. let parser = new Parser("if foo == 1 then a = 1 endif");
  656. expect(() => parser.parse()).toThrow(new Error(Errors.if));
  657. parser = new Parser("if (foo == 1 then a = 1 endif");
  658. expect(() => parser.parse()).toThrow(new Error(Errors.if));
  659. parser = new Parser(
  660. "if (foo == 1) then a = 1 elseiff (foo == 2) then a = 2 endif"
  661. );
  662. expect(() => parser.parse()).toThrow(new Error(Errors.if));
  663. parser = new Parser(
  664. "if (foo == 1) then a = 1 elseif (foo == 2) then a = 2 end"
  665. );
  666. expect(() => parser.parse()).toThrow(new Error(Errors.if));
  667. });
  668. it("should parse som predicate", () => {
  669. const parser = new Parser("a.b <= 3");
  670. const expr = parser.parse().expressions[0];
  671. expect(expr.isSomPredicate()).toEqual(true);
  672. expect(expr.left.isSomPredicate()).toEqual(true);
  673. });
  674. });
  675. });