Skip to content

Commit c8f6173

Browse files
authored
Add testing for graph I/O (#57)
- Add testing for digraph I/O - Implement from multidigraph - Add testing for multidigraph I/O
1 parent 14fcdbe commit c8f6173

4 files changed

Lines changed: 46 additions & 8 deletions

File tree

src/semra/io/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""I/O functions for SeMRA."""
22

3-
from .graph import from_digraph, to_digraph, to_multidigraph
3+
from .graph import from_digraph, from_multidigraph, to_digraph, to_multidigraph
44
from .io import (
55
from_bioontologies,
66
from_cache_df,
@@ -21,6 +21,7 @@
2121
"from_cache_df",
2222
"from_digraph",
2323
"from_jsonl",
24+
"from_multidigraph",
2425
"from_pickle",
2526
"from_pyobo",
2627
"from_sssom",

src/semra/io/graph.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"DIGRAPH_DATA_KEY",
1515
"MULTIDIGRAPH_DATA_KEY",
1616
"from_digraph",
17+
"from_multidigraph",
1718
"to_digraph",
1819
"to_multidigraph",
1920
]
@@ -94,3 +95,11 @@ def to_multidigraph(mappings: t.Iterable[Mapping], *, progress: bool = False) ->
9495
**{MULTIDIGRAPH_DATA_KEY: mapping.evidence},
9596
)
9697
return graph
98+
99+
100+
def from_multidigraph(graph: nx.MultiDiGraph) -> list[Mapping]:
101+
"""Extract mappings from a multi-directed graph data model."""
102+
return [
103+
Mapping(s=s, p=p, o=o, evidence=data[MULTIDIGRAPH_DATA_KEY])
104+
for s, o, p, data in graph.edges(keys=True, data=True)
105+
]

src/semra/struct.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,9 @@ def key(self) -> StrTriple:
359359
"""Get a hashable key for the mapping, based on the subject, predicate, and object."""
360360
return triple_key(self.triple)
361361

362+
def __lt__(self, other: Mapping) -> bool:
363+
return self.triple < other.triple
364+
362365
@classmethod
363366
def from_triple(cls, triple: Triple, evidence: list[Evidence] | None = None) -> Mapping:
364367
"""Instantiate a mapping from a triple."""

tests/test_io.py

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,16 @@
99
import pandas as pd
1010

1111
from semra import Mapping, MappingSet, ReasonedEvidence, Reference, SimpleEvidence
12-
from semra.io import from_jsonl, from_pyobo, from_sssom_df, write_jsonl
12+
from semra.io import (
13+
from_digraph,
14+
from_jsonl,
15+
from_multidigraph,
16+
from_pyobo,
17+
from_sssom_df,
18+
to_digraph,
19+
to_multidigraph,
20+
write_jsonl,
21+
)
1322
from semra.rules import (
1423
BEN_ORCID,
1524
CHAIN_MAPPING,
@@ -44,7 +53,7 @@ def test_from_pyobo(self) -> None:
4453
self.assertEqual("mesh", mapping.o.prefix)
4554

4655

47-
class TestIO(unittest.TestCase):
56+
class TestSSSOM(unittest.TestCase):
4857
"""Tests for I/O functions."""
4958

5059
def test_from_sssom_df(self) -> None:
@@ -173,8 +182,12 @@ def test_from_sssom_df_with_license(self) -> None:
173182
)
174183
self.assertEqual(expected_mappings, actual_mappings)
175184

176-
def test_jsonl(self) -> None:
177-
"""Test JSONL I/O."""
185+
186+
class TestIO(unittest.TestCase):
187+
"""Test I/O funcitons."""
188+
189+
def setUp(self) -> None:
190+
"""Set up the test case."""
178191
r1 = Reference.from_curie("mesh:C406527", name="R 115866")
179192
r2 = Reference.from_curie("chebi:101854", name="talarozole")
180193
r3 = Reference.from_curie("chembl.compound:CHEMBL459505", name="TALAROZOLE")
@@ -214,13 +227,25 @@ def test_jsonl(self) -> None:
214227
m3_e1 = ReasonedEvidence(justification=CHAIN_MAPPING, mappings=[m1, m2])
215228
m3 = Mapping.from_triple(t3, evidence=[m3_e1])
216229

217-
mappings = [m1, m2, m3]
230+
self.mappings = [m1, m2, m3]
218231

232+
def test_jsonl(self) -> None:
233+
"""Test JSONL I/O."""
219234
with tempfile.TemporaryDirectory() as directory_:
220235
for path in [
221236
Path(directory_).joinpath("test.jsonl"),
222237
Path(directory_).joinpath("test.jsonl.gz"),
223238
]:
224-
write_jsonl(mappings, path)
239+
write_jsonl(self.mappings, path)
225240
new_mappings = from_jsonl(path, show_progress=False)
226-
self.assertEqual(mappings, new_mappings)
241+
self.assertEqual(self.mappings, new_mappings)
242+
243+
def test_digraph(self) -> None:
244+
"""Test I/O to a directed graph."""
245+
self.assertEqual(sorted(self.mappings), sorted(from_digraph(to_digraph(self.mappings))))
246+
247+
def test_multidigraph(self) -> None:
248+
"""Test I/O with multi-directed graph."""
249+
self.assertEqual(
250+
sorted(self.mappings), sorted(from_multidigraph(to_multidigraph(self.mappings)))
251+
)

0 commit comments

Comments
 (0)