Skip to content

Commit 5b6462a

Browse files
committed
[test/RDFWriter] Add subClassOf tests
1 parent 143519e commit 5b6462a

File tree

1 file changed

+164
-2
lines changed

1 file changed

+164
-2
lines changed

test/test_rdf_writer.py

Lines changed: 164 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44

55
import yaml
66

7+
from owlrl import DeductiveClosure, RDFS_Semantics
8+
79
from rdflib import URIRef, Literal
8-
from rdflib.namespace import XSD, RDF
10+
from rdflib.namespace import Namespace, RDF, RDFS, XSD
11+
from rdflib.plugins.sparql import prepareQuery
912

1013
import odml
1114

1215
from odml.format import Format
13-
from odml.tools.rdf_converter import RDFWriter
16+
from odml.tools.rdf_converter import ODML_NS, RDFWriter
1417

1518
from .test_samplefile import SampleFileCreator
1619
from .test_samplefile import parse
@@ -312,6 +315,11 @@ def test_rdf_subclassing_switch(self):
312315
self.assertNotIn("odml:Cell", result)
313316

314317
def test_rdf_custom_subclasses(self):
318+
"""
319+
Test collection of the odml RDF subclassing feature.
320+
Tests that the resulting output RDF document contains any required
321+
additional RDF subclasses.
322+
"""
315323
sub_class_term = "cell"
316324

