-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathtest_gql_create.py
More file actions
246 lines (201 loc) · 9.58 KB
/
test_gql_create.py
File metadata and controls
246 lines (201 loc) · 9.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
from typing import Any
import pytest
from neo4j_viz.gql_create import from_gql_create
def test_from_gql_create_syntax() -> None:
query = """
CREATE
(a:User {name: 'Alice', age: 23, labels: ['Happy'], "id": 42}),
(b:User:person {name: "Bridget", age: 34, "caption": "Bridget"}),
(wizardMan:User {name: 'Charles: The wizard, man', hello: true, height: NULL}),
(d:User),
(a)-[:LINK {weight: 0.5}]->(b),
(e:User {age: 67, my_map: {key: 'value', key2: 3.14, key3: [1, 2, 3], key4: {a: 1, b: null}}}),
(:User {age: 42, pets: ['cat', false, 'dog']}),
(),
(f:User&Person
{name: 'Fawad', age: 78}),
({age: 29}),
(a)-[:LINK {weight: 4}]->(wizardMan),
(e)-[:LINK]->(d),
(e)-[:OTHER_LINK {weight: -2, type: 1, source: 1337, caption: "Balloon"}]->(f),
()-[:LINK]->({name: 'Florentin'});
"""
expected_node_dicts: list[dict[str, dict[str, Any]]] = [
{
"top_level": {},
"properties": {"name": "Alice", "age": 23, "labels": ["User"], "__labels": ["Happy"], "id": 42},
},
{
"top_level": {},
"properties": {"name": "Bridget", "caption": "Bridget", "age": 34, "labels": ["User", "person"]},
},
{
"top_level": {},
"properties": {"name": "Charles: The wizard, man", "hello": True, "height": None, "labels": ["User"]},
},
{"top_level": {}, "properties": {"labels": ["User"]}},
{
"top_level": {},
"properties": {
"age": 67,
"my_map": {"key": "value", "key2": 3.14, "key3": [1, 2, 3], "key4": {"a": 1, "b": None}},
"labels": ["User"],
},
},
{"top_level": {}, "properties": {"age": 42, "pets": ["cat", False, "dog"], "labels": ["User"]}},
{"top_level": {}, "properties": {"labels": []}},
{"top_level": {}, "properties": {"name": "Fawad", "age": 78, "labels": ["Person", "User"]}},
{"top_level": {}, "properties": {"age": 29, "labels": []}},
{"top_level": {}, "properties": {"labels": []}},
{"top_level": {}, "properties": {"name": "Florentin", "labels": []}},
]
VG = from_gql_create(query, node_caption=None, relationship_caption=None)
assert len(VG.nodes) == len(expected_node_dicts)
for i, exp_node in enumerate(expected_node_dicts):
created_node = VG.nodes[i]
assert created_node.model_dump(exclude_none=True, exclude={"properties", "id"}) == exp_node["top_level"]
assert created_node.properties == exp_node["properties"]
expected_relationships_dicts: list[dict[str, Any]] = [
{"source_idx": 0, "target_idx": 1, "top_level": {}, "properties": {"weight": 0.5, "type": "LINK"}},
{"source_idx": 0, "target_idx": 2, "top_level": {}, "properties": {"weight": 4, "type": "LINK"}},
{"source_idx": 4, "target_idx": 3, "top_level": {}, "properties": {"type": "LINK"}},
{
"source_idx": 4,
"target_idx": 7,
"top_level": {},
"properties": {"weight": -2, "caption": "Balloon", "type": "OTHER_LINK", "__type": 1, "source": 1337},
},
{"source_idx": 9, "target_idx": 10, "top_level": {}, "properties": {"type": "LINK"}},
]
assert len(VG.relationships) == len(expected_relationships_dicts)
for i, exp_rel in enumerate(expected_relationships_dicts):
created_rel = VG.relationships[i]
assert created_rel.source == VG.nodes[exp_rel["source_idx"]].id
assert created_rel.target == VG.nodes[exp_rel["target_idx"]].id
assert (
created_rel.model_dump(exclude_none=True, exclude={"properties", "id", "source", "target"})
== exp_rel["top_level"]
)
assert created_rel.properties == exp_rel["properties"]
def test_from_gql_create_captions() -> None:
query = """
CREATE
(a:User {name: 'Alice', age: 23}),
(b:User:person {name: "Bridget", age: 34, "caption": "Bridget"}),
(a)-[:LINK {weight: 0.5}]->(b);
"""
expected_node_dicts: list[dict[str, dict[str, Any]]] = [
{
"top_level": {"caption": "User"},
"properties": {"name": "Alice", "age": 23, "labels": ["User"]},
},
{
"top_level": {"caption": "User:person"},
"properties": {"name": "Bridget", "caption": "Bridget", "age": 34, "labels": ["User", "person"]},
},
]
VG = from_gql_create(query)
assert len(VG.nodes) == len(expected_node_dicts)
for i, exp_node in enumerate(expected_node_dicts):
created_node = VG.nodes[i]
assert created_node.model_dump(exclude_none=True, exclude={"properties", "id"}) == exp_node["top_level"]
assert created_node.properties == exp_node["properties"]
expected_relationships_dicts: list[dict[str, Any]] = [
{
"source_idx": 0,
"target_idx": 1,
"top_level": {"caption": "LINK"},
"properties": {"weight": 0.5, "type": "LINK"},
},
]
assert len(VG.relationships) == len(expected_relationships_dicts)
for i, exp_rel in enumerate(expected_relationships_dicts):
created_rel = VG.relationships[i]
assert created_rel.source == VG.nodes[exp_rel["source_idx"]].id
assert created_rel.target == VG.nodes[exp_rel["target_idx"]].id
assert (
created_rel.model_dump(exclude_none=True, exclude={"properties", "id", "source", "target"})
== exp_rel["top_level"]
)
assert created_rel.properties == exp_rel["properties"]
def test_from_gql_create_sizes() -> None:
query = """
CREATE
(a:User {name: 'Alice', age: 23}),
(b:User:person {name: "Bridget", age: 34, "caption": "Bridget"});
"""
expected_node_dicts: list[dict[str, dict[str, Any]]] = [
{
"top_level": {"size": 3.0},
"properties": {"name": "Alice", "age": 23, "labels": ["User"]},
},
{
"top_level": {"size": 60.0},
"properties": {"name": "Bridget", "caption": "Bridget", "age": 34, "labels": ["User", "person"]},
},
]
VG = from_gql_create(query, size_property="age", node_caption=None, relationship_caption=None)
assert len(VG.nodes) == len(expected_node_dicts)
for i, exp_node in enumerate(expected_node_dicts):
created_node = VG.nodes[i]
assert created_node.model_dump(exclude_none=True, exclude={"properties", "id"}) == exp_node["top_level"]
assert created_node.properties == exp_node["properties"]
def test_unbalanced_parentheses_snippet() -> None:
query = "CREATE (a:User, (b:User })"
with pytest.raises(ValueError, match=r"Unbalanced parentheses near: `.*\(b:User.*"):
from_gql_create(query)
def test_unbalanced_brackets_snippet() -> None:
query = "CREATE (a)-[:LINK {weight: 0.5}->(b)"
with pytest.raises(ValueError, match=r"Unbalanced square brackets near: `eight: 0.5}->\(b\)`."):
from_gql_create(query)
def test_node_property_syntax_error_snippet1() -> None:
query = "CREATE (a:User {x, y:4})"
with pytest.raises(ValueError, match=r"Property syntax error near: `.*x, y.*"):
from_gql_create(query)
def test_node_property_paren_imbalance() -> None:
query = "CREATE (a:User {a: [1, b: 2, c: (3, 4)})"
with pytest.raises(ValueError, match=r"Unbalanced square brackets near: `: 2, c: \(3, 4\)}"):
from_gql_create(query)
def test_node_property_syntax_error_snippet2() -> None:
query = "CREATE (a:User {x:5,, y:4})"
with pytest.raises(ValueError, match=r"Property syntax error near: `.*x:5,, y.*"):
from_gql_create(query)
def test_invalid_element_in_create_snippet() -> None:
query = "CREATE [not_a_node]"
with pytest.raises(ValueError, match=r"Invalid element in CREATE near: `\[not_a_node.*"):
from_gql_create(query)
def test_rel_property_syntax_error_snippet() -> None:
query = "CREATE (a:User), (b:User), (a)-[:LINK {weight0.5}]->(b)"
with pytest.raises(ValueError, match=r"Property syntax error near: `\), \(a\)-\[:LINK {weight0.5}\]->\(b`."):
from_gql_create(query)
def test_unknown_node_alias() -> None:
query = "CREATE (a)-[:LINK {weight0.5}]->(b)"
with pytest.raises(
ValueError, match=r"Relationship references unknown node alias: 'a' near: `\(a\)-\[:LINK {weig`"
):
from_gql_create(query)
def test_no_create_keyword() -> None:
query = "(a:User {y:4})"
with pytest.raises(ValueError, match=r"Query must begin with 'CREATE' \(case insensitive\)."):
from_gql_create(query)
def test_illegal_node_x() -> None:
query = "CREATE (a:User {x:'tennis'})"
with pytest.raises(
ValueError,
match="Error for node property 'x' with provided input 'tennis'. Reason: Input should be a valid integer, unable to parse string as an integer",
):
from_gql_create(query)
def test_illegal_node_size() -> None:
query = "CREATE (a:User {hello: 'tennis'})"
with pytest.raises(
ValueError,
match="Error for node property 'hello' with provided input 'tennis'",
):
from_gql_create(query, size_property="hello")
def test_illegal_rel_caption_size() -> None:
query = "CREATE ()-[:LINK {caption_size: -42}]->()"
with pytest.raises(
ValueError,
match="Error for relationship property 'caption_size' with provided input '-42'. Reason: Input should be greater than 0",
):
from_gql_create(query)