diff options
author | Matthias Baumgartner <dev@igsor.net> | 2023-03-05 19:22:46 +0100 |
---|---|---|
committer | Matthias Baumgartner <dev@igsor.net> | 2023-03-05 19:22:46 +0100 |
commit | af81318ae9311fd0b0e16949cef3cfaf7996970b (patch) | |
tree | fb220da28bb7248ebf37ce09af5de88f2c1aaad4 /test/extractor | |
parent | 7bf6b33fa6d6b901e4933bfe0b2a9939d7b3f3f3 (diff) | |
parent | 8b460aa0232cd841af7b7734c91982bc83486e03 (diff) | |
download | bsie-af81318ae9311fd0b0e16949cef3cfaf7996970b.tar.gz bsie-af81318ae9311fd0b0e16949cef3cfaf7996970b.tar.bz2 bsie-af81318ae9311fd0b0e16949cef3cfaf7996970b.zip |
Merge branch 'mb/diogenes' into develop
Diffstat (limited to 'test/extractor')
-rw-r--r-- | test/extractor/generic/test_constant.py | 21 | ||||
-rw-r--r-- | test/extractor/generic/test_path.py | 13 | ||||
-rw-r--r-- | test/extractor/generic/test_stat.py | 13 | ||||
-rw-r--r-- | test/extractor/image/test_colors_spatial.py | 17 | ||||
-rw-r--r-- | test/extractor/image/test_photometrics.py | 143 | ||||
-rw-r--r-- | test/extractor/test_base.py | 13 | ||||
-rw-r--r-- | test/extractor/test_builder.py | 21 | ||||
-rw-r--r-- | test/extractor/test_preview.py | 29 |
8 files changed, 189 insertions, 81 deletions
diff --git a/test/extractor/generic/test_constant.py b/test/extractor/generic/test_constant.py index bde3805..77ee02b 100644 --- a/test/extractor/generic/test_constant.py +++ b/test/extractor/generic/test_constant.py @@ -1,9 +1,4 @@ -""" -Part of the bsie test suite. -A copy of the license is provided with the project. -Author: Matthias Baumgartner, 2022 -""" # standard imports import unittest @@ -20,11 +15,11 @@ class TestConstant(unittest.TestCase): def test_extract(self): schema = ''' bse:author rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; + rdfs:domain bsn:Entity ; rdfs:range xsd:string ; bsfs:unique "true"^^xsd:boolean . bse:comment rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; + rdfs:domain bsn:Entity ; rdfs:range xsd:string ; bsfs:unique "false"^^xsd:boolean . ''' @@ -33,10 +28,10 @@ class TestConstant(unittest.TestCase): (ns.bse.comment, 'the quick brown fox jumps over the lazy dog.'), ] ext = Constant(schema, tuples) - node = _node.Node(ns.bsfs.Entity, '') # Blank node + node = _node.Node(ns.bsn.Entity, '') # 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.bsfs.Entity) + entity = ext.schema.node(ns.bsfs.Node).child(ns.bsn.Entity) string = ext.schema.literal(ns.bsfs.Literal).child(ns.xsd.string) # baseline self.assertSetEqual(set(ext.extract(node, None, (p_author, p_comment))), @@ -55,11 +50,11 @@ class TestConstant(unittest.TestCase): # schema compliance schema = ''' bse:author rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; + rdfs:domain bsn:Entity ; rdfs:range xsd:string ; bsfs:unique "true"^^xsd:boolean . bse:comment rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; + rdfs:domain bsn:Entity ; rdfs:range xsd:string ; bsfs:unique "false"^^xsd:boolean . ''' @@ -80,13 +75,13 @@ class TestConstant(unittest.TestCase): def test_eq(self): schema_a = ''' bse:author rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; + rdfs:domain bsn:Entity ; rdfs:range xsd:string ; bsfs:unique "true"^^xsd:boolean . ''' schema_b = ''' bse:comment rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; + rdfs:domain bsn:Entity ; rdfs:range xsd:string ; bsfs:unique "false"^^xsd:boolean . ''' diff --git a/test/extractor/generic/test_path.py b/test/extractor/generic/test_path.py index ae68686..0beb37e 100644 --- a/test/extractor/generic/test_path.py +++ b/test/extractor/generic/test_path.py @@ -1,9 +1,4 @@ -""" -Part of the bsie test suite. -A copy of the license is provided with the project. -Author: Matthias Baumgartner, 2022 -""" # standard imports import unittest @@ -31,17 +26,17 @@ class TestPath(unittest.TestCase): self.assertEqual(Path().schema, bsfs.schema.from_string(base.SCHEMA_PREAMBLE + ''' bse:filename rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:File ; + rdfs:domain bsn:Entity ; rdfs:range xsd:string ; - bsfs:unique "false"^^xsd:boolean . + bsfs:unique "true"^^xsd:boolean . ''')) def test_extract(self): ext = Path() - node = _node.Node(ns.bsfs.File, '') # Blank node + node = _node.Node(ns.bsn.Entity, '') # Blank node content = '/tmp/foo/bar' p_filename = ext.schema.predicate(ns.bse.filename) - entity = ext.schema.node(ns.bsfs.Node).child(ns.bsfs.Entity) + entity = ext.schema.node(ns.bsfs.Node).child(ns.bsn.Entity) string = ext.schema.literal(ns.bsfs.Literal).child(ns.xsd.string) # baseline diff --git a/test/extractor/generic/test_stat.py b/test/extractor/generic/test_stat.py index e5562d1..0e83e24 100644 --- a/test/extractor/generic/test_stat.py +++ b/test/extractor/generic/test_stat.py @@ -1,9 +1,4 @@ -""" -Part of the bsie test suite. -A copy of the license is provided with the project. -Author: Matthias Baumgartner, 2022 -""" # standard imports import os import unittest @@ -32,17 +27,17 @@ class TestStat(unittest.TestCase): self.assertEqual(Stat().schema, bsfs.schema.from_string(base.SCHEMA_PREAMBLE + ''' bse:filesize rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:File ; + rdfs:domain bsn:Entity ; rdfs:range xsd:integer ; - bsfs:unique "false"^^xsd:boolean . + bsfs:unique "true"^^xsd:boolean . ''')) def test_extract(self): ext = Stat() - node = _node.Node(ns.bsfs.File, '') # Blank node + node = _node.Node(ns.bsn.Entity, '') # Blank node content = os.stat(__file__) p_filesize = ext.schema.predicate(ns.bse.filesize) - entity = ext.schema.node(ns.bsfs.Node).child(ns.bsfs.Entity) + entity = ext.schema.node(ns.bsfs.Node).child(ns.bsn.Entity) string = ext.schema.literal(ns.bsfs.Literal).child(ns.xsd.string) # baseline diff --git a/test/extractor/image/test_colors_spatial.py b/test/extractor/image/test_colors_spatial.py index ba551f3..902ab6d 100644 --- a/test/extractor/image/test_colors_spatial.py +++ b/test/extractor/image/test_colors_spatial.py @@ -1,9 +1,4 @@ -""" -Part of the bsie test suite. -A copy of the license is provided with the project. -Author: Matthias Baumgartner, 2022 -""" # standard imports import os import unittest @@ -24,8 +19,8 @@ from bsie.extractor.image.colors_spatial import ColorsSpatial class TestColorsSpatial(unittest.TestCase): def setUp(self): # content id with default constructors (width=32, height=32, exp=4) - self.instance_prefix = 'http://ie.bsfs.ai/schema/Feature/ColorsSpatial' - self.predicate_prefix = 'http://bsfs.ai/schema/Entity/colors_spatial' + self.instance_prefix = 'https://schema.bsfs.io/ie/Literal/Array/Feature/ColorsSpatial' + self.predicate_prefix = 'https://schema.bsfs.io/ie/Node/Entity#colors_spatial_' self.uuid = 'adee8d6c43687021e1c5bffe56bcfe727f1638d792744137181304ef889dac2a' def test_essentials(self): @@ -55,7 +50,7 @@ class TestColorsSpatial(unittest.TestCase): def test_schema(self): schema = bsfs.schema.from_string(base.SCHEMA_PREAMBLE + f''' - <{self.instance_prefix}> rdfs:subClassOf bsfs:Feature ; + <{self.instance_prefix}> rdfs:subClassOf bsa:Feature ; # annotations rdfs:label "Spatially dominant colors"^^xsd:string ; schema:description "Domiant colors of subregions in an image."^^xsd:string ; @@ -68,8 +63,8 @@ class TestColorsSpatial(unittest.TestCase): <{self.instance_prefix}/args#height> "32"^^xsd:integer ; <{self.instance_prefix}/args#exp> "4"^^xsd:float . - <{self.predicate_prefix}#{self.uuid}> rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:File ; + <{self.predicate_prefix}{self.uuid}> rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsn:Entity ; rdfs:range <{self.instance_prefix}#{self.uuid}> ; bsfs:unique "true"^^xsd:boolean . ''') @@ -78,7 +73,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.bsfs.Entity, bsfs.URI('http://example.com/entity#1234')) + node = _node.Node(ns.bsn.Entity, bsfs.URI('http://example.com/entity#1234')) principals = set(ext.principals) self.assertEqual(len(principals), 1) # valid invocation yields feature diff --git a/test/extractor/image/test_photometrics.py b/test/extractor/image/test_photometrics.py new file mode 100644 index 0000000..fb219e2 --- /dev/null +++ b/test/extractor/image/test_photometrics.py @@ -0,0 +1,143 @@ + +# standard imports +import unittest + +# bsie imports +from bsie.extractor import base +from bsie.utils import bsfs, node as _node, ns + +# objects to test +from bsie.extractor.image.photometrics import Exif, _gps_to_dec + + +## code ## + +class TestExif(unittest.TestCase): + + def test_gps_to_dec(self): + # deg+min+sec format + self.assertAlmostEqual(_gps_to_dec('29/1 58/1 45/1'.split()), 29.979167, 6) + self.assertAlmostEqual(_gps_to_dec('31 08 03'.split()), 31.134167, 6) + self.assertAlmostEqual(_gps_to_dec('20 40 586/10'.split()), 20.682944, 6) + self.assertAlmostEqual(_gps_to_dec('88/1 34 68/10'.split()), 88.568556, 6) + # deg+min format + self.assertAlmostEqual(_gps_to_dec('13 472167/10000 0/1 '.split()), 13.786945, 6) + self.assertAlmostEqual(_gps_to_dec('104/1 3215/100 0/1'.split()), 104.535833, 6) + + def test_eq(self): + # identical instances are equal + self.assertEqual(Exif(), Exif()) + self.assertEqual(hash(Exif()), hash(Exif())) + # comparison respects type + class Foo(): pass + self.assertNotEqual(Exif(), Foo()) + self.assertNotEqual(hash(Exif()), hash(Foo())) + self.assertNotEqual(Exif(), 1234) + self.assertNotEqual(hash(Exif()), hash(1234)) + self.assertNotEqual(Exif(), None) + self.assertNotEqual(hash(Exif()), hash(None)) + + def test_schema(self): + self.assertSetEqual({pred.uri for pred in Exif().schema.predicates()}, { + ns.bsfs.Predicate, + ns.bse.exposure, + ns.bse.aperture, + ns.bse.iso, + ns.bse.focal_length, + ns.bse.width, + ns.bse.height, + ns.bse.orientation, + ns.bse.orientation_label, + ns.bse.altitude, + ns.bse.latitude, + ns.bse.longitude, + }) + + def test_extract(self): + ext = Exif() + node = _node.Node(ns.bsfs.File, '') # Blank node + content = { + 'Exif.Photo.ExposureTime': '10/600', + 'Exif.Photo.FNumber': '48/10', + 'Exif.Photo.ISOSpeedRatings': '400', + 'Exif.Photo.FocalLength': '460/10', + 'Exif.Photo.PixelXDimension': '4288', + 'Exif.Photo.PixelYDimension': '2848', + 'Exif.Image.Orientation': '1', + 'Exif.GPSInfo.GPSAltitude': '431/1', + 'Exif.GPSInfo.GPSLatitude': '46/1 11397/625 0/1', + 'Exif.GPSInfo.GPSLongitude': '7/1 131250/2500 0/1', + } + + # invalid principals are ignored + self.assertSetEqual(set(ext.extract(node, content, {ns.bse.filename})), set()) + # extract finds all relevant information + self.assertSetEqual(set(ext.extract(node, content, {ext.schema.predicate(ns.bse.exposure)})), + {(node, ext.schema.predicate(ns.bse.exposure), 60.0)}) + self.assertSetEqual(set(ext.extract(node, content, {ext.schema.predicate(ns.bse.aperture)})), + {(node, ext.schema.predicate(ns.bse.aperture), 4.8)}) + self.assertSetEqual(set(ext.extract(node, content, {ext.schema.predicate(ns.bse.iso)})), + {(node, ext.schema.predicate(ns.bse.iso), 400)}) + self.assertSetEqual(set(ext.extract(node, content, {ext.schema.predicate(ns.bse.focal_length)})), + {(node, ext.schema.predicate(ns.bse.focal_length), 46.0)}) + self.assertSetEqual(set(ext.extract(node, content, {ext.schema.predicate(ns.bse.width)})), + {(node, ext.schema.predicate(ns.bse.width), 4288)}) + self.assertSetEqual(set(ext.extract(node, content, {ext.schema.predicate(ns.bse.height)})), + {(node, ext.schema.predicate(ns.bse.height), 2848)}) + self.assertSetEqual(set(ext.extract(node, content, {ext.schema.predicate(ns.bse.orientation)})), + {(node, ext.schema.predicate(ns.bse.orientation), 1)}) + self.assertSetEqual(set(ext.extract(node, content, {ext.schema.predicate(ns.bse.orientation_label)})), + {(node, ext.schema.predicate(ns.bse.orientation_label), 'landscape')}) + self.assertSetEqual(set(ext.extract(node, content, {ext.schema.predicate(ns.bse.altitude)})), + {(node, ext.schema.predicate(ns.bse.altitude), 431.0)}) + self.assertSetEqual(set(ext.extract(node, content, {ext.schema.predicate(ns.bse.latitude)})), + {(node, ext.schema.predicate(ns.bse.latitude), 46.30392)}) + self.assertSetEqual(set(ext.extract(node, content, {ext.schema.predicate(ns.bse.longitude)})), + {(node, ext.schema.predicate(ns.bse.longitude), 7.875)}) + + # check orientation label + self.assertSetEqual(set(ext.extract( + node, { + 'Exif.Photo.PixelXDimension': '4288', + 'Exif.Photo.PixelYDimension': '2848', + 'Exif.Image.Orientation': '5', + }, + {ext.schema.predicate(ns.bse.orientation_label)})), + {(node, ext.schema.predicate(ns.bse.orientation_label), 'portrait')}) + + # can pass multiple principals + self.assertSetEqual(set(ext.extract(node, content, { + ext.schema.predicate(ns.bse.exposure), + ext.schema.predicate(ns.bse.iso), + ext.schema.predicate(ns.bse.focal_length), + })), { + (node, ext.schema.predicate(ns.bse.exposure), 60.0), + (node, ext.schema.predicate(ns.bse.iso), 400), + (node, ext.schema.predicate(ns.bse.focal_length), 46.0), + }) + + # principals w/o content are ignored + self.assertSetEqual(set(ext.extract( + node, + content={'Exif.Photo.ExposureTime': '10/600'}, + principals={ + ext.schema.predicate(ns.bse.exposure), + ext.schema.predicate(ns.bse.iso), + ext.schema.predicate(ns.bse.focal_length), + }) + ), { + (node, ext.schema.predicate(ns.bse.exposure), 60.0), + }) + + # empty content is acceptable + self.assertSetEqual(set(ext.extract(node, {}, set(ext.principals))), set()) + # no principals is acceptable + self.assertSetEqual(set(ext.extract(node, content, set())), set()) + + +## main ## + +if __name__ == '__main__': + unittest.main() + +## EOF ## diff --git a/test/extractor/test_base.py b/test/extractor/test_base.py index acfaf58..81865e1 100644 --- a/test/extractor/test_base.py +++ b/test/extractor/test_base.py @@ -1,9 +1,4 @@ -""" -Part of the bsie test suite. -A copy of the license is provided with the project. -Author: Matthias Baumgartner, 2022 -""" # standard imports import unittest @@ -20,11 +15,11 @@ class StubExtractor(base.Extractor): def __init__(self): super().__init__(bsfs.schema.from_string(base.SCHEMA_PREAMBLE + ''' bse:author rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; + rdfs:domain bsn:Entity ; rdfs:range xsd:string ; bsfs:unique "false"^^xsd:boolean . bse:comment rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; + rdfs:domain bsn:Entity ; rdfs:range xsd:string ; bsfs:unique "false"^^xsd:boolean . ''')) @@ -53,8 +48,8 @@ class TestExtractor(unittest.TestCase): def test_principals(self): schema = bsfs.schema.Schema() - entity = schema.node(ns.bsfs.Node).child(ns.bsfs.Entity) - string = schema.literal(ns.bsfs.Literal).child(bsfs.URI('http://www.w3.org/2001/XMLSchema#string')) + entity = schema.node(ns.bsfs.Node).child(ns.bsn.Entity) + string = schema.literal(ns.bsfs.Literal).child(ns.xsd.string) p_author = schema.predicate(ns.bsfs.Predicate).child(ns.bse.author, domain=entity, range=string) p_comment = schema.predicate(ns.bsfs.Predicate).child(ns.bse.comment, domain=entity, range=string) ext = StubExtractor() diff --git a/test/extractor/test_builder.py b/test/extractor/test_builder.py index 039ea53..fbb0895 100644 --- a/test/extractor/test_builder.py +++ b/test/extractor/test_builder.py @@ -1,9 +1,4 @@ -""" -Part of the bsie test suite. -A copy of the license is provided with the project. -Author: Matthias Baumgartner, 2022 -""" # standard imports import unittest @@ -51,33 +46,33 @@ class TestExtractorBuilder(unittest.TestCase): {'bsie.extractor.generic.constant.Constant': { 'schema': ''' bse:author rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; + rdfs:domain bsn:Entity ; rdfs:range xsd:string ; bsfs:unique "true"^^xsd:boolean . bse:rating rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; + rdfs:domain bsn:Entity ; rdfs:range xsd:integer ; bsfs:unique "true"^^xsd:boolean . ''', 'tuples': [ - ('http://bsfs.ai/schema/Entity#author', 'Me, myself, and I'), - ('http://bsfs.ai/schema/Entity#rating', 123), + ('https://schema.bsfs.io/ie/Node/Entity#author', 'Me, myself, and I'), + ('https://schema.bsfs.io/ie/Node/Entity#rating', 123), ], }}]) obj = builder.build(0) import bsie.extractor.generic.constant self.assertEqual(obj, bsie.extractor.generic.constant.Constant(''' bse:author rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; + rdfs:domain bsn:Entity ; rdfs:range xsd:string ; bsfs:unique "true"^^xsd:boolean . bse:rating rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; + rdfs:domain bsn:Entity ; rdfs:range xsd:integer ; bsfs:unique "true"^^xsd:boolean . ''', [ - ('http://bsfs.ai/schema/Entity#author', 'Me, myself, and I'), - ('http://bsfs.ai/schema/Entity#rating', 123), + ('https://schema.bsfs.io/ie/Node/Entity#author', 'Me, myself, and I'), + ('https://schema.bsfs.io/ie/Node/Entity#rating', 123), ])) # building with invalid args diff --git a/test/extractor/test_preview.py b/test/extractor/test_preview.py index 10d2a7f..6526783 100644 --- a/test/extractor/test_preview.py +++ b/test/extractor/test_preview.py @@ -1,9 +1,4 @@ -""" -Part of the bsie test suite. -A copy of the license is provided with the project. -Author: Matthias Baumgartner, 2022 -""" # standard imports import io import os @@ -45,28 +40,28 @@ class TestPreview(unittest.TestCase): def test_schema(self): self.assertEqual(Preview([1,2,3]).schema, bsfs.schema.from_string(base.SCHEMA_PREAMBLE + ''' - bsfs:Preview rdfs:subClassOf bsfs:Node . - bsfs:BinaryBlob rdfs:subClassOf bsfs:Literal . - bsfs:JPEG rdfs:subClassOf bsfs:BinaryBlob . + bsn:Preview rdfs:subClassOf bsfs:Node . + bsl:BinaryBlob rdfs:subClassOf bsfs:Literal . + <https://schema.bsfs.io/ie/Literal/BinaryBlob/JPEG> rdfs:subClassOf bsl:BinaryBlob . bse:preview rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:File ; - rdfs:range bsfs:Preview ; + rdfs:domain bsn:Entity ; + rdfs:range bsn:Preview ; bsfs:unique "false"^^xsd:boolean . bsp:width rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Preview ; + rdfs:domain bsn:Preview ; rdfs:range xsd:integer ; bsfs:unique "true"^^xsd:boolean . bsp:height rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Preview ; + rdfs:domain bsn:Preview ; rdfs:range xsd:integer ; bsfs:unique "true"^^xsd:boolean . bsp:asset rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Preview ; - rdfs:range bsfs:JPEG ; + rdfs:domain bsn:Preview ; + rdfs:range <https://schema.bsfs.io/ie/Literal/BinaryBlob/JPEG> ; bsfs:unique "true"^^xsd:boolean . ''')) @@ -74,7 +69,7 @@ class TestPreview(unittest.TestCase): def test_extract(self): # setup dependents rdr = Reader() - subject = _node.Node(ns.bsfs.File) + subject = _node.Node(ns.bsn.Entity) path = os.path.join(os.path.dirname(__file__), 'testimage.jpg') # setup extractor @@ -88,7 +83,7 @@ class TestPreview(unittest.TestCase): gen(10) # NOTE: consume some image to avoid resource error warning # extract a preview triples = set(ext.extract(subject, rdr(path), principals)) - thumbs = {node for node, _, _ in triples if node.node_type == ns.bsfs.Preview} + thumbs = {node for node, _, _ in triples if node.node_type == ns.bsn.Preview} self.assertEqual(len(thumbs), 1) thumb = list(thumbs)[0] # test properties @@ -112,7 +107,7 @@ class TestPreview(unittest.TestCase): self.assertEqual(principals, {ext.schema.predicate(ns.bse.preview)}) # extract a preview triples = set(ext.extract(subject, rdr(path), principals)) - thumbs = {node for node, _, _ in triples if node.node_type == ns.bsfs.Preview} + thumbs = {node for node, _, _ in triples if node.node_type == ns.bsn.Preview} self.assertEqual(len(thumbs), 2) self.assertSetEqual({10, 20}, { value for _, pred, value in triples if pred == ext.schema.predicate(ns.bsp.width)}) |