317325
# Create minimal document
@@ -354,3 +362,157 @@ def test_rdf_custom_subclasses(self):
354362
rdf_writer = RDFWriter([doc], custom_subclasses=custom_class_dict)
355363
self.assertNotIn("odml:Cell", rdf_writer.get_rdf_str())
356364
self.assertIn("odml:Neuron", rdf_writer.get_rdf_str())
365+
366+
def test_rdf_subclassing_definitions(self):
367+
"""
368+
Test that RDF Subclass definitions are written to the resulting graph.
369+
"""
370+
# -- Test default subclassing
371+
doc = odml.Document()
372+
_ = odml.Section(name="test_subclassing", type="cell", parent=doc)
373+
374+
rdf_writer = RDFWriter([doc])
375+
curr_str = " ".join(rdf_writer.get_rdf_str().split())
376+
self.assertIn("odml:Cell a rdfs:Class ; rdfs:subClassOf odml:Section", curr_str)
377+
self.assertIn("odml:Section a rdfs:Class", curr_str)
378+
379+
# -- Test multiple entries; a definition should only occur once in an RDF document
380+
doc = odml.Document()
381+
sec = odml.Section(name="test_subclassing", type="cell", parent=doc)
382+
sub_sec = odml.Section(name="test_subclassing", type="cell", parent=sec)
383+
_ = odml.Section(name="test_subclassing", type="cell", parent=sub_sec)
384+
385+
rdf_writer = RDFWriter([doc])
386+
curr_str = " ".join(rdf_writer.get_rdf_str().split())
387+
self.assertIn("odml:Cell a rdfs:Class ; rdfs:subClassOf odml:Section", curr_str)
388+
self.assertIs(curr_str.count("odml:Cell a rdfs:Class ; rdfs:subClassOf odml:Section"), 1)
389+
self.assertIn("odml:Section a rdfs:Class", curr_str)
390+
self.assertIs(curr_str.count("odml:Section a rdfs:Class"), 1)
391+
392+
# -- Test custom subclassing
393+
type_custom_class = "species"
394+
custom_class_dict = {type_custom_class: "Species"}
395+
396+
doc = odml.Document()
397+
_ = odml.Section(name="test_subclassing", type="cell", parent=doc)
398+
_ = odml.Section(name="test_custom_subclassing", type=type_custom_class, parent=doc)
399+
400+
rdf_writer = RDFWriter([doc], custom_subclasses=custom_class_dict)
401+
curr_str = " ".join(rdf_writer.get_rdf_str().split())
402+
self.assertIn("odml:Cell a rdfs:Class ; rdfs:subClassOf odml:Section", curr_str)
403+
self.assertIn("odml:Species a rdfs:Class ; rdfs:subClassOf odml:Section", curr_str)
404+
self.assertIn("odml:Section a rdfs:Class", curr_str)
405+
406+
# -- Test inactive subclassing
407+
doc = odml.Document()
408+
_ = odml.Section(name="test_subclassing", type="cell", parent=doc)
409+
410+
rdf_writer = RDFWriter([doc], rdf_subclassing=False)
411+
curr_str = " ".join(rdf_writer.get_rdf_str().split())
412+
self.assertNotIn("odml:Section a rdfs:Class", curr_str)
413+
self.assertNotIn("odml:Cell a rdfs:Class ; rdfs:subClassOf odml:Section", curr_str)
414+
415+
def test_rdf_subclassing_queries(self):
416+
"""
417+
Test the proper implementation of the RDF subclassing feature. Tests ensure, that queries
418+
relying on RDF Subclasses return appropriate results.
419+
"""
420+
namespace_map = {"odml": Namespace(ODML_NS), "rdf": RDF, "rdfs": RDFS}
421+
422+
doc = odml.Document()
423+
_ = odml.Section(name="test_subclass", type="cell", parent=doc)
424+
_ = odml.Section(name="test_regular_class", type="regular", parent=doc)
425+
426+
rdf_writer = RDFWriter([doc])
427+
_ = rdf_writer.get_rdf_str()
428+
429+
use_graph = rdf_writer.graph
430+
DeductiveClosure(RDFS_Semantics).expand(use_graph)
431+
432+
q_string = "SELECT * WHERE {?s rdf:type odml:Section .}"
433+
curr_query = prepareQuery(q_string, initNs=namespace_map)
434+
435+
# Make sure the query finds two sections
436+
self.assertIs(len(use_graph.query(curr_query)), 2)
437+
438+
# Make sure the query finds
439+
result_section = []
440+
for row in use_graph.query(curr_query):
441+
result_section.append(row.s)
442+
443+
q_string = "SELECT * WHERE {?s rdf:type odml:Cell .}"
444+
curr_query = prepareQuery(q_string, initNs=namespace_map)
445+
446+
self.assertIs(len(use_graph.query(curr_query)), 1)
447+
for row in use_graph.query(curr_query):
448+
self.assertIn(row.s, result_section)
449+
450+
# -- Test custom subclassing queries
451+
type_custom_class = "species"
452+
type_overwrite_class = "cell"
453+
custom_class_dict = {type_custom_class: "Species", type_overwrite_class: "Neuron"}
454+
455+
doc = odml.Document()
456+
sec = odml.Section(name="test_subclass", type="species", parent=doc)
457+
_ = odml.Section(name="test_subclass_overwrite", type="cell", parent=sec)
458+
_ = odml.Section(name="test_regular_class", type="regular", parent=sec)
459+
460+
rdf_writer = RDFWriter([doc], custom_subclasses=custom_class_dict)
461+
_ = rdf_writer.get_rdf_str()
462+
463+
use_graph = rdf_writer.graph
464+
DeductiveClosure(RDFS_Semantics).expand(use_graph)
465+
466+
q_string = "SELECT * WHERE {?s rdf:type odml:Section .}"
467+
curr_query = prepareQuery(q_string, initNs=namespace_map)
468+
469+
# Make sure the query finds three sections
470+
self.assertIs(len(use_graph.query(curr_query)), 3)
471+
472+
# Make sure the query finds
473+
result_section = []
474+
for row in use_graph.query(curr_query):
475+
result_section.append(row.s)
476+
477+
# Custom class 'Species' should be found.
478+
q_string = "SELECT * WHERE {?s rdf:type odml:Species .}"
479+
curr_query = prepareQuery(q_string, initNs=namespace_map)
480+
481+
self.assertIs(len(use_graph.query(curr_query)), 1)
482+
for row in use_graph.query(curr_query):
483+
self.assertIn(row.s, result_section)
484+
485+
# Custom class 'Neuron' should be found.
486+
q_string = "SELECT * WHERE {?s rdf:type odml:Neuron .}"
487+
curr_query = prepareQuery(q_string, initNs=namespace_map)
488+
489+
self.assertIs(len(use_graph.query(curr_query)), 1)
490+
for row in use_graph.query(curr_query):
491+
self.assertIn(row.s, result_section)
492+
493+
# Default class 'Cell' was replaced and should not return any result.
494+
q_string = "SELECT * WHERE {?s rdf:type odml:Cell .}"
495+
curr_query = prepareQuery(q_string, initNs=namespace_map)
496+
497+
self.assertIs(len(use_graph.query(curr_query)), 0)
498+
499+
# -- Test inactivated subclassing
500+
doc = odml.Document()
501+
_ = odml.Section(name="test_regular_class", type="regular", parent=doc)
502+
_ = odml.Section(name="test_subclass", type="cell", parent=doc)
503+
504+
rdf_writer = RDFWriter([doc], rdf_subclassing=False)
505+
_ = rdf_writer.get_rdf_str()
506+
507+
use_graph = rdf_writer.graph
508+
DeductiveClosure(RDFS_Semantics).expand(use_graph)
509+
510+
q_string = "SELECT * WHERE {?s rdf:type odml:Section .}"
511+
curr_query = prepareQuery(q_string, initNs=namespace_map)
512+
513+
self.assertIs(len(use_graph.query(curr_query)), 2)
514+
515+
q_string = "SELECT * WHERE {?s rdf:type odml:Cell .}"
516+
curr_query = prepareQuery(q_string, initNs=namespace_map)
517+
518+
self.assertIs(len(use_graph.query(curr_query)), 0)

0 commit comments

Comments
 (0)