304 lines
7.7 KiB
Gherkin
304 lines
7.7 KiB
Gherkin
|
#
|
||
|
# Copyright 2017 "Neo Technology",
|
||
|
# Network Engine for Objects in Lund AB (http://neotechnology.com)
|
||
|
#
|
||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
# you may not use this file except in compliance with the License.
|
||
|
# You may obtain a copy of the License at
|
||
|
#
|
||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||
|
#
|
||
|
# Unless required by applicable law or agreed to in writing, software
|
||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
# See the License for the specific language governing permissions and
|
||
|
# limitations under the License.
|
||
|
#
|
||
|
|
||
|
Feature: PatternComprehension
|
||
|
|
||
|
Scenario: Pattern comprehension and ORDER BY
|
||
|
Given an empty graph
|
||
|
And having executed:
|
||
|
"""
|
||
|
CREATE (a {time: 10}), (b {time: 20})
|
||
|
CREATE (a)-[:T]->(b)
|
||
|
"""
|
||
|
When executing query:
|
||
|
"""
|
||
|
MATCH (liker)
|
||
|
RETURN [p = (liker)--() | p] AS isNew
|
||
|
ORDER BY liker.time
|
||
|
"""
|
||
|
Then the result should be:
|
||
|
| isNew |
|
||
|
| [<({time: 10})-[:T]->({time: 20})>] |
|
||
|
| [<({time: 20})<-[:T]-({time: 10})>] |
|
||
|
And no side effects
|
||
|
|
||
|
Scenario: Returning a pattern comprehension
|
||
|
Given an empty graph
|
||
|
And having executed:
|
||
|
"""
|
||
|
CREATE (a:A)
|
||
|
CREATE (a)-[:T]->(:B),
|
||
|
(a)-[:T]->(:C)
|
||
|
"""
|
||
|
When executing query:
|
||
|
"""
|
||
|
MATCH (n)
|
||
|
RETURN [p = (n)-->() | p] AS ps
|
||
|
"""
|
||
|
Then the result should be (ignoring element order for lists):
|
||
|
| ps |
|
||
|
| [<(:A)-[:T]->(:C)>, <(:A)-[:T]->(:B)>] |
|
||
|
| [] |
|
||
|
| [] |
|
||
|
And no side effects
|
||
|
|
||
|
Scenario: Returning a pattern comprehension with label predicate
|
||
|
Given an empty graph
|
||
|
And having executed:
|
||
|
"""
|
||
|
CREATE (a:A), (b:B), (c:C), (d:D)
|
||
|
CREATE (a)-[:T]->(b),
|
||
|
(a)-[:T]->(c),
|
||
|
(a)-[:T]->(d)
|
||
|
"""
|
||
|
When executing query:
|
||
|
"""
|
||
|
MATCH (n:A)
|
||
|
RETURN [p = (n)-->(:B) | p] AS x
|
||
|
"""
|
||
|
Then the result should be:
|
||
|
|
||
|
| x |
|
||
|
| [<(:A)-[:T]->(:B)>] |
|
||
|
And no side effects
|
||
|
|
||
|
Scenario: Returning a pattern comprehension with bound nodes
|
||
|
Given an empty graph
|
||
|
And having executed:
|
||
|
"""
|
||
|
CREATE (a:A), (b:B)
|
||
|
CREATE (a)-[:T]->(b)
|
||
|
"""
|
||
|
When executing query:
|
||
|
"""
|
||
|
MATCH (a:A), (b:B)
|
||
|
RETURN [p = (a)-[*]->(b) | p] AS paths
|
||
|
"""
|
||
|
Then the result should be:
|
||
|
| paths |
|
||
|
| [<(:A)-[:T]->(:B)>] |
|
||
|
And no side effects
|
||
|
|
||
|
Scenario: Using a pattern comprehension in a WITH
|
||
|
Given an empty graph
|
||
|
And having executed:
|
||
|
"""
|
||
|
CREATE (a:A)
|
||
|
CREATE (a)-[:T]->(:B),
|
||
|
(a)-[:T]->(:C)
|
||
|
"""
|
||
|
When executing query:
|
||
|
"""
|
||
|
MATCH (n)-->(b)
|
||
|
WITH [p = (n)-->() | p] AS ps, count(b) AS c
|
||
|
RETURN ps, c
|
||
|
"""
|
||
|
Then the result should be (ignoring element order for lists):
|
||
|
| ps | c |
|
||
|
| [<(:A)-[:T]->(:C)>, <(:A)-[:T]->(:B)>] | 2 |
|
||
|
And no side effects
|
||
|
|
||
|
Scenario: Using a variable-length pattern comprehension in a WITH
|
||
|
Given an empty graph
|
||
|
And having executed:
|
||
|
"""
|
||
|
CREATE (:A)-[:T]->(:B)
|
||
|
"""
|
||
|
When executing query:
|
||
|
"""
|
||
|
MATCH (a:A), (b:B)
|
||
|
WITH [p = (a)-[*]->(b) | p] AS paths, count(a) AS c
|
||
|
RETURN paths, c
|
||
|
"""
|
||
|
Then the result should be:
|
||
|
| paths | c |
|
||
|
| [<(:A)-[:T]->(:B)>] | 1 |
|
||
|
And no side effects
|
||
|
|
||
|
Scenario: Using pattern comprehension in RETURN
|
||
|
Given an empty graph
|
||
|
And having executed:
|
||
|
"""
|
||
|
CREATE (a:A), (:A), (:A)
|
||
|
CREATE (a)-[:HAS]->()
|
||
|
"""
|
||
|
When executing query:
|
||
|
"""
|
||
|
MATCH (n:A)
|
||
|
RETURN [p = (n)-[:HAS]->() | p] AS ps
|
||
|
"""
|
||
|
Then the result should be:
|
||
|
| ps |
|
||
|
| [<(:A)-[:HAS]->()>] |
|
||
|
| [] |
|
||
|
| [] |
|
||
|
And no side effects
|
||
|
|
||
|
Scenario: Aggregating on pattern comprehension
|
||
|
Given an empty graph
|
||
|
And having executed:
|
||
|
"""
|
||
|
CREATE (a:A), (:A), (:A)
|
||
|
CREATE (a)-[:HAS]->()
|
||
|
"""
|
||
|
When executing query:
|
||
|
"""
|
||
|
MATCH (n:A)
|
||
|
RETURN count([p = (n)-[:HAS]->() | p]) AS c
|
||
|
"""
|
||
|
Then the result should be:
|
||
|
| c |
|
||
|
| 3 |
|
||
|
And no side effects
|
||
|
|
||
|
Scenario: Using pattern comprehension to test existence
|
||
|
Given an empty graph
|
||
|
And having executed:
|
||
|
"""
|
||
|
CREATE (a:X {prop: 42}), (:X {prop: 43})
|
||
|
CREATE (a)-[:T]->()
|
||
|
"""
|
||
|
When executing query:
|
||
|
"""
|
||
|
MATCH (n:X)
|
||
|
RETURN n, size([(n)--() | 1]) > 0 AS b
|
||
|
"""
|
||
|
Then the result should be:
|
||
|
| n | b |
|
||
|
| (:X {prop: 42}) | true |
|
||
|
| (:X {prop: 43}) | false |
|
||
|
And no side effects
|
||
|
|
||
|
Scenario: Pattern comprehension inside list comprehension
|
||
|
Given an empty graph
|
||
|
And having executed:
|
||
|
"""
|
||
|
CREATE (n1:X {n: 1}), (m1:Y), (i1:Y), (i2:Y)
|
||
|
CREATE (n1)-[:T]->(m1),
|
||
|
(m1)-[:T]->(i1),
|
||
|
(m1)-[:T]->(i2)
|
||
|
CREATE (n2:X {n: 2}), (m2), (i3:L), (i4:Y)
|
||
|
CREATE (n2)-[:T]->(m2),
|
||
|
(m2)-[:T]->(i3),
|
||
|
(m2)-[:T]->(i4)
|
||
|
"""
|
||
|
When executing query:
|
||
|
"""
|
||
|
MATCH p = (n:X)-->(b)
|
||
|
RETURN n, [x IN nodes(p) | size([(x)-->(:Y) | 1])] AS list
|
||
|
"""
|
||
|
Then the result should be:
|
||
|
| n | list |
|
||
|
| (:X {n: 1}) | [1, 2] |
|
||
|
| (:X {n: 2}) | [0, 1] |
|
||
|
And no side effects
|
||
|
|
||
|
Scenario: Get node degree via size of pattern comprehension
|
||
|
Given an empty graph
|
||
|
And having executed:
|
||
|
"""
|
||
|
CREATE (x:X),
|
||
|
(x)-[:T]->(),
|
||
|
(x)-[:T]->(),
|
||
|
(x)-[:T]->()
|
||
|
"""
|
||
|
When executing query:
|
||
|
"""
|
||
|
MATCH (a:X)
|
||
|
RETURN size([(a)-->() | 1]) AS length
|
||
|
"""
|
||
|
Then the result should be:
|
||
|
| length |
|
||
|
| 3 |
|
||
|
And no side effects
|
||
|
|
||
|
Scenario: Get node degree via size of pattern comprehension that specifies a relationship type
|
||
|
Given an empty graph
|
||
|
And having executed:
|
||
|
"""
|
||
|
CREATE (x:X),
|
||
|
(x)-[:T]->(),
|
||
|
(x)-[:T]->(),
|
||
|
(x)-[:T]->(),
|
||
|
(x)-[:OTHER]->()
|
||
|
"""
|
||
|
When executing query:
|
||
|
"""
|
||
|
MATCH (a:X)
|
||
|
RETURN size([(a)-[:T]->() | 1]) AS length
|
||
|
"""
|
||
|
Then the result should be:
|
||
|
| length |
|
||
|
| 3 |
|
||
|
And no side effects
|
||
|
|
||
|
Scenario: Get node degree via size of pattern comprehension that specifies multiple relationship types
|
||
|
Given an empty graph
|
||
|
And having executed:
|
||
|
"""
|
||
|
CREATE (x:X),
|
||
|
(x)-[:T]->(),
|
||
|
(x)-[:T]->(),
|
||
|
(x)-[:T]->(),
|
||
|
(x)-[:OTHER]->()
|
||
|
"""
|
||
|
When executing query:
|
||
|
"""
|
||
|
MATCH (a:X)
|
||
|
RETURN size([(a)-[:T|OTHER]->() | 1]) AS length
|
||
|
"""
|
||
|
Then the result should be:
|
||
|
| length |
|
||
|
| 4 |
|
||
|
And no side effects
|
||
|
|
||
|
Scenario: Introducing new node variable in pattern comprehension
|
||
|
Given an empty graph
|
||
|
And having executed:
|
||
|
"""
|
||
|
CREATE (a), (b {prop: 'val'})
|
||
|
CREATE (a)-[:T]->(b)
|
||
|
"""
|
||
|
When executing query:
|
||
|
"""
|
||
|
MATCH (n)
|
||
|
RETURN [(n)-[:T]->(b) | b.prop] AS list
|
||
|
"""
|
||
|
Then the result should be:
|
||
|
| list |
|
||
|
| ['val'] |
|
||
|
| [] |
|
||
|
And no side effects
|
||
|
|
||
|
Scenario: Introducing new relationship variable in pattern comprehension
|
||
|
Given an empty graph
|
||
|
And having executed:
|
||
|
"""
|
||
|
CREATE (a), (b)
|
||
|
CREATE (a)-[:T {prop: 'val'}]->(b)
|
||
|
"""
|
||
|
When executing query:
|
||
|
"""
|
||
|
MATCH (n)
|
||
|
RETURN [(n)-[r:T]->() | r.prop] AS list
|
||
|
"""
|
||
|
Then the result should be:
|
||
|
| list |
|
||
|
| ['val'] |
|
||
|
| [] |
|
||
|
And no side effects
|