[gexiv2] Implement python-based testsuite.
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gexiv2] Implement python-based testsuite.
- Date: Tue, 25 Apr 2017 16:48:10 +0000 (UTC)
commit 2498a4a468d3148781028f2c530015af6f104399
Author: Robert Bruce Park <r robru ca>
Date: Fri Feb 8 14:00:46 2013 -0800
Implement python-based testsuite.
https://bugzilla.gnome.org/show_bug.cgi?id=712455
tests/__init__.py | 1 +
tests/data/original.jpg | Bin 0 -> 56080 bytes
tests/test_metadata.py | 768 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 769 insertions(+), 0 deletions(-)
---
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..e094eec
--- /dev/null
+++ b/tests/__init__.py
@@ -0,0 +1 @@
+"""This file is necessary. Don't question it."""
diff --git a/tests/data/original.jpg b/tests/data/original.jpg
new file mode 100644
index 0000000..48056ca
Binary files /dev/null and b/tests/data/original.jpg differ
diff --git a/tests/test_metadata.py b/tests/test_metadata.py
new file mode 100644
index 0000000..6e35857
--- /dev/null
+++ b/tests/test_metadata.py
@@ -0,0 +1,768 @@
+# GExiv2 -- GNOME wrapper for libexiv2 library.
+# Copyright (C) 2013 Robert Bruce Park <r robru ca>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""Test that GExiv2 is functioning correctly."""
+
+__all__ = [
+ 'TestMetadata',
+ ]
+
+
+import os
+import sys
+import errno
+import shutil
+import unittest
+
+PY3K = sys.version_info[0] == 3
+
+from gi.repository import GExiv2
+from fractions import Fraction
+
+
+class TestMetadata(unittest.TestCase):
+ maxDiff = None
+
+ def setUp(self):
+ self.metadata = GExiv2.Metadata()
+ self.metadata.open_path('tests/data/original.jpg')
+
+ def tearDown(self):
+ try:
+ os.unlink('tests/data/withgps.jpg')
+ except Exception as e:
+ if e.errno != errno.ENOENT:
+ raise
+
+ def test_presence_of_expected_methods(self):
+ metadata = GExiv2.Metadata()
+ methods = [m for m in dir(metadata) if not m.startswith('_')]
+ for method in ['bind_property',
+ 'bind_property_full',
+ 'chain',
+ 'clear',
+ 'clear_comment',
+ 'clear_exif',
+ 'clear_iptc',
+ 'clear_tag',
+ 'clear_xmp',
+ 'compat_control',
+ 'connect',
+ 'connect_after',
+ 'connect_object',
+ 'connect_object_after',
+ 'delete_gps_info',
+ 'disconnect',
+ 'disconnect_by_func',
+ 'emit',
+ 'emit_stop_by_name',
+ 'erase_exif_thumbnail',
+ 'force_floating',
+ 'free',
+ 'freeze_notify',
+ 'from_app1_segment',
+ 'g_type_instance',
+ 'get_comment',
+ 'get_data',
+ 'get_exif_tag_rational',
+ 'get_exif_tags',
+ 'get_exif_thumbnail',
+ 'get_exposure_time',
+ 'get_fnumber',
+ 'get_focal_length',
+ 'get_gps_altitude',
+ 'get_gps_info',
+ 'get_gps_latitude',
+ 'get_gps_longitude',
+ 'get_iptc_tags',
+ 'get_iso_speed',
+ 'get_mime_type',
+ 'get_orientation',
+ 'get_pixel_height',
+ 'get_pixel_width',
+ 'get_preview_image',
+ 'get_preview_properties',
+ 'get_properties',
+ 'get_property',
+ 'get_qdata',
+ 'get_supports_exif',
+ 'get_supports_iptc',
+ 'get_supports_xmp',
+ 'get_tag_description',
+ 'get_tag_interpreted_string',
+ 'get_tag_label',
+ 'get_tag_long',
+ 'get_tag_multiple',
+ 'get_tag_string',
+ 'get_tag_type',
+ 'get_xmp_packet',
+ 'get_xmp_tags',
+ 'handler_block',
+ 'handler_block_by_func',
+ 'handler_disconnect',
+ 'handler_is_connected',
+ 'handler_unblock',
+ 'handler_unblock_by_func',
+ 'has_exif',
+ 'has_iptc',
+ 'has_tag',
+ 'has_xmp',
+ 'interface_find_property',
+ 'interface_install_property',
+ 'interface_list_properties',
+ 'is_exif_tag',
+ 'is_floating',
+ 'is_iptc_tag',
+ 'is_xmp_tag',
+ 'new',
+ 'notify',
+ 'notify_by_pspec',
+ 'open_buf',
+ 'open_path',
+ 'parent_instance',
+ 'priv',
+ 'props',
+ 'qdata',
+ 'ref',
+ 'ref_count',
+ 'ref_sink',
+ 'register_xmp_namespace',
+ 'replace_data',
+ 'replace_qdata',
+ 'run_dispose',
+ 'save_file',
+ 'set_comment',
+ 'set_data',
+ 'set_exif_tag_rational',
+ 'set_exif_thumbnail_from_buffer',
+ 'set_exif_thumbnail_from_file',
+ 'set_gps_info',
+ 'set_orientation',
+ 'set_properties',
+ 'set_property',
+ 'set_tag_long',
+ 'set_tag_multiple',
+ 'set_tag_string',
+ 'steal_data',
+ 'steal_qdata',
+ 'stop_emission',
+ 'stop_emission_by_name',
+ 'thaw_notify',
+ 'unref',
+ 'unregister_all_xmp_namespaces',
+ 'unregister_xmp_namespace',
+ 'watch_closure',
+ 'weak_ref']:
+ self.assertIn(method, methods)
+
+ def test_open_buf(self):
+ with open('tests/data/original.jpg', 'rb' if PY3K else 'r') as fd:
+ buf = fd.read()
+ metadata = GExiv2.Metadata()
+ metadata.open_buf(buf)
+ self.assertEqual(len(metadata.get_exif_tags()), 112)
+
+ def test_open_path(self):
+ metadata = GExiv2.Metadata()
+ metadata.open_path('tests/data/original.jpg')
+ self.assertEqual(len(metadata.get_exif_tags()), 112)
+
+ def test_get_tag_string(self):
+ self.assertEqual(
+ [(tag, self.metadata.get_tag_string(tag))
+ for tag in self.metadata.get_exif_tags()
+ if len(self.metadata.get_tag_string(tag)) < 100],
+ [('Exif.Image.DateTime', '2012:11:02 09:04:27'),
+ ('Exif.Image.ExifTag', '302'),
+ ('Exif.Image.ImageDescription', ' '),
+ ('Exif.Image.Make', 'NIKON'),
+ ('Exif.Image.Model', 'COOLPIX P310'),
+ ('Exif.Image.Orientation', '1'),
+ ('Exif.Image.ResolutionUnit', '2'),
+ ('Exif.Image.Software', 'COOLPIX P310 V1.0'),
+ ('Exif.Image.XResolution', '300/1'),
+ ('Exif.Image.YCbCrPositioning', '2'),
+ ('Exif.Image.YResolution', '300/1'),
+ ('Exif.Iop.InteroperabilityIndex', 'R98'),
+ ('Exif.Iop.InteroperabilityVersion', '48 49 48 48'),
+ ('Exif.MakerNote.ByteOrder', 'II'),
+ ('Exif.MakerNote.Offset', '1114'),
+ ('Exif.Nikon3.0x000a', '7810/1000'),
+ ('Exif.Nikon3.0x0026', '257 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0'),
+ ('Exif.Nikon3.0x0027', '0 0 0 0 0 0 0 0 0 0 0 0 0 0'),
+ ('Exif.Nikon3.0x002d', '512 0 0'),
+ ('Exif.Nikon3.0x002e', '1'),
+ ('Exif.Nikon3.0x0030', '0'),
+ ('Exif.Nikon3.0x0035', '48 49 48 48 0 0 0 0'),
+ ('Exif.Nikon3.0x0036', '48 49 48 48 0 0'),
+ ('Exif.Nikon3.0x0038', '48 49 48 48 0 0 0 0 0 0'),
+ ('Exif.Nikon3.0x003a', '48 49 48 48 0 0 255'),
+ ('Exif.Nikon3.0x009b', '0 0'),
+ ('Exif.Nikon3.0x009d', '0'),
+ ('Exif.Nikon3.0x009f', '56'),
+ ('Exif.Nikon3.0x00b2', ' '),
+ ('Exif.Nikon3.ActiveDLighting', '0'),
+ ('Exif.Nikon3.AuxiliaryLens', 'OFF '),
+ ('Exif.Nikon3.ColorMode', 'COLOR '),
+ ('Exif.Nikon3.DigitalZoom', '100/100'),
+ ('Exif.Nikon3.FlashSetting', ' '),
+ ('Exif.Nikon3.Focus', 'AF-S '),
+ ('Exif.Nikon3.FocusDistance', '0/0'),
+ ('Exif.Nikon3.ISOSelection', 'AUTO '),
+ ('Exif.Nikon3.ISOSpeed', '0 0'),
+ ('Exif.Nikon3.ImageAdjustment', 'NORMAL '),
+ ('Exif.Nikon3.ImageStabilization', 'VR-ON '),
+ ('Exif.Nikon3.NoiseReduction', 'OFF '),
+ ('Exif.Nikon3.Preview', '2496'),
+ ('Exif.Nikon3.Quality', 'FINE '),
+ ('Exif.Nikon3.RetouchHistory', '0 0 0 0 0 0 0 0 0 0'),
+ ('Exif.Nikon3.Saturation', '0'),
+ ('Exif.Nikon3.Saturation', '0'),
+ ('Exif.Nikon3.SceneAssist', ' '),
+ ('Exif.Nikon3.SceneMode', ' '),
+ ('Exif.Nikon3.Sharpening', 'NORMAL'),
+ ('Exif.Nikon3.ToneComp', 'NORMAL '),
+ ('Exif.Nikon3.ToningEffect', ' '),
+ ('Exif.Nikon3.Version', '0 2 0 0'),
+ ('Exif.Nikon3.WhiteBalance', 'AUTO1 '),
+ ('Exif.Nikon3.WhiteBalanceBias', '0'),
+ ('Exif.NikonAf.AFAreaMode', '1'),
+ ('Exif.NikonAf.AFPoint', '0'),
+ ('Exif.NikonAf.AFPointsInFocus', '19'),
+ ('Exif.NikonPreview.Compression', '6'),
+ ('Exif.NikonPreview.JPEGInterchangeFormat', '13328'),
+ ('Exif.NikonPreview.JPEGInterchangeFormatLength', '27981'),
+ ('Exif.NikonPreview.ResolutionUnit', '2'),
+ ('Exif.NikonPreview.XResolution', '300/1'),
+ ('Exif.NikonPreview.YCbCrPositioning', '2'),
+ ('Exif.NikonPreview.YResolution', '300/1'),
+ ('Exif.Photo.ColorSpace', '1'),
+ ('Exif.Photo.ComponentsConfiguration', '1 2 3 0'),
+ ('Exif.Photo.CompressedBitsPerPixel', '4/1'),
+ ('Exif.Photo.Contrast', '0'),
+ ('Exif.Photo.CustomRendered', '0'),
+ ('Exif.Photo.DateTimeDigitized', '2012:11:02 09:04:27'),
+ ('Exif.Photo.DateTimeOriginal', '2012:11:02 09:04:27'),
+ ('Exif.Photo.DigitalZoomRatio', '0/100'),
+ ('Exif.Photo.ExifVersion', '48 50 51 48'),
+ ('Exif.Photo.ExposureBiasValue', '0/10'),
+ ('Exif.Photo.ExposureMode', '0'),
+ ('Exif.Photo.ExposureProgram', '2'),
+ ('Exif.Photo.ExposureTime', '10/150'),
+ ('Exif.Photo.FNumber', '47/10'),
+ ('Exif.Photo.FileSource', '3'),
+ ('Exif.Photo.Flash', '16'),
+ ('Exif.Photo.FlashpixVersion', '48 49 48 48'),
+ ('Exif.Photo.FocalLength', '138/10'),
+ ('Exif.Photo.FocalLengthIn35mmFilm', '77'),
+ ('Exif.Photo.GainControl', '2'),
+ ('Exif.Photo.ISOSpeedRatings', '400'),
+ ('Exif.Photo.InteroperabilityTag', '1084'),
+ ('Exif.Photo.LightSource', '0'),
+ ('Exif.Photo.MaxApertureValue', '17/10'),
+ ('Exif.Photo.MeteringMode', '5'),
+ ('Exif.Photo.PixelXDimension', '4608'),
+ ('Exif.Photo.PixelYDimension', '3456'),
+ ('Exif.Photo.Saturation', '0'),
+ ('Exif.Photo.SceneCaptureType', '0'),
+ ('Exif.Photo.SceneType', '1'),
+ ('Exif.Photo.SensitivityType', '1'),
+ ('Exif.Photo.Sharpness', '0'),
+ ('Exif.Photo.SubjectDistanceRange', '0'),
+ ('Exif.Photo.WhiteBalance', '0'),
+ ('Exif.Thumbnail.Compression', '6'),
+ ('Exif.Thumbnail.JPEGInterchangeFormat', '4084'),
+ ('Exif.Thumbnail.JPEGInterchangeFormatLength', '4534'),
+ ('Exif.Thumbnail.ResolutionUnit', '2'),
+ ('Exif.Thumbnail.XResolution', '300/1'),
+ ('Exif.Thumbnail.YResolution', '300/1'),
+ ])
+
+ def test_get_tag_interpreted_string(self):
+ self.assertEqual(
+ [(tag, self.metadata.get_tag_interpreted_string(tag))
+ for tag in self.metadata.get_exif_tags()
+ if len(self.metadata.get_tag_interpreted_string(tag)) < 100],
+ [('Exif.Image.DateTime', '2012:11:02 09:04:27'),
+ ('Exif.Image.ExifTag', '302'),
+ ('Exif.Image.ImageDescription', ' '),
+ ('Exif.Image.Make', 'NIKON'),
+ ('Exif.Image.Model', 'COOLPIX P310'),
+ ('Exif.Image.Orientation', 'top, left'),
+ ('Exif.Image.ResolutionUnit', 'inch'),
+ ('Exif.Image.Software', 'COOLPIX P310 V1.0'),
+ ('Exif.Image.XResolution', '300'),
+ ('Exif.Image.YCbCrPositioning', 'Co-sited'),
+ ('Exif.Image.YResolution', '300'),
+ ('Exif.Iop.InteroperabilityIndex', 'R98'),
+ ('Exif.Iop.InteroperabilityVersion', '1.00'),
+ ('Exif.MakerNote.ByteOrder', 'II'),
+ ('Exif.MakerNote.Offset', '1114'),
+ ('Exif.Nikon3.0x000a', '7810/1000'),
+ ('Exif.Nikon3.0x0026', '257 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0'),
+ ('Exif.Nikon3.0x0027', '0 0 0 0 0 0 0 0 0 0 0 0 0 0'),
+ ('Exif.Nikon3.0x002d', '512 0 0'),
+ ('Exif.Nikon3.0x002e', '1'),
+ ('Exif.Nikon3.0x0030', '0'),
+ ('Exif.Nikon3.0x0035', '48 49 48 48 0 0 0 0'),
+ ('Exif.Nikon3.0x0036', '48 49 48 48 0 0'),
+ ('Exif.Nikon3.0x0038', '48 49 48 48 0 0 0 0 0 0'),
+ ('Exif.Nikon3.0x003a', '48 49 48 48 0 0 255'),
+ ('Exif.Nikon3.0x009b', '0 0'),
+ ('Exif.Nikon3.0x009d', '0'),
+ ('Exif.Nikon3.0x009f', '56'),
+ ('Exif.Nikon3.0x00b2', ' '),
+ ('Exif.Nikon3.ActiveDLighting', 'Off'),
+ ('Exif.Nikon3.AuxiliaryLens', 'OFF '),
+ ('Exif.Nikon3.ColorMode', 'COLOR '),
+ ('Exif.Nikon3.DigitalZoom', '1.0x'),
+ ('Exif.Nikon3.FlashSetting', ' '),
+ ('Exif.Nikon3.Focus', 'Single autofocus'),
+ ('Exif.Nikon3.FocusDistance', 'Unknown'),
+ ('Exif.Nikon3.ISOSelection', 'AUTO '),
+ ('Exif.Nikon3.ISOSpeed', '0'),
+ ('Exif.Nikon3.ImageAdjustment', 'NORMAL '),
+ ('Exif.Nikon3.ImageStabilization', 'VR-ON '),
+ ('Exif.Nikon3.NoiseReduction', 'OFF '),
+ ('Exif.Nikon3.Preview', '2496'),
+ ('Exif.Nikon3.Quality', 'FINE '),
+ ('Exif.Nikon3.RetouchHistory', 'None'),
+ ('Exif.Nikon3.Saturation', '0'),
+ ('Exif.Nikon3.Saturation', '0'),
+ ('Exif.Nikon3.SceneAssist', ' '),
+ ('Exif.Nikon3.SceneMode', ' '),
+ ('Exif.Nikon3.Sharpening', 'NORMAL'),
+ ('Exif.Nikon3.ToneComp', 'NORMAL '),
+ ('Exif.Nikon3.ToningEffect', ' '),
+ ('Exif.Nikon3.Version', '()'),
+ ('Exif.Nikon3.WhiteBalance', 'AUTO1 '),
+ ('Exif.Nikon3.WhiteBalanceBias', '0'),
+ ('Exif.NikonAf.AFAreaMode', 'Dynamic Area'),
+ ('Exif.NikonAf.AFPoint', 'Center'),
+ ('Exif.NikonAf.AFPointsInFocus', 'Center, Top, Mid-right'),
+ ('Exif.NikonPreview.Compression', 'JPEG (old-style)'),
+ ('Exif.NikonPreview.JPEGInterchangeFormat', '13328'),
+ ('Exif.NikonPreview.JPEGInterchangeFormatLength', '27981'),
+ ('Exif.NikonPreview.ResolutionUnit', 'inch'),
+ ('Exif.NikonPreview.XResolution', '300'),
+ ('Exif.NikonPreview.YCbCrPositioning', 'Co-sited'),
+ ('Exif.NikonPreview.YResolution', '300'),
+ ('Exif.Photo.ColorSpace', 'sRGB'),
+ ('Exif.Photo.ComponentsConfiguration', 'YCbCr'),
+ ('Exif.Photo.CompressedBitsPerPixel', '4'),
+ ('Exif.Photo.Contrast', 'Normal'),
+ ('Exif.Photo.CustomRendered', 'Normal process'),
+ ('Exif.Photo.DateTimeDigitized', '2012:11:02 09:04:27'),
+ ('Exif.Photo.DateTimeOriginal', '2012:11:02 09:04:27'),
+ ('Exif.Photo.DigitalZoomRatio', '0.0'),
+ ('Exif.Photo.ExifVersion', '2.30'),
+ ('Exif.Photo.ExposureBiasValue', '0 EV'),
+ ('Exif.Photo.ExposureMode', 'Auto'),
+ ('Exif.Photo.ExposureProgram', 'Auto'),
+ ('Exif.Photo.ExposureTime', '1/15 s'),
+ ('Exif.Photo.FNumber', 'F4.7'),
+ ('Exif.Photo.FileSource', 'Digital still camera'),
+ ('Exif.Photo.Flash', 'No, compulsory'),
+ ('Exif.Photo.FlashpixVersion', '1.00'),
+ ('Exif.Photo.FocalLength', '13.8 mm'),
+ ('Exif.Photo.FocalLengthIn35mmFilm', '77.0 mm'),
+ ('Exif.Photo.GainControl', 'High gain up'),
+ ('Exif.Photo.ISOSpeedRatings', '400'),
+ ('Exif.Photo.InteroperabilityTag', '1084'),
+ ('Exif.Photo.LightSource', 'Unknown'),
+ ('Exif.Photo.MaxApertureValue', 'F1.8'),
+ ('Exif.Photo.MeteringMode', 'Multi-segment'),
+ ('Exif.Photo.PixelXDimension', '4608'),
+ ('Exif.Photo.PixelYDimension', '3456'),
+ ('Exif.Photo.Saturation', 'Normal'),
+ ('Exif.Photo.SceneCaptureType', 'Standard'),
+ ('Exif.Photo.SceneType', 'Directly photographed'),
+ ('Exif.Photo.SensitivityType', '1'),
+ ('Exif.Photo.Sharpness', 'Normal'),
+ ('Exif.Photo.SubjectDistanceRange', 'Unknown'),
+ ('Exif.Photo.WhiteBalance', 'Auto'),
+ ('Exif.Thumbnail.Compression', 'JPEG (old-style)'),
+ ('Exif.Thumbnail.JPEGInterchangeFormat', '4084'),
+ ('Exif.Thumbnail.JPEGInterchangeFormatLength', '4534'),
+ ('Exif.Thumbnail.ResolutionUnit', 'inch'),
+ ('Exif.Thumbnail.XResolution', '300'),
+ ('Exif.Thumbnail.YResolution', '300'),
+ ])
+
+ def test_has_tag(self):
+ self.assertTrue(self.metadata.has_tag('Exif.Image.DateTime'))
+ self.assertTrue(self.metadata.has_tag('Exif.Thumbnail.XResolution'))
+ self.assertFalse(self.metadata.has_tag('Iptc.Application2.City'))
+ self.assertFalse(self.metadata.has_tag('Some.Invalid.Tag'))
+
+ def test_clear_tag(self):
+ self.assertTrue(self.metadata.has_tag('Exif.Image.DateTime'))
+ self.assertTrue(self.metadata.clear_tag('Exif.Image.DateTime'))
+ self.assertFalse(self.metadata.has_tag('Exif.Image.DateTime'))
+
+ def test_clear(self):
+ self.assertEqual(len(self.metadata.get_exif_tags()), 112)
+ self.assertTrue(self.metadata.has_tag('Exif.Image.DateTime'))
+ self.assertIsNone(self.metadata.clear())
+ self.assertFalse(self.metadata.has_tag('Exif.Image.DateTime'))
+ self.assertEqual(len(self.metadata.get_exif_tags()), 0)
+
+ def test_get_mime_type(self):
+ self.assertEqual(self.metadata.get_mime_type(), 'image/jpeg')
+
+ def test_supports(self):
+ self.assertTrue(self.metadata.get_supports_exif())
+ self.assertTrue(self.metadata.get_supports_iptc())
+ self.assertTrue(self.metadata.get_supports_xmp())
+
+ def test_get_orientation(self):
+ results = []
+ for i in range(9):
+ self.metadata.set_tag_string('Exif.Image.Orientation', str(i))
+ orient = self.metadata.get_orientation()
+ results.append((int(orient), orient))
+
+ self.assertEqual(
+ results, [
+ (0, GExiv2.Orientation.MIN),
+ (1, GExiv2.Orientation.NORMAL),
+ (2, GExiv2.Orientation.HFLIP),
+ (3, GExiv2.Orientation.ROT_180),
+ (4, GExiv2.Orientation.VFLIP),
+ (5, GExiv2.Orientation.ROT_90_HFLIP),
+ (6, GExiv2.Orientation.ROT_90),
+ (7, GExiv2.Orientation.ROT_90_VFLIP),
+ (8, GExiv2.Orientation.ROT_270),
+ ])
+
+ def test_set_orientation(self):
+ rotations = [
+ GExiv2.Orientation.MIN,
+ GExiv2.Orientation.NORMAL,
+ GExiv2.Orientation.HFLIP,
+ GExiv2.Orientation.ROT_180,
+ GExiv2.Orientation.VFLIP,
+ GExiv2.Orientation.ROT_90_HFLIP,
+ GExiv2.Orientation.ROT_90,
+ GExiv2.Orientation.ROT_90_VFLIP,
+ GExiv2.Orientation.ROT_270,
+ ]
+
+ results = []
+ for i, o in enumerate(rotations):
+ self.metadata.set_orientation(o)
+ results.append((i, self.metadata.get_tag_string(
+ 'Exif.Image.Orientation')))
+
+ self.assertEqual(
+ results, [
+ (0, '0'),
+ (1, '1'),
+ (2, '2'),
+ (3, '3'),
+ (4, '4'),
+ (5, '5'),
+ (6, '6'),
+ (7, '7'),
+ (8, '8'),
+ ])
+
+ def test_get_pixel_width_and_height(self):
+ self.assertEqual(self.metadata.get_pixel_width(), 16)
+ self.assertEqual(self.metadata.get_pixel_height(), 12)
+
+ def test_get_comment(self):
+ self.assertEqual(self.metadata.get_comment().strip(), '')
+ self.metadata.set_tag_string('Exif.Image.ImageDescription',
+ 'Lego Dragon, Copenhagen.')
+ self.assertEqual(self.metadata.get_comment(),
+ 'Lego Dragon, Copenhagen.')
+
+ def test_set_tag_string(self):
+ self.assertTrue(
+ self.metadata.set_tag_string('Exif.Image.Model', 'FooCam'))
+ self.assertEqual(
+ self.metadata.get_tag_string('Exif.Image.Model'), 'FooCam')
+
+ def test_get_tag_long(self):
+ self.assertEqual(
+ self.metadata.get_tag_long('Exif.Image.XResolution'), 300)
+ self.assertEqual(
+ self.metadata.get_tag_long('Exif.Image.YResolution'), 300)
+ self.assertEqual(
+ self.metadata.get_tag_long('Exif.Photo.FocalLength'), 13)
+ self.assertEqual(
+ self.metadata.get_tag_long('Exif.Photo.ISOSpeedRatings'), 400)
+
+ def test_set_tag_long(self):
+ self.metadata.set_tag_long('Exif.Photo.FocalLength', 500)
+ self.assertEqual(
+ self.metadata.get_tag_long('Exif.Photo.FocalLength'), 500)
+ self.assertEqual(
+ self.metadata.get_tag_string('Exif.Photo.FocalLength'), '500')
+
+ def test_get_tag_multiple(self):
+ self.metadata.set_tag_multiple(
+ 'Xmp.dc.subject', 'some darn picture'.split())
+ self.assertEqual(
+ self.metadata.get_tag_multiple('Xmp.dc.subject'),
+ ['some', 'darn', 'picture'])
+
+ def test_get_exposure_time(self):
+ exposure = self.metadata.get_exposure_time()
+ if isinstance(exposure, Fraction):
+ self.assertEqual(exposure, Fraction(1, 15))
+ else:
+ self.assertEqual(exposure, (10, 150))
+
+ def test_get_fnumber(self):
+ #FIXME: WTF? 400 is the ISO, not the F number.
+ self.assertEqual(self.metadata.get_fnumber(), 400)
+
+ def test_get_focal_length(self):
+ self.assertEqual(self.metadata.get_focal_length(), 13)
+
+ def test_get_iso_speed(self):
+ self.assertEqual(self.metadata.get_iso_speed(), 400)
+
+ def test_get_tag_label(self):
+ self.assertEqual(
+ self.metadata.get_tag_label('Exif.Image.DateTime'),
+ 'Date and Time')
+ self.assertEqual(
+ self.metadata.get_tag_label('Exif.Image.Make'),
+ 'Manufacturer')
+ self.assertEqual(
+ self.metadata.get_tag_label('Exif.Nikon3.Preview'),
+ 'Pointer to a preview image')
+
+ def test_get_tag_description(self):
+ self.assertEqual(
+ self.metadata.get_tag_description('Exif.Image.DateTime'),
+ """The date and time of image creation. In Exif standard, it is the \
+date and time the file was changed.""")
+ self.assertEqual(
+ self.metadata.get_tag_description('Exif.Image.Make'),
+ """The manufacturer of the recording equipment. This is the \
+manufacturer of the DSC, scanner, video digitizer or other equipment that \
+generated the image. When the field is left blank, it is treated as unknown.""")
+
+ def test_has_exif(self):
+ self.assertTrue(self.metadata.has_exif())
+ self.metadata.clear()
+ self.assertFalse(self.metadata.has_exif())
+
+ def test_clear_exif(self):
+ self.assertTrue('Exif.Image.Make' in self.metadata.get_exif_tags())
+ self.metadata.set_tag_string('Xmp.dc.subject', 'Dragons!')
+ self.metadata.clear_exif()
+ self.assertEqual(
+ {tag: self.metadata.get_tag_string(tag)
+ for tag in self.metadata.get_exif_tags()
+ + self.metadata.get_xmp_tags()},
+ {'Xmp.dc.subject': 'Dragons!'})
+
+ def test_get_exif_tag_rational(self):
+ fnumber = self.metadata.get_exif_tag_rational('Exif.Photo.FNumber')
+ focal = self.metadata.get_exif_tag_rational('Exif.Photo.FocalLength')
+ aperture = self.metadata.get_exif_tag_rational('Exif.Photo.MaxApertureValue')
+
+ if isinstance(fnumber, Fraction):
+ self.assertEqual(fnumber, Fraction(47, 10))
+ self.assertEqual(focal, Fraction(138, 10))
+ self.assertEqual(aperture, Fraction(17, 10))
+ else:
+ self.assertEqual(fnumber, (47, 10))
+ self.assertEqual(focal, (138, 10))
+ self.assertEqual(aperture, (17, 10))
+
+ def test_set_exif_tag_rational(self):
+ try:
+ self.metadata.set_exif_tag_rational(
+ 'Exif.Photo.FocalLength', 355, 113)
+ except TypeError:
+ self.metadata.set_exif_tag_rational(
+ 'Exif.Photo.FocalLength', Fraction(355, 113))
+ focal = self.metadata.get_exif_tag_rational('Exif.Photo.FocalLength')
+ if isinstance(focal, Fraction):
+ self.assertEqual(focal, Fraction(355, 113))
+ else:
+ self.assertEqual(focal, (355, 113))
+ self.assertEqual(self.metadata.get_tag_string('Exif.Photo.FocalLength'), '355/113')
+
+ def test_get_exif_thumbnail(self):
+ thumb = self.metadata.get_exif_thumbnail()
+ self.assertEqual(len(thumb), 4534)
+
+ def test_set_exif_thumbnail_from_file(self):
+ self.metadata.set_exif_thumbnail_from_file('tests/data/original.jpg')
+ thumb = self.metadata.get_exif_thumbnail()
+ self.assertEqual(len(thumb), 56080)
+
+ def test_set_exif_thumbnail_from_buffer(self):
+ with open('tests/data/original.jpg', 'rb' if PY3K else 'r') as fd:
+ buf = fd.read()
+ self.metadata.set_exif_thumbnail_from_buffer(buf)
+ thumb = self.metadata.get_exif_thumbnail()
+ self.assertEqual(len(thumb), 56080)
+
+ def test_erase_exif_thumbnail(self):
+ self.metadata.erase_exif_thumbnail()
+ thumb = self.metadata.get_exif_thumbnail()
+ self.assertEqual(thumb, b'' if PY3K else '')
+
+ def test_has_xmp(self):
+ self.assertFalse(self.metadata.has_xmp())
+ self.metadata.set_tag_string('Xmp.dc.subject', 'Dragons!')
+ self.assertTrue(self.metadata.has_xmp())
+
+ def test_clear_xmp(self):
+ self.metadata.set_tag_string('Xmp.dc.subject', 'Dragons!')
+ self.metadata.clear_xmp()
+ self.assertFalse(self.metadata.has_xmp())
+ self.assertTrue(self.metadata.has_exif())
+
+ def test_get_xmp_packet(self):
+ self.assertEqual(self.metadata.get_xmp_packet(), '')
+
+ def test_get_xmp_tags(self):
+ self.assertEqual(self.metadata.get_xmp_tags(), [])
+ self.metadata.set_tag_string('Xmp.dc.subject', 'Dragons!')
+ self.assertEqual(self.metadata.get_xmp_tags(), ['Xmp.dc.subject'])
+
+ def test_is_xmp_tag(self):
+ self.assertTrue(self.metadata.is_xmp_tag('Xmp.dc.subject'))
+ self.assertFalse(self.metadata.is_xmp_tag('Exif.Image.Make'))
+ self.assertFalse(self.metadata.is_xmp_tag('Iptc.Application2.City'))
+
+ def test_is_exif_tag(self):
+ self.assertFalse(self.metadata.is_exif_tag('Xmp.dc.subject'))
+ self.assertTrue(self.metadata.is_exif_tag('Exif.Image.Make'))
+ self.assertFalse(self.metadata.is_exif_tag('Iptc.Application2.City'))
+
+ def test_is_iptc_tag(self):
+ self.assertFalse(self.metadata.is_iptc_tag('Xmp.dc.subject'))
+ self.assertFalse(self.metadata.is_iptc_tag('Exif.Image.Make'))
+ self.assertTrue(self.metadata.is_iptc_tag('Iptc.Application2.City'))
+
+ def test_has_iptc(self):
+ self.assertFalse(self.metadata.has_iptc())
+ self.metadata.set_tag_string('Iptc.Application2.City', 'Copenhagen')
+ self.assertTrue(self.metadata.has_iptc())
+
+ def test_clear_iptc(self):
+ self.metadata.set_tag_string('Iptc.Application2.City', 'Copenhagen')
+ self.metadata.clear_iptc()
+ self.assertFalse(self.metadata.has_iptc())
+ self.assertTrue(self.metadata.has_exif())
+
+ def test_get_iptc_tags(self):
+ self.assertEqual(self.metadata.get_iptc_tags(), [])
+ self.metadata.set_tag_string('Iptc.Application2.City', 'Copenhagen')
+ self.assertEqual(
+ self.metadata.get_iptc_tags(), ['Iptc.Application2.City'])
+
+ def test_delete_gps_info(self):
+ # Longitude, latitude, altitude
+ self.metadata.set_gps_info(-123.35, 48.43, 10)
+ self.assertTrue('Exif.GPSInfo.GPSLongitude' in self.metadata.get_exif_tags())
+ self.metadata.delete_gps_info()
+ self.assertFalse('Exif.GPSInfo.GPSLongitude' in self.metadata.get_exif_tags())
+
+ def test_get_gps_longitude(self):
+ # Longitude, latitude, altitude
+ self.metadata.set_gps_info(-123.35, 48.43, 10)
+ # Should accurate to 9 decimal places despite rounding errors.
+ self.assertAlmostEqual(self.metadata.get_gps_longitude(), -123.35, 9)
+
+ def test_get_gps_latitude(self):
+ # Longitude, latitude, altitude
+ self.metadata.set_gps_info(-123.35, 48.43, 10)
+ # Should accurate to 9 decimal places despite rounding errors.
+ self.assertAlmostEqual(self.metadata.get_gps_latitude(), 48.43, 9)
+
+ def test_get_gps_altitude(self):
+ # Longitude, latitude, altitude
+ self.metadata.set_gps_info(-123.35, 48.43, 10)
+ # Should accurate to 9 decimal places despite rounding errors.
+ self.assertEqual(self.metadata.get_gps_altitude(), 10)
+
+ def test_get_gps_info(self):
+ # Longitude, latitude, altitude
+ self.metadata.set_gps_info(-123.35, 48.43, 10)
+ # Should accurate to 9 decimal places despite rounding errors.
+ lon, lat, alt = self.metadata.get_gps_info()
+ self.assertAlmostEqual(lon, -123.35, 9)
+ self.assertAlmostEqual(lat, 48.43, 9)
+ self.assertEqual(alt, 10)
+
+ def test_set_gps_info(self):
+ # Longitude, latitude, altitude
+ self.metadata.set_gps_info(-123.35, 48.43, 10)
+ self.assertEqual(
+ [(tag, self.metadata.get_tag_string(tag))
+ for tag in self.metadata.get_exif_tags()
+ if 'GPS' in tag],
+ [('Exif.GPSInfo.GPSAltitude', '10000000/1000000'),
+ ('Exif.GPSInfo.GPSAltitudeRef', '0'),
+ ('Exif.GPSInfo.GPSLatitude', '48/1 25/1 47999999/1000000'),
+ ('Exif.GPSInfo.GPSLatitudeRef', 'N'),
+ ('Exif.GPSInfo.GPSLongitude', '123/1 20/1 59999999/1000000'),
+ ('Exif.GPSInfo.GPSLongitudeRef', 'W'),
+ ('Exif.GPSInfo.GPSMapDatum', 'WGS-84'),
+ ('Exif.GPSInfo.GPSVersionID', '2 0 0 0')])
+
+ def test_get_preview_properties(self):
+ previews = self.metadata.get_preview_properties()
+ self.assertEqual(len(previews), 2)
+ widths = [640, 160]
+ heights = [480, 120]
+ nbytes = [27981, 4534]
+ for preview in previews:
+ self.assertIsInstance(preview, GExiv2.PreviewProperties)
+ self.assertEqual(preview.get_width(), widths.pop())
+ self.assertEqual(preview.get_height(), heights.pop())
+ thumb = self.metadata.get_preview_image(preview)
+ self.assertEqual(len(thumb.get_data()), nbytes.pop())
+
+ def test_save_file(self):
+ shutil.copyfile('tests/data/original.jpg', 'tests/data/withgps.jpg')
+ self.metadata.set_gps_info(12.5683371, 55.6760968, 42)
+ self.metadata.save_file('tests/data/withgps.jpg')
+
+ newfile = GExiv2.Metadata()
+ newfile.open_path('tests/data/withgps.jpg')
+ self.assertEqual(
+ [(tag, newfile.get_tag_string(tag))
+ for tag in newfile.get_exif_tags()
+ if 'GPSInfo' in tag],
+ [(tag, self.metadata.get_tag_string(tag))
+ for tag in newfile.get_exif_tags()
+ if 'GPSInfo' in tag])
+
+ def test_set_comment(self):
+ self.metadata.set_comment('foobar')
+ self.assertEqual(self.metadata.get_comment(), 'foobar')
+ self.assertEqual(
+ self.metadata.get_tag_string('Exif.Image.ImageDescription'),
+ 'foobar')
+
+ def FIXME_test_clear_comment(self):
+ self.metadata.set_tag_string('Exif.Image.ImageDescription',
+ 'Lego Dragon, Copenhagen.')
+ self.assertEqual(self.metadata.get_comment(), 'Lego Dragon, Copenhagen.')
+ self.metadata.clear_comment()
+ self.assertEqual(self.metadata.get_comment().strip(), '')
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]