odatafy-parser
Version:
generate odatafy ast from odata query parameters
478 lines (477 loc) • 23 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 selectParser_1 = __importDefault(require("../../src/parsing/selectParser"));
const nodes_1 = require("../../src/types/nodes");
function testParsingAndAST(testcase) {
it(`should parse ${testcase.type}: ${testcase.input}`, () => {
let ast = selectParser_1.default.parse(testcase.input);
assert_1.default.deepStrictEqual(ast, testcase.expectedAST);
});
}
//ADD test from https://github.com/oasis-tcs/odata-abnf/blob/main/abnf/odata-abnf-testcases.yaml line 2467 when all parsers are finished
describe('Select Parser tests', () => {
describe('official url-convention examples', () => {
[{
type: "Example 127",
input: "Rating,ReleaseDate",
expectedAST: {
nodeType: nodes_1.NodeTypes.SelectNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Rating",
}]
},
{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "ReleaseDate",
}]
}]
}
},
{
type: "Example 128",
input: "*",
expectedAST: {
nodeType: nodes_1.NodeTypes.SelectNode,
value: []
}
},
{
type: "Example 130",
input: "Namespace.PreferredSupplier/AccountRepresentative,Address/Street,Address/Namespace.AddressWithLocation/Location",
expectedAST: {
nodeType: nodes_1.NodeTypes.SelectNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Namespace.PreferredSupplier",
},
{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "AccountRepresentative",
}]
},
{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Address",
},
{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Street",
}]
},
{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Address",
},
{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Namespace.AddressWithLocation",
},
{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Location",
}]
}]
}
},
{
type: "Example 131",
input: "Addresses($filter=startswith(City,'H');$top=5;$orderby=Country/Name,City,Street)",
expectedAST: {
nodeType: nodes_1.NodeTypes.SelectNode,
value: [
{
nodeType: nodes_1.NodeTypes.SelectPathNodeWithOptions,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Addresses",
}],
options: {
filter: {
nodeType: nodes_1.NodeTypes.FuncNode2Args,
func: "startswith",
args: [
{
nodeType: nodes_1.NodeTypes.SymbolNode,
type: "Identifier",
value: "City"
},
{
nodeType: nodes_1.NodeTypes.ConstantNode,
type: "String",
value: "H"
}
]
},
orderby: {
nodeType: nodes_1.NodeTypes.OrderbyNode,
value: [
{
nodeType: nodes_1.NodeTypes.OrderbyItemNode,
type: "asc",
value: "Country/Name"
},
{
nodeType: nodes_1.NodeTypes.OrderbyItemNode,
type: "asc",
value: "City"
},
{
nodeType: nodes_1.NodeTypes.OrderbyItemNode,
type: "asc",
value: "Street"
}
]
},
top: 5
}
}
]
}
},
{
type: "Example 132",
input: "ID,Model.ActionName,Model2.*",
expectedAST: {
nodeType: nodes_1.NodeTypes.SelectNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "ID"
}]
},
{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Model.ActionName"
}]
},
{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Model2",
flag: nodes_1.SelectIdentifierFlags.AllOperationsInSchema
}]
}]
}
}
].forEach(testParsingAndAST);
});
describe('additional tests', () => {
[{
type: "select expression with 1 Item - odataIdentifier",
input: "Name",
expectedAST: {
nodeType: nodes_1.NodeTypes.SelectNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Name",
}]
}]
}
},
{
type: "select expression with 1 Item - odataIdentifierWithNamespace",
input: "namespace.Name",
expectedAST: {
nodeType: nodes_1.NodeTypes.SelectNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "namespace.Name",
}]
}]
}
},
{
type: "select expression with 1 Item - Function",
input: "namespace.function(arg)",
expectedAST: {
nodeType: nodes_1.NodeTypes.SelectNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectFunctionNode,
func: "namespace.function",
args: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "arg"
}]
}]
}]
}
},
{
type: "select expression with 1 Item - Path with odataIdentifiers",
input: "Adresse/Name",
expectedAST: {
nodeType: nodes_1.NodeTypes.SelectNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Adresse",
},
{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Name",
}]
}]
}
},
{
type: "select expression with 1 Item - Path with odataIdentifiersWithNamespace",
input: "namespace.Adresse/namespace.Name",
expectedAST: {
nodeType: nodes_1.NodeTypes.SelectNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "namespace.Adresse",
},
{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "namespace.Name",
}]
}]
}
},
{
type: "select expression with 1 Item - allOperationsInSchema",
input: "Adresse.*",
expectedAST: {
nodeType: nodes_1.NodeTypes.SelectNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Adresse",
flag: nodes_1.SelectIdentifierFlags.AllOperationsInSchema
}]
}]
}
},
{
type: "select expression with 1 Item - Wildcard",
input: "*",
expectedAST: {
nodeType: nodes_1.NodeTypes.SelectNode,
value: []
}
},
{
type: "select expression with multiple items",
input: "Name, namespace.Adresse, Adresse/Name, namespace.Adresse/namespace.Name, Adresse.*",
expectedAST: {
nodeType: nodes_1.NodeTypes.SelectNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Name"
}]
},
{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "namespace.Adresse"
}]
},
{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Adresse",
},
{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Name",
}]
},
{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "namespace.Adresse",
},
{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "namespace.Name",
}]
},
{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Adresse",
flag: nodes_1.SelectIdentifierFlags.AllOperationsInSchema
}]
}]
}
},
{
type: "select expression with annotation and options",
input: "@Core.Messages($top=5)",
expectedAST: {
nodeType: nodes_1.NodeTypes.SelectNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectPathNodeWithOptions,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
flag: nodes_1.SelectIdentifierFlags.Annotation,
value: "Core.Messages"
}],
options: {
top: 5
}
}]
}
},
{
type: "select expression with annotation in path and options",
input: "Address/@Core.Messages($top=5)",
expectedAST: {
nodeType: nodes_1.NodeTypes.SelectNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectPathNodeWithOptions,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Address"
}, {
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
flag: nodes_1.SelectIdentifierFlags.Annotation,
value: "Core.Messages"
}],
options: {
top: 5
}
}]
}
},
{
type: "select expression with two annotations and options",
input: "@Measures.Currency,@Core.MayImplement($top=2)",
expectedAST: {
nodeType: nodes_1.NodeTypes.SelectNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
flag: nodes_1.SelectIdentifierFlags.Annotation,
value: "Measures.Currency"
}]
},
{
nodeType: nodes_1.NodeTypes.SelectPathNodeWithOptions,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
flag: nodes_1.SelectIdentifierFlags.Annotation,
value: "Core.MayImplement",
}],
options: {
top: 2
}
}]
}
},
{
type: "nested select expression",
input: "Addresses($select=Street,City)",
expectedAST: {
nodeType: nodes_1.NodeTypes.SelectNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectPathNodeWithOptions,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Addresses"
}],
options: {
select: {
nodeType: nodes_1.NodeTypes.SelectNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Street"
}]
},
{
nodeType: nodes_1.NodeTypes.SelectPathNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "City"
}]
}]
}
}
}]
}
},
{
type: "Expressions with select options for skip, count, expand, compute, !search(deactivated)",
input: "Addresses($skip=0;$count=true;$expand=Addresses/Country;$compute=Name as LastName)",
expectedAST: {
nodeType: nodes_1.NodeTypes.SelectNode,
value: [{
nodeType: nodes_1.NodeTypes.SelectPathNodeWithOptions,
value: [{
nodeType: nodes_1.NodeTypes.SelectIdentifierNode,
value: "Addresses"
}],
options: {
skip: 0,
count: true,
expand: {
nodeType: nodes_1.NodeTypes.ExpandNode,
value: [{
nodeType: nodes_1.NodeTypes.ExpandPathNode,
value: [{
nodeType: nodes_1.NodeTypes.ExpandIdentifierNode,
value: "Addresses"
},
{
nodeType: nodes_1.NodeTypes.ExpandIdentifierNode,
value: "Country"
}]
}]
},
compute: {
nodeType: nodes_1.NodeTypes.ComputeNode,
value: [{
nodeType: nodes_1.NodeTypes.ComputeItemNode,
commonExpr: {
nodeType: nodes_1.NodeTypes.SymbolNode,
type: nodes_1.SymbolNodeTypes.Identifier,
value: "Name"
},
computeIdentifier: "LastName"
}]
}
},
}]
}
},].forEach(testParsingAndAST);
});
});