odatafy-parser
Version:
generate odatafy ast from odata query parameters
389 lines (388 loc) • 16.1 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const assert_1 = __importDefault(require("assert"));
const searchParser_1 = __importDefault(require("../../src/parsing/searchParser"));
const nodes_1 = require("../../src/types/nodes");
function testParsingAndAST(testcase) {
it(`should parse ${testcase.type}: ${testcase.input}`, () => {
let ast = searchParser_1.default.parse(testcase.input);
assert_1.default.deepStrictEqual(ast, testcase.expectedAST);
});
}
function testParsingANDAST_Failing(testcase) {
it(`should throw Error because of ${testcase.type}`, () => {
assert_1.default.throws(() => {
searchParser_1.default.parse(testcase.input);
});
});
}
describe("Search Parser tests", () => {
describe("No operator", () => {
[
{
type: "simple term",
input: "blue",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "blue",
},
},
{
type: "simple term with umlaut ä / ö",
input: "Hörgerät",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "Hörgerät",
},
},
{
type: "simple term with umlaut ü",
input: "Tür",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "Tür",
},
},
{
type: "simple term with dot",
input: "1.2",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "1.2",
},
},
{
type: "simple term with comma",
input: "1,2",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "1,2",
},
},
{
type: "simple term with dash",
input: "blue-white",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "blue-white",
},
},
{
type: "simple term with quote",
input: "Robin's",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "Robin's",
},
},
{
type: "AND is a word here, not an operator",
input: "AND",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "AND",
},
},
{
type: "simple phrase",
input: "'blue%20green'",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Phrase,
value: "blue%20green"
}
},
{
type: "phrase with unbalanced double-quotes - still ok",
input: "'\"blue\" \"green'",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Phrase,
value: "\"blue\" \"green"
}
}
].forEach(testParsingAndAST);
}),
describe("Single Operator", () => {
[
{
type: "single operator NOT",
input: "NOT blue",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchOperatorNode,
op: nodes_1.SearchOperators.Not,
right: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "blue",
},
},
},
{
type: "single operator NOT with two values",
input: "NOT (blue green)",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchOperatorNode,
op: nodes_1.SearchOperators.Not,
right: {
nodeType: nodes_1.NodeTypes.SearchOperatorNode,
op: nodes_1.SearchOperators.And,
left: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "blue",
},
right: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "green",
},
},
},
},
{
type: "AND and OR are words here, search for items that match both AND and OR",
input: "AND OR",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchOperatorNode,
op: nodes_1.SearchOperators.And,
left: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "AND",
},
right: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "OR",
},
},
},
{
type: "single operator OR",
input: "blue OR red",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchOperatorNode,
op: nodes_1.SearchOperators.Or,
left: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "red",
},
right: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "blue",
},
},
},
{
type: "single operator AND",
input: "blue AND red",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchOperatorNode,
op: nodes_1.SearchOperators.And,
left: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "red",
},
right: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "blue",
},
},
}
/*|TBD|
implicit AND is not working correctly; different order than explicit AND
{
type: "implicit AND",
input: "blue red",
expectedAST: <SearchNode>{
nodeType: NodeTypes.SearchOperatorNode,
op: SearchOperators.And,
left: {
nodeType: NodeTypes.SearchItemNode,
type: SearchItemTypes.Word,
value: "red",
},
right: {
nodeType: NodeTypes.SearchItemNode,
type: SearchItemTypes.Word,
value: "blue",
},
},
}
*/
].forEach(testParsingAndAST);
}),
describe("Multi Operator", () => {
[
{
type: "multi operator OR OR",
input: "blue OR green OR red",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchOperatorNode,
op: nodes_1.SearchOperators.Or,
left: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "red",
},
right: {
nodeType: nodes_1.NodeTypes.SearchOperatorNode,
op: nodes_1.SearchOperators.Or,
left: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "green",
},
right: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "blue",
},
},
},
},
{
type: "multi operator OR AND",
input: "blue OR green AND red",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchOperatorNode,
op: nodes_1.SearchOperators.And,
left: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "red",
},
right: {
nodeType: nodes_1.NodeTypes.SearchOperatorNode,
op: nodes_1.SearchOperators.Or,
left: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "green",
},
right: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "blue",
},
},
},
},
{
type: "multi operator AND AND",
input: "blue AND green AND red",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchOperatorNode,
op: nodes_1.SearchOperators.And,
left: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "red",
},
right: {
nodeType: nodes_1.NodeTypes.SearchOperatorNode,
op: nodes_1.SearchOperators.And,
left: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "green",
},
right: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "blue",
},
},
},
},
].forEach(testParsingAndAST);
}),
describe("grouping Operator", () => {
[
{
type: "AND (OR)",
input: "blue AND (green OR red)",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchOperatorNode,
op: nodes_1.SearchOperators.And,
left: {
nodeType: nodes_1.NodeTypes.SearchOperatorNode,
op: nodes_1.SearchOperators.Or,
left: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "red",
},
right: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "green",
},
},
right: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "blue",
},
},
},
{
type: "(NOT) OR",
input: "(NOT blue) OR red",
expectedAST: {
nodeType: nodes_1.NodeTypes.SearchOperatorNode,
op: nodes_1.SearchOperators.Or,
left: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "red"
},
right: {
nodeType: nodes_1.NodeTypes.SearchOperatorNode,
op: nodes_1.SearchOperators.Not,
right: {
nodeType: nodes_1.NodeTypes.SearchItemNode,
type: nodes_1.SearchItemTypes.Word,
value: "blue",
},
},
},
},
].forEach(testParsingAndAST);
});
describe('error tests', () => {
[{
type: 'phrase with unbalanced double-quotes',
input: '"blue',
},
{
type: 'simple term with unencoded ampersand',
input: 'more&more',
},
{
type: 'simple term with unencoded hash',
input: '#1',
},
{
type: 'simple term with unencoded semicolon',
input: 'a;b',
}
].forEach(testParsingANDAST_Failing);
});
});