flowquery 1.0.15 → 1.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/python-publish.yml +97 -0
- package/dist/compute/runner.d.ts +3 -2
- package/dist/compute/runner.d.ts.map +1 -1
- package/dist/compute/runner.js +7 -7
- package/dist/compute/runner.js.map +1 -1
- package/dist/flowquery.min.js +1 -1
- package/dist/graph/data.d.ts +31 -0
- package/dist/graph/data.d.ts.map +1 -0
- package/dist/graph/data.js +110 -0
- package/dist/graph/data.js.map +1 -0
- package/dist/graph/database.d.ts +20 -0
- package/dist/graph/database.d.ts.map +1 -0
- package/dist/graph/database.js +77 -0
- package/dist/graph/database.js.map +1 -0
- package/dist/graph/hops.d.ts +11 -0
- package/dist/graph/hops.d.ts.map +1 -0
- package/dist/graph/hops.js +25 -0
- package/dist/graph/hops.js.map +1 -0
- package/dist/graph/node.d.ts +35 -0
- package/dist/graph/node.d.ts.map +1 -0
- package/dist/graph/node.js +113 -0
- package/dist/graph/node.js.map +1 -0
- package/dist/graph/node_data.d.ts +11 -0
- package/dist/graph/node_data.d.ts.map +1 -0
- package/dist/graph/node_data.js +20 -0
- package/dist/graph/node_data.js.map +1 -0
- package/dist/graph/node_reference.d.ts +10 -0
- package/dist/graph/node_reference.d.ts.map +1 -0
- package/dist/graph/node_reference.js +52 -0
- package/dist/graph/node_reference.js.map +1 -0
- package/dist/graph/pattern.d.ts +18 -0
- package/dist/graph/pattern.d.ts.map +1 -0
- package/dist/graph/pattern.js +114 -0
- package/dist/graph/pattern.js.map +1 -0
- package/dist/graph/pattern_expression.d.ts +14 -0
- package/dist/graph/pattern_expression.d.ts.map +1 -0
- package/dist/graph/pattern_expression.js +58 -0
- package/dist/graph/pattern_expression.js.map +1 -0
- package/dist/graph/patterns.d.ts +11 -0
- package/dist/graph/patterns.d.ts.map +1 -0
- package/dist/graph/patterns.js +49 -0
- package/dist/graph/patterns.js.map +1 -0
- package/dist/graph/physical_node.d.ts +10 -0
- package/dist/graph/physical_node.d.ts.map +1 -0
- package/dist/graph/physical_node.js +40 -0
- package/dist/graph/physical_node.js.map +1 -0
- package/dist/graph/physical_relationship.d.ts +10 -0
- package/dist/graph/physical_relationship.d.ts.map +1 -0
- package/dist/graph/physical_relationship.js +40 -0
- package/dist/graph/physical_relationship.js.map +1 -0
- package/dist/graph/relationship.d.ts +40 -0
- package/dist/graph/relationship.d.ts.map +1 -0
- package/dist/graph/relationship.js +124 -0
- package/dist/graph/relationship.js.map +1 -0
- package/dist/graph/relationship_data.d.ts +12 -0
- package/dist/graph/relationship_data.d.ts.map +1 -0
- package/dist/graph/relationship_data.js +40 -0
- package/dist/graph/relationship_data.js.map +1 -0
- package/dist/graph/relationship_match_collector.d.ts +19 -0
- package/dist/graph/relationship_match_collector.d.ts.map +1 -0
- package/dist/graph/relationship_match_collector.js +55 -0
- package/dist/graph/relationship_match_collector.js.map +1 -0
- package/dist/graph/relationship_reference.d.ts +8 -0
- package/dist/graph/relationship_reference.d.ts.map +1 -0
- package/dist/graph/relationship_reference.js +37 -0
- package/dist/graph/relationship_reference.js.map +1 -0
- package/dist/parsing/base_parser.d.ts +1 -0
- package/dist/parsing/base_parser.d.ts.map +1 -1
- package/dist/parsing/base_parser.js +4 -1
- package/dist/parsing/base_parser.js.map +1 -1
- package/dist/parsing/context.d.ts +2 -2
- package/dist/parsing/context.js +5 -5
- package/dist/parsing/expressions/boolean.d.ts +8 -0
- package/dist/parsing/expressions/boolean.d.ts.map +1 -0
- package/dist/parsing/expressions/boolean.js +26 -0
- package/dist/parsing/expressions/boolean.js.map +1 -0
- package/dist/parsing/expressions/expression.d.ts +4 -1
- package/dist/parsing/expressions/expression.d.ts.map +1 -1
- package/dist/parsing/expressions/expression.js +15 -8
- package/dist/parsing/expressions/expression.js.map +1 -1
- package/dist/parsing/expressions/expression_map.d.ts +1 -0
- package/dist/parsing/expressions/expression_map.d.ts.map +1 -1
- package/dist/parsing/expressions/expression_map.js +3 -0
- package/dist/parsing/expressions/expression_map.js.map +1 -1
- package/dist/parsing/expressions/operator.d.ts +1 -1
- package/dist/parsing/expressions/operator.d.ts.map +1 -1
- package/dist/parsing/expressions/operator.js.map +1 -1
- package/dist/parsing/functions/function_factory.d.ts +13 -13
- package/dist/parsing/functions/function_factory.d.ts.map +1 -1
- package/dist/parsing/functions/function_factory.js +20 -18
- package/dist/parsing/functions/function_factory.js.map +1 -1
- package/dist/parsing/operations/call.d.ts.map +1 -1
- package/dist/parsing/operations/call.js +3 -1
- package/dist/parsing/operations/call.js.map +1 -1
- package/dist/parsing/operations/create_node.d.ts +14 -0
- package/dist/parsing/operations/create_node.d.ts.map +1 -0
- package/dist/parsing/operations/create_node.js +51 -0
- package/dist/parsing/operations/create_node.js.map +1 -0
- package/dist/parsing/operations/create_relationship.d.ts +14 -0
- package/dist/parsing/operations/create_relationship.d.ts.map +1 -0
- package/dist/parsing/operations/create_relationship.js +51 -0
- package/dist/parsing/operations/create_relationship.js.map +1 -0
- package/dist/parsing/operations/match.d.ts +15 -0
- package/dist/parsing/operations/match.d.ts.map +1 -0
- package/dist/parsing/operations/match.js +45 -0
- package/dist/parsing/operations/match.js.map +1 -0
- package/dist/parsing/operations/operation.d.ts +1 -0
- package/dist/parsing/operations/operation.d.ts.map +1 -1
- package/dist/parsing/operations/operation.js +6 -0
- package/dist/parsing/operations/operation.js.map +1 -1
- package/dist/parsing/operations/return.d.ts +1 -0
- package/dist/parsing/operations/return.d.ts.map +1 -1
- package/dist/parsing/operations/return.js +7 -1
- package/dist/parsing/operations/return.js.map +1 -1
- package/dist/parsing/operations/where.d.ts +1 -1
- package/dist/parsing/operations/where.d.ts.map +1 -1
- package/dist/parsing/operations/where.js +4 -0
- package/dist/parsing/operations/where.js.map +1 -1
- package/dist/parsing/parser.d.ts +10 -0
- package/dist/parsing/parser.d.ts.map +1 -1
- package/dist/parsing/parser.js +344 -5
- package/dist/parsing/parser.js.map +1 -1
- package/dist/parsing/token_to_node.d.ts.map +1 -1
- package/dist/parsing/token_to_node.js +7 -0
- package/dist/parsing/token_to_node.js.map +1 -1
- package/dist/tokenization/keyword.d.ts +1 -0
- package/dist/tokenization/keyword.d.ts.map +1 -1
- package/dist/tokenization/keyword.js +1 -0
- package/dist/tokenization/keyword.js.map +1 -1
- package/dist/tokenization/token.d.ts +4 -0
- package/dist/tokenization/token.d.ts.map +1 -1
- package/dist/tokenization/token.js +14 -1
- package/dist/tokenization/token.js.map +1 -1
- package/dist/tokenization/token_type.d.ts +1 -0
- package/dist/tokenization/token_type.d.ts.map +1 -1
- package/dist/tokenization/token_type.js +1 -0
- package/dist/tokenization/token_type.js.map +1 -1
- package/dist/tokenization/tokenizer.d.ts +2 -1
- package/dist/tokenization/tokenizer.d.ts.map +1 -1
- package/dist/tokenization/tokenizer.js +25 -12
- package/dist/tokenization/tokenizer.js.map +1 -1
- package/docs/flowquery.min.js +1 -1
- package/flowquery-py/README.md +166 -0
- package/flowquery-py/pyproject.toml +75 -0
- package/flowquery-py/setup_env.ps1 +92 -0
- package/flowquery-py/setup_env.sh +87 -0
- package/flowquery-py/src/__init__.py +34 -0
- package/flowquery-py/src/__main__.py +10 -0
- package/flowquery-py/src/compute/__init__.py +5 -0
- package/flowquery-py/src/compute/runner.py +60 -0
- package/flowquery-py/src/extensibility.py +52 -0
- package/flowquery-py/src/graph/__init__.py +31 -0
- package/flowquery-py/src/graph/data.py +118 -0
- package/flowquery-py/src/graph/database.py +82 -0
- package/flowquery-py/src/graph/hops.py +43 -0
- package/flowquery-py/src/graph/node.py +112 -0
- package/flowquery-py/src/graph/node_data.py +26 -0
- package/flowquery-py/src/graph/node_reference.py +49 -0
- package/flowquery-py/src/graph/pattern.py +125 -0
- package/flowquery-py/src/graph/pattern_expression.py +62 -0
- package/flowquery-py/src/graph/patterns.py +42 -0
- package/flowquery-py/src/graph/physical_node.py +40 -0
- package/flowquery-py/src/graph/physical_relationship.py +36 -0
- package/flowquery-py/src/graph/relationship.py +135 -0
- package/flowquery-py/src/graph/relationship_data.py +33 -0
- package/flowquery-py/src/graph/relationship_match_collector.py +77 -0
- package/flowquery-py/src/graph/relationship_reference.py +21 -0
- package/flowquery-py/src/io/__init__.py +5 -0
- package/flowquery-py/src/io/command_line.py +67 -0
- package/flowquery-py/src/parsing/__init__.py +17 -0
- package/flowquery-py/src/parsing/alias.py +20 -0
- package/flowquery-py/src/parsing/alias_option.py +11 -0
- package/flowquery-py/src/parsing/ast_node.py +146 -0
- package/flowquery-py/src/parsing/base_parser.py +84 -0
- package/flowquery-py/src/parsing/components/__init__.py +19 -0
- package/flowquery-py/src/parsing/components/csv.py +8 -0
- package/flowquery-py/src/parsing/components/from_.py +10 -0
- package/flowquery-py/src/parsing/components/headers.py +12 -0
- package/flowquery-py/src/parsing/components/json.py +8 -0
- package/flowquery-py/src/parsing/components/null.py +10 -0
- package/flowquery-py/src/parsing/components/post.py +8 -0
- package/flowquery-py/src/parsing/components/text.py +8 -0
- package/flowquery-py/src/parsing/context.py +50 -0
- package/flowquery-py/src/parsing/data_structures/__init__.py +15 -0
- package/flowquery-py/src/parsing/data_structures/associative_array.py +41 -0
- package/flowquery-py/src/parsing/data_structures/json_array.py +30 -0
- package/flowquery-py/src/parsing/data_structures/key_value_pair.py +38 -0
- package/flowquery-py/src/parsing/data_structures/lookup.py +49 -0
- package/flowquery-py/src/parsing/data_structures/range_lookup.py +42 -0
- package/flowquery-py/src/parsing/expressions/__init__.py +57 -0
- package/flowquery-py/src/parsing/expressions/boolean.py +20 -0
- package/flowquery-py/src/parsing/expressions/expression.py +138 -0
- package/flowquery-py/src/parsing/expressions/expression_map.py +26 -0
- package/flowquery-py/src/parsing/expressions/f_string.py +27 -0
- package/flowquery-py/src/parsing/expressions/identifier.py +20 -0
- package/flowquery-py/src/parsing/expressions/number.py +32 -0
- package/flowquery-py/src/parsing/expressions/operator.py +169 -0
- package/flowquery-py/src/parsing/expressions/reference.py +47 -0
- package/flowquery-py/src/parsing/expressions/string.py +27 -0
- package/flowquery-py/src/parsing/functions/__init__.py +75 -0
- package/flowquery-py/src/parsing/functions/aggregate_function.py +60 -0
- package/flowquery-py/src/parsing/functions/async_function.py +62 -0
- package/flowquery-py/src/parsing/functions/avg.py +55 -0
- package/flowquery-py/src/parsing/functions/collect.py +75 -0
- package/flowquery-py/src/parsing/functions/function.py +68 -0
- package/flowquery-py/src/parsing/functions/function_factory.py +173 -0
- package/flowquery-py/src/parsing/functions/function_metadata.py +149 -0
- package/flowquery-py/src/parsing/functions/functions.py +59 -0
- package/flowquery-py/src/parsing/functions/join.py +47 -0
- package/flowquery-py/src/parsing/functions/keys.py +34 -0
- package/flowquery-py/src/parsing/functions/predicate_function.py +46 -0
- package/flowquery-py/src/parsing/functions/predicate_sum.py +47 -0
- package/flowquery-py/src/parsing/functions/rand.py +28 -0
- package/flowquery-py/src/parsing/functions/range_.py +34 -0
- package/flowquery-py/src/parsing/functions/reducer_element.py +15 -0
- package/flowquery-py/src/parsing/functions/replace.py +37 -0
- package/flowquery-py/src/parsing/functions/round_.py +32 -0
- package/flowquery-py/src/parsing/functions/size.py +32 -0
- package/flowquery-py/src/parsing/functions/split.py +47 -0
- package/flowquery-py/src/parsing/functions/stringify.py +47 -0
- package/flowquery-py/src/parsing/functions/sum.py +51 -0
- package/flowquery-py/src/parsing/functions/to_json.py +33 -0
- package/flowquery-py/src/parsing/functions/type_.py +47 -0
- package/flowquery-py/src/parsing/functions/value_holder.py +24 -0
- package/flowquery-py/src/parsing/logic/__init__.py +15 -0
- package/flowquery-py/src/parsing/logic/case.py +29 -0
- package/flowquery-py/src/parsing/logic/else_.py +12 -0
- package/flowquery-py/src/parsing/logic/end.py +8 -0
- package/flowquery-py/src/parsing/logic/then.py +12 -0
- package/flowquery-py/src/parsing/logic/when.py +10 -0
- package/flowquery-py/src/parsing/operations/__init__.py +35 -0
- package/flowquery-py/src/parsing/operations/aggregated_return.py +24 -0
- package/flowquery-py/src/parsing/operations/aggregated_with.py +22 -0
- package/flowquery-py/src/parsing/operations/call.py +74 -0
- package/flowquery-py/src/parsing/operations/create_node.py +34 -0
- package/flowquery-py/src/parsing/operations/create_relationship.py +34 -0
- package/flowquery-py/src/parsing/operations/group_by.py +130 -0
- package/flowquery-py/src/parsing/operations/limit.py +22 -0
- package/flowquery-py/src/parsing/operations/load.py +140 -0
- package/flowquery-py/src/parsing/operations/match.py +29 -0
- package/flowquery-py/src/parsing/operations/operation.py +69 -0
- package/flowquery-py/src/parsing/operations/projection.py +21 -0
- package/flowquery-py/src/parsing/operations/return_op.py +50 -0
- package/flowquery-py/src/parsing/operations/unwind.py +37 -0
- package/flowquery-py/src/parsing/operations/where.py +41 -0
- package/flowquery-py/src/parsing/operations/with_op.py +18 -0
- package/flowquery-py/src/parsing/parser.py +1011 -0
- package/flowquery-py/src/parsing/token_to_node.py +109 -0
- package/flowquery-py/src/tokenization/__init__.py +23 -0
- package/flowquery-py/src/tokenization/keyword.py +48 -0
- package/flowquery-py/src/tokenization/operator.py +29 -0
- package/flowquery-py/src/tokenization/string_walker.py +158 -0
- package/flowquery-py/src/tokenization/symbol.py +19 -0
- package/flowquery-py/src/tokenization/token.py +659 -0
- package/flowquery-py/src/tokenization/token_mapper.py +52 -0
- package/flowquery-py/src/tokenization/token_type.py +21 -0
- package/flowquery-py/src/tokenization/tokenizer.py +214 -0
- package/flowquery-py/src/tokenization/trie.py +124 -0
- package/flowquery-py/src/utils/__init__.py +6 -0
- package/flowquery-py/src/utils/object_utils.py +20 -0
- package/flowquery-py/src/utils/string_utils.py +113 -0
- package/flowquery-py/tests/__init__.py +1 -0
- package/flowquery-py/tests/compute/__init__.py +1 -0
- package/flowquery-py/tests/compute/test_runner.py +1335 -0
- package/flowquery-py/tests/graph/__init__.py +1 -0
- package/flowquery-py/tests/graph/test_create.py +56 -0
- package/flowquery-py/tests/graph/test_data.py +73 -0
- package/flowquery-py/tests/graph/test_match.py +40 -0
- package/flowquery-py/tests/parsing/__init__.py +1 -0
- package/flowquery-py/tests/parsing/test_context.py +34 -0
- package/flowquery-py/tests/parsing/test_expression.py +49 -0
- package/flowquery-py/tests/parsing/test_parser.py +674 -0
- package/flowquery-py/tests/test_extensibility.py +611 -0
- package/flowquery-py/tests/tokenization/__init__.py +1 -0
- package/flowquery-py/tests/tokenization/test_token_mapper.py +60 -0
- package/flowquery-py/tests/tokenization/test_tokenizer.py +164 -0
- package/flowquery-py/tests/tokenization/test_trie.py +30 -0
- package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -1
- package/misc/apps/RAG/package.json +1 -1
- package/misc/apps/RAG/src/components/AdaptiveCardRenderer.tsx +76 -8
- package/misc/apps/RAG/src/components/index.ts +19 -10
- package/misc/apps/RAG/src/plugins/loaders/CatFacts.ts +21 -26
- package/misc/apps/RAG/src/plugins/loaders/FetchJson.ts +24 -25
- package/misc/apps/RAG/src/plugins/loaders/Form.ts +163 -147
- package/misc/apps/RAG/src/plugins/loaders/Llm.ts +103 -90
- package/misc/apps/RAG/src/plugins/loaders/MockData.ts +80 -130
- package/misc/apps/RAG/src/plugins/loaders/Table.ts +104 -101
- package/misc/apps/RAG/src/plugins/loaders/Weather.ts +47 -36
- package/misc/apps/RAG/src/prompts/FlowQuerySystemPrompt.ts +89 -78
- package/package.json +1 -1
- package/src/compute/runner.ts +24 -19
- package/src/graph/data.ts +112 -0
- package/src/graph/database.ts +63 -0
- package/src/graph/hops.ts +22 -0
- package/src/graph/node.ts +99 -0
- package/src/graph/node_data.ts +18 -0
- package/src/graph/node_reference.ts +33 -0
- package/src/graph/pattern.ts +101 -0
- package/src/graph/pattern_expression.ts +37 -0
- package/src/graph/patterns.ts +36 -0
- package/src/graph/physical_node.ts +23 -0
- package/src/graph/physical_relationship.ts +23 -0
- package/src/graph/relationship.ts +116 -0
- package/src/graph/relationship_data.ts +27 -0
- package/src/graph/relationship_match_collector.ts +58 -0
- package/src/graph/relationship_reference.ts +24 -0
- package/src/parsing/base_parser.ts +20 -14
- package/src/parsing/context.ts +14 -14
- package/src/parsing/expressions/boolean.ts +21 -0
- package/src/parsing/expressions/expression.ts +34 -26
- package/src/parsing/expressions/expression_map.ts +3 -0
- package/src/parsing/expressions/operator.ts +19 -1
- package/src/parsing/functions/function_factory.ts +45 -45
- package/src/parsing/operations/call.ts +3 -1
- package/src/parsing/operations/create_node.ts +39 -0
- package/src/parsing/operations/create_relationship.ts +38 -0
- package/src/parsing/operations/match.ts +31 -0
- package/src/parsing/operations/operation.ts +3 -0
- package/src/parsing/operations/return.ts +11 -7
- package/src/parsing/operations/where.ts +10 -6
- package/src/parsing/parser.ts +346 -8
- package/src/parsing/token_to_node.ts +6 -0
- package/src/tokenization/keyword.ts +41 -40
- package/src/tokenization/token.ts +21 -1
- package/src/tokenization/token_type.ts +2 -1
- package/src/tokenization/tokenizer.ts +52 -31
- package/tests/compute/runner.test.ts +660 -6
- package/tests/extensibility.test.ts +97 -93
- package/tests/graph/create.test.ts +36 -0
- package/tests/graph/data.test.ts +58 -0
- package/tests/graph/match.test.ts +29 -0
- package/tests/parsing/parser.test.ts +276 -8
- package/tests/tokenization/tokenizer.test.ts +107 -17
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import Runner from "../../src/compute/runner";
|
|
2
|
+
import PhysicalNode from "../../src/graph/physical_node";
|
|
3
|
+
import CreateNode from "../../src/parsing/operations/create_node";
|
|
4
|
+
import Parser from "../../src/parsing/parser";
|
|
5
|
+
|
|
6
|
+
test("Test CreateNode and match operations", async () => {
|
|
7
|
+
const node = new PhysicalNode(null, "Person");
|
|
8
|
+
expect(node.label).toBe("Person");
|
|
9
|
+
expect(node.statement).toBeNull();
|
|
10
|
+
const parser = new Parser();
|
|
11
|
+
const statement = parser.parse(`
|
|
12
|
+
unwind [
|
|
13
|
+
{id: 1, name: 'Person 1'},
|
|
14
|
+
{id: 2, name: 'Person 2'}
|
|
15
|
+
] as record
|
|
16
|
+
RETURN record.id as id, record.name as name
|
|
17
|
+
`);
|
|
18
|
+
const op = new CreateNode(node, statement);
|
|
19
|
+
await op.run();
|
|
20
|
+
const runner = new Runner("match (n:Person) RETURN n");
|
|
21
|
+
await runner.run();
|
|
22
|
+
expect(runner.results.length).toBe(2);
|
|
23
|
+
expect(runner.results[0].n).toBeDefined();
|
|
24
|
+
expect(runner.results[0].n.id).toBe(1);
|
|
25
|
+
expect(runner.results[0].n.name).toBe("Person 1");
|
|
26
|
+
expect(runner.results[1].n).toBeDefined();
|
|
27
|
+
expect(runner.results[1].n.id).toBe(2);
|
|
28
|
+
expect(runner.results[1].n.name).toBe("Person 2");
|
|
29
|
+
});
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import Node from "../../src/graph/node";
|
|
2
|
+
import NodeReference from "../../src/graph/node_reference";
|
|
3
|
+
import Relationship from "../../src/graph/relationship";
|
|
1
4
|
import AsyncFunction from "../../src/parsing/functions/async_function";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
import { FunctionDef } from "../../src/parsing/functions/function_metadata";
|
|
6
|
+
import CreateNode from "../../src/parsing/operations/create_node";
|
|
7
|
+
import CreateRelationship from "../../src/parsing/operations/create_relationship";
|
|
8
|
+
import Match from "../../src/parsing/operations/match";
|
|
6
9
|
import Parser from "../../src/parsing/parser";
|
|
7
10
|
|
|
8
11
|
// Test class for CALL operation parsing test - defined at module level for Prettier compatibility
|
|
@@ -12,7 +15,7 @@ import Parser from "../../src/parsing/parser";
|
|
|
12
15
|
parameters: [],
|
|
13
16
|
output: { description: "Yields test values", type: "any" },
|
|
14
17
|
})
|
|
15
|
-
class
|
|
18
|
+
class Test extends AsyncFunction {
|
|
16
19
|
constructor() {
|
|
17
20
|
super();
|
|
18
21
|
this._expectedParameterCount = 0;
|
|
@@ -427,7 +430,7 @@ test("Test non-well formed statements", () => {
|
|
|
427
430
|
"Only one RETURN statement is allowed"
|
|
428
431
|
);
|
|
429
432
|
expect(() => new Parser().parse("return 1 with 1 as n")).toThrow(
|
|
430
|
-
"Last statement must be a RETURN, WHERE, or
|
|
433
|
+
"Last statement must be a RETURN, WHERE, CALL, or CREATE statement"
|
|
431
434
|
);
|
|
432
435
|
});
|
|
433
436
|
|
|
@@ -468,12 +471,18 @@ test("Test limit", () => {
|
|
|
468
471
|
test("Test return -2", () => {
|
|
469
472
|
const parser = new Parser();
|
|
470
473
|
const ast = parser.parse("return -2");
|
|
471
|
-
|
|
474
|
+
// prettier-ignore
|
|
475
|
+
expect(ast.print()).toBe(
|
|
476
|
+
"ASTNode\n" +
|
|
477
|
+
"- Return\n" +
|
|
478
|
+
"-- Expression\n" +
|
|
479
|
+
"--- Number (-2)"
|
|
480
|
+
);
|
|
472
481
|
});
|
|
473
482
|
|
|
474
483
|
test("Test call operation", () => {
|
|
475
484
|
const parser = new Parser();
|
|
476
|
-
const ast = parser.parse("CALL
|
|
485
|
+
const ast = parser.parse("CALL test() YIELD result RETURN result");
|
|
477
486
|
expect(ast.print()).toBe(
|
|
478
487
|
"ASTNode\n" +
|
|
479
488
|
"- Call\n" +
|
|
@@ -484,3 +493,262 @@ test("Test call operation", () => {
|
|
|
484
493
|
"--- Reference (result)"
|
|
485
494
|
);
|
|
486
495
|
});
|
|
496
|
+
|
|
497
|
+
test("Test f-string", () => {
|
|
498
|
+
const parser = new Parser();
|
|
499
|
+
const ast = parser.parse("with 1 as value RETURN f'Value is: {value}.'");
|
|
500
|
+
expect(ast.print()).toBe(
|
|
501
|
+
"ASTNode\n" +
|
|
502
|
+
"- With\n" +
|
|
503
|
+
"-- Expression (value)\n" +
|
|
504
|
+
"--- Number (1)\n" +
|
|
505
|
+
"- Return\n" +
|
|
506
|
+
"-- Expression\n" +
|
|
507
|
+
"--- FString\n" +
|
|
508
|
+
"---- String (Value is: )\n" +
|
|
509
|
+
"---- Expression\n" +
|
|
510
|
+
"----- Reference (value)\n" +
|
|
511
|
+
"---- String (.)"
|
|
512
|
+
);
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
test("Test create node operation", () => {
|
|
516
|
+
const parser = new Parser();
|
|
517
|
+
const ast = parser.parse(`
|
|
518
|
+
CREATE VIRTUAL (:Person) AS {
|
|
519
|
+
unwind range(1, 3) AS id
|
|
520
|
+
return id, f'Person {id}' AS name
|
|
521
|
+
}
|
|
522
|
+
`);
|
|
523
|
+
// prettier-ignore
|
|
524
|
+
expect(ast.print()).toBe(
|
|
525
|
+
"ASTNode\n" +
|
|
526
|
+
"- CreateNode"
|
|
527
|
+
);
|
|
528
|
+
const create: CreateNode = ast.firstChild() as CreateNode;
|
|
529
|
+
expect(create.node).not.toBeNull();
|
|
530
|
+
expect(create.node!.label).toBe("Person");
|
|
531
|
+
expect(create.statement!.print()).toBe(
|
|
532
|
+
"ASTNode\n" +
|
|
533
|
+
"- Unwind\n" +
|
|
534
|
+
"-- Expression (id)\n" +
|
|
535
|
+
"--- Function (range)\n" +
|
|
536
|
+
"---- Expression\n" +
|
|
537
|
+
"----- Number (1)\n" +
|
|
538
|
+
"---- Expression\n" +
|
|
539
|
+
"----- Number (3)\n" +
|
|
540
|
+
"- Return\n" +
|
|
541
|
+
"-- Expression (id)\n" +
|
|
542
|
+
"--- Reference (id)\n" +
|
|
543
|
+
"-- Expression (name)\n" +
|
|
544
|
+
"--- FString\n" +
|
|
545
|
+
"---- String (Person )\n" +
|
|
546
|
+
"---- Expression\n" +
|
|
547
|
+
"----- Reference (id)\n" +
|
|
548
|
+
"---- String ()"
|
|
549
|
+
);
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
test("Test match operation", () => {
|
|
553
|
+
const parser = new Parser();
|
|
554
|
+
const ast = parser.parse("MATCH (n:Person) RETURN n");
|
|
555
|
+
// prettier-ignore
|
|
556
|
+
expect(ast.print()).toBe(
|
|
557
|
+
"ASTNode\n" +
|
|
558
|
+
"- Match\n" +
|
|
559
|
+
"- Return\n" +
|
|
560
|
+
"-- Expression (n)\n" +
|
|
561
|
+
"--- Reference (n)"
|
|
562
|
+
);
|
|
563
|
+
const match = ast.firstChild() as Match;
|
|
564
|
+
expect(match.patterns[0].startNode).not.toBeNull();
|
|
565
|
+
expect(match.patterns[0].startNode!.label).toBe("Person");
|
|
566
|
+
expect(match.patterns[0].startNode!.identifier).toBe("n");
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
test("Test create relationship operation", () => {
|
|
570
|
+
const parser = new Parser();
|
|
571
|
+
const ast = parser.parse(`
|
|
572
|
+
CREATE VIRTUAL (:Person)-[:KNOWS]-(:Person) AS {
|
|
573
|
+
unwind [
|
|
574
|
+
{from_id: 1, to_id: 2, since: '2020-01-01'},
|
|
575
|
+
{from_id: 2, to_id: 3, since: '2021-01-01'}
|
|
576
|
+
] AS pair
|
|
577
|
+
return pair.from_id AS from, pair.to_id AS to, pair.since AS since
|
|
578
|
+
}
|
|
579
|
+
`);
|
|
580
|
+
// prettier-ignore
|
|
581
|
+
expect(ast.print()).toBe(
|
|
582
|
+
"ASTNode\n" +
|
|
583
|
+
"- CreateRelationship"
|
|
584
|
+
);
|
|
585
|
+
const create = ast.firstChild() as CreateRelationship;
|
|
586
|
+
expect(create.relationship).not.toBeNull();
|
|
587
|
+
expect(create.relationship!.type).toBe("KNOWS");
|
|
588
|
+
expect(create.statement!.print()).toBe(
|
|
589
|
+
"ASTNode\n" +
|
|
590
|
+
"- Unwind\n" +
|
|
591
|
+
"-- Expression (pair)\n" +
|
|
592
|
+
"--- JSONArray\n" +
|
|
593
|
+
"---- Expression\n" +
|
|
594
|
+
"----- AssociativeArray\n" +
|
|
595
|
+
"------ KeyValuePair\n" +
|
|
596
|
+
"------- String (from_id)\n" +
|
|
597
|
+
"------- Expression\n" +
|
|
598
|
+
"-------- Number (1)\n" +
|
|
599
|
+
"------ KeyValuePair\n" +
|
|
600
|
+
"------- String (to_id)\n" +
|
|
601
|
+
"------- Expression\n" +
|
|
602
|
+
"-------- Number (2)\n" +
|
|
603
|
+
"------ KeyValuePair\n" +
|
|
604
|
+
"------- String (since)\n" +
|
|
605
|
+
"------- Expression\n" +
|
|
606
|
+
"-------- String (2020-01-01)\n" +
|
|
607
|
+
"---- Expression\n" +
|
|
608
|
+
"----- AssociativeArray\n" +
|
|
609
|
+
"------ KeyValuePair\n" +
|
|
610
|
+
"------- String (from_id)\n" +
|
|
611
|
+
"------- Expression\n" +
|
|
612
|
+
"-------- Number (2)\n" +
|
|
613
|
+
"------ KeyValuePair\n" +
|
|
614
|
+
"------- String (to_id)\n" +
|
|
615
|
+
"------- Expression\n" +
|
|
616
|
+
"-------- Number (3)\n" +
|
|
617
|
+
"------ KeyValuePair\n" +
|
|
618
|
+
"------- String (since)\n" +
|
|
619
|
+
"------- Expression\n" +
|
|
620
|
+
"-------- String (2021-01-01)\n" +
|
|
621
|
+
"- Return\n" +
|
|
622
|
+
"-- Expression (from)\n" +
|
|
623
|
+
"--- Lookup\n" +
|
|
624
|
+
"---- Identifier (from_id)\n" +
|
|
625
|
+
"---- Reference (pair)\n" +
|
|
626
|
+
"-- Expression (to)\n" +
|
|
627
|
+
"--- Lookup\n" +
|
|
628
|
+
"---- Identifier (to_id)\n" +
|
|
629
|
+
"---- Reference (pair)\n" +
|
|
630
|
+
"-- Expression (since)\n" +
|
|
631
|
+
"--- Lookup\n" +
|
|
632
|
+
"---- Identifier (since)\n" +
|
|
633
|
+
"---- Reference (pair)"
|
|
634
|
+
);
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
test("Match with graph pattern including relationships", () => {
|
|
638
|
+
const parser = new Parser();
|
|
639
|
+
const ast = parser.parse("MATCH (a:Person)-[:KNOWS]-(b:Person) RETURN a, b");
|
|
640
|
+
// prettier-ignore
|
|
641
|
+
expect(ast.print()).toBe(
|
|
642
|
+
"ASTNode\n" +
|
|
643
|
+
"- Match\n" +
|
|
644
|
+
"- Return\n" +
|
|
645
|
+
"-- Expression (a)\n" +
|
|
646
|
+
"--- Reference (a)\n" +
|
|
647
|
+
"-- Expression (b)\n" +
|
|
648
|
+
"--- Reference (b)"
|
|
649
|
+
);
|
|
650
|
+
const match = ast.firstChild() as Match;
|
|
651
|
+
expect(match.patterns[0].chain.length).toBe(3);
|
|
652
|
+
const source = match.patterns[0].chain[0] as Node;
|
|
653
|
+
const relationship = match.patterns[0].chain[1] as Relationship;
|
|
654
|
+
const target = match.patterns[0].chain[2] as Node;
|
|
655
|
+
expect(source.identifier).toBe("a");
|
|
656
|
+
expect(source.label).toBe("Person");
|
|
657
|
+
expect(relationship.type).toBe("KNOWS");
|
|
658
|
+
expect(target.identifier).toBe("b");
|
|
659
|
+
expect(target.label).toBe("Person");
|
|
660
|
+
});
|
|
661
|
+
|
|
662
|
+
test("Test not equal operator", () => {
|
|
663
|
+
const parser = new Parser();
|
|
664
|
+
const ast = parser.parse("RETURN 1 <> 2");
|
|
665
|
+
expect(ast.print()).toBe(
|
|
666
|
+
"ASTNode\n" +
|
|
667
|
+
"- Return\n" +
|
|
668
|
+
"-- Expression\n" +
|
|
669
|
+
"--- NotEquals\n" +
|
|
670
|
+
"---- Number (1)\n" +
|
|
671
|
+
"---- Number (2)"
|
|
672
|
+
);
|
|
673
|
+
});
|
|
674
|
+
|
|
675
|
+
test("Test equal operator", () => {
|
|
676
|
+
const parser = new Parser();
|
|
677
|
+
const ast = parser.parse("RETURN 1 = 2");
|
|
678
|
+
expect(ast.print()).toBe(
|
|
679
|
+
"ASTNode\n" +
|
|
680
|
+
"- Return\n" +
|
|
681
|
+
"-- Expression\n" +
|
|
682
|
+
"--- Equals\n" +
|
|
683
|
+
"---- Number (1)\n" +
|
|
684
|
+
"---- Number (2)"
|
|
685
|
+
);
|
|
686
|
+
});
|
|
687
|
+
|
|
688
|
+
test("Test not operator", () => {
|
|
689
|
+
const parser = new Parser();
|
|
690
|
+
const ast = parser.parse("RETURN NOT true");
|
|
691
|
+
// prettier-ignore
|
|
692
|
+
expect(ast.print()).toBe(
|
|
693
|
+
"ASTNode\n" +
|
|
694
|
+
"- Return\n" +
|
|
695
|
+
"-- Expression\n" +
|
|
696
|
+
"--- Not\n" +
|
|
697
|
+
"---- Expression\n" +
|
|
698
|
+
"----- Boolean"
|
|
699
|
+
);
|
|
700
|
+
});
|
|
701
|
+
|
|
702
|
+
test("Parse relationship with hops", () => {
|
|
703
|
+
const parser = new Parser();
|
|
704
|
+
const ast = parser.parse("MATCH (a:Test)-[:KNOWS*1..3]->(b:Test) RETURN a, b");
|
|
705
|
+
// prettier-ignore
|
|
706
|
+
expect(ast.print()).toBe(
|
|
707
|
+
"ASTNode\n" +
|
|
708
|
+
"- Match\n" +
|
|
709
|
+
"- Return\n" +
|
|
710
|
+
"-- Expression (a)\n" +
|
|
711
|
+
"--- Reference (a)\n" +
|
|
712
|
+
"-- Expression (b)\n" +
|
|
713
|
+
"--- Reference (b)"
|
|
714
|
+
);
|
|
715
|
+
const match = ast.firstChild() as Match;
|
|
716
|
+
expect(match.patterns[0].chain.length).toBe(3);
|
|
717
|
+
const source = match.patterns[0].chain[0] as Node;
|
|
718
|
+
const relationship = match.patterns[0].chain[1] as Relationship;
|
|
719
|
+
const target = match.patterns[0].chain[2] as Node;
|
|
720
|
+
expect(source.identifier).toBe("a");
|
|
721
|
+
expect(relationship.type).toBe("KNOWS");
|
|
722
|
+
expect(relationship.hops).not.toBeNull();
|
|
723
|
+
expect(relationship.hops!.min).toBe(1);
|
|
724
|
+
expect(relationship.hops!.max).toBe(3);
|
|
725
|
+
expect(target.identifier).toBe("b");
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
test("Parse statement with graph pattern in where clause", () => {
|
|
729
|
+
const parser = new Parser();
|
|
730
|
+
const ast = parser.parse("MATCH (a:Person) WHERE (a)-[:KNOWS]->(:Person) RETURN a");
|
|
731
|
+
// prettier-ignore
|
|
732
|
+
expect(ast.print()).toBe(
|
|
733
|
+
"ASTNode\n" +
|
|
734
|
+
"- Match\n" +
|
|
735
|
+
"- Where\n" +
|
|
736
|
+
"-- Expression\n" +
|
|
737
|
+
"--- PatternExpression\n" +
|
|
738
|
+
"- Return\n" +
|
|
739
|
+
"-- Expression (a)\n" +
|
|
740
|
+
"--- Reference (a)"
|
|
741
|
+
);
|
|
742
|
+
const match = ast.firstChild() as Match;
|
|
743
|
+
expect(match.patterns[0].startNode).not.toBeNull();
|
|
744
|
+
expect(match.patterns[0].startNode!.identifier).toBe("a");
|
|
745
|
+
const where = match.next as any;
|
|
746
|
+
const pattern = where.firstChild().firstChild() as any;
|
|
747
|
+
expect(pattern.chain.length).toBe(3);
|
|
748
|
+
const source = pattern.chain[0] as NodeReference;
|
|
749
|
+
const relationship = pattern.chain[1] as Relationship;
|
|
750
|
+
const target = pattern.chain[2] as Node;
|
|
751
|
+
expect(source.reference?.identifier).toBe("a");
|
|
752
|
+
expect(relationship.type).toBe("KNOWS");
|
|
753
|
+
expect(target.label).toBe("Person");
|
|
754
|
+
});
|
|
@@ -1,62 +1,69 @@
|
|
|
1
|
-
import Tokenizer from
|
|
1
|
+
import Tokenizer from "../../src/tokenization/tokenizer";
|
|
2
2
|
|
|
3
|
-
test(
|
|
4
|
-
const tokenizer = new Tokenizer(
|
|
3
|
+
test("Tokenizer.tokenize() should return an array of tokens", () => {
|
|
4
|
+
const tokenizer = new Tokenizer("MATCH (n:Person) RETURN n");
|
|
5
5
|
const tokens = tokenizer.tokenize();
|
|
6
6
|
expect(tokens).toBeDefined();
|
|
7
7
|
expect(tokens.length).toBeGreaterThan(0);
|
|
8
8
|
});
|
|
9
9
|
|
|
10
|
-
test(
|
|
10
|
+
test("Tokenizer.tokenize() should handle escaped quotes", () => {
|
|
11
11
|
const tokenizer = new Tokenizer('return "hello \\"world"');
|
|
12
12
|
const tokens = tokenizer.tokenize();
|
|
13
13
|
expect(tokens).toBeDefined();
|
|
14
14
|
expect(tokens.length).toBeGreaterThan(0);
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
test(
|
|
18
|
-
const tokenizer = new Tokenizer(
|
|
17
|
+
test("Test predicate function", () => {
|
|
18
|
+
const tokenizer = new Tokenizer("RETURN sum(n in [1, 2, 3] | n where n > 1)");
|
|
19
19
|
const tokens = tokenizer.tokenize();
|
|
20
20
|
expect(tokens).toBeDefined();
|
|
21
21
|
expect(tokens.length).toBeGreaterThan(0);
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
test(
|
|
24
|
+
test("Test f-string", () => {
|
|
25
25
|
const tokenizer = new Tokenizer('RETURN f"hello {world}"');
|
|
26
26
|
const tokens = tokenizer.tokenize();
|
|
27
27
|
expect(tokens).toBeDefined();
|
|
28
28
|
expect(tokens.length).toBeGreaterThan(0);
|
|
29
29
|
});
|
|
30
30
|
|
|
31
|
-
test(
|
|
32
|
-
const tokenizer = new Tokenizer(
|
|
31
|
+
test("Test another f-string", () => {
|
|
32
|
+
const tokenizer = new Tokenizer("RETURN f`Value is: {value}`");
|
|
33
33
|
const tokens = tokenizer.tokenize();
|
|
34
34
|
expect(tokens).toBeDefined();
|
|
35
35
|
expect(tokens.length).toBeGreaterThan(0);
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
-
test(
|
|
39
|
-
const tokenizer = new Tokenizer(
|
|
38
|
+
test("Test", () => {
|
|
39
|
+
const tokenizer = new Tokenizer("WITH 1 AS n RETURN n");
|
|
40
40
|
const tokens = tokenizer.tokenize();
|
|
41
41
|
expect(tokens).toBeDefined();
|
|
42
42
|
expect(tokens.length).toBeGreaterThan(0);
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
-
test(
|
|
46
|
-
const tokenizer = new Tokenizer(
|
|
45
|
+
test("Test associative array with backtick string", () => {
|
|
46
|
+
const tokenizer = new Tokenizer("RETURN {`key`: `value`}");
|
|
47
47
|
const tokens = tokenizer.tokenize();
|
|
48
48
|
expect(tokens).toBeDefined();
|
|
49
49
|
expect(tokens.length).toBeGreaterThan(0);
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
-
test(
|
|
53
|
-
const tokenizer = new Tokenizer(
|
|
52
|
+
test("Test limit", () => {
|
|
53
|
+
const tokenizer = new Tokenizer("unwind range(1, 10) as n limit 5 return n");
|
|
54
54
|
const tokens = tokenizer.tokenize();
|
|
55
55
|
expect(tokens).toBeDefined();
|
|
56
56
|
expect(tokens.length).toBeGreaterThan(0);
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
-
test(
|
|
59
|
+
test("Test return -2", () => {
|
|
60
|
+
const tokenizer = new Tokenizer("return [:-2], -2");
|
|
61
|
+
const tokens = tokenizer.tokenize();
|
|
62
|
+
expect(tokens).toBeDefined();
|
|
63
|
+
expect(tokens.length).toBeGreaterThan(0);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("Test range with function", () => {
|
|
60
67
|
const tokenizer = new Tokenizer(`
|
|
61
68
|
with range(1,10) as data
|
|
62
69
|
return range(0, size(data)-1) as indices
|
|
@@ -64,4 +71,87 @@ test('Test range with function', () => {
|
|
|
64
71
|
const tokens = tokenizer.tokenize();
|
|
65
72
|
expect(tokens).toBeDefined();
|
|
66
73
|
expect(tokens.length).toBeGreaterThan(0);
|
|
67
|
-
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("Test create virtual node", () => {
|
|
77
|
+
const tokenizer = new Tokenizer(`
|
|
78
|
+
CREATE VIRTUAL (:Person) AS {
|
|
79
|
+
call users() YIELD id, name
|
|
80
|
+
}
|
|
81
|
+
`);
|
|
82
|
+
const tokens = tokenizer.tokenize();
|
|
83
|
+
expect(tokens).toBeDefined();
|
|
84
|
+
expect(tokens.length).toBeGreaterThan(0);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test("Test create virtual relationship", () => {
|
|
88
|
+
const tokenizer = new Tokenizer(`
|
|
89
|
+
CREATE VIRTUAL (:Person)-[:KNOWS]->(:Person) AS {
|
|
90
|
+
call friendships() YIELD user1_id, user2_id
|
|
91
|
+
}
|
|
92
|
+
`);
|
|
93
|
+
const tokens = tokenizer.tokenize();
|
|
94
|
+
expect(tokens).toBeDefined();
|
|
95
|
+
expect(tokens.length).toBeGreaterThan(0);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test("Match based on virtual node", () => {
|
|
99
|
+
const tokenizer = new Tokenizer(`
|
|
100
|
+
MATCH (a:Person)
|
|
101
|
+
RETURN a.name
|
|
102
|
+
`);
|
|
103
|
+
const tokens = tokenizer.tokenize();
|
|
104
|
+
expect(tokens).toBeDefined();
|
|
105
|
+
expect(tokens.length).toBeGreaterThan(0);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test("Match based on virtual nodes and relationships", () => {
|
|
109
|
+
const tokenizer = new Tokenizer(`
|
|
110
|
+
MATCH (a:Person)-[r:KNOWS]->(b:Person)
|
|
111
|
+
RETURN a.name, b.name
|
|
112
|
+
`);
|
|
113
|
+
const tokens = tokenizer.tokenize();
|
|
114
|
+
expect(tokens).toBeDefined();
|
|
115
|
+
expect(tokens.length).toBeGreaterThan(0);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test("Test not equal operator", () => {
|
|
119
|
+
const tokenizer = new Tokenizer(`
|
|
120
|
+
MATCH (n:Person)
|
|
121
|
+
WHERE n.age <> 30
|
|
122
|
+
RETURN n.name AS name, n.age AS age
|
|
123
|
+
`);
|
|
124
|
+
const tokens = tokenizer.tokenize();
|
|
125
|
+
expect(tokens).toBeDefined();
|
|
126
|
+
expect(tokens.length).toBeGreaterThan(0);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test("Test equal operator", () => {
|
|
130
|
+
const tokenizer = new Tokenizer(`
|
|
131
|
+
MATCH (n:Person)
|
|
132
|
+
WHERE n.age = 30
|
|
133
|
+
RETURN n.name AS name, n.age AS age
|
|
134
|
+
`);
|
|
135
|
+
const tokens = tokenizer.tokenize();
|
|
136
|
+
expect(tokens).toBeDefined();
|
|
137
|
+
expect(tokens.length).toBeGreaterThan(0);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
test("Test boolean operators", () => {
|
|
141
|
+
const tokenizer = new Tokenizer(`
|
|
142
|
+
return true AND false OR true NOT false
|
|
143
|
+
`);
|
|
144
|
+
const tokens = tokenizer.tokenize();
|
|
145
|
+
expect(tokens).toBeDefined();
|
|
146
|
+
expect(tokens.length).toBeGreaterThan(0);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test("Test relationship with hops", () => {
|
|
150
|
+
const tokenizer = new Tokenizer(`
|
|
151
|
+
MATCH (a:Person)-[r:KNOWS*1..3]->(b:Person)
|
|
152
|
+
RETURN a.name, b.name
|
|
153
|
+
`);
|
|
154
|
+
const tokens = tokenizer.tokenize();
|
|
155
|
+
expect(tokens).toBeDefined();
|
|
156
|
+
expect(tokens.length).toBeGreaterThan(0);
|
|
157
|
+
});
|