aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Baumgartner <dev@igsor.net>2022-11-25 14:39:18 +0100
committerMatthias Baumgartner <dev@igsor.net>2022-11-25 14:39:18 +0100
commit9ce32829b2bb85907a34a543bfcaa9183d1e362c (patch)
tree200dcfcdf98d9cba6f8ada52a873484289db6dbd
parentb96c6e2096c387b70e2a4c1f0bc53b6044a0dc6f (diff)
downloadbsie-9ce32829b2bb85907a34a543bfcaa9183d1e362c.tar.gz
bsie-9ce32829b2bb85907a34a543bfcaa9183d1e362c.tar.bz2
bsie-9ce32829b2bb85907a34a543bfcaa9183d1e362c.zip
string conversion and equality checks
-rw-r--r--bsie/base/extractor.py7
-rw-r--r--bsie/base/reader.py6
-rw-r--r--bsie/extractor/generic/constant.py6
-rw-r--r--bsie/utils/node.py18
-rw-r--r--test/base/__init__.py0
-rw-r--r--test/base/test_extractor.py70
-rw-r--r--test/base/test_reader.py45
-rw-r--r--test/extractor/generic/test_constant.py37
-rw-r--r--test/utils/__init__.py0
-rw-r--r--test/utils/test_node.py66
10 files changed, 253 insertions, 2 deletions
diff --git a/bsie/base/extractor.py b/bsie/base/extractor.py
index 7acf2bd..2fc4f18 100644
--- a/bsie/base/extractor.py
+++ b/bsie/base/extractor.py
@@ -63,6 +63,13 @@ class Extractor(abc.ABC):
def __repr__(self) -> str:
return f'{typename(self)}()'
+ def __eq__(self, other: typing.Any) -> bool:
+ return isinstance(other, type(self)) \
+ and self.CONTENT_READER == other.CONTENT_READER \
+ and self.schema == other.schema
+
+ def __hash__(self) -> int:
+ return hash((type(self), self.CONTENT_READER, self.schema))
def predicates(self) -> typing.Iterator[_schema.Predicate]:
"""Return the predicates that may be part of extracted triples."""
diff --git a/bsie/base/reader.py b/bsie/base/reader.py
index e59abef..b7eabf7 100644
--- a/bsie/base/reader.py
+++ b/bsie/base/reader.py
@@ -32,6 +32,12 @@ class Reader(abc.ABC):
def __repr__(self) -> str:
return f'{typename(self)}()'
+ def __eq__(self, other: typing.Any) -> bool:
+ return isinstance(other, type(self))
+
+ def __hash__(self) -> int:
+ return hash(type(self))
+
@abc.abstractmethod
def __call__(self, path: URI) -> typing.Any:
"""Return some content of the file at *path*.
diff --git a/bsie/extractor/generic/constant.py b/bsie/extractor/generic/constant.py
index 795bac6..7da792a 100644
--- a/bsie/extractor/generic/constant.py
+++ b/bsie/extractor/generic/constant.py
@@ -38,6 +38,12 @@ class Constant(extractor.Extractor):
self._tuples = tuple((self.schema.predicate(p_uri), value) for p_uri, value in tuples)
# FIXME: use schema instance for value checking
+ def __eq__(self, other: typing.Any) -> bool:
+ return super().__eq__(other) \
+ and self._tuples == other._tuples
+
+ def __hash__(self) -> int:
+ return hash((super().__hash__(), self._tuples))
def extract(
self,
diff --git a/bsie/utils/node.py b/bsie/utils/node.py
index 3a0f06b..c9c494f 100644
--- a/bsie/utils/node.py
+++ b/bsie/utils/node.py
@@ -7,8 +7,8 @@ Author: Matthias Baumgartner, 2022
# imports
import typing
-# inner-module imports
-from bsie.utils.bsfs import URI
+# bsie imports
+from bsie.utils.bsfs import URI, typename
# exports
__all__: typing.Sequence[str] = (
@@ -36,4 +36,18 @@ class Node():
self.node_type = URI(node_type)
self.uri = URI(uri)
+ def __eq__(self, other: typing.Any) -> bool:
+ return isinstance(other, Node) \
+ and other.node_type == self.node_type \
+ and other.uri == self.uri
+
+ def __hash__(self) -> int:
+ return hash((type(self), self.node_type, self.uri))
+
+ def __str__(self) -> str:
+ return f'{typename(self)}({self.node_type}, {self.uri})'
+
+ def __repr__(self) -> str:
+ return f'{typename(self)}({self.node_type}, {self.uri})'
+
## EOF ##
diff --git a/test/base/__init__.py b/test/base/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/base/__init__.py
diff --git a/test/base/test_extractor.py b/test/base/test_extractor.py
new file mode 100644
index 0000000..7a00079
--- /dev/null
+++ b/test/base/test_extractor.py
@@ -0,0 +1,70 @@
+"""
+
+Part of the bsie test suite.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# imports
+import unittest
+
+# bsie imports
+from bsie.utils import ns
+from bsie.utils.bsfs import schema as _schema, URI
+
+# objects to test
+from bsie.base import extractor
+
+
+## code ##
+
+class StubExtractor(extractor.Extractor):
+ def __init__(self):
+ super().__init__(_schema.Schema.from_string(extractor.SCHEMA_PREAMBLE + '''
+ bse:author rdfs:subClassOf bsfs:Predicate ;
+ rdfs:domain bsfs:Entity ;
+ rdfs:range xsd:string ;
+ owl:maxCardinality "INF"^^xsd:number .
+ bse:comment rdfs:subClassOf bsfs:Predicate ;
+ rdfs:domain bsfs:Entity ;
+ rdfs:range xsd:string ;
+ owl:maxCardinality "INF"^^xsd:number .
+ '''))
+
+ def extract(self, subject, content, predicates):
+ raise NotImplementedError()
+
+class StubSub(StubExtractor):
+ pass
+
+class TestExtractor(unittest.TestCase):
+ def test_essentials(self):
+ ext = StubExtractor()
+ self.assertEqual(str(ext), 'StubExtractor')
+ self.assertEqual(repr(ext), 'StubExtractor()')
+ self.assertEqual(ext, StubExtractor())
+ self.assertEqual(hash(ext), hash(StubExtractor()))
+
+ sub = StubSub()
+ self.assertEqual(str(sub), 'StubSub')
+ self.assertEqual(repr(sub), 'StubSub()')
+ self.assertEqual(sub, StubSub())
+ self.assertEqual(hash(sub), hash(StubSub()))
+ self.assertNotEqual(ext, sub)
+ self.assertNotEqual(hash(ext), hash(sub))
+
+ def test_predicates(self):
+ schema = _schema.Schema.Empty()
+ entity = schema.node(ns.bsfs.Node).get_child(ns.bsfs.Entity)
+ string = schema.literal(ns.bsfs.Literal).get_child(URI('http://www.w3.org/2001/XMLSchema#string'))
+ p_author = schema.predicate(ns.bsfs.Predicate).get_child(ns.bse.author, domain=entity, range=string)
+ p_comment = schema.predicate(ns.bsfs.Predicate).get_child(ns.bse.comment, domain=entity, range=string)
+ ext = StubExtractor()
+ self.assertSetEqual(set(ext.predicates()), {p_author, p_comment} | set(schema.predicates()))
+
+
+## main ##
+
+if __name__ == '__main__':
+ unittest.main()
+
+## EOF ##
diff --git a/test/base/test_reader.py b/test/base/test_reader.py
new file mode 100644
index 0000000..802b314
--- /dev/null
+++ b/test/base/test_reader.py
@@ -0,0 +1,45 @@
+"""
+
+Part of the bsie test suite.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# imports
+import unittest
+
+# objects to test
+from bsie.base import reader
+
+
+## code ##
+
+class StubReader(reader.Reader):
+ def __call__(self, path):
+ raise NotImplementedError()
+
+class StubSub(StubReader):
+ pass
+
+class TestReader(unittest.TestCase):
+ def test_essentials(self):
+ ext = StubReader()
+ self.assertEqual(str(ext), 'StubReader')
+ self.assertEqual(repr(ext), 'StubReader()')
+ self.assertEqual(ext, StubReader())
+ self.assertEqual(hash(ext), hash(StubReader()))
+
+ sub = StubSub()
+ self.assertEqual(str(sub), 'StubSub')
+ self.assertEqual(repr(sub), 'StubSub()')
+ self.assertEqual(sub, StubSub())
+ self.assertEqual(hash(sub), hash(StubSub()))
+ self.assertNotEqual(ext, sub)
+ self.assertNotEqual(hash(ext), hash(sub))
+
+
+## main ##
+
+if __name__ == '__main__':
+ unittest.main()
+
+## EOF ##
diff --git a/test/extractor/generic/test_constant.py b/test/extractor/generic/test_constant.py
index 7fdb8ac..aa33fb4 100644
--- a/test/extractor/generic/test_constant.py
+++ b/test/extractor/generic/test_constant.py
@@ -78,6 +78,43 @@ class TestConstant(unittest.TestCase):
#self.assertRaises(ValueError, Constant, schema, [
# (ns.bse.author, Foo())])
+ def test_eq(self):
+ schema_a = '''
+ bse:author rdfs:subClassOf bsfs:Predicate ;
+ rdfs:domain bsfs:Entity ;
+ rdfs:range xsd:string ;
+ owl:maxCardinality "1"^^xsd:number .
+ '''
+ schema_b = '''
+ bse:comment rdfs:subClassOf bsfs:Predicate ;
+ rdfs:domain bsfs:Entity ;
+ rdfs:range xsd:string ;
+ owl:maxCardinality "INF"^^xsd:number .
+ '''
+ tuples_a = [(ns.bse.author, 'Me, myself, and I')]
+ tuples_b = [(ns.bse.comment, 'the quick brown fox jumps over the lazy dog.') ]
+ # distinct instances, same data
+ self.assertEqual(
+ Constant(schema_a, tuples_a),
+ Constant(schema_a, tuples_a))
+ self.assertEqual(
+ hash(Constant(schema_a, tuples_a)),
+ hash(Constant(schema_a, tuples_a)))
+ # different data
+ self.assertNotEqual(
+ Constant(schema_a, tuples_a),
+ Constant(schema_b, tuples_b))
+ self.assertNotEqual(
+ hash(Constant(schema_a, tuples_a)),
+ hash(Constant(schema_b, tuples_b)))
+ # different objects
+ class Foo(): pass
+ self.assertNotEqual(Constant(schema_a, tuples_a), Foo())
+ self.assertNotEqual(hash(Constant(schema_a, tuples_a)), hash(Foo()))
+ self.assertNotEqual(Constant(schema_a, tuples_a), 123)
+ self.assertNotEqual(hash(Constant(schema_a, tuples_a)), hash(123))
+ self.assertNotEqual(Constant(schema_a, tuples_a), None)
+ self.assertNotEqual(hash(Constant(schema_a, tuples_a)), hash(None))
## main ##
diff --git a/test/utils/__init__.py b/test/utils/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/utils/__init__.py
diff --git a/test/utils/test_node.py b/test/utils/test_node.py
new file mode 100644
index 0000000..826f199
--- /dev/null
+++ b/test/utils/test_node.py
@@ -0,0 +1,66 @@
+"""
+
+Part of the bsie test suite.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# imports
+import unittest
+
+# bsie imports
+from bsie.utils.bsfs import URI
+from bsie.utils import ns
+
+# objects to test
+from bsie.utils.node import Node
+
+
+## code ##
+
+class TestNode(unittest.TestCase):
+ def test_equality(self):
+ uri = URI('http://example.com/me/entity#1234')
+ node = Node(ns.bsfs.Entity, uri)
+ # basic equivalence
+ self.assertEqual(node, Node(ns.bsfs.Entity, URI('http://example.com/me/entity#1234')))
+ self.assertEqual(hash(node), hash(Node(ns.bsfs.Entity, URI('http://example.com/me/entity#1234'))))
+ # equality respects uri
+ self.assertNotEqual(node, Node(ns.bsfs.Entity, URI('http://example.com/me/entity#4321')))
+ self.assertNotEqual(hash(node), hash(Node(ns.bsfs.Entity, URI('http://example.com/me/entity#4321'))))
+ # equality respects node_type
+ self.assertNotEqual(node, Node(ns.bsfs.Foo, uri))
+ self.assertNotEqual(hash(node), hash(Node(ns.bsfs.Foo, uri)))
+ # not equal to other types
+ self.assertNotEqual(node, 1234)
+ self.assertNotEqual(hash(node), hash(1234))
+ self.assertNotEqual(node, uri)
+ self.assertNotEqual(hash(node), hash(uri))
+ self.assertNotEqual(node, ns.bsfs.Entity)
+ self.assertNotEqual(hash(node), hash(ns.bsfs.Entity))
+ class Foo(): pass
+ self.assertNotEqual(node, Foo())
+ self.assertNotEqual(hash(node), hash(Foo()))
+
+ def test_str(self):
+ uri = URI('http://example.com/me/entity#1234')
+ # basic string conversion
+ node = Node(ns.bsfs.Entity, uri)
+ self.assertEqual(str(node), 'Node(http://bsfs.ai/schema/Entity, http://example.com/me/entity#1234)')
+ self.assertEqual(repr(node), 'Node(http://bsfs.ai/schema/Entity, http://example.com/me/entity#1234)')
+ # string conversion respects node_type
+ node = Node(ns.bsfs.Foo, uri)
+ self.assertEqual(str(node), 'Node(http://bsfs.ai/schema/Foo, http://example.com/me/entity#1234)')
+ self.assertEqual(repr(node), 'Node(http://bsfs.ai/schema/Foo, http://example.com/me/entity#1234)')
+ # string conversion respects uri
+ node = Node(ns.bsfs.Entity, URI('http://example.com/me/entity#4321'))
+ self.assertEqual(str(node), 'Node(http://bsfs.ai/schema/Entity, http://example.com/me/entity#4321)')
+ self.assertEqual(repr(node), 'Node(http://bsfs.ai/schema/Entity, http://example.com/me/entity#4321)')
+
+
+
+## main ##
+
+if __name__ == '__main__':
+ unittest.main()
+
+## EOF ##