flowquery 1.0.16 → 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/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/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/MockData.ts +70 -140
- package/misc/apps/RAG/src/prompts/FlowQuerySystemPrompt.ts +12 -0
- 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/operator.ts +19 -1
- package/src/parsing/functions/function_factory.ts +45 -45
- 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 +654 -0
- 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 +273 -2
- package/tests/tokenization/tokenizer.test.ts +90 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Graph tests package."""
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""Tests for graph node and relationship creation."""
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from flowquery.graph.database import Database
|
|
5
|
+
from flowquery.graph.physical_node import PhysicalNode
|
|
6
|
+
from flowquery.graph.physical_relationship import PhysicalRelationship
|
|
7
|
+
from flowquery.parsing.operations.create_node import CreateNode
|
|
8
|
+
from flowquery.parsing.operations.create_relationship import CreateRelationship
|
|
9
|
+
from flowquery.parsing.parser import Parser
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class TestCreateNode:
|
|
13
|
+
"""Test cases for CreateNode operation."""
|
|
14
|
+
|
|
15
|
+
@pytest.mark.asyncio
|
|
16
|
+
async def test_create_node_operation(self):
|
|
17
|
+
"""Test CreateNode operation."""
|
|
18
|
+
node = PhysicalNode(None, "Person")
|
|
19
|
+
assert node.label == "Person"
|
|
20
|
+
assert node.statement is None
|
|
21
|
+
|
|
22
|
+
parser = Parser()
|
|
23
|
+
statement = parser.parse("WITH 1 as x RETURN x")
|
|
24
|
+
op = CreateNode(node, statement)
|
|
25
|
+
await op.run()
|
|
26
|
+
|
|
27
|
+
db = Database.get_instance()
|
|
28
|
+
found = db.get_node(node)
|
|
29
|
+
assert found is not None
|
|
30
|
+
assert found.label == node.label
|
|
31
|
+
|
|
32
|
+
data = await found.data()
|
|
33
|
+
assert data == [{"x": 1}]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class TestCreateRelationship:
|
|
37
|
+
"""Test cases for CreateRelationship operation."""
|
|
38
|
+
|
|
39
|
+
@pytest.mark.asyncio
|
|
40
|
+
async def test_create_relationship_operation(self):
|
|
41
|
+
"""Test CreateRelationship operation."""
|
|
42
|
+
relationship = PhysicalRelationship()
|
|
43
|
+
relationship.type = "KNOWS"
|
|
44
|
+
assert relationship.type == "KNOWS"
|
|
45
|
+
assert relationship.statement is None
|
|
46
|
+
|
|
47
|
+
parser = Parser()
|
|
48
|
+
statement = parser.parse("WITH 1 as x RETURN x")
|
|
49
|
+
op = CreateRelationship(relationship, statement)
|
|
50
|
+
await op.run()
|
|
51
|
+
|
|
52
|
+
db = Database.get_instance()
|
|
53
|
+
found = db.get_relationship(relationship)
|
|
54
|
+
|
|
55
|
+
data = await found.data()
|
|
56
|
+
assert data == [{"x": 1}]
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""Tests for graph data iteration."""
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from flowquery.graph.data import Data
|
|
5
|
+
from flowquery.graph.node_data import NodeData
|
|
6
|
+
from flowquery.graph.relationship_data import RelationshipData
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestDataIteration:
|
|
10
|
+
"""Test cases for Data class iteration."""
|
|
11
|
+
|
|
12
|
+
def test_data_iteration(self):
|
|
13
|
+
"""Test data iteration."""
|
|
14
|
+
records = [
|
|
15
|
+
{"id": "1", "name": "Alice"},
|
|
16
|
+
{"id": "2", "name": "Bob"},
|
|
17
|
+
{"id": "3", "name": "Charlie"},
|
|
18
|
+
]
|
|
19
|
+
data = Data(records)
|
|
20
|
+
assert data.next() is True
|
|
21
|
+
assert data.next() is True
|
|
22
|
+
assert data.next() is True
|
|
23
|
+
assert data.next() is False
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class TestNodeDataFind:
|
|
27
|
+
"""Test cases for NodeData find operations."""
|
|
28
|
+
|
|
29
|
+
def test_data_find(self):
|
|
30
|
+
"""Test data find."""
|
|
31
|
+
records = [
|
|
32
|
+
{"id": "1", "name": "Alice"},
|
|
33
|
+
{"id": "2", "name": "Bob"},
|
|
34
|
+
{"id": "3", "name": "Charlie"},
|
|
35
|
+
{"id": "2", "name": "Bob Duplicate"},
|
|
36
|
+
]
|
|
37
|
+
data = NodeData(records)
|
|
38
|
+
data.find("2")
|
|
39
|
+
assert data.current() == {"id": "2", "name": "Bob"}
|
|
40
|
+
assert data.find("2") is True
|
|
41
|
+
assert data.current() == {"id": "2", "name": "Bob Duplicate"}
|
|
42
|
+
assert data.find("2") is False
|
|
43
|
+
|
|
44
|
+
def test_data_find_non_existing(self):
|
|
45
|
+
"""Test data find non-existing."""
|
|
46
|
+
records = [
|
|
47
|
+
{"id": "1", "name": "Alice"},
|
|
48
|
+
{"id": "2", "name": "Bob"},
|
|
49
|
+
]
|
|
50
|
+
data = NodeData(records)
|
|
51
|
+
assert data.find("3") is False
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class TestRelationshipDataFind:
|
|
55
|
+
"""Test cases for RelationshipData find operations."""
|
|
56
|
+
|
|
57
|
+
def test_relationship_data_find(self):
|
|
58
|
+
"""Test RelationshipData find."""
|
|
59
|
+
records = [
|
|
60
|
+
{"left_id": "1", "right_id": "2", "type": "FRIEND", "id": "r1"},
|
|
61
|
+
{"left_id": "2", "right_id": "3", "type": "COLLEAGUE", "id": "r2"},
|
|
62
|
+
{"left_id": "1", "right_id": "3", "type": "FRIEND", "id": "r3"},
|
|
63
|
+
]
|
|
64
|
+
data = RelationshipData(records)
|
|
65
|
+
data.find("1")
|
|
66
|
+
assert data.current() == {"left_id": "1", "right_id": "2", "type": "FRIEND", "id": "r1"}
|
|
67
|
+
assert data.find("1") is True
|
|
68
|
+
assert data.current() == {"left_id": "1", "right_id": "3", "type": "FRIEND", "id": "r3"}
|
|
69
|
+
assert data.find("1") is False
|
|
70
|
+
assert data.find("2") is True
|
|
71
|
+
assert data.current() == {"left_id": "2", "right_id": "3", "type": "COLLEAGUE", "id": "r2"}
|
|
72
|
+
assert data.find("2") is False
|
|
73
|
+
assert data.find("4") is False
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""Tests for graph pattern matching."""
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from flowquery.compute.runner import Runner
|
|
5
|
+
from flowquery.graph.physical_node import PhysicalNode
|
|
6
|
+
from flowquery.parsing.operations.create_node import CreateNode
|
|
7
|
+
from flowquery.parsing.parser import Parser
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TestMatch:
|
|
11
|
+
"""Test cases for Match operation."""
|
|
12
|
+
|
|
13
|
+
@pytest.mark.asyncio
|
|
14
|
+
async def test_create_node_and_match_operations(self):
|
|
15
|
+
"""Test CreateNode and match operations."""
|
|
16
|
+
node = PhysicalNode(None, "Person")
|
|
17
|
+
assert node.label == "Person"
|
|
18
|
+
assert node.statement is None
|
|
19
|
+
|
|
20
|
+
parser = Parser()
|
|
21
|
+
statement = parser.parse("""
|
|
22
|
+
unwind [
|
|
23
|
+
{id: 1, name: 'Person 1'},
|
|
24
|
+
{id: 2, name: 'Person 2'}
|
|
25
|
+
] as record
|
|
26
|
+
RETURN record.id as id, record.name as name
|
|
27
|
+
""")
|
|
28
|
+
op = CreateNode(node, statement)
|
|
29
|
+
await op.run()
|
|
30
|
+
|
|
31
|
+
runner = Runner("match (n:Person) RETURN n")
|
|
32
|
+
await runner.run()
|
|
33
|
+
|
|
34
|
+
assert len(runner.results) == 2
|
|
35
|
+
assert runner.results[0]["n"] is not None
|
|
36
|
+
assert runner.results[0]["n"]["id"] == 1
|
|
37
|
+
assert runner.results[0]["n"]["name"] == "Person 1"
|
|
38
|
+
assert runner.results[1]["n"] is not None
|
|
39
|
+
assert runner.results[1]["n"]["id"] == 2
|
|
40
|
+
assert runner.results[1]["n"]["name"] == "Person 2"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Parsing tests package."""
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Tests for the parsing context."""
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from flowquery.parsing.context import Context
|
|
5
|
+
from flowquery.parsing.functions.sum import Sum
|
|
6
|
+
from flowquery.parsing.functions.aggregate_function import AggregateFunction
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestContext:
|
|
10
|
+
"""Test cases for the Context class."""
|
|
11
|
+
|
|
12
|
+
def test_context_contains_type(self):
|
|
13
|
+
"""Test Context containsType."""
|
|
14
|
+
context = Context()
|
|
15
|
+
sum_func = Sum()
|
|
16
|
+
context.push(sum_func)
|
|
17
|
+
assert context.contains_type(AggregateFunction) is True
|
|
18
|
+
|
|
19
|
+
def test_context_contains_type_false(self):
|
|
20
|
+
"""Test Context containsType false."""
|
|
21
|
+
context = Context()
|
|
22
|
+
assert context.contains_type(AggregateFunction) is False
|
|
23
|
+
|
|
24
|
+
def test_context_push_and_pop(self):
|
|
25
|
+
"""Test Context push and pop."""
|
|
26
|
+
context = Context()
|
|
27
|
+
sum_func = Sum()
|
|
28
|
+
context.push(sum_func)
|
|
29
|
+
assert context.pop() is sum_func
|
|
30
|
+
|
|
31
|
+
def test_context_pop_none(self):
|
|
32
|
+
"""Test Context pop returns None when empty."""
|
|
33
|
+
context = Context()
|
|
34
|
+
assert context.pop() is None
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Tests for expression evaluation."""
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from flowquery.parsing.expressions.expression import Expression
|
|
5
|
+
from flowquery.parsing.expressions.operator import (
|
|
6
|
+
Add, Subtract, Multiply, Power, GreaterThan, And
|
|
7
|
+
)
|
|
8
|
+
from flowquery.parsing.expressions.number import Number
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TestExpression:
|
|
12
|
+
"""Test cases for the Expression class."""
|
|
13
|
+
|
|
14
|
+
def test_expression_shunting_yard_algorithm(self):
|
|
15
|
+
"""Test Expression Shunting Yard algorithm."""
|
|
16
|
+
expression = Expression()
|
|
17
|
+
expression.add_node(Number("2"))
|
|
18
|
+
expression.add_node(Add())
|
|
19
|
+
expression.add_node(Number("3"))
|
|
20
|
+
expression.add_node(Multiply())
|
|
21
|
+
expression.add_node(Number("4"))
|
|
22
|
+
expression.add_node(Subtract())
|
|
23
|
+
expression.add_node(Number("2"))
|
|
24
|
+
expression.add_node(Power())
|
|
25
|
+
expression.add_node(Number("2"))
|
|
26
|
+
expression.finish()
|
|
27
|
+
assert expression.value() == 10
|
|
28
|
+
|
|
29
|
+
def test_expression_with_and_operator(self):
|
|
30
|
+
"""Test Expression with and operator."""
|
|
31
|
+
expression = Expression()
|
|
32
|
+
expression.add_node(Number("2"))
|
|
33
|
+
expression.add_node(And())
|
|
34
|
+
expression.add_node(Number("3"))
|
|
35
|
+
expression.finish()
|
|
36
|
+
assert expression.value() == 1
|
|
37
|
+
|
|
38
|
+
def test_comparison_with_and(self):
|
|
39
|
+
"""Test 1 > 0 and 2 > 1."""
|
|
40
|
+
expression = Expression()
|
|
41
|
+
expression.add_node(Number("1"))
|
|
42
|
+
expression.add_node(GreaterThan())
|
|
43
|
+
expression.add_node(Number("0"))
|
|
44
|
+
expression.add_node(And())
|
|
45
|
+
expression.add_node(Number("2"))
|
|
46
|
+
expression.add_node(GreaterThan())
|
|
47
|
+
expression.add_node(Number("1"))
|
|
48
|
+
expression.finish()
|
|
49
|
+
assert expression.value() == 1
|