A work-in-progress SQL parser written in TypeScript
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

parser.test.ts 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /* tslint:disable:no-unused-expression */
  2. import { expect } from "chai";
  3. import * as AST from "../src/ast";
  4. import { isError } from "../src/error";
  5. import Lexer from "../src/lexer";
  6. import Parser from "../src/parser";
  7. const parse = (source: string): AST.Statement[] => {
  8. const tokens = new Lexer(source).scan();
  9. if (isError(tokens)) {
  10. throw tokens.message;
  11. } else {
  12. const tree = new Parser(tokens).parse();
  13. if (isError(tree)) {
  14. throw tree.message;
  15. }
  16. return tree;
  17. }
  18. };
  19. describe("Parser", () => {
  20. it("should parse a number selection", () => {
  21. const tree = parse("select 5");
  22. expect(tree).to.deep.equal([
  23. new AST.SelectStatement({
  24. arguments: [new AST.Number(5)],
  25. }),
  26. ]);
  27. });
  28. it("should parse a multiple number selection", () => {
  29. const tree = parse("select 5, 6");
  30. expect(tree).to.deep.equal([
  31. new AST.SelectStatement({
  32. arguments: [new AST.Number(5), new AST.Number(6)],
  33. }),
  34. ]);
  35. });
  36. it("should parse a selection of identifiers", () => {
  37. const tree = parse("select a, b");
  38. expect(tree).to.deep.equal([
  39. new AST.SelectStatement({
  40. arguments: [new AST.Identifier("a"), new AST.Identifier("b")],
  41. }),
  42. ]);
  43. });
  44. it("should parse a selection of identifiers and numbers", () => {
  45. const tree = parse("select a, 5");
  46. expect(tree).to.deep.equal([
  47. new AST.SelectStatement({
  48. arguments: [new AST.Identifier("a"), new AST.Number(5)],
  49. }),
  50. ]);
  51. });
  52. it("should parse the from of a selection", () => {
  53. const tree = parse("select a from t");
  54. expect(tree).to.deep.equal([
  55. new AST.SelectStatement({
  56. arguments: [new AST.Identifier("a")],
  57. from: new AST.Identifier("t"),
  58. }),
  59. ]);
  60. });
  61. it("should parse aliases", () => {
  62. const tree = parse("select a as b");
  63. expect(tree).to.deep.equal([
  64. new AST.SelectStatement({
  65. arguments: [
  66. new AST.Alias(new AST.Identifier("a"), new AST.Identifier("b")),
  67. ],
  68. }),
  69. ]);
  70. });
  71. it("should parse aliases as from targets", () => {
  72. const tree = parse("select a from t as u");
  73. expect(tree).to.deep.equal([
  74. new AST.SelectStatement({
  75. arguments: [new AST.Identifier("a")],
  76. from: new AST.Alias(new AST.Identifier("t"), new AST.Identifier("u")),
  77. }),
  78. ]);
  79. });
  80. it("should not allow a number as a from target", () => {
  81. const fn = () => parse("select 1 from 2");
  82. expect(fn).to.throw("Unexpected token: { kind: NUMBER, value: 2 }");
  83. });
  84. it("should parse a where with a number", () => {
  85. const tree = parse("select a from b where 1");
  86. expect(tree).to.deep.equal([
  87. new AST.SelectStatement({
  88. arguments: [new AST.Identifier("a")],
  89. from: new AST.Identifier("b"),
  90. where: new AST.Number(1),
  91. }),
  92. ]);
  93. });
  94. it("should parse a where with an identifier", () => {
  95. const tree = parse("select a from b where c");
  96. expect(tree).to.deep.equal([
  97. new AST.SelectStatement({
  98. arguments: [new AST.Identifier("a")],
  99. from: new AST.Identifier("b"),
  100. where: new AST.Identifier("c"),
  101. }),
  102. ]);
  103. });
  104. });