memgraph/tck_engine/tests/openCypher_M05/tck/features/FunctionsAcceptance.feature
2017-03-14 12:52:32 +00:00

488 lines
12 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: FunctionsAcceptance
Scenario: Run coalesce
Given an empty graph
And having executed:
"""
CREATE ({name: 'Emil Eifrem', title: 'CEO'}), ({name: 'Nobody'})
"""
When executing query:
"""
MATCH (a)
RETURN coalesce(a.title, a.name)
"""
Then the result should be:
| coalesce(a.title, a.name) |
| 'CEO' |
| 'Nobody' |
And no side effects
Scenario: Functions should return null if they get path containing unbound
Given any graph
When executing query:
"""
WITH null AS a
OPTIONAL MATCH p = (a)-[r]->()
RETURN length(nodes(p)), type(r), nodes(p), relationships(p)
"""
Then the result should be:
| length(nodes(p)) | type(r) | nodes(p) | relationships(p) |
| null | null | null | null |
And no side effects
Scenario: `split()`
Given any graph
When executing query:
"""
UNWIND split('one1two', '1') AS item
RETURN count(item) AS item
"""
Then the result should be:
| item |
| 2 |
And no side effects
Scenario: `properties()` on a node
Given an empty graph
And having executed:
"""
CREATE (n:Person {name: 'Popeye', level: 9001})
"""
When executing query:
"""
MATCH (p:Person)
RETURN properties(p) AS m
"""
Then the result should be:
| m |
| {name: 'Popeye', level: 9001} |
And no side effects
Scenario: `properties()` on a relationship
Given an empty graph
And having executed:
"""
CREATE (n)-[:R {name: 'Popeye', level: 9001}]->(n)
"""
When executing query:
"""
MATCH ()-[r:R]->()
RETURN properties(r) AS m
"""
Then the result should be:
| m |
| {name: 'Popeye', level: 9001} |
And no side effects
Scenario: `properties()` on a map
Given any graph
When executing query:
"""
RETURN properties({name: 'Popeye', level: 9001}) AS m
"""
Then the result should be:
| m |
| {name: 'Popeye', level: 9001} |
And no side effects
Scenario: `properties()` failing on an integer literal
Given any graph
When executing query:
"""
RETURN properties(1)
"""
Then a SyntaxError should be raised at compile time: InvalidArgumentType
Scenario: `properties()` failing on a string literal
Given any graph
When executing query:
"""
RETURN properties('Cypher')
"""
Then a SyntaxError should be raised at compile time: InvalidArgumentType
Scenario: `properties()` failing on a list of booleans
Given any graph
When executing query:
"""
RETURN properties([true, false])
"""
Then a SyntaxError should be raised at compile time: InvalidArgumentType
Scenario: `properties()` on null
Given any graph
When executing query:
"""
RETURN properties(null)
"""
Then the result should be:
| properties(null) |
| null |
And no side effects
Scenario: `reverse()`
Given any graph
When executing query:
"""
RETURN reverse('raksO')
"""
Then the result should be:
| reverse('raksO') |
| 'Oskar' |
And no side effects
Scenario: `exists()` with dynamic property lookup
Given an empty graph
And having executed:
"""
CREATE (:Person {prop: 'foo'}),
(:Person)
"""
When executing query:
"""
MATCH (n:Person)
WHERE exists(n['prop'])
RETURN n
"""
Then the result should be:
| n |
| (:Person {prop: 'foo'}) |
And no side effects
Scenario Outline: `exists()` with literal maps
Given any graph
When executing query:
"""
WITH <map> AS map
RETURN exists(map.name) AS exists
"""
Then the result should be:
| exists |
| <result> |
And no side effects
Examples:
| map | result |
| {name: 'Mats', name2: 'Pontus'} | true |
| {name: null} | false |
| {notName: 0, notName2: null} | false |
Scenario Outline: IS NOT NULL with literal maps
Given any graph
When executing query:
"""
WITH <map> AS map
RETURN map.name IS NOT NULL
"""
Then the result should be:
| map.name IS NOT NULL |
| <result> |
And no side effects
Examples:
| map | result |
| {name: 'Mats', name2: 'Pontus'} | true |
| {name: null} | false |
| {notName: 0, notName2: null} | false |
Scenario Outline: `percentileDisc()`
Given an empty graph
And having executed:
"""
CREATE ({prop: 10.0}),
({prop: 20.0}),
({prop: 30.0})
"""
And parameters are:
| params | p |
| percentile | <p> |
When executing query:
"""
MATCH (n)
RETURN percentileDisc(n.prop, $percentile) AS p
"""
Then the result should be:
| p |
| <result> |
And no side effects
Examples:
| p | result |
| 0.0 | 10.0 |
| 0.5 | 20.0 |
| 1.0 | 30.0 |
Scenario Outline: `percentileCont()`
Given an empty graph
And having executed:
"""
CREATE ({prop: 10.0}),
({prop: 20.0}),
({prop: 30.0})
"""
And parameters are:
| params | p |
| percentile | <p> |
When executing query:
"""
MATCH (n)
RETURN percentileCont(n.prop, $percentile) AS p
"""
Then the result should be:
| p |
| <result> |
And no side effects
Examples:
| p | result |
| 0.0 | 10.0 |
| 0.5 | 20.0 |
| 1.0 | 30.0 |
Scenario Outline: `percentileCont()` failing on bad arguments
Given an empty graph
And having executed:
"""
CREATE ({prop: 10.0})
"""
And parameters are:
| param | <percentile> |
When executing query:
"""
MATCH (n)
RETURN percentileCont(n.prop, $param)
"""
Then a ArgumentError should be raised at runtime: NumberOutOfRange
Examples:
| percentile |
| 1000 |
| -1 |
| 1.1 |
Scenario Outline: `percentileDisc()` failing on bad arguments
Given an empty graph
And having executed:
"""
CREATE ({prop: 10.0})
"""
And parameters are:
| param | <percentile> |
When executing query:
"""
MATCH (n)
RETURN percentileDisc(n.prop, $param)
"""
Then a ArgumentError should be raised at runtime: NumberOutOfRange
Examples:
| percentile |
| 1000 |
| -1 |
| 1.1 |
Scenario: `percentileDisc()` failing in more involved query
Given an empty graph
And having executed:
"""
UNWIND range(0, 10) AS i
CREATE (s:S)
WITH s, i
UNWIND range(0, i) AS j
CREATE (s)-[:REL]->()
"""
When executing query:
"""
MATCH (n:S)
WITH n, size([(n)-->() | 1]) AS deg
WHERE deg > 2
WITH deg
LIMIT 100
RETURN percentileDisc(0.90, deg), deg
"""
Then a ArgumentError should be raised at runtime: NumberOutOfRange
Scenario: `type()`
Given an empty graph
And having executed:
"""
CREATE ()-[:T]->()
"""
When executing query:
"""
MATCH ()-[r]->()
RETURN type(r)
"""
Then the result should be:
| type(r) |
| 'T' |
And no side effects
Scenario: `type()` on two relationships
Given an empty graph
And having executed:
"""
CREATE ()-[:T1]->()-[:T2]->()
"""
When executing query:
"""
MATCH ()-[r1]->()-[r2]->()
RETURN type(r1), type(r2)
"""
Then the result should be:
| type(r1) | type(r2) |
| 'T1' | 'T2' |
And no side effects
Scenario: `type()` on null relationship
Given an empty graph
And having executed:
"""
CREATE ()
"""
When executing query:
"""
MATCH (a)
OPTIONAL MATCH (a)-[r:NOT_THERE]->()
RETURN type(r)
"""
Then the result should be:
| type(r) |
| null |
And no side effects
Scenario: `type()` on mixed null and non-null relationships
Given an empty graph
And having executed:
"""
CREATE ()-[:T]->()
"""
When executing query:
"""
MATCH (a)
OPTIONAL MATCH (a)-[r:T]->()
RETURN type(r)
"""
Then the result should be:
| type(r) |
| 'T' |
| null |
And no side effects
Scenario: `type()` handling Any type
Given an empty graph
And having executed:
"""
CREATE ()-[:T]->()
"""
When executing query:
"""
MATCH (a)-[r]->()
WITH [r, 1] AS list
RETURN type(list[0])
"""
Then the result should be:
| type(list[0]) |
| 'T' |
And no side effects
Scenario Outline: `type()` failing on invalid arguments
Given an empty graph
And having executed:
"""
CREATE ()-[:T]->()
"""
When executing query:
"""
MATCH p = (n)-[r:T]->()
RETURN [x IN [r, <invalid>] | type(x) ] AS list
"""
Then a TypeError should be raised at runtime: InvalidArgumentValue
Examples:
| invalid |
| 0 |
| 1.0 |
| true |
| '' |
| [] |
Scenario: `labels()` should accept type Any
Given an empty graph
And having executed:
"""
CREATE (:Foo), (:Foo:Bar)
"""
When executing query:
"""
MATCH (a)
WITH [a, 1] AS list
RETURN labels(list[0]) AS l
"""
Then the result should be (ignoring element order for lists):
| l |
| ['Foo'] |
| ['Foo', 'Bar'] |
And no side effects
Scenario: `labels()` should accept type Any
Given an empty graph
And having executed:
"""
CREATE (:Foo), (:Foo:Bar)
"""
When executing query:
"""
MATCH p = (a)
RETURN labels(p) AS l
"""
Then a SyntaxError should be raised at compile time: InvalidArgumentType
Scenario: `labels()` should accept type Any
Given an empty graph
And having executed:
"""
CREATE (:Foo), (:Foo:Bar)
"""
When executing query:
"""
MATCH (a)
WITH [a, 1] AS list
RETURN labels(list[1]) AS l
"""
Then a TypeError should be raised at runtime: InvalidArgumentValue
Scenario: `exists()` is case insensitive
Given an empty graph
And having executed:
"""
CREATE (a:X {prop: 42}), (:X)
"""
When executing query:
"""
MATCH (n:X)
RETURN n, EXIsTS(n.prop) AS b
"""
Then the result should be:
| n | b |
| (:X {prop: 42}) | true |
| (:X) | false |
And no side effects