""" Part of the bsie test suite. A copy of the license is provided with the project. Author: Matthias Baumgartner, 2022 """ # 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)}) # 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 ##