Skip to content

Commit

Permalink
Reduce dependency to mocks for tests (#70)
Browse files Browse the repository at this point in the history
* useful to test node accessors with something different than
  node_ids or node_ids list
  • Loading branch information
tomdele committed Jul 7, 2020
1 parent f90fc4f commit 8903edf
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 49 deletions.
28 changes: 13 additions & 15 deletions tests/test_edges.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
from bluepysnap.bbp import Synapse
from bluepysnap.exceptions import BluepySnapError
from bluepysnap.sonata_constants import Edge
from bluepysnap.node_sets import NodeSets

import bluepysnap.edges as test_module

from utils import TEST_DATA_DIR
from utils import TEST_DATA_DIR, create_node_population


def index_as_uint64(values):
Expand Down Expand Up @@ -74,27 +75,24 @@ def test_population(self):
class TestEdgePopulation(object):

@staticmethod
def mocking_nodes(pop_name):
node_population = Mock()
node_population.name = pop_name
node_population.ids = lambda x: x
return node_population

@staticmethod
def create_population(filepath, pop_name):
def create_edge_population(filepath, pop_name):
config = {
'edges_file': filepath,
'edge_types_file': None,
}
node_population = TestEdgePopulation.mocking_nodes("default")
circuit = Mock()
circuit.nodes = {node_population.name: node_population}

create_node_population(str(TEST_DATA_DIR / 'nodes.h5'), "default", circuit=circuit,
node_sets=NodeSets(str(TEST_DATA_DIR / 'node_sets.json')))
storage = test_module.EdgeStorage(config, circuit)
return storage.population(pop_name)
pop = storage.population(pop_name)

# check if the source and target populations are in the circuit nodes
assert pop.source.name in pop._edge_storage.circuit.nodes
assert pop.target.name in pop._edge_storage.circuit.nodes
return pop

def setup(self):
self.test_obj = TestEdgePopulation.create_population(
self.test_obj = TestEdgePopulation.create_edge_population(
str(TEST_DATA_DIR / "edges.h5"), 'default')

def test_basic(self):
Expand Down Expand Up @@ -447,7 +445,7 @@ def test_iter_connections_10(self):
)

def test_iter_connection_unique(self):
test_obj = TestEdgePopulation.create_population(
test_obj = TestEdgePopulation.create_edge_population(
str(TEST_DATA_DIR / "edges_complete_graph.h5"), 'default')
it = test_obj.iter_connections([0, 1, 2], [0, 1, 2])
assert sorted(it) == [(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)]
Expand Down
15 changes: 3 additions & 12 deletions tests/test_morph.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,13 @@
from bluepysnap.sonata_constants import Node
from bluepysnap.exceptions import BluepySnapError

from utils import TEST_DATA_DIR, copy_circuit, edit_config
from utils import TEST_DATA_DIR, copy_circuit, edit_config, create_node_population


class TestMorphHelper(object):

@staticmethod
def create_population(filepath, pop_name):
config = {
'nodes_file': filepath,
'node_types_file': None,
}
circuit = Mock()
return NodeStorage(config, circuit).population(pop_name)

def setup(self):
self.nodes = self.create_population(
self.nodes = create_node_population(
str(TEST_DATA_DIR / 'nodes_quaternions.h5'),
"default")
self.morph_path = TEST_DATA_DIR / 'morphologies'
Expand Down Expand Up @@ -118,7 +109,7 @@ def test_get_morphology_simple_rotation(self):
npt.assert_almost_equal(expected, actual[:2])

def test_get_morphology_standard_rotation(self):
nodes = self.create_population(
nodes = create_node_population(
str(TEST_DATA_DIR / 'nodes.h5'),
"default")
test_obj = test_module.MorphHelper(str(self.morph_path), nodes)
Expand Down
33 changes: 11 additions & 22 deletions tests/test_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

import bluepysnap.nodes as test_module

from utils import TEST_DATA_DIR
from utils import TEST_DATA_DIR, create_node_population


class TestNodeStorage:
Expand Down Expand Up @@ -57,21 +57,10 @@ def test_load_population_data(self):

class TestNodePopulation:

@staticmethod
def create_population(filepath, pop_name):
config = {
'nodes_file': filepath,
'node_types_file': None,
}
circuit = Mock()
circuit.node_sets = NodeSets(str(TEST_DATA_DIR / 'node_sets.json'))
storage = test_module.NodeStorage(config, circuit)
return storage.population(pop_name)

def setup(self):
self.test_obj = TestNodePopulation.create_population(
str(TEST_DATA_DIR / 'nodes.h5'),
"default")
self.test_obj = create_node_population(
str(TEST_DATA_DIR / 'nodes.h5'), "default",
node_sets=NodeSets(str(TEST_DATA_DIR / 'node_sets.json')))

def test_basic(self):
assert self.test_obj._node_storage._h5_filepath == str(TEST_DATA_DIR / 'nodes.h5')
Expand Down Expand Up @@ -106,7 +95,7 @@ def test_property_values(self):
self.test_obj.property_values(Cell.MORPHOLOGY) ==
{'morph-A', 'morph-B', 'morph-C'}
)
test_obj_library = TestNodePopulation.create_population(
test_obj_library = create_node_population(
str(TEST_DATA_DIR / 'nodes_with_library.h5'),
"default")
assert test_obj_library.property_values("categorical") == {"A", "B", "C"}
Expand Down Expand Up @@ -235,7 +224,7 @@ def test_ids(self):
_call({'no-such-node-property': 42})

def test_node_ids_by_filter_complex_query(self):
test_obj = TestNodePopulation.create_population(str(TEST_DATA_DIR / 'nodes.h5'), "default")
test_obj = create_node_population(str(TEST_DATA_DIR / 'nodes.h5'), "default")
data = pd.DataFrame({
Cell.MTYPE: ['L23_MC', 'L4_BP', 'L6_BP', 'L6_BPC'],
})
Expand Down Expand Up @@ -306,7 +295,7 @@ def test_get(self):
_call([0, 999]) # one of node ids is invalid

def test_get_with_library(self):
test_obj = TestNodePopulation.create_population(
test_obj = create_node_population(
str(TEST_DATA_DIR / 'nodes_with_library.h5'),
"default")
assert test_obj.property_names == {"categorical", "string", "int", "float"}
Expand Down Expand Up @@ -370,7 +359,7 @@ def test_orientations(self):
)

# NodePopulation without rotation_angle[x|z]
_call_no_xz = TestNodePopulation.create_population(
_call_no_xz = create_node_population(
str(TEST_DATA_DIR / 'nodes_no_xz_rotation.h5'),
"default").orientations
# 0 and 2 node_ids have x|z rotation angles equal to zero
Expand All @@ -387,7 +376,7 @@ def test_orientations(self):
)

# NodePopulation without rotation_angle
_call_no_rot = TestNodePopulation.create_population(
_call_no_rot = create_node_population(
str(TEST_DATA_DIR / 'nodes_no_rotation.h5'),
"default").orientations

Expand All @@ -401,7 +390,7 @@ def test_orientations(self):
)

# NodePopulation with quaternions
_call_quat = TestNodePopulation.create_population(
_call_quat = create_node_population(
str(TEST_DATA_DIR / 'nodes_quaternions.h5'),
"default").orientations

Expand Down Expand Up @@ -444,7 +433,7 @@ def test_orientations(self):
)
)

_call_missing_quat = TestNodePopulation.create_population(
_call_missing_quat = create_node_population(
str(TEST_DATA_DIR / 'nodes_quaternions_w_missing.h5'),
"default").orientations

Expand Down
30 changes: 30 additions & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import tempfile
import json
import six
import mock
from contextlib import contextmanager
from distutils.dir_util import copy_tree

Expand All @@ -12,6 +13,9 @@
except ImportError:
from pathlib2 import Path

from bluepysnap.nodes import NodeStorage


TEST_DIR = Path(__file__).resolve().parent
TEST_DATA_DIR = TEST_DIR / 'data'

Expand Down Expand Up @@ -59,3 +63,29 @@ def edit_config(config_path):
finally:
with config_path.open('w') as f:
f.write(six.u(json.dumps(config)))


def create_node_population(filepath, pop_name, circuit=None, node_sets=None):
"""Creates a node population.
Args:
filepath (str): path to the node file.
pop_name (str): population name inside the file.
circuit (Mock/Circuit): either a real circuit or a Mock containing the nodes.
node_sets: (Mock/NodeSets): either a real node_sets or a mocked node_sets.
Returns:
NodePopulation: return a node population.
"""
config = {
'nodes_file': filepath,
'node_types_file': None,
}
if circuit is None:
circuit = mock.Mock()
if node_sets is not None:
circuit.node_sets = node_sets
node_pop = NodeStorage(config, circuit).population(pop_name)
if isinstance(circuit.nodes, dict):
circuit.nodes[node_pop.name] = node_pop
else:
circuit.nodes = {node_pop.name: node_pop}
return node_pop

0 comments on commit 8903edf

Please sign in to comment.