diff --git a/tests/test_network.py b/tests/test_network.py
index 7c39c35..aed3244 100644
--- a/tests/test_network.py
+++ b/tests/test_network.py
@@ -1,15 +1,475 @@
import pytest
from tools4rdf.network.ontology import read_ontology
-from rdflib import Graph
+from tools4rdf.network.network import (
+ Network,
+ OntologyNetwork,
+ OntologyNetworkBase,
+ _replace_name,
+ _strip_name,
+)
+from tools4rdf.network.parser import OntoParser
+from tools4rdf.network.term import OntoTerm
+from rdflib import Graph, Namespace, RDF, RDFS, OWL, URIRef
+
def test_network():
onto = read_ontology()
kg = Graph()
kg.parse("tests/triples", format="turtle")
- df = onto.query(kg, onto.terms.cmso.AtomicScaleSample, [onto.terms.cmso.hasSpaceGroupSymbol, onto.terms.cmso.hasNumberOfAtoms==4])
+ df = onto.query(
+ kg,
+ onto.terms.cmso.AtomicScaleSample,
+ [onto.terms.cmso.hasSpaceGroupSymbol, onto.terms.cmso.hasNumberOfAtoms == 4],
+ )
assert len(df) == 14
+
def test_owlThing():
onto = read_ontology()
- query = (onto.create_query(onto.terms.cmso.AtomicScaleSample, [[onto.terms.cmso.CrystalStructure, onto.terms.cmso.hasAltName]]))
- assert "CrystalStructure_hasAltNamevalue" in query
\ No newline at end of file
+ query = onto.create_query(
+ onto.terms.cmso.AtomicScaleSample,
+ [[onto.terms.cmso.CrystalStructure, onto.terms.cmso.hasAltName]],
+ )
+ assert "CrystalStructure_hasAltNamevalue" in query
+
+
+@pytest.fixture
+def simple_onto():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+ g.add((ex.Food, RDF.type, OWL.Class))
+ g.add((ex.Person, RDF.type, OWL.Class))
+ g.add((ex.Pizza, RDFS.subClassOf, ex.Food))
+ g.add((ex.hasTopping, RDF.type, OWL.ObjectProperty))
+ g.add((ex.hasTopping, RDFS.domain, ex.Pizza))
+ g.add((ex.hasTopping, RDFS.range, ex.Food))
+ g.add((ex.hasPrice, RDF.type, OWL.DatatypeProperty))
+ g.add((ex.hasPrice, RDFS.domain, ex.Pizza))
+ return OntoParser(g)
+
+
+@pytest.fixture
+def network_fixture(simple_onto):
+ return Network(simple_onto)
+
+
+def test_replace_name():
+ assert _replace_name("ex:Pizza") == "ex.Pizza"
+ assert _replace_name("simple") == "simple"
+
+
+def test_strip_name():
+ assert _strip_name("ex:Pizza") == "Pizza"
+ assert _strip_name("Pizza") == "Pizza"
+
+
+def test_network_init(simple_onto):
+ network = Network(simple_onto)
+ assert network.terms is not None
+ assert network.g is not None
+ assert network.namespaces is not None
+ assert network.extra_namespaces is not None
+
+
+def test_network_draw(network_fixture):
+ dot = network_fixture.draw()
+ assert dot is not None
+
+
+def test_network_draw_custom_style(network_fixture):
+ style = {
+ "class": {"shape": "circle"},
+ "object_property": {"shape": "diamond"},
+ "data_property": {"shape": "box"},
+ "literal": {"shape": "parallelogram"},
+ }
+ dot = network_fixture.draw(styledict=style)
+ assert dot is not None
+
+
+def test_get_shortest_path_simple(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ target = network_fixture.terms.ex.hasTopping
+ paths = network_fixture._get_shortest_path(source, target, num_paths=1)
+ assert len(paths) > 0
+ assert paths[0][0] == source.variable_name
+
+
+def test_get_shortest_path_multiple_paths(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ target = network_fixture.terms.ex.hasTopping
+ paths = network_fixture._get_shortest_path(source, target, num_paths=2)
+ assert len(paths) <= 2
+
+
+def test_get_shortest_path_with_triples(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ target = network_fixture.terms.ex.hasTopping
+ result = network_fixture.get_shortest_path(
+ source, target, triples=True, num_paths=1
+ )
+ assert isinstance(result, list)
+ assert isinstance(result[0], list)
+
+
+def test_get_shortest_path_without_triples(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ target = network_fixture.terms.ex.hasTopping
+ result = network_fixture.get_shortest_path(
+ source, target, triples=False, num_paths=1
+ )
+ assert isinstance(result, list)
+
+
+def test_get_shortest_path_stepped_query(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ target = network_fixture.terms.ex.Food
+ parent = network_fixture.terms.ex.hasTopping
+ target._parents.append(parent)
+ result = network_fixture.get_shortest_path(source, target, triples=False)
+ assert isinstance(result, list)
+ target._parents = []
+
+
+def test_get_shortest_path_stepped_multiple_paths_error(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ target = network_fixture.terms.ex.hasTopping
+ parent = network_fixture.terms.ex.Food
+ target._parents.append(parent)
+ with pytest.raises(ValueError):
+ network_fixture.get_shortest_path(source, target, num_paths=2)
+ target._parents = []
+
+
+def test_insert_namespaces(network_fixture):
+ namespaces = {"ex": "http://example.org/ontology#"}
+ result = network_fixture._insert_namespaces(namespaces)
+ assert len(result) > 0
+ assert "PREFIX ex:" in result[0]
+
+
+def test_modify_destinations(network_fixture):
+ dest1 = network_fixture.terms.ex.Pizza
+ dest2 = network_fixture.terms.ex.Food
+ destinations = [[dest1, dest2]]
+ modified = network_fixture._modify_destinations(destinations)
+ assert len(modified) == 1
+ assert dest1 in modified[0]._parents
+
+
+def test_is_already_in_destinations(network_fixture):
+ obj_prop = network_fixture.terms.ex.hasTopping
+ destinations = [obj_prop]
+ assert network_fixture._is_already_in_destinations(obj_prop, destinations)
+
+
+def test_is_not_in_destinations(network_fixture):
+ obj_prop = network_fixture.terms.ex.hasTopping
+ other_prop = network_fixture.terms.ex.hasPrice
+ destinations = [obj_prop]
+ assert not network_fixture._is_already_in_destinations(other_prop, destinations)
+
+
+def test_create_query_single_source(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ query = network_fixture.create_query(source)
+ assert isinstance(query, str)
+ assert "SELECT DISTINCT" in query
+
+
+def test_create_query_with_destination(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ dest = network_fixture.terms.ex.hasTopping
+ query = network_fixture.create_query(source, dest)
+ assert isinstance(query, str)
+ assert "SELECT DISTINCT" in query
+
+
+def test_create_query_multiple_destinations(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ dest1 = network_fixture.terms.ex.hasTopping
+ dest2 = network_fixture.terms.ex.hasPrice
+ query = network_fixture.create_query(source, [dest1, dest2], num_paths=1)
+ assert isinstance(query, str)
+
+
+def test_create_query_return_list(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ query = network_fixture.create_query(source, return_list=True)
+ assert isinstance(query, list)
+
+
+def test_create_query_data_property_source_error(network_fixture):
+ source = network_fixture.terms.ex.hasPrice
+ with pytest.raises(ValueError):
+ network_fixture.create_query(source)
+
+
+def test_create_query_multiple_destinations_multiple_paths_error(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ dest1 = network_fixture.terms.ex.hasTopping
+ dest2 = network_fixture.terms.ex.hasPrice
+ with pytest.raises(TypeError):
+ network_fixture.create_query(source, [dest1, dest2], num_paths=2)
+
+
+def test_prepare_destinations(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ dest = network_fixture.terms.ex.hasTopping
+ destinations = [dest]
+ result = network_fixture._prepare_destinations(destinations, source)
+ assert len(result) > 0
+
+
+def test_prepare_destinations_source_any_error(network_fixture):
+ source = network_fixture.terms.ex.Pizza.any
+ with pytest.raises(ValueError):
+ network_fixture._prepare_destinations(None, source)
+
+
+def test_prepare_destinations_multiple_conditions_error(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ dest1 = network_fixture.terms.ex.Pizza
+ dest2 = network_fixture.terms.ex.Pizza
+ dest1._condition = "condition1"
+ dest2._condition = "condition2"
+ with pytest.raises(ValueError):
+ network_fixture._prepare_destinations([dest1, dest2], source)
+ dest1._condition = None
+ dest2._condition = None
+
+
+def test_create_query_prefix(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ dest = network_fixture.terms.ex.hasTopping
+ result = network_fixture._create_query_prefix(source, [dest])
+ assert "SELECT DISTINCT" in result[0]
+ assert "WHERE" in result[1]
+
+
+def test_create_query_prefix_with_remote_source(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ dest = network_fixture.terms.ex.hasTopping
+ result = network_fixture._create_query_prefix(
+ source, [dest], remote_source="https://example.org/sparql"
+ )
+ assert "SERVICE" in result[2]
+
+
+def test_create_query_prefix_invalid_remote_url(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ dest = network_fixture.terms.ex.hasTopping
+ with pytest.raises(ValueError):
+ network_fixture._create_query_prefix(source, [dest], remote_source="not-a-url")
+
+
+def test_get_triples(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ dest = network_fixture.terms.ex.hasTopping
+ queries, namespaces = network_fixture._get_triples(source, [dest], num_paths=1)
+ assert len(queries) > 0
+ assert len(namespaces) > 0
+
+
+def test_add_types_for_source(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ query, namespaces = network_fixture._add_types_for_source(source)
+ assert isinstance(query, list)
+ assert isinstance(namespaces, list)
+
+
+def test_add_types_for_destination(network_fixture):
+ dest = network_fixture.terms.ex.Pizza.only
+ query, namespaces = network_fixture._add_types_for_destination([dest])
+ assert isinstance(query, list)
+ assert isinstance(namespaces, list)
+
+
+def test_add_filters_no_condition(network_fixture):
+ dest = network_fixture.terms.ex.hasTopping
+ result = network_fixture._add_filters([dest])
+ assert "}" in result
+
+
+def test_add_filters_with_condition(network_fixture):
+ dest = network_fixture.terms.ex.Pizza
+ dest._condition = "(?Pizza > 10)"
+ result = network_fixture._add_filters([dest])
+ assert "FILTER" in result[0]
+ dest._condition = None
+
+
+def test_add_limit_none(network_fixture):
+ result = network_fixture._add_limit(None)
+ assert result == []
+
+
+def test_add_limit_with_value(network_fixture):
+ result = network_fixture._add_limit(10)
+ assert "LIMIT 10" in result[0]
+
+
+def test_create_query_full(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ dest = network_fixture.terms.ex.hasTopping
+ queries = network_fixture._create_query(source, [dest], num_paths=1)
+ assert len(queries) > 0
+ assert "SELECT DISTINCT" in queries[0]
+
+
+def test_create_query_with_limit(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ dest = network_fixture.terms.ex.hasTopping
+ queries = network_fixture._create_query(source, [dest], limit=10)
+ assert "LIMIT 10" in queries[0]
+
+
+def test_query_execution(network_fixture):
+ kg = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ kg.bind("ex", ex)
+ kg.add((ex.MyPizza, RDF.type, ex.Pizza))
+ kg.add((ex.MyPizza, ex.hasTopping, ex.Cheese))
+
+ source = network_fixture.terms.ex.Pizza
+ dest = network_fixture.terms.ex.hasTopping
+ result = network_fixture.query(kg, source, [dest])
+ assert result is not None
+
+
+def test_query_execution_no_results(network_fixture):
+ kg = Graph()
+ source = network_fixture.terms.ex.Pizza
+ dest = network_fixture.terms.ex.hasTopping
+ result = network_fixture.query(kg, source, [dest])
+ assert result is not None
+ assert len(result) == 0
+
+
+def test_query_execution_with_limit(network_fixture):
+ kg = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ kg.bind("ex", ex)
+ kg.add((ex.MyPizza, RDF.type, ex.Pizza))
+ kg.add((ex.MyPizza, ex.hasTopping, ex.Cheese))
+
+ source = network_fixture.terms.ex.Pizza
+ dest = network_fixture.terms.ex.hasTopping
+ result = network_fixture.query(kg, source, [dest], limit=1)
+ assert result is not None
+
+
+def test_query_with_remote_endpoint(network_fixture):
+ source = network_fixture.terms.ex.Pizza
+ dest = network_fixture.terms.ex.hasTopping
+ with pytest.raises(Exception):
+ network_fixture.query("https://example.org/sparql", source, [dest])
+
+
+def test_query_internal(network_fixture):
+ kg = Graph()
+ query_string = "SELECT DISTINCT ?s WHERE { ?s ?p ?o }"
+ result = network_fixture._query(kg, query_string, return_df=True)
+ assert result is not None
+ assert len(result) == 0
+
+
+def test_ontology_network_base_init(simple_onto):
+ network = OntologyNetworkBase(simple_onto)
+ assert network.onto == simple_onto
+ assert network._terms is None
+ assert network._g is None
+
+
+def test_ontology_network_base_terms_lazy(simple_onto):
+ network = OntologyNetworkBase(simple_onto)
+ assert network._terms is None
+ terms = network.terms
+ assert network._terms is not None
+
+
+def test_ontology_network_base_g_lazy(simple_onto):
+ network = OntologyNetworkBase(simple_onto)
+ assert network._g is None
+ g = network.g
+ assert network._g is not None
+
+
+def test_ontology_network_base_add(simple_onto):
+ network1 = OntologyNetworkBase(simple_onto)
+ network2 = OntologyNetworkBase(simple_onto)
+ combined = network1 + network2
+ assert isinstance(combined, OntologyNetworkBase)
+
+
+def test_ontology_network_base_radd(simple_onto):
+ network1 = OntologyNetworkBase(simple_onto)
+ network2 = OntologyNetworkBase(simple_onto)
+ combined = network2.__radd__(network1)
+ assert isinstance(combined, OntologyNetworkBase)
+
+
+def test_ontology_network_base_attributes(simple_onto):
+ network = OntologyNetworkBase(simple_onto)
+ attrs = network.attributes
+ assert attrs is not None
+
+
+def test_ontology_network_base_namespaces(simple_onto):
+ network = OntologyNetworkBase(simple_onto)
+ ns = network.namespaces
+ assert ns is not None
+
+
+def test_ontology_network_base_extra_namespaces(simple_onto):
+ network = OntologyNetworkBase(simple_onto)
+ extra_ns = network.extra_namespaces
+ assert extra_ns is not None
+
+
+def test_ontology_network_base_add_namespace(simple_onto):
+ network = OntologyNetworkBase(simple_onto)
+ network.add_namespace("test", "http://test.org/")
+ assert network._terms is None
+
+
+def test_ontology_network_base_add_term(simple_onto):
+ network = OntologyNetworkBase(simple_onto)
+ network.add_term("http://example.org/ontology#NewClass", "class", namespace="ex")
+ assert network._terms is None
+ assert network._g is None
+
+
+def test_ontology_network_base_add_path(simple_onto):
+ network = OntologyNetworkBase(simple_onto)
+ network.add_path(("ex:Pizza", "ex:hasTopping", "ex:Food"))
+ assert network._terms is None
+ assert network._g is None
+
+
+def test_ontology_network_base_add_path_invalid_subject(simple_onto):
+ network = OntologyNetworkBase(simple_onto)
+ with pytest.raises(ValueError):
+ network.add_path(("ex:Invalid", "ex:hasTopping", "ex:Food"))
+
+
+def test_ontology_network_base_add_path_invalid_object(simple_onto):
+ network = OntologyNetworkBase(simple_onto)
+ with pytest.raises(ValueError):
+ network.add_path(("ex:Pizza", "ex:hasTopping", "ex:Invalid"))
+
+
+def test_ontology_network_init(tmp_path):
+ owl_file = tmp_path / "test.owl"
+ owl_content = """
+
+
+
+ """
+ owl_file.write_text(owl_content)
+ network = OntologyNetwork(str(owl_file), format="xml")
+ assert network.onto is not None
diff --git a/tests/test_parser.py b/tests/test_parser.py
new file mode 100644
index 0000000..4a2b88e
--- /dev/null
+++ b/tests/test_parser.py
@@ -0,0 +1,660 @@
+import pytest
+from rdflib import Graph, Namespace, RDF, RDFS, OWL, URIRef, Literal, BNode
+from tools4rdf.network.parser import OntoParser, parse_ontology
+from tools4rdf.network.term import OntoTerm
+
+
+@pytest.fixture
+def simple_graph():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+ g.add((ex.Food, RDF.type, OWL.Class))
+ g.add((ex.Pizza, RDFS.subClassOf, ex.Food))
+ return g
+
+
+@pytest.fixture
+def parser_with_properties():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+ g.add((ex.Person, RDF.type, OWL.Class))
+
+ g.add((ex.hasTopping, RDF.type, OWL.ObjectProperty))
+ g.add((ex.hasTopping, RDFS.domain, ex.Pizza))
+ g.add((ex.hasTopping, RDFS.range, ex.Food))
+
+ g.add((ex.hasPrice, RDF.type, OWL.DatatypeProperty))
+ g.add((ex.hasPrice, RDFS.domain, ex.Pizza))
+
+ return OntoParser(g)
+
+
+@pytest.fixture
+def parser_with_union():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+ g.add((ex.Pasta, RDF.type, OWL.Class))
+ g.add((ex.Person, RDF.type, OWL.Class))
+
+ union_node = BNode()
+ g.add((union_node, RDF.type, OWL.Class))
+ collection = BNode()
+ g.add((union_node, OWL.unionOf, collection))
+ g.add((collection, RDF.first, ex.Pizza))
+ rest_node = BNode()
+ g.add((collection, RDF.rest, rest_node))
+ g.add((rest_node, RDF.first, ex.Pasta))
+ g.add((rest_node, RDF.rest, RDF.nil))
+
+ g.add((ex.hasFood, RDF.type, OWL.ObjectProperty))
+ g.add((ex.hasFood, RDFS.domain, union_node))
+
+ return OntoParser(g)
+
+
+def test_parse_ontology_xml(tmp_path):
+ owl_file = tmp_path / "test.owl"
+ owl_content = """
+
+
+
+ """
+ owl_file.write_text(owl_content)
+ parser = parse_ontology(str(owl_file), format="xml")
+ assert isinstance(parser, OntoParser)
+
+
+def test_ontoparser_init():
+ g = Graph()
+ parser = OntoParser(g)
+ assert parser.graph == g
+ assert parser._data_dict is None
+
+
+def test_ontoparser_lazy_initialization():
+ g = Graph()
+ parser = OntoParser(g)
+ assert parser._data_dict is None
+ classes = parser.classes
+ assert parser._data_dict is not None
+
+
+def test_ontoparser_add():
+ g1 = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g1.add((ex.Pizza, RDF.type, OWL.Class))
+
+ g2 = Graph()
+ g2.add((ex.Pasta, RDF.type, OWL.Class))
+
+ parser1 = OntoParser(g1)
+ parser2 = OntoParser(g2)
+ combined = parser1 + parser2
+
+ assert isinstance(combined, OntoParser)
+ assert (ex.Pizza, RDF.type, OWL.Class) in combined.graph
+ assert (ex.Pasta, RDF.type, OWL.Class) in combined.graph
+
+
+def test_ontoparser_radd():
+ g1 = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g1.add((ex.Pizza, RDF.type, OWL.Class))
+
+ g2 = Graph()
+ g2.add((ex.Pasta, RDF.type, OWL.Class))
+
+ parser1 = OntoParser(g1)
+ parser2 = OntoParser(g2)
+ combined = parser2.__radd__(parser1)
+
+ assert isinstance(combined, OntoParser)
+
+
+def test_base_iri():
+ g = Graph()
+ base = URIRef("http://example.org/ontology")
+ g.add((base, RDF.type, OWL.Ontology))
+ parser = OntoParser(g)
+ assert parser.base_iri == "http://example.org/ontology"
+
+
+def test_base_iri_none():
+ g = Graph()
+ parser = OntoParser(g)
+ assert parser.base_iri is None
+
+
+def test_extract_default_namespaces():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+ parser = OntoParser(g)
+ parser._extract_default_namespaces()
+ assert "ex" in parser.namespaces
+ assert parser.namespaces["ex"] == "http://example.org/ontology#"
+
+
+def test_extract_classes(simple_graph):
+ parser = OntoParser(simple_graph)
+ parser._initialize()
+ assert len(parser.classes) > 0
+ assert OWL.Thing in parser.classes
+
+
+def test_extract_object_properties():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+ g.add((ex.hasTopping, RDF.type, OWL.ObjectProperty))
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+ g.add((ex.hasTopping, RDFS.domain, ex.Pizza))
+
+ parser = OntoParser(g)
+ parser._initialize()
+
+ assert "ex:hasTopping" in parser.attributes["object_property"]
+ assert (
+ parser.attributes["object_property"]["ex:hasTopping"].node_type
+ == "object_property"
+ )
+
+
+def test_extract_data_properties():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+ g.add((ex.hasPrice, RDF.type, OWL.DatatypeProperty))
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+ g.add((ex.hasPrice, RDFS.domain, ex.Pizza))
+
+ parser = OntoParser(g)
+ parser._initialize()
+
+ assert "ex:hasPrice" in parser.attributes["data_property"]
+ assert (
+ parser.attributes["data_property"]["ex:hasPrice"].node_type == "data_property"
+ )
+ assert "ex:hasPricevalue" in parser.attributes["data_nodes"]
+
+
+def test_extract_subproperties():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+ g.add((ex.hasTopping, RDF.type, OWL.ObjectProperty))
+ g.add((ex.hasMozzarella, RDF.type, OWL.ObjectProperty))
+ g.add((ex.hasMozzarella, RDFS.subPropertyOf, ex.hasTopping))
+
+ parser = OntoParser(g)
+ parser._initialize()
+
+ assert (
+ "ex:hasMozzarella"
+ in parser.attributes["object_property"]["ex:hasTopping"].subclasses
+ )
+
+
+def test_create_term():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+ g.add((ex.Pizza, RDFS.comment, Literal("A delicious food")))
+
+ parser = OntoParser(g)
+ parser._extract_default_namespaces()
+ term = parser.create_term(ex.Pizza)
+
+ assert isinstance(term, OntoTerm)
+ assert term.uri == "http://example.org/ontology#Pizza"
+ assert term.description.toPython() == "A delicious food"
+
+
+def test_get_description_with_comment():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.add((ex.Pizza, RDFS.comment, Literal("Pizza comment")))
+
+ parser = OntoParser(g)
+ desc = parser.get_description(ex.Pizza)
+ assert desc.toPython() == "Pizza comment"
+
+
+def test_get_description_empty():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+
+ parser = OntoParser(g)
+ desc = parser.get_description(ex.Pizza)
+ assert desc == ""
+
+
+def test_lookup_namespace():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+ parser = OntoParser(g)
+ parser._extract_default_namespaces()
+
+ result = parser._lookup_namespace("http://example.org/ontology#Pizza")
+ assert result == "ex"
+
+
+def test_lookup_namespace_not_found():
+ g = Graph()
+ parser = OntoParser(g)
+ result = parser._lookup_namespace("http://unknown.org/Pizza")
+ assert result is None
+
+
+def test_parse_subclasses():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+ g.add((ex.Margherita, RDF.type, OWL.Class))
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+ g.add((ex.Margherita, RDFS.subClassOf, ex.Pizza))
+
+ parser = OntoParser(g)
+ parser._initialize()
+
+ assert "ex:Margherita" in parser.attributes["class"]["ex:Pizza"].subclasses
+
+
+def test_add_subclasses_to_owlthing():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+
+ parser = OntoParser(g)
+ parser._initialize()
+
+ assert "ex:Pizza" in parser.attributes["class"]["owl:Thing"].subclasses
+
+
+def test_parse_equivalents():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+ g.add((ex.Pie, RDF.type, OWL.Class))
+ g.add((ex.Pizza, OWL.equivalentClass, ex.Pie))
+
+ parser = OntoParser(g)
+ parser._initialize()
+
+ assert "ex:Pie" in parser.attributes["class"]["ex:Pizza"].equivalent_classes
+ assert "ex:Pizza" in parser.attributes["class"]["ex:Pie"].equivalent_classes
+
+
+def test_parse_named_individuals():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+ g.add((ex.MyPizza, RDF.type, OWL.NamedIndividual))
+ g.add((ex.MyPizza, RDF.type, ex.Pizza))
+
+ parser = OntoParser(g)
+ parser._initialize()
+
+ assert "ex:MyPizza" in parser.attributes["class"]["ex:Pizza"].named_individuals
+
+
+def test_get_domain(parser_with_properties):
+ domain = parser_with_properties.attributes["object_property"][
+ "ex:hasTopping"
+ ].domain
+ assert "ex:Pizza" in domain
+
+
+def test_get_range(parser_with_properties):
+ rng = parser_with_properties.attributes["object_property"]["ex:hasTopping"].range
+ assert "ex:Food" in rng
+
+
+def test_unravel_relation():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+
+ collection = BNode()
+ g.add((collection, RDF.first, ex.Pizza))
+ rest_node = BNode()
+ g.add((collection, RDF.rest, rest_node))
+ g.add((rest_node, RDF.first, ex.Pasta))
+ g.add((rest_node, RDF.rest, RDF.nil))
+
+ parser = OntoParser(g)
+ result = parser.unravel_relation(collection, [])
+
+ assert len(result) == 2
+ assert ex.Pizza in result
+ assert ex.Pasta in result
+
+
+def test_lookup_node_simple():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+
+ parser = OntoParser(g)
+ parser._extract_default_namespaces()
+ parser.extract_classes()
+ parser.add_classes_to_attributes()
+
+ result = parser.lookup_node(ex.Pizza)
+ assert "ex:Pizza" in result
+
+
+def test_lookup_node_blank():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+
+ union_node = BNode()
+ g.add((union_node, RDF.type, OWL.Class))
+ collection = BNode()
+ g.add((union_node, OWL.unionOf, collection))
+ g.add((collection, RDF.first, ex.Pizza))
+ g.add((collection, RDF.rest, RDF.nil))
+
+ parser = OntoParser(g)
+ parser._extract_default_namespaces()
+ parser.extract_classes()
+
+ node_str = union_node.toPython()
+ assert node_str in parser.mappings
+
+
+def test_lookup_class():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+
+ parser = OntoParser(g)
+ parser._initialize()
+
+ result = parser.lookup_class(ex.Pizza)
+ assert "ex:Pizza" in result
+
+
+def test_lookup_class_blank_node():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+
+ union_node = BNode()
+
+ parser = OntoParser(g)
+ parser._initialize()
+
+ result = parser.lookup_class(union_node)
+ assert isinstance(result, list)
+
+
+def test_get_attributes():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+ g.add((ex.hasTopping, RDF.type, OWL.ObjectProperty))
+
+ parser = OntoParser(g)
+ parser._initialize()
+
+ attrs = parser.get_attributes()
+ assert "ex" in attrs
+ assert "Pizza" in attrs["ex"]
+
+
+def test_get_networkx_graph():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+ g.add((ex.hasTopping, RDF.type, OWL.ObjectProperty))
+ g.add((ex.hasTopping, RDFS.domain, ex.Pizza))
+
+ parser = OntoParser(g)
+ parser._initialize()
+
+ nx_graph = parser.get_networkx_graph()
+ assert "ex:Pizza" in nx_graph.nodes()
+ assert "ex:hasTopping" in nx_graph.nodes()
+
+
+def test_add_term_class():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+
+ parser = OntoParser(g)
+ parser.add_term("http://example.org/ontology#NewPizza", "class", namespace="ex")
+
+ assert (
+ URIRef("http://example.org/ontology#NewPizza"),
+ RDF.type,
+ OWL.Class,
+ ) in parser.graph
+
+
+def test_add_term_object_property():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+
+ parser = OntoParser(g)
+ parser.add_term(
+ "http://example.org/ontology#newProperty", "object_property", namespace="ex"
+ )
+
+ assert (
+ URIRef("http://example.org/ontology#newProperty"),
+ RDF.type,
+ OWL.ObjectProperty,
+ ) in parser.graph
+
+
+def test_add_term_data_property():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+
+ parser = OntoParser(g)
+ parser.add_term(
+ "http://example.org/ontology#newDataProp", "data_property", namespace="ex"
+ )
+
+ assert (
+ URIRef("http://example.org/ontology#newDataProp"),
+ RDF.type,
+ OWL.DatatypeProperty,
+ ) in parser.graph
+
+
+def test_add_term_invalid_type():
+ g = Graph()
+ parser = OntoParser(g)
+
+ with pytest.raises(ValueError):
+ parser.add_term("http://example.org/ontology#Invalid", "invalid_type")
+
+
+def test_add_term_with_domain_range():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+
+ parser = OntoParser(g)
+ parser.add_term(
+ "http://example.org/ontology#hasProperty",
+ "object_property",
+ namespace="ex",
+ dm=["http://example.org/ontology#Pizza"],
+ rn=["http://example.org/ontology#Topping"],
+ )
+
+ assert (
+ URIRef("http://example.org/ontology#hasProperty"),
+ RDFS.domain,
+ URIRef("http://example.org/ontology#Pizza"),
+ ) in parser.graph
+ assert (
+ URIRef("http://example.org/ontology#hasProperty"),
+ RDFS.range,
+ URIRef("http://example.org/ontology#Topping"),
+ ) in parser.graph
+
+
+def test_add_namespace():
+ g = Graph()
+ parser = OntoParser(g)
+ parser._initialize()
+
+ parser.add_namespace("custom", "http://custom.org/")
+
+ assert parser._data_dict is None
+
+
+def test_extract_values():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.add((ex.Pizza, RDFS.comment, Literal("comment")))
+
+ parser = OntoParser(g)
+ result = parser.extract_values(ex.Pizza, RDFS.comment)
+
+ assert result == Literal("comment")
+
+
+def test_extract_values_none():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+
+ parser = OntoParser(g)
+ result = parser.extract_values(ex.Pizza, RDFS.comment)
+
+ assert result is None
+
+
+def test_union_class_extraction():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+ g.add((ex.Pasta, RDF.type, OWL.Class))
+
+ union_node = BNode()
+ g.add((union_node, RDF.type, OWL.Class))
+ collection = BNode()
+ g.add((union_node, OWL.unionOf, collection))
+ g.add((collection, RDF.first, ex.Pizza))
+ rest_node = BNode()
+ g.add((collection, RDF.rest, rest_node))
+ g.add((rest_node, RDF.first, ex.Pasta))
+ g.add((rest_node, RDF.rest, RDF.nil))
+
+ parser = OntoParser(g)
+ parser._initialize()
+
+ union_key = union_node.toPython()
+ assert union_key in parser.mappings
+ assert parser.mappings[union_key]["type"] == "union"
+ assert "ex:Pizza" in parser.mappings[union_key]["items"]
+ assert "ex:Pasta" in parser.mappings[union_key]["items"]
+
+
+def test_intersection_class_extraction():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+ g.add((ex.Italian, RDF.type, OWL.Class))
+
+ intersection_node = BNode()
+ g.add((intersection_node, RDF.type, OWL.Class))
+ collection = BNode()
+ g.add((intersection_node, OWL.intersectionOf, collection))
+ g.add((collection, RDF.first, ex.Pizza))
+ rest_node = BNode()
+ g.add((collection, RDF.rest, rest_node))
+ g.add((rest_node, RDF.first, ex.Italian))
+ g.add((rest_node, RDF.rest, RDF.nil))
+
+ parser = OntoParser(g)
+ parser._initialize()
+
+ intersection_key = intersection_node.toPython()
+ assert intersection_key in parser.mappings
+ assert parser.mappings[intersection_key]["type"] == "intersection"
+
+
+def test_domain_with_union(parser_with_union):
+ domain = parser_with_union.attributes["object_property"]["ex:hasFood"].domain
+ assert "ex:Pizza" in domain
+ assert "ex:Pasta" in domain
+
+
+def test_recursively_add_subclasses():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+
+ g.add((ex.Food, RDF.type, OWL.Class))
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+ g.add((ex.Margherita, RDF.type, OWL.Class))
+
+ g.add((ex.Pizza, RDFS.subClassOf, ex.Food))
+ g.add((ex.Margherita, RDFS.subClassOf, ex.Pizza))
+
+ parser = OntoParser(g)
+ parser._initialize()
+
+ assert "ex:Margherita" in parser.attributes["class"]["ex:Food"].subclasses
+
+
+def test_recursively_add_equivalents():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+ g.add((ex.Pie, RDF.type, OWL.Class))
+ g.add((ex.FlatBread, RDF.type, OWL.Class))
+
+ g.add((ex.Pizza, OWL.equivalentClass, ex.Pie))
+ g.add((ex.Pie, OWL.equivalentClass, ex.FlatBread))
+
+ parser = OntoParser(g)
+ parser._initialize()
+
+ assert "ex:FlatBread" in parser.attributes["class"]["ex:Pizza"].equivalent_classes
+
+
+def test_recheck_namespaces():
+ g = Graph()
+ ex = Namespace("http://example.org/ontology#")
+ g.bind("ex", ex)
+ g.add((ex.Pizza, RDF.type, OWL.Class))
+
+ parser = OntoParser(g)
+ parser._initialize()
+
+ assert "ex" in parser.namespaces
diff --git a/tests/test_term.py b/tests/test_term.py
new file mode 100644
index 0000000..4895b11
--- /dev/null
+++ b/tests/test_term.py
@@ -0,0 +1,384 @@
+import pytest
+from tools4rdf.network.term import (
+ OntoTerm,
+ is_url,
+ _get_namespace_and_name,
+ _get_namespace_with_prefix,
+ strip_name,
+)
+
+
+def test_is_url_valid():
+ assert is_url("https://example.org/ontology")
+ assert is_url("http://example.org")
+ assert is_url("ftp://files.example.com/data")
+
+
+def test_is_url_invalid():
+ assert not is_url("not a url")
+ assert not is_url("example.org")
+ assert not is_url("/local/path")
+
+
+def test_get_namespace_and_name_with_hash():
+ uri = "http://example.org/ontology#Pizza"
+ namespace, name = _get_namespace_and_name(uri)
+ assert namespace == "ontology"
+ assert name == "Pizza"
+
+
+def test_get_namespace_and_name_with_slash():
+ uri = "http://example.org/ontology/Pizza"
+ namespace, name = _get_namespace_and_name(uri)
+ assert namespace == "ontology"
+ assert name == "Pizza"
+
+
+def test_get_namespace_and_name_simple():
+ uri = "Pizza"
+ namespace, name = _get_namespace_and_name(uri)
+ assert namespace == ""
+ assert name == "Pizza"
+
+
+def test_get_namespace_with_prefix_hash():
+ uri = "http://example.org/ontology#Pizza"
+ result = _get_namespace_with_prefix(uri)
+ assert result == "http://example.org/ontology"
+
+
+def test_get_namespace_with_prefix_slash():
+ uri = "http://example.org/ontology/Pizza"
+ result = _get_namespace_with_prefix(uri)
+ assert result == "http://example.org/ontology/"
+
+
+def test_strip_name_returns_name():
+ uri = "http://example.org/ontology#Pizza"
+ result = strip_name(uri, get_what="name")
+ assert result == "ontology:Pizza"
+
+
+def test_strip_name_returns_namespace():
+ uri = "http://example.org/ontology#Pizza"
+ result = strip_name(uri, get_what="namespace")
+ assert result == "ontology"
+
+
+def test_strip_name_with_provided_namespace():
+ uri = "http://example.org/ontology#Pizza"
+ result = strip_name(uri, get_what="name", namespace="custom")
+ assert result == "custom:Pizza"
+
+
+def test_strip_name_invalid_option():
+ uri = "http://example.org/ontology#Pizza"
+ with pytest.raises(ValueError):
+ strip_name(uri, get_what="invalid")
+
+
+def test_ontoterm_init_with_uri():
+ term = OntoTerm(uri="http://example.org/ontology#Pizza")
+ assert term.uri == "http://example.org/ontology#Pizza"
+ assert term.namespace == "ontology"
+
+
+def test_ontoterm_init_with_name():
+ term = OntoTerm(name="pizza:Pizza", uri="http://example.org#Pizza")
+ assert term.name == "pizza:Pizza"
+
+
+def test_ontoterm_init_without_uri_and_name():
+ with pytest.raises(ValueError):
+ OntoTerm()
+
+
+def test_ontoterm_uri_property():
+ term = OntoTerm(uri="http://example.org#Pizza")
+ assert term.uri == "http://example.org#Pizza"
+ term.uri = "http://new.org#Food"
+ assert term.uri == "http://new.org#Food"
+
+
+def test_ontoterm_description_single_string():
+ term = OntoTerm(uri="http://example.org#Pizza", description="A pizza")
+ assert term.description == "A pizza"
+
+
+def test_ontoterm_description_list():
+ term = OntoTerm(uri="http://example.org#Pizza", description=["First", "Second"])
+ assert term.description == "First. Second"
+
+
+def test_ontoterm_description_empty_list():
+ term = OntoTerm(uri="http://example.org#Pizza", description=[])
+ assert term.description == ""
+
+
+def test_ontoterm_name_without_prefix():
+ term = OntoTerm(uri="http://example.org#Pizza", name="pizza:Margherita-Special")
+ assert term.name_without_prefix == "MargheritaSpecial"
+
+
+def test_ontoterm_query_name_data_property():
+ term = OntoTerm(
+ uri="http://example.org#hasPrice",
+ name="pizza:hasPrice",
+ node_type="data_property",
+ )
+ assert term.query_name == "pizza:hasPricevalue"
+
+
+def test_ontoterm_query_name_other_type():
+ term = OntoTerm(
+ uri="http://example.org#Pizza", name="pizza:Pizza", node_type="class"
+ )
+ assert term.query_name == "pizza:Pizza"
+
+
+def test_ontoterm_variable_name_no_parents():
+ term = OntoTerm(uri="http://example.org#Pizza", name="pizza:Pizza")
+ assert term.variable_name == "Pizza"
+
+
+def test_ontoterm_variable_name_with_parents():
+ parent = OntoTerm(uri="http://example.org#Food", name="pizza:Food")
+ term = OntoTerm(uri="http://example.org#Pizza", name="pizza:Pizza")
+ term._parents.append(parent)
+ assert term.variable_name == "Food_Pizza"
+
+
+def test_ontoterm_variable_name_data_property():
+ term = OntoTerm(
+ uri="http://example.org#hasPrice",
+ name="pizza:hasPrice",
+ node_type="data_property",
+ )
+ assert term.variable_name == "hasPricevalue"
+
+
+def test_ontoterm_any_property():
+ term = OntoTerm(uri="http://example.org#Pizza", name="pizza:Pizza")
+ any_term = term.any
+ assert any_term._enforce_type is False
+ assert any_term._add_subclass is False
+
+
+def test_ontoterm_all_subtypes_property():
+ term = OntoTerm(uri="http://example.org#Pizza", name="pizza:Pizza")
+ all_term = term.all_subtypes
+ assert all_term._enforce_type is False
+ assert all_term._add_subclass is True
+
+
+def test_ontoterm_only_property():
+ term = OntoTerm(uri="http://example.org#Pizza", name="pizza:Pizza")
+ only_term = term.only
+ assert only_term._enforce_type is True
+ assert only_term._add_subclass is False
+
+
+def test_ontoterm_repr():
+ term = OntoTerm(uri="http://example.org#Pizza", name="pizza:Pizza")
+ assert str(term) == "pizza:Pizza"
+
+
+def test_ontoterm_clean_datatype():
+ term = OntoTerm(uri="http://example.org#Pizza")
+ assert term._clean_datatype("str") == "string"
+ assert term._clean_datatype("int") == "int"
+
+
+def test_ontoterm_eq_operator_data_property():
+ term = OntoTerm(
+ uri="http://example.org#hasPrice",
+ name="pizza:hasPrice",
+ node_type="data_property",
+ rn=["float"],
+ )
+ result = term == 10.5
+ assert result._condition == '(?hasPricevalue="10.5"^^xsd:float)'
+
+
+def test_ontoterm_eq_operator_non_data_property():
+ term1 = OntoTerm(
+ uri="http://example.org#Pizza", name="pizza:Pizza", node_type="class"
+ )
+ term2 = OntoTerm(
+ uri="http://example.org#Pizza", name="pizza:Pizza", node_type="class"
+ )
+ assert (term1 == term2) is True
+
+
+def test_ontoterm_lt_operator():
+ term = OntoTerm(
+ uri="http://example.org#hasPrice",
+ name="pizza:hasPrice",
+ node_type="data_property",
+ rn=["float"],
+ )
+ result = term < 10.5
+ assert result._condition == '(?hasPricevalue<"10.5"^^xsd:float)'
+
+
+def test_ontoterm_le_operator():
+ term = OntoTerm(
+ uri="http://example.org#hasPrice",
+ name="pizza:hasPrice",
+ node_type="data_property",
+ rn=["float"],
+ )
+ result = term <= 10.5
+ assert result._condition == '(?hasPricevalue<="10.5"^^xsd:float)'
+
+
+def test_ontoterm_gt_operator():
+ term = OntoTerm(
+ uri="http://example.org#hasPrice",
+ name="pizza:hasPrice",
+ node_type="data_property",
+ rn=["float"],
+ )
+ result = term > 10.5
+ assert result._condition == '(?hasPricevalue>"10.5"^^xsd:float)'
+
+
+def test_ontoterm_ge_operator():
+ term = OntoTerm(
+ uri="http://example.org#hasPrice",
+ name="pizza:hasPrice",
+ node_type="data_property",
+ rn=["float"],
+ )
+ result = term >= 10.5
+ assert result._condition == '(?hasPricevalue>="10.5"^^xsd:float)'
+
+
+def test_ontoterm_ne_operator():
+ term = OntoTerm(
+ uri="http://example.org#hasPrice",
+ name="pizza:hasPrice",
+ node_type="data_property",
+ rn=["float"],
+ )
+ result = term != 10.5
+ assert result._condition == '(?hasPricevalue!="10.5"^^xsd:float)'
+
+
+def test_ontoterm_and_operator():
+ term1 = OntoTerm(
+ uri="http://example.org#hasPrice",
+ name="pizza:hasPrice",
+ node_type="data_property",
+ rn=["float"],
+ )
+ term2 = OntoTerm(
+ uri="http://example.org#hasWeight",
+ name="pizza:hasWeight",
+ node_type="data_property",
+ rn=["float"],
+ )
+ cond1 = term1 > 10
+ cond2 = term2 < 5
+ result = cond1 & cond2
+ assert "&&" in result._condition
+ assert "hasPricevalue" in result._condition
+ assert "hasWeightvalue" in result._condition
+
+
+def test_ontoterm_or_operator():
+ term1 = OntoTerm(
+ uri="http://example.org#hasPrice",
+ name="pizza:hasPrice",
+ node_type="data_property",
+ rn=["float"],
+ )
+ term2 = OntoTerm(
+ uri="http://example.org#hasWeight",
+ name="pizza:hasWeight",
+ node_type="data_property",
+ rn=["float"],
+ )
+ cond1 = term1 > 10
+ cond2 = term2 < 5
+ result = cond1 | cond2
+ assert "||" in result._condition
+ assert "hasPricevalue" in result._condition
+ assert "hasWeightvalue" in result._condition
+
+
+def test_ontoterm_matmul_operator_deprecated():
+ term1 = OntoTerm(uri="http://example.org#Pizza", name="pizza:Pizza")
+ term2 = OntoTerm(uri="http://example.org#Food", name="pizza:Food")
+ with pytest.warns(UserWarning):
+ result = term1 @ term2
+ assert len(result._parents) == 1
+
+
+def test_ontoterm_refresh_condition():
+ term = OntoTerm(
+ uri="http://example.org#hasPrice",
+ name="pizza:hasPrice",
+ node_type="data_property",
+ rn=["float"],
+ )
+ cond = term > 10
+ cond.refresh_condition()
+ assert cond._condition is None
+ assert cond._condition_parents == []
+
+
+def test_ontoterm_refresh():
+ term = OntoTerm(uri="http://example.org#Pizza", name="pizza:Pizza")
+ parent = OntoTerm(uri="http://example.org#Food", name="pizza:Food")
+ term._parents.append(parent)
+ term._condition = "test"
+ term.refresh()
+ assert term._condition is None
+ assert term._parents == []
+ assert term._condition_parents == []
+
+
+def test_ontoterm_operator_type_checking():
+ term = OntoTerm(
+ uri="http://example.org#Pizza", name="pizza:Pizza", node_type="class"
+ )
+ with pytest.raises(TypeError):
+ term < 10
+
+
+def test_ontoterm_operator_requires_data_property():
+ term = OntoTerm(
+ uri="http://example.org#Pizza", name="pizza:Pizza", node_type="class"
+ )
+ with pytest.raises(TypeError):
+ term > 5
+
+
+def test_ontoterm_and_requires_condition():
+ term1 = OntoTerm(
+ uri="http://example.org#hasPrice",
+ name="pizza:hasPrice",
+ node_type="data_property",
+ rn=["float"],
+ )
+ term2 = OntoTerm(
+ uri="http://example.org#hasWeight",
+ name="pizza:hasWeight",
+ node_type="data_property",
+ rn=["float"],
+ )
+ with pytest.raises(ValueError):
+ term1 & term2
+
+
+def test_ontoterm_and_requires_ontoterm():
+ term = OntoTerm(
+ uri="http://example.org#hasPrice",
+ name="pizza:hasPrice",
+ node_type="data_property",
+ rn=["float"],
+ )
+ cond = term > 10
+ with pytest.raises(TypeError):
+ cond & "not a term"