From d6a5c0f596a212f0e1d4e4b351b5b0e6857d74f7 Mon Sep 17 00:00:00 2001 From: Matthias Baumgartner Date: Wed, 26 Jul 2023 12:48:54 +0200 Subject: refactored naming policy into uri matcher --- test/extractor/generic/test_constant.py | 5 +- test/extractor/generic/test_path.py | 7 +- test/extractor/generic/test_stat.py | 5 +- test/extractor/image/face/test_detect.py | 8 +- test/extractor/image/face/test_identify.py | 15 +-- test/extractor/image/test_colors_spatial.py | 5 +- test/extractor/image/test_iptc.py | 21 ++-- test/extractor/image/test_photometrics.py | 5 +- test/extractor/test_preview.py | 5 +- test/lib/test_bsie.py | 24 +++-- test/lib/test_naming_policy.py | 158 ---------------------------- test/lib/test_pipeline.py | 5 +- test/matcher/__init__.py | 0 test/matcher/test_default_matcher.py | 104 ++++++++++++++++++ test/matcher/test_matcher.py | 62 +++++++++++ test/matcher/test_nodes.py | 96 +++++++++++++++++ test/utils/test_node.py | 92 ---------------- 17 files changed, 323 insertions(+), 294 deletions(-) delete mode 100644 test/lib/test_naming_policy.py create mode 100644 test/matcher/__init__.py create mode 100644 test/matcher/test_default_matcher.py create mode 100644 test/matcher/test_matcher.py create mode 100644 test/matcher/test_nodes.py delete mode 100644 test/utils/test_node.py (limited to 'test') diff --git a/test/extractor/generic/test_constant.py b/test/extractor/generic/test_constant.py index 77ee02b..ea18385 100644 --- a/test/extractor/generic/test_constant.py +++ b/test/extractor/generic/test_constant.py @@ -3,7 +3,8 @@ import unittest # bsie imports -from bsie.utils import node as _node, ns +from bsie.matcher import nodes +from bsie.utils import ns # objects to test from bsie.extractor.generic.constant import Constant @@ -28,7 +29,7 @@ class TestConstant(unittest.TestCase): (ns.bse.comment, 'the quick brown fox jumps over the lazy dog.'), ] ext = Constant(schema, tuples) - node = _node.Node(ns.bsn.Entity, '') # Blank node + node = nodes.Entity(ucid='abc123') # Blank node p_author = ext.schema.predicate(ns.bse.author) p_comment = ext.schema.predicate(ns.bse.comment) entity = ext.schema.node(ns.bsfs.Node).child(ns.bsn.Entity) diff --git a/test/extractor/generic/test_path.py b/test/extractor/generic/test_path.py index 569703d..132b670 100644 --- a/test/extractor/generic/test_path.py +++ b/test/extractor/generic/test_path.py @@ -5,7 +5,8 @@ import unittest # bsie imports from bsie.extractor import base -from bsie.utils import bsfs, node as _node, ns +from bsie.matcher import nodes +from bsie.utils import bsfs, ns # objects to test from bsie.extractor.generic.path import Path @@ -40,7 +41,7 @@ class TestPath(unittest.TestCase): def test_extract(self): ext = Path() - node = _node.Node(ns.bsn.Entity, '') # Blank node + node = nodes.Entity(ucid='abc123') content = '/tmp/foo/bar' p_filename = ext.schema.predicate(ns.bse.filename) p_dirname = ext.schema.predicate(ns.bse.dirname) @@ -68,7 +69,7 @@ class TestPath(unittest.TestCase): self.assertSetEqual(set(ext.extract(node, '', (p_filename, p_dirname))), {(node, p_filename, ''), (node, p_dirname, os.path.dirname(os.getcwd()))}) # errors are suppressed - self.assertSetEqual(set(ext.extract(node, None, (p_filename, ))), set()) + self.assertSetEqual(set(ext.extract(node, None, (p_filename, p_dirname))), set()) ## main ## diff --git a/test/extractor/generic/test_stat.py b/test/extractor/generic/test_stat.py index 0e83e24..38a9c0c 100644 --- a/test/extractor/generic/test_stat.py +++ b/test/extractor/generic/test_stat.py @@ -5,7 +5,8 @@ import unittest # bsie imports from bsie.extractor import base -from bsie.utils import bsfs, node as _node, ns +from bsie.matcher import nodes +from bsie.utils import bsfs, ns # objects to test from bsie.extractor.generic.stat import Stat @@ -34,7 +35,7 @@ class TestStat(unittest.TestCase): def test_extract(self): ext = Stat() - node = _node.Node(ns.bsn.Entity, '') # Blank node + node = nodes.Entity(ucid='abc123') content = os.stat(__file__) p_filesize = ext.schema.predicate(ns.bse.filesize) entity = ext.schema.node(ns.bsfs.Node).child(ns.bsn.Entity) diff --git a/test/extractor/image/face/test_detect.py b/test/extractor/image/face/test_detect.py index 92375a2..89a3461 100644 --- a/test/extractor/image/face/test_detect.py +++ b/test/extractor/image/face/test_detect.py @@ -8,8 +8,9 @@ import unittest # bsie imports from bsie.extractor import base +from bsie.matcher import nodes from bsie.reader.face import FaceExtract -from bsie.utils import bsfs, node as _node, ns +from bsie.utils import bsfs, ns # objects to test from bsie.extractor.image.face.detect import FaceDetect, bsf @@ -31,10 +32,11 @@ class TestFaceDetect(unittest.TestCase): # setup rdr = FaceExtract() ext = FaceDetect() - subject = _node.Node(ns.bsfs.Entity) + subject = nodes.Entity(ucid='abc123') content = rdr(os.path.join(os.path.dirname(__file__), 'testface1.jpg')) principals = set(ext.principals) - face = _node.Node(ns.bsn.Face, ucid='2a7203c1515e0caa66a7461452c0b4552f1433a613cb3033e59ed2361790ad45') + face = nodes.Face( + ucid='2a7203c1515e0caa66a7461452c0b4552f1433a613cb3033e59ed2361790ad45') triples = list(ext.extract(subject, content, principals)) # principals is bse:face self.assertSetEqual(principals, {ext.schema.predicate(ns.bse.face)}) diff --git a/test/extractor/image/face/test_identify.py b/test/extractor/image/face/test_identify.py index dde41db..2d52353 100644 --- a/test/extractor/image/face/test_identify.py +++ b/test/extractor/image/face/test_identify.py @@ -10,8 +10,9 @@ import requests # bsie imports from bsie.extractor import base +from bsie.matcher import nodes from bsie.reader.face import FaceExtract -from bsie.utils import bsfs, node as _node, ns +from bsie.utils import bsfs, ns # objects to test from bsie.extractor.image.face.identify import FaceIdentify, bsf @@ -106,11 +107,12 @@ class TestFaceIdentify(unittest.TestCase): os.path.join(os.path.dirname(__file__), 'ref_embeds.npy'), os.path.join(os.path.dirname(__file__), 'ref_mapping.csv'), ) - subject = _node.Node(ns.bsfs.Entity) + subject = nodes.Entity(ucid='abc123') content = rdr(os.path.join(os.path.dirname(__file__), 'testface1.jpg')) principals = set(ext.principals) - face = _node.Node(ns.bsn.Face, ucid='2a7203c1515e0caa66a7461452c0b4552f1433a613cb3033e59ed2361790ad45') - person = _node.Node(ns.bsn.Person, uri='https://example.com/user/Angelina_Jolie') + face = nodes.Face( + ucid='2a7203c1515e0caa66a7461452c0b4552f1433a613cb3033e59ed2361790ad45') + person = nodes.Person(uri='https://example.com/user/Angelina_Jolie') triples = list(ext.extract(subject, content, principals)) # principls is bse:face, bsf:depicts self.assertSetEqual(set(ext.principals), { @@ -128,10 +130,11 @@ class TestFaceIdentify(unittest.TestCase): self.assertListEqual(list(ext.extract(subject, content, principals)), []) # identifies the correct person despite somewhat similar options content = rdr(os.path.join(os.path.dirname(__file__), 'testface3.jpg')) - face = _node.Node(ns.bsn.Face, ucid='f61fac01ef686ee05805afef1e7a10ba54c30dc1aa095d9e77d79ccdfeb40dc5') + face = nodes.Face( + ucid='f61fac01ef686ee05805afef1e7a10ba54c30dc1aa095d9e77d79ccdfeb40dc5') triples = list(ext.extract(subject, content, principals)) self.assertEqual(len(triples), 2) - person = _node.Node(ns.bsn.Person, uri='https://example.com/user/Paul_Rudd') + person = nodes.Person(uri='https://example.com/user/Paul_Rudd') self.assertIn((subject, ext.schema.predicate(ns.bse.face), face), triples) self.assertIn((face, ext.schema.predicate(bsf.depicts), person), triples) # no triples on principal mismatch diff --git a/test/extractor/image/test_colors_spatial.py b/test/extractor/image/test_colors_spatial.py index 902ab6d..1c87bb7 100644 --- a/test/extractor/image/test_colors_spatial.py +++ b/test/extractor/image/test_colors_spatial.py @@ -8,7 +8,8 @@ import PIL.Image # bsie imports from bsie.extractor import base -from bsie.utils import bsfs, ns, node as _node +from bsie.matcher import nodes +from bsie.utils import bsfs, ns # objects to test from bsie.extractor.image.colors_spatial import ColorsSpatial @@ -73,7 +74,7 @@ class TestColorsSpatial(unittest.TestCase): def test_extract(self): ext = ColorsSpatial(2,2,2) img = PIL.Image.open(os.path.join(os.path.dirname(__file__), 'testimage.jpg')) - node = _node.Node(ns.bsn.Entity, bsfs.URI('http://example.com/entity#1234')) + node = nodes.Entity(ucid='1234') principals = set(ext.principals) self.assertEqual(len(principals), 1) # valid invocation yields feature diff --git a/test/extractor/image/test_iptc.py b/test/extractor/image/test_iptc.py index 5fa763d..7efbdfe 100644 --- a/test/extractor/image/test_iptc.py +++ b/test/extractor/image/test_iptc.py @@ -4,7 +4,8 @@ import unittest # bsie imports from bsie.extractor import base -from bsie.utils import bsfs, node as _node, ns +from bsie.matcher import nodes +from bsie.utils import bsfs, ns # objects to test from bsie.extractor.image.iptc import Iptc @@ -36,29 +37,29 @@ class TestIptc(unittest.TestCase): def test_extract(self): ext = Iptc() - node = _node.Node(ns.bsfs.File, '') # Blank node + subject = nodes.Entity(ucid='abc123') content = { 'Iptc.Application2.Keywords': ['hello', 'world'], 'Iptc.Application2.RecordVersion': '4', } # target tags - t_hello = _node.Node(ns.bsn.Tag, label='hello') - t_world = _node.Node(ns.bsn.Tag, label='world') + t_hello = nodes.Tag(label='hello') + t_world = nodes.Tag(label='world') # invalid principals are ignored - self.assertSetEqual(set(ext.extract(node, content, {ns.bse.filename})), set()) + self.assertSetEqual(set(ext.extract(subject, content, {ns.bse.filename})), set()) # extract finds all relevant information - self.assertSetEqual(set(ext.extract(node, content, {ext.schema.predicate(ns.bse.tag)})), { - (node, ext.schema.predicate(ns.bse.tag), t_hello), - (node, ext.schema.predicate(ns.bse.tag), t_world), + self.assertSetEqual(set(ext.extract(subject, content, {ext.schema.predicate(ns.bse.tag)})), { + (subject, ext.schema.predicate(ns.bse.tag), t_hello), + (subject, ext.schema.predicate(ns.bse.tag), t_world), (t_hello, ext.schema.predicate(ns.bst.label), 'hello'), (t_world, ext.schema.predicate(ns.bst.label), 'world'), }) # empty content is acceptable - self.assertSetEqual(set(ext.extract(node, {}, set(ext.principals))), set()) + self.assertSetEqual(set(ext.extract(subject, {}, set(ext.principals))), set()) # no principals is acceptable - self.assertSetEqual(set(ext.extract(node, content, set())), set()) + self.assertSetEqual(set(ext.extract(subject, content, set())), set()) ## main ## diff --git a/test/extractor/image/test_photometrics.py b/test/extractor/image/test_photometrics.py index fb219e2..1316618 100644 --- a/test/extractor/image/test_photometrics.py +++ b/test/extractor/image/test_photometrics.py @@ -4,7 +4,8 @@ import unittest # bsie imports from bsie.extractor import base -from bsie.utils import bsfs, node as _node, ns +from bsie.matcher import nodes +from bsie.utils import bsfs, ns # objects to test from bsie.extractor.image.photometrics import Exif, _gps_to_dec @@ -55,7 +56,7 @@ class TestExif(unittest.TestCase): def test_extract(self): ext = Exif() - node = _node.Node(ns.bsfs.File, '') # Blank node + node = nodes.Entity(ucid='abc123') content = { 'Exif.Photo.ExposureTime': '10/600', 'Exif.Photo.FNumber': '48/10', diff --git a/test/extractor/test_preview.py b/test/extractor/test_preview.py index 6526783..7b60520 100644 --- a/test/extractor/test_preview.py +++ b/test/extractor/test_preview.py @@ -9,7 +9,8 @@ import PIL.Image # bsie imports from bsie.extractor import base -from bsie.utils import bsfs, node as _node, ns +from bsie.matcher import nodes +from bsie.utils import bsfs, ns from bsie.reader.preview import Preview as Reader # objects to test @@ -69,7 +70,7 @@ class TestPreview(unittest.TestCase): def test_extract(self): # setup dependents rdr = Reader() - subject = _node.Node(ns.bsn.Entity) + subject = nodes.Entity(ucid='abc123') path = os.path.join(os.path.dirname(__file__), 'testimage.jpg') # setup extractor diff --git a/test/lib/test_bsie.py b/test/lib/test_bsie.py index 6586e58..a154477 100644 --- a/test/lib/test_bsie.py +++ b/test/lib/test_bsie.py @@ -6,9 +6,10 @@ import unittest # bsie imports from bsie.extractor import ExtractorBuilder from bsie.extractor.base import SCHEMA_PREAMBLE -from bsie.lib import PipelineBuilder, DefaultNamingPolicy +from bsie.lib import PipelineBuilder +from bsie.matcher import nodes, DefaultMatcher from bsie.reader import ReaderBuilder -from bsie.utils import bsfs, node, ns +from bsie.utils import bsfs, ns # objects to test from bsie.lib.bsie import BSIE @@ -35,13 +36,13 @@ class TestBSIE(unittest.TestCase): )}, ]) # build pipeline - self.naming_policy = DefaultNamingPolicy(host='http://example.com/local', user='me') + self.matcher = DefaultMatcher(host='http://example.com/local', user='me') pbuild = PipelineBuilder(rbuild, ebuild) self.pipeline = pbuild.build() def test_construction(self): # only pipeline and naming policy - lib = BSIE(self.pipeline, self.naming_policy) + lib = BSIE(self.pipeline, self.matcher) self.assertSetEqual(set(lib.principals), { ns.bse.filename, ns.bse.dirname, @@ -71,7 +72,7 @@ class TestBSIE(unittest.TestCase): ''')) # specify collect - lib = BSIE(self.pipeline, self.naming_policy, collect={ + lib = BSIE(self.pipeline, self.matcher, collect={ ns.bse.filesize, ns.bse.author, ns.bse.inexistent, @@ -92,7 +93,7 @@ class TestBSIE(unittest.TestCase): bsfs:unique "true"^^xsd:boolean . ''')) # empty collect is disregarded - lib = BSIE(self.pipeline, self.naming_policy, collect={}) + lib = BSIE(self.pipeline, self.matcher, collect={}) self.assertSetEqual(set(lib.principals), { ns.bse.filename, ns.bse.dirname, @@ -123,7 +124,7 @@ class TestBSIE(unittest.TestCase): ''')) # specify discard - lib = BSIE(self.pipeline, self.naming_policy, discard={ + lib = BSIE(self.pipeline, self.matcher, discard={ ns.bse.filesize, ns.bse.filename, ns.bse.inexistent, @@ -151,7 +152,7 @@ class TestBSIE(unittest.TestCase): ''')) # specify collect and discard - lib = BSIE(self.pipeline, self.naming_policy, + lib = BSIE(self.pipeline, self.matcher, collect={ns.bse.filesize, ns.bse.author, ns.bse.foo, ns.bse.bar}, discard={ns.bse.author, ns.bse.foo, ns.bse.foobar}, ) @@ -168,7 +169,7 @@ class TestBSIE(unittest.TestCase): def test_from_file(self): # setup - lib = BSIE(self.pipeline, self.naming_policy) + lib = BSIE(self.pipeline, self.matcher) self.assertSetEqual(set(lib.principals), { ns.bse.filesize, ns.bse.filename, @@ -176,7 +177,10 @@ class TestBSIE(unittest.TestCase): ns.bse.author, }) content_hash = 'a948904f2f0f479b8f8197694b30184b0d2ed1c1cd2a1ec0fb85d299a192a447' - subject = node.Node(ns.bsn.Entity, uri=f'http://example.com/local/me/file#{content_hash}') + subject = nodes.Entity( + uri=f'http://example.com/local/me/file#{content_hash}', + ucid=content_hash, + ) testfile = os.path.join(os.path.dirname(__file__), 'testfile.t') # from_file extracts all available triples diff --git a/test/lib/test_naming_policy.py b/test/lib/test_naming_policy.py deleted file mode 100644 index a078fbd..0000000 --- a/test/lib/test_naming_policy.py +++ /dev/null @@ -1,158 +0,0 @@ - -# standard imports -import unittest - -# bsie imports -from bsie.utils import ns, errors -from bsie.utils.bsfs import URI -from bsie.utils.node import Node - -# objects to test -from bsie.lib.naming_policy import NamingPolicy, NamingPolicyIterator, DefaultNamingPolicy - - - -## code ## - -class TestDefaultNamingPolicy(unittest.TestCase): - - def test_handle_node(self): - # setup - policy = DefaultNamingPolicy('http://example.com', 'me') - # handle_node doesn't modify existing uris - self.assertEqual(policy.handle_node( - Node(ns.bsn.Invalid, uri='http://example.com/you/foo#bar')).uri, - URI('http://example.com/you/foo#bar')) - # processes bsn:Entity - self.assertEqual(policy.handle_node( - Node(ns.bsn.Entity, ucid='abc123cba')).uri, - URI('http://example.com/me/file#abc123cba')) - # processes bsn:Preview - self.assertEqual(policy.handle_node( - Node(ns.bsn.Preview, ucid='abc123cba', size=123)).uri, - URI('http://example.com/me/preview#abc123cba_s123')) - # processes bsn:Tag - self.assertEqual(policy.handle_node( - Node(ns.bsn.Tag, label='hello')).uri, - URI('http://example.com/me/tag#hello')) - # processes bsn:Face - self.assertEqual(policy.handle_node( - Node(ns.bsn.Face, ucid='hello')).uri, - URI('http://example.com/me/face#hello')) - # raises an exception on unknown types - self.assertRaises(errors.ProgrammingError, policy.handle_node, - Node(ns.bsn.Invalid, ucid='abc123cba', size=123)) - - def test_name_entity(self): - # setup - policy = DefaultNamingPolicy('http://example.com', 'me') - # name_entity uses ucid - self.assertEqual(policy.name_entity( - Node(ns.bsn.Entity, ucid='123abc321')).uri, - URI('http://example.com/me/file#123abc321')) - # name_entity falls back to a random guid - self.assertTrue(policy.name_entity( - Node(ns.bsn.Entity)).uri.startswith('http://example.com/me/file#')) - - def test_name_preview(self): - # setup - policy = DefaultNamingPolicy('http://example.com', 'me') - # name_preview uses ucid - self.assertEqual(policy.name_preview( - Node(ns.bsn.Preview, ucid='123abc321')).uri, - URI('http://example.com/me/preview#123abc321')) - self.assertEqual(policy.name_preview( - Node(ns.bsn.Preview, ucid='123abc321', size=400)).uri, - URI('http://example.com/me/preview#123abc321_s400')) - # name_preview uses source - self.assertEqual(policy.name_preview( - Node(ns.bsn.Preview, source=Node(ns.bsn.Entity, ucid='123file321'))).uri, - URI('http://example.com/me/preview#123file321')) - self.assertEqual(policy.name_preview( - Node(ns.bsn.Preview, source=Node(ns.bsn.Entity, ucid='123file321'), size=300)).uri, - URI('http://example.com/me/preview#123file321_s300')) - # name_preview falls back to a random guid - self.assertTrue(policy.name_preview( - Node(ns.bsn.Preview)).uri.startswith('http://example.com/me/preview#')) - self.assertTrue(policy.name_preview( - Node(ns.bsn.Preview, size=200)).uri.startswith('http://example.com/me/preview#')) - self.assertTrue(policy.name_preview( - Node(ns.bsn.Preview, size=200)).uri.endswith('_s200')) - - def test_name_tag(self): - # setup - policy = DefaultNamingPolicy('http://example.com', 'me') - # name_tag uses label - self.assertEqual(policy.name_tag( - Node(ns.bsn.Tag, label='hello')).uri, - URI('http://example.com/me/tag#hello')) - # name_tag matches the label - self.assertEqual( - policy.name_tag(Node(ns.bsn.Tag, label='world')), - policy.name_tag(Node(ns.bsn.Tag, label='world')), - ) - self.assertNotEqual( - policy.name_tag(Node(ns.bsn.Tag, label='hello')), - policy.name_tag(Node(ns.bsn.Tag, label='world')), - ) - # label can include characters that are not valid for an uri - self.assertEqual(policy.name_tag( - Node(ns.bsn.Preview, label='hello world { foo bar ] ')).uri, - URI('http://example.com/me/tag#hello%20world%20%7B%20foo%20bar%20%5D%20')) - # name_tag falls back to a random guid - self.assertTrue(policy.name_tag( - Node(ns.bsn.Tag,)).uri.startswith('http://example.com/me/tag#')) - - def test_name_face(self): - # setup - policy = DefaultNamingPolicy('http://example.com', 'me') - # name_face uses ucid - self.assertEqual(policy.name_face( - Node(ns.bsn.Face, ucid='hello_world')).uri, - URI('http://example.com/me/face#hello_world')) - # name_face falls back to a random guid - self.assertTrue(policy.name_face( - Node(ns.bsn.Face)).uri.startswith('http://example.com/me/face#')) - - -class TestNamingPolicyIterator(unittest.TestCase): - - def test_call(self): # NOTE: We test NamingPolicy.__call__ here - # setup - policy = DefaultNamingPolicy('http://example.com', 'me') - # call accepts list - triples = [('node', 'pred', 'value'), ('node', 'pred', 'value')] - it = policy(triples) - self.assertIsInstance(it, NamingPolicyIterator) - self.assertEqual(it._iterable, triples) - self.assertEqual(it._policy, policy) - # call accepts iterator - triples = iter([('node', 'pred', 'value'), ('node', 'pred', 'value')]) - it = policy(triples) - self.assertIsInstance(it, NamingPolicyIterator) - self.assertEqual(it._iterable, triples) - self.assertEqual(it._policy, policy) - - def test_iter(self): - # setup - policy = DefaultNamingPolicy('http://example.com', 'me') - triples = [ - (Node(ns.bsn.Entity, ucid='foo'), 'predA', 'hello'), - (Node(ns.bsn.Preview, ucid='bar'), 'predB', 1234), - (Node(ns.bsn.Preview, ucid='hello'), 'predC', Node(ns.bsn.Entity, ucid='world')) - ] - # handles nodes, handles values, ignores predicate - self.assertListEqual(list(policy(triples)), [ - (Node(ns.bsn.Entity, uri='http://example.com/me/file#foo'), 'predA', 'hello'), - (Node(ns.bsn.Preview, uri='http://example.com/me/preview#bar'), 'predB', 1234), - (Node(ns.bsn.Preview, uri='http://example.com/me/preview#hello'), 'predC', - Node(ns.bsn.Entity, uri='http://example.com/me/file#world')), - ]) - - -## main ## - -if __name__ == '__main__': - unittest.main() - -## EOF ## diff --git a/test/lib/test_pipeline.py b/test/lib/test_pipeline.py index 8d836fd..05c6768 100644 --- a/test/lib/test_pipeline.py +++ b/test/lib/test_pipeline.py @@ -5,7 +5,8 @@ import os import unittest # bsie imports -from bsie.utils import bsfs, errors, node, ns +from bsie.matcher import nodes +from bsie.utils import bsfs, errors, ns import bsie.extractor.generic.constant import bsie.extractor.generic.path import bsie.extractor.generic.stat @@ -84,7 +85,7 @@ class TestPipeline(unittest.TestCase): pipeline = Pipeline(self.ext2rdr) # build objects for tests content_hash = 'a948904f2f0f479b8f8197694b30184b0d2ed1c1cd2a1ec0fb85d299a192a447' - subject = node.Node(ns.bsn.Entity, ucid=content_hash) + subject = nodes.Entity(ucid=content_hash) testfile = os.path.join(os.path.dirname(__file__), 'testfile.t') p_filename = pipeline.schema.predicate(ns.bse.filename) p_dirname = pipeline.schema.predicate(ns.bse.dirname) diff --git a/test/matcher/__init__.py b/test/matcher/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/matcher/test_default_matcher.py b/test/matcher/test_default_matcher.py new file mode 100644 index 0000000..2ed371f --- /dev/null +++ b/test/matcher/test_default_matcher.py @@ -0,0 +1,104 @@ + +# standard imports +from dataclasses import dataclass +import unittest + +# bsie imports +from bsie.matcher import nodes +from bsie.utils import ns, errors +from bsie.utils.bsfs import URI + +# objects to test +from bsie.matcher.default_matcher import DefaultMatcher + + +## code ## + +@dataclass(kw_only=True, unsafe_hash=True) +class Invalid(nodes.Node): + ucid: str + +class TestDefaultMatcher(unittest.TestCase): + + def test_match_node(self): + # setup + matcher = DefaultMatcher('http://example.com', 'me') + # match_node doesn't modify existing uris + self.assertEqual(matcher.match_node( + nodes.Node(uri='http://example.com/you/foo#bar')).uri, + URI('http://example.com/you/foo#bar')) + # processes bsn:Entity + self.assertEqual(matcher.match_node( + nodes.Entity(ucid='abc123cba')).uri, + URI('http://example.com/me/file#abc123cba')) + # processes bsn:Preview + self.assertEqual(matcher.match_node( + nodes.Preview(ucid='abc123cba', size=123)).uri, + URI('http://example.com/me/preview#abc123cba_s123')) + # processes bsn:Tag + self.assertEqual(matcher.match_node( + nodes.Tag(label='hello')).uri, + URI('http://example.com/me/tag#hello')) + # processes bsn:Face + self.assertEqual(matcher.match_node( + nodes.Face(ucid='hello')).uri, + URI('http://example.com/me/face#hello')) + # raises an exception on unknown types + self.assertRaises(ValueError, matcher.match_node, + Invalid(ucid='abc123cba')) + + def test_match_entity(self): + # setup + matcher = DefaultMatcher('http://example.com', 'me') + # match_entity uses ucid + self.assertEqual(matcher.match_entity( + nodes.Entity(ucid='123abc321')).uri, + URI('http://example.com/me/file#123abc321')) + + def test_match_preview(self): + # setup + matcher = DefaultMatcher('http://example.com', 'me') + # match_preview uses ucid + self.assertEqual(matcher.match_preview( + nodes.Preview(ucid='123abc321', size=400)).uri, + URI('http://example.com/me/preview#123abc321_s400')) + self.assertEqual(matcher.match_preview( + nodes.Preview(ucid='321cba123', size=200)).uri, + URI('http://example.com/me/preview#321cba123_s200')) + + def test_match_tag(self): + # setup + matcher = DefaultMatcher('http://example.com', 'me') + # match_tag uses label + self.assertEqual(matcher.match_tag( + nodes.Tag(label='hello')).uri, + URI('http://example.com/me/tag#hello')) + # match_tag matches the label + self.assertEqual( + matcher.match_tag(nodes.Tag(label='world')), + matcher.match_tag(nodes.Tag(label='world')), + ) + self.assertNotEqual( + matcher.match_tag(nodes.Tag(label='hello')), + matcher.match_tag(nodes.Tag(label='world')), + ) + # label can include characters that are not valid for an uri + self.assertEqual(matcher.match_tag( + nodes.Tag(label='hello world { foo bar ] ')).uri, + URI('http://example.com/me/tag#hello%20world%20%7B%20foo%20bar%20%5D%20')) + + def test_match_face(self): + # setup + matcher = DefaultMatcher('http://example.com', 'me') + # match_face uses ucid + self.assertEqual(matcher.match_face( + nodes.Face(ucid='hello_world')).uri, + URI('http://example.com/me/face#hello_world')) + + +## main ## + +if __name__ == '__main__': + unittest.main() + +## EOF ## diff --git a/test/matcher/test_matcher.py b/test/matcher/test_matcher.py new file mode 100644 index 0000000..eaa4766 --- /dev/null +++ b/test/matcher/test_matcher.py @@ -0,0 +1,62 @@ + +# standard imports +import unittest + +# bsie imports +from bsie.matcher import nodes +from bsie.utils import ns, errors +from bsie.utils.bsfs import URI + +# objects to test +from bsie.matcher.matcher import Matcher, MatcherIterator + + +## code ## + +class StubMatcher(Matcher): + def match_node(self, node): + if node.uri is None: + node.uri = 'foo' + return node + +class TestMatcherIterator(unittest.TestCase): + + def test_call(self): + # setup + matcher = StubMatcher() + # call accepts list + triples = [('node', 'pred', 'value'), ('node', 'pred', 'value')] + it = matcher(triples) + self.assertIsInstance(it, MatcherIterator) + self.assertEqual(it._iterable, triples) + self.assertEqual(it._matcher, matcher) + # call accepts iterator + triples = iter([('node', 'pred', 'value'), ('node', 'pred', 'value')]) + it = matcher(triples) + self.assertIsInstance(it, MatcherIterator) + self.assertEqual(it._iterable, triples) + self.assertEqual(it._matcher, matcher) + + def test_iter(self): + # setup + matcher = StubMatcher() + triples = [ + (nodes.Entity(ucid='foo'), 'predA', 'hello'), + (nodes.Preview(ucid='bar', size=123), 'predB', 1234), + (nodes.Preview(ucid='hello', size=321), 'predC', nodes.Entity(ucid='world')) + ] + # handles nodes, handles values, ignores predicate + self.assertListEqual(list(matcher(triples)), [ + (nodes.Entity(uri='foo', ucid='foo'), 'predA', 'hello'), + (nodes.Preview(uri='foo', ucid='bar', size=123), 'predB', 1234), + (nodes.Preview(uri='foo', ucid='hello', size=321), 'predC', + nodes.Entity(uri='foo', ucid='world')), + ]) + + +## main ## + +if __name__ == '__main__': + unittest.main() + +## EOF ## diff --git a/test/matcher/test_nodes.py b/test/matcher/test_nodes.py new file mode 100644 index 0000000..d884132 --- /dev/null +++ b/test/matcher/test_nodes.py @@ -0,0 +1,96 @@ + +# standard imports +import unittest + +# bsie imports +from bsie.utils import bsfs, ns + +# objects to test +from bsie.matcher import nodes + + +## code ## + +class TestNode(unittest.TestCase): + def test_node(self): + # cannot pass additional kwargs + self.assertRaises(TypeError, nodes.Node, foo='bar') + # may pass uri + self.assertIsInstance(nodes.Node(uri='bar'), nodes.Node) + self.assertEqual(nodes.Node(uri='bar').uri, 'bar') + + def test_entity(self): + # must pass ucid + self.assertRaises(TypeError, nodes.Entity) + self.assertRaises(TypeError, nodes.Entity, uri='foo') + self.assertIsInstance(nodes.Entity(ucid='foo'), nodes.Entity) + self.assertIsInstance(nodes.Entity(ucid='bar'), nodes.Entity) + # cannot pass additional kwargs + self.assertRaises(TypeError, nodes.Entity, ucid='foo', foo='bar') + # may pass uri + self.assertIsInstance(nodes.Entity(ucid='foo', uri='bar'), nodes.Entity) + self.assertEqual(nodes.Entity(ucid='foo', uri='bar').uri, 'bar') + # has node_type + self.assertEqual(nodes.Entity(ucid='foo').node_type, ns.bsn.Entity) + + def test_face(self): + # must pass ucid + self.assertRaises(TypeError, nodes.Face) + self.assertRaises(TypeError, nodes.Face, uri='foo') + self.assertIsInstance(nodes.Face(ucid='foo'), nodes.Face) + self.assertIsInstance(nodes.Face(ucid='bar'), nodes.Face) + # cannot pass additional kwargs + self.assertRaises(TypeError, nodes.Face, ucid='foo', foo='bar') + # may pass uri + self.assertIsInstance(nodes.Face(ucid='foo', uri='bar'), nodes.Face) + self.assertEqual(nodes.Face(ucid='foo', uri='bar').uri, 'bar') + # has node_type + self.assertEqual(nodes.Face(ucid='foo').node_type, ns.bsn.Face) + + def test_person(self): + # cannot pass additional kwargs + self.assertRaises(TypeError, nodes.Person, foo='bar') + # may pass uri + self.assertIsInstance(nodes.Person(uri='bar'), nodes.Person) + self.assertEqual(nodes.Person(uri='bar').uri, 'bar') + # has node_type + self.assertEqual(nodes.Person().node_type, ns.bsn.Person) + + def test_preview(self): + # must pass ucid and size + self.assertRaises(TypeError, nodes.Preview) + self.assertRaises(TypeError, nodes.Preview, ucid='foo') + self.assertRaises(TypeError, nodes.Preview, size=123) + self.assertRaises(TypeError, nodes.Preview, ucid='foo', uri='foo') + self.assertRaises(TypeError, nodes.Preview, size=123, uri='foo') + self.assertIsInstance(nodes.Preview(ucid='foo', size=123), nodes.Preview) + self.assertIsInstance(nodes.Preview(ucid='bar', size=321), nodes.Preview) + # cannot pass additional kwargs + self.assertRaises(TypeError, nodes.Preview, ucid='foo', size=123, foo='bar') + # may pass uri + self.assertIsInstance(nodes.Preview(ucid='foo', size=123, uri='bar'), nodes.Preview) + self.assertEqual(nodes.Preview(ucid='foo', size=123, uri='bar').uri, 'bar') + # has node_type + self.assertEqual(nodes.Preview(ucid='foo', size=123).node_type, ns.bsn.Preview) + + def test_tag(self): + # must pass label + self.assertRaises(TypeError, nodes.Tag) + self.assertRaises(TypeError, nodes.Tag, uri='foo') + self.assertIsInstance(nodes.Tag(label='foo'), nodes.Tag) + self.assertIsInstance(nodes.Tag(label='bar'), nodes.Tag) + # cannot pass additional kwargs + self.assertRaises(TypeError, nodes.Tag, label='foo', foo='bar') + # may pass uri + self.assertIsInstance(nodes.Tag(label='foo', uri='bar'), nodes.Tag) + self.assertEqual(nodes.Tag(label='foo', uri='bar').uri, 'bar') + # has node_type + self.assertEqual(nodes.Tag(label='foo').node_type, ns.bsn.Tag) + + +## main ## + +if __name__ == '__main__': + unittest.main() + +## EOF ## diff --git a/test/utils/test_node.py b/test/utils/test_node.py deleted file mode 100644 index c0662a1..0000000 --- a/test/utils/test_node.py +++ /dev/null @@ -1,92 +0,0 @@ - -# standard imports -import unittest - -# bsie imports -from bsie.utils import bsfs, ns - -# objects to test -from bsie.utils.node import Node - - -## code ## - -class TestNode(unittest.TestCase): - def test_equality(self): - uri1 = bsfs.URI('http://example.com/me/entity#1234') - uri2 = bsfs.URI('http://example.com/me/entity#4321') - node = Node(ns.bsfs.Entity, uri1) - # equality respects uri - self.assertEqual(node, Node(ns.bsfs.Entity, uri1)) - self.assertEqual(hash(node), hash(Node(ns.bsfs.Entity, uri1))) - self.assertNotEqual(node, Node(ns.bsfs.Entity, uri2)) - self.assertNotEqual(hash(node), hash(Node(ns.bsfs.Entity, uri2))) - # equality respects hints - self.assertEqual( - Node(ns.bsfs.Entity, foo='foo'), - Node(ns.bsfs.Entity, foo='foo')) - self.assertEqual( - hash(Node(ns.bsfs.Entity, foo='foo')), - hash(Node(ns.bsfs.Entity, foo='foo'))) - self.assertNotEqual( - Node(ns.bsfs.Entity, foo='foo'), - Node(ns.bsfs.Entity, foo='bar')) - self.assertNotEqual( - hash(Node(ns.bsfs.Entity, foo='foo')), - hash(Node(ns.bsfs.Entity, foo='bar'))) - self.assertNotEqual( - Node(ns.bsfs.Entity, foo='bar'), - Node(ns.bsfs.Entity, bar='foo')) - self.assertNotEqual( - hash(Node(ns.bsfs.Entity, foo='bar')), - hash(Node(ns.bsfs.Entity, bar='foo'))) - # hints are irrelevant if uri is set - self.assertEqual( - Node(ns.bsfs.Entity, uri=uri1, foo='bar'), - Node(ns.bsfs.Entity, uri=uri1, bar='foo')) - self.assertEqual( - hash(Node(ns.bsfs.Entity, uri=uri1, foo='bar')), - hash(Node(ns.bsfs.Entity, uri=uri1, bar='foo'))) - self.assertNotEqual( - Node(ns.bsfs.Entity, uri=uri1, foo='bar'), - Node(ns.bsfs.Entity, uri=uri2, bar='foo')) - self.assertNotEqual( - hash(Node(ns.bsfs.Entity, uri=uri1, foo='bar')), - hash(Node(ns.bsfs.Entity, uri=uri2, bar='foo'))) - # equality respects node_type - self.assertNotEqual(node, Node(ns.bsfs.Foo, uri1)) - self.assertNotEqual(hash(node), hash(Node(ns.bsfs.Foo, uri1))) - # not equal to other types - self.assertNotEqual(node, 1234) - self.assertNotEqual(hash(node), hash(1234)) - self.assertNotEqual(node, uri1) - self.assertNotEqual(hash(node), hash(uri1)) - 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 = bsfs.URI('http://example.com/me/entity#1234') - # basic string conversion - node = Node(ns.bsn.Entity, uri) - self.assertEqual(str(node), 'Node(https://schema.bsfs.io/ie/Node/Entity, http://example.com/me/entity#1234)') - self.assertEqual(repr(node), 'Node(https://schema.bsfs.io/ie/Node/Entity, http://example.com/me/entity#1234)') - # string conversion respects node_type - node = Node(ns.bsn.Foo, uri) - self.assertEqual(str(node), 'Node(https://schema.bsfs.io/ie/Node/Foo, http://example.com/me/entity#1234)') - self.assertEqual(repr(node), 'Node(https://schema.bsfs.io/ie/Node/Foo, http://example.com/me/entity#1234)') - # string conversion respects uri - node = Node(ns.bsn.Entity, bsfs.URI('http://example.com/me/entity#4321')) - self.assertEqual(str(node), 'Node(https://schema.bsfs.io/ie/Node/Entity, http://example.com/me/entity#4321)') - self.assertEqual(repr(node), 'Node(https://schema.bsfs.io/ie/Node/Entity, http://example.com/me/entity#4321)') - - - -## main ## - -if __name__ == '__main__': - unittest.main() - -## EOF ## -- cgit v1.2.3