diff --git a/tests/integration/io/__init__.py b/tests/integration/io/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/integration/test_graph_types.py b/tests/integration/test_graph_types.py deleted file mode 100644 index 33949ba33..000000000 --- a/tests/integration/test_graph_types.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- - -# Copyright (c) "Neo4j" -# Neo4j Sweden AB [http://neo4j.com] -# -# This file is part of Neo4j. -# -# 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. - - -from neo4j.graph import ( - Node, - Relationship, - Path, -) - - -def test_node(cypher_eval): - a = cypher_eval("CREATE (a:Person {name:'Alice'}) " - "RETURN a") - assert isinstance(a, Node) - assert set(a.labels) == {"Person"} - assert dict(a) == {"name": "Alice"} - - -def test_relationship(cypher_eval): - a, b, r = cypher_eval("CREATE (a)-[r:KNOWS {since:1999}]->(b) " - "RETURN [a, b, r]") - assert isinstance(r, Relationship) - assert r.type == "KNOWS" - assert dict(r) == {"since": 1999} - assert r.start_node == a - assert r.end_node == b - - -def test_path(cypher_eval): - a, b, c, ab, bc, p = cypher_eval("CREATE p=(a)-[ab:X]->(b)-[bc:X]->(c) " - "RETURN [a, b, c, ab, bc, p]") - assert isinstance(p, Path) - assert len(p) == 2 - assert p.nodes == (a, b, c) - assert p.relationships == (ab, bc) - assert p.start_node == a - assert p.end_node == c diff --git a/tests/integration/test_neo4j_driver.py b/tests/integration/test_neo4j_driver.py index 4be1a2e15..805e03dee 100644 --- a/tests/integration/test_neo4j_driver.py +++ b/tests/integration/test_neo4j_driver.py @@ -45,126 +45,6 @@ # python -m pytest tests/integration/test_neo4j_driver.py -s -v -def test_neo4j_uri(neo4j_uri, auth, target): - # python -m pytest tests/integration/test_neo4j_driver.py -s -v -k test_neo4j_uri - try: - with GraphDatabase.driver(neo4j_uri, auth=auth) as driver: - with driver.session() as session: - value = session.run("RETURN 1").single().value() - assert value == 1 - except ServiceUnavailable as error: - if error.args[0] == "Server does not support routing": - # This is because a single instance Neo4j 3.5 does not have dbms.routing.cluster.getRoutingTable() call - pytest.skip(error.args[0]) - elif isinstance(error.__cause__, BoltHandshakeError): - pytest.skip(error.args[0]) - - -def test_supports_multi_db(neo4j_driver, requires_bolt_4x): - # python -m pytest tests/integration/test_neo4j_driver.py -s -v -k test_supports_multi_db - assert neo4j_driver.supports_multi_db() - - -def test_test_multi_db_specify_database(neo4j_uri, auth, target): - # python -m pytest tests/integration/test_neo4j_driver.py -s -v -k test_test_multi_db_specify_database - try: - with GraphDatabase.driver(neo4j_uri, auth=auth, database="test_database") as driver: - with driver.session() as session: - result = session.run("RETURN 1") - assert next(result) == 1 - summary = result.consume() - assert summary.database == "test_database" - except ServiceUnavailable as error: - if isinstance(error.__cause__, BoltHandshakeError): - pytest.skip(error.args[0]) - except ConfigurationError as error: - assert "Database name parameter for selecting database is not supported in Bolt Protocol Version(3, 0)." in error.args[0] - except ClientError as error: - # FAILURE {'code': 'Neo.ClientError.Database.DatabaseNotFound' - This message is sent from the server - assert error.code == "Neo.ClientError.Database.DatabaseNotFound" - assert "test_database" in error.message - - -def test_neo4j_multi_database_support_create(neo4j_uri, auth, target, requires_bolt_4x): - # python -m pytest tests/integration/test_neo4j_driver.py -s -v -k test_neo4j_multi_database_support_create - with GraphDatabase.driver(neo4j_uri, auth=auth) as driver: - with driver.session(database="system") as session: - session.run("DROP DATABASE test IF EXISTS").consume() - result = session.run("SHOW DATABASES") - databases = set() - for record in result: - databases.add(record.get("name")) - assert "system" in databases - assert "neo4j" in databases - - session.run("CREATE DATABASE test").consume() - result = session.run("SHOW DATABASES") - for record in result: - databases.add(record.get("name")) - assert "system" in databases - assert "neo4j" in databases - assert "test" in databases - with driver.session(database="system") as session: - session.run("DROP DATABASE test IF EXISTS").consume() - - -def test_neo4j_multi_database_support_different(neo4j_uri, auth, target, requires_bolt_4x): - # python -m pytest tests/integration/test_neo4j_driver.py -s -v -k test_neo4j_multi_database_support_different - with GraphDatabase.driver(neo4j_uri, auth=auth) as driver: - with driver.session() as session: - # Test that default database is empty - session.run("MATCH (n) DETACH DELETE n").consume() - result = session.run("MATCH (p:Person) RETURN p") - names = set() - for ix in result: - names.add(ix["p"].get("name")) - assert names == set() # THIS FAILS? - with driver.session(database="system") as session: - session.run("DROP DATABASE testa IF EXISTS").consume() - session.run("DROP DATABASE testb IF EXISTS").consume() - with driver.session(database="system") as session: - result = session.run("SHOW DATABASES") - databases = set() - for record in result: - databases.add(record.get("name")) - assert databases == {"system", "neo4j"} - result = session.run("CREATE DATABASE testa") - result.consume() - result = session.run("CREATE DATABASE testb") - result.consume() - with driver.session(database="testa") as session: - result = session.run('CREATE (p:Person {name: "ALICE"})') - result.consume() - with driver.session(database="testb") as session: - result = session.run('CREATE (p:Person {name: "BOB"})') - result.consume() - with driver.session() as session: - # Test that default database is still empty - result = session.run("MATCH (p:Person) RETURN p") - names = set() - for ix in result: - names.add(ix["p"].get("name")) - assert names == set() # THIS FAILS? - with driver.session(database="testa") as session: - result = session.run("MATCH (p:Person) RETURN p") - names = set() - for ix in result: - names.add(ix["p"].get("name")) - assert names == {"ALICE", } - with driver.session(database="testb") as session: - result = session.run("MATCH (p:Person) RETURN p") - names = set() - for ix in result: - names.add(ix["p"].get("name")) - assert names == {"BOB", } - with driver.session(database="system") as session: - session.run("DROP DATABASE testa IF EXISTS").consume() - with driver.session(database="system") as session: - session.run("DROP DATABASE testb IF EXISTS").consume() - with driver.session() as session: - session.run("MATCH (n) DETACH DELETE n").consume() - - def test_neo4j_multi_database_test_routing_table_creates_new_if_deleted(neo4j_uri, auth, target, requires_bolt_4x): # python -m pytest tests/integration/test_neo4j_driver.py -s -v -k test_neo4j_multi_database_test_routing_table_creates_new_if_deleted with GraphDatabase.driver(neo4j_uri, auth=auth) as driver: diff --git a/tests/unit/test_types.py b/tests/unit/test_types.py index 68c0473a1..c24543165 100644 --- a/tests/unit/test_types.py +++ b/tests/unit/test_types.py @@ -18,8 +18,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +from itertools import product -from unittest import TestCase +import pytest from neo4j.data import DataHydrator from neo4j.graph import ( @@ -39,14 +40,20 @@ def test_can_create_node(): g = Graph() gh = Graph.Hydrator(g) - alice = gh.hydrate_node(1, {"Person"}, {"name": "Alice", "age": 33}) + alice = gh.hydrate_node(123, {"Person"}, {"name": "Alice", "age": 33}) assert isinstance(alice, Node) + assert alice.id == 123 assert alice.labels == {"Person"} assert set(alice.keys()) == {"name", "age"} assert set(alice.values()) == {"Alice", 33} assert set(alice.items()) == {("name", "Alice"), ("age", 33)} + assert dict(alice) == {"name": "Alice", "age": 33} assert alice.get("name") == "Alice" assert alice.get("age") == 33 + assert alice.get("unknown") is None + assert alice.get("unknown", None) is None + assert alice.get("unknown", False) is False + assert alice.get("unknown", "default") == "default" assert len(alice) == 2 assert alice["name"] == "Alice" assert alice["age"] == 33 @@ -55,10 +62,11 @@ def test_can_create_node(): assert set(iter(alice)) == {"name", "age"} -def test_null_properties(): +def test_node_with_null_properties(): g = Graph() gh = Graph.Hydrator(g) - stuff = gh.hydrate_node(1, (), {"good": ["puppies", "kittens"], "bad": None}) + stuff = gh.hydrate_node(1, (), {"good": ["puppies", "kittens"], + "bad": None}) assert isinstance(stuff, Node) assert set(stuff.keys()) == {"good"} assert stuff.get("good") == ["puppies", "kittens"] @@ -70,13 +78,26 @@ def test_null_properties(): assert "bad" not in stuff -def test_node_equality(): - g = Graph() - node_1 = Node(g, 1234) - node_2 = Node(g, 1234) - node_3 = Node(g, 5678) - assert node_1 == node_2 - assert node_1 != node_3 +@pytest.mark.parametrize(("g1", "id1", "props1", "g2", "id2", "props2"), ( + (*n1, *n2) + for n1, n2 in product( + ( + (g, id_, props) + for g in (0, 1) + for id_ in (1, 1234) + for props in (None, {}, {"a": 1}) + ), + repeat=2 + ) +)) +def test_node_equality(g1, id1, props1, g2, id2, props2): + graphs = (Graph(), Graph()) + node_1 = Node(graphs[g1], id1, props1) + node_2 = Node(graphs[g2], id2, props2) + if g1 == g2 and id1 == id2: + assert node_1 == node_2 + else: + assert node_1 != node_2 assert node_1 != "this is not a node" @@ -109,6 +130,7 @@ def test_can_create_relationship(): assert alice_knows_bob.start_node == alice assert alice_knows_bob.type == "KNOWS" assert alice_knows_bob.end_node == bob + assert dict(alice_knows_bob) == {"since": 1999} assert set(alice_knows_bob.keys()) == {"since"} assert set(alice_knows_bob.values()) == {1999} assert set(alice_knows_bob.items()) == {("since", 1999)} @@ -133,32 +155,41 @@ def test_can_create_path(): alice = gh.hydrate_node(1, {"Person"}, {"name": "Alice", "age": 33}) bob = gh.hydrate_node(2, {"Person"}, {"name": "Bob", "age": 44}) carol = gh.hydrate_node(3, {"Person"}, {"name": "Carol", "age": 55}) - alice_knows_bob = gh.hydrate_relationship(1, alice.id, bob.id, "KNOWS", {"since": 1999}) - carol_dislikes_bob = gh.hydrate_relationship(2, carol.id, bob.id, "DISLIKES", {}) + alice_knows_bob = gh.hydrate_relationship(1, alice.id, bob.id, "KNOWS", + {"since": 1999}) + carol_dislikes_bob = gh.hydrate_relationship(2, carol.id, bob.id, + "DISLIKES", {}) path = Path(alice, alice_knows_bob, carol_dislikes_bob) assert isinstance(path, Path) - assert path.start_node == alice - assert path.end_node == carol + assert path.start_node is alice + assert path.end_node is carol assert path.nodes == (alice, bob, carol) assert path.relationships == (alice_knows_bob, carol_dislikes_bob) assert list(path) == [alice_knows_bob, carol_dislikes_bob] -def test_can_hydrate_path(): +@pytest.mark.parametrize("cyclic", (True, False)) +def test_can_hydrate_path(cyclic): g = Graph() gh = Graph.Hydrator(g) alice = gh.hydrate_node(1, {"Person"}, {"name": "Alice", "age": 33}) bob = gh.hydrate_node(2, {"Person"}, {"name": "Bob", "age": 44}) - carol = gh.hydrate_node(3, {"Person"}, {"name": "Carol", "age": 55}) + if cyclic: + carol = alice + else: + carol = gh.hydrate_node(3, {"Person"}, {"name": "Carol", "age": 55}) r = [gh.hydrate_unbound_relationship(1, "KNOWS", {"since": 1999}), gh.hydrate_unbound_relationship(2, "DISLIKES", {})] path = gh.hydrate_path([alice, bob, carol], r, [1, 1, -2, 2]) - assert path.start_node == alice - assert path.end_node == carol + assert path.start_node is alice + assert path.end_node is carol assert path.nodes == (alice, bob, carol) - expected_alice_knows_bob = gh.hydrate_relationship(1, alice.id, bob.id, "KNOWS", {"since": 1999}) - expected_carol_dislikes_bob = gh.hydrate_relationship(2, carol.id, bob.id, "DISLIKES", {}) - assert path.relationships == (expected_alice_knows_bob, expected_carol_dislikes_bob) + expected_alice_knows_bob = gh.hydrate_relationship(1, alice.id, bob.id, + "KNOWS", {"since": 1999}) + expected_carol_dislikes_bob = gh.hydrate_relationship(2, carol.id, bob.id, + "DISLIKES", {}) + assert path.relationships == (expected_alice_knows_bob, + expected_carol_dislikes_bob) assert list(path) == [expected_alice_knows_bob, expected_carol_dislikes_bob]