~osomon/pyexiv2/pyexiv2-0.3

86 by Olivier Tilloy
Added some unit tests for basic functionalities. These tests will help spot regressions in the future.
1
# -*- coding: utf-8 -*-
2
3
# ******************************************************************************
4
#
241.2.1 by Olivier Tilloy
Updated copyright headers for 2010.
5
# Copyright (C) 2008-2010 Olivier Tilloy <olivier@tilloy.net>
86 by Olivier Tilloy
Added some unit tests for basic functionalities. These tests will help spot regressions in the future.
6
#
7
# This file is part of the pyexiv2 distribution.
8
#
9
# pyexiv2 is free software; you can redistribute it and/or
10
# modify it under the terms of the GNU General Public License
11
# as published by the Free Software Foundation; either version 2
12
# of the License, or (at your option) any later version.
13
#
14
# pyexiv2 is distributed in the hope that it will be useful,
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
# GNU General Public License for more details.
18
#
19
# You should have received a copy of the GNU General Public License
20
# along with pyexiv2; if not, write to the Free Software
21
# Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
22
#
270.2.4 by Olivier Tilloy
Header cosmetics.
23
# Authors: Olivier Tilloy <olivier@tilloy.net>
299 by Olivier Tilloy
Updated Mark Lee's e-mail address.
24
#          Mark Lee <pyexiv2@lazymalevolence.com>
86 by Olivier Tilloy
Added some unit tests for basic functionalities. These tests will help spot regressions in the future.
25
#
26
# ******************************************************************************
27
347.1.2 by Olivier Tilloy
Handle fractions in a transparent manner,
28
import pyexiv2
29
from pyexiv2.utils import is_fraction, make_fraction
30
86 by Olivier Tilloy
Added some unit tests for basic functionalities. These tests will help spot regressions in the future.
31
import unittest
32
import os.path
33
import datetime
34
347.1.2 by Olivier Tilloy
Handle fractions in a transparent manner,
35
import testutils
36
37
38
FRACTION = 'fraction'
39
40
86 by Olivier Tilloy
Added some unit tests for basic functionalities. These tests will help spot regressions in the future.
41
class ReadMetadataTestCase(unittest.TestCase):
42
43
    """
44
    Test case on reading the metadata contained in a file.
45
    """
46
270.2.6 by Olivier Tilloy
Consistent type and value(s) checks.
47
    def check_type_and_value(self, tag, etype, evalue):
347.1.2 by Olivier Tilloy
Handle fractions in a transparent manner,
48
        if etype == FRACTION:
49
            self.assert_(is_fraction(tag.value))
50
        else:
51
            self.assert_(isinstance(tag.value, etype))
270.2.1 by Mark Lee
Port the ReadMetadataTestCase to the 0.2 API.
52
        self.assertEqual(tag.value, evalue)
53
270.2.6 by Olivier Tilloy
Consistent type and value(s) checks.
54
    def check_type_and_values(self, tag, etype, evalues):
331.1.1 by Olivier Tilloy
Rename the .raw_values and .values properties of IPTC tags to .raw_value and .value,
55
        for value in tag.value:
338 by Olivier Tilloy
Use isinstance(…) instead of type(…) everywhere, as recommended by Python’s documentation
56
            self.assert_(isinstance(value, etype))
331.1.1 by Olivier Tilloy
Rename the .raw_values and .values properties of IPTC tags to .raw_value and .value,
57
        self.assertEqual(tag.value, evalues)
86 by Olivier Tilloy
Added some unit tests for basic functionalities. These tests will help spot regressions in the future.
58
270.2.2 by Mark Lee
Add an XMP metadata test.
59
    def assertCorrectFile(self, filename, md5sum):
60
        """
61
        Ensure that the filename and the MD5 checksum match up.
62
        """
63
        self.assert_(testutils.CheckFileSum(filename, md5sum))
64
86 by Olivier Tilloy
Added some unit tests for basic functionalities. These tests will help spot regressions in the future.
65
    def testReadMetadata(self):
66
        """
67
        Perform various tests on reading the metadata contained in a file.
68
        """
69
        # Check that the reference file is not corrupted
70
        filename = os.path.join('data', 'smiley1.jpg')
301.1.1 by Olivier Tilloy
Allow running the unit tests from anywhere.
71
        filepath = testutils.get_absolute_file_path(filename)
86 by Olivier Tilloy
Added some unit tests for basic functionalities. These tests will help spot regressions in the future.
72
        md5sum = 'c066958457c685853293058f9bf129c1'
301.1.1 by Olivier Tilloy
Allow running the unit tests from anywhere.
73
        self.assertCorrectFile(filepath, md5sum)
86 by Olivier Tilloy
Added some unit tests for basic functionalities. These tests will help spot regressions in the future.
74
75
        # Read the image metadata
301.1.1 by Olivier Tilloy
Allow running the unit tests from anywhere.
76
        image = pyexiv2.ImageMetadata(filepath)
270.2.1 by Mark Lee
Port the ReadMetadataTestCase to the 0.2 API.
77
        image.read()
86 by Olivier Tilloy
Added some unit tests for basic functionalities. These tests will help spot regressions in the future.
78
79
        # Exhaustive tests on the values of EXIF metadata
80
        exifTags = [('Exif.Image.ImageDescription', str, 'Well it is a smiley that happens to be green'),
347.1.2 by Olivier Tilloy
Handle fractions in a transparent manner,
81
                    ('Exif.Image.XResolution', FRACTION, make_fraction(72, 1)),
82
                    ('Exif.Image.YResolution', FRACTION, make_fraction(72, 1)),
86 by Olivier Tilloy
Added some unit tests for basic functionalities. These tests will help spot regressions in the future.
83
                    ('Exif.Image.ResolutionUnit', int, 2),
84
                    ('Exif.Image.Software', str, 'ImageReady'),
85
                    ('Exif.Image.DateTime', datetime.datetime, datetime.datetime(2004, 7, 13, 21, 23, 44)),
86
                    ('Exif.Image.Artist', str, 'No one'),
87
                    ('Exif.Image.Copyright', str, ''),
88
                    ('Exif.Image.ExifTag', long, 226L),
89
                    ('Exif.Photo.Flash', int, 80),
90
                    ('Exif.Photo.PixelXDimension', long, 167L),
91
                    ('Exif.Photo.PixelYDimension', long, 140L)]
270.2.1 by Mark Lee
Port the ReadMetadataTestCase to the 0.2 API.
92
        self.assertEqual(image.exif_keys, [tag[0] for tag in exifTags])
93
        for key, ktype, value in exifTags:
270.2.6 by Olivier Tilloy
Consistent type and value(s) checks.
94
            self.check_type_and_value(image[key], ktype, value)
86 by Olivier Tilloy
Added some unit tests for basic functionalities. These tests will help spot regressions in the future.
95
96
        # Exhaustive tests on the values of IPTC metadata
270.2.5 by Olivier Tilloy
Always check all values of IPTC tags.
97
        iptcTags = [('Iptc.Application2.Caption', str, ['yelimS green faced dude (iptc caption)']),
98
                    ('Iptc.Application2.Writer', str, ['Nobody']),
99
                    ('Iptc.Application2.Byline', str, ['Its me']),
100
                    ('Iptc.Application2.ObjectName', str, ['GreeenDude']),
101
                    ('Iptc.Application2.DateCreated', datetime.date, [datetime.date(2004, 7, 13)]),
102
                    ('Iptc.Application2.City', str, ['Seattle']),
103
                    ('Iptc.Application2.ProvinceState', str, ['WA']),
104
                    ('Iptc.Application2.CountryName', str, ['USA']),
105
                    ('Iptc.Application2.Category', str, ['Things']),
106
                    ('Iptc.Application2.Keywords', str, ['Green', 'Smiley', 'Dude']),
107
                    ('Iptc.Application2.Copyright', str, ['\xa9 2004 Nobody'])]
270.2.1 by Mark Lee
Port the ReadMetadataTestCase to the 0.2 API.
108
        self.assertEqual(image.iptc_keys, [tag[0] for tag in iptcTags])
270.2.5 by Olivier Tilloy
Always check all values of IPTC tags.
109
        for key, ktype, values in iptcTags:
270.2.6 by Olivier Tilloy
Consistent type and value(s) checks.
110
            self.check_type_and_values(image[key], ktype, values)
270.2.2 by Mark Lee
Add an XMP metadata test.
111
112
    def testReadMetadataXMP(self):
113
        filename = os.path.join('data', 'exiv2-bug540.jpg')
301.1.1 by Olivier Tilloy
Allow running the unit tests from anywhere.
114
        filepath = testutils.get_absolute_file_path(filename)
270.2.2 by Mark Lee
Add an XMP metadata test.
115
        md5sum = '64d4b7eab1e78f1f6bfb3c966e99eef2'
301.1.1 by Olivier Tilloy
Allow running the unit tests from anywhere.
116
        self.assertCorrectFile(filepath, md5sum)
270.2.2 by Mark Lee
Add an XMP metadata test.
117
118
        # Read the image metadata
301.1.1 by Olivier Tilloy
Allow running the unit tests from anywhere.
119
        image = pyexiv2.ImageMetadata(filepath)
270.2.2 by Mark Lee
Add an XMP metadata test.
120
        image.read()
121
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
122
        xmpTags = [('Xmp.dc.creator', list, [u'Ian Britton']),
123
                   ('Xmp.dc.description', dict, {u'x-default': u'Communications'}),
124
                   ('Xmp.dc.rights', dict, {u'x-default': u'ian Britton - FreeFoto.com'}),
125
                   ('Xmp.dc.source', unicode, u'FreeFoto.com'),
126
                   ('Xmp.dc.subject', list, [u'Communications']),
127
                   ('Xmp.dc.title', dict, {u'x-default': u'Communications'}),
347.1.2 by Olivier Tilloy
Handle fractions in a transparent manner,
128
                   ('Xmp.exif.ApertureValue', FRACTION, make_fraction(8, 1)),
129
                   ('Xmp.exif.BrightnessValue', FRACTION, make_fraction(333, 1280)),
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
130
                   ('Xmp.exif.ColorSpace', int, 1),
270.2.2 by Mark Lee
Add an XMP metadata test.
131
                   ('Xmp.exif.DateTimeOriginal',
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
132
                    datetime.datetime,
270.2.2 by Mark Lee
Add an XMP metadata test.
133
                    datetime.datetime(2002, 7, 13, 15, 58, 28, tzinfo=pyexiv2.utils.FixedOffset())),
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
134
                   ('Xmp.exif.ExifVersion', unicode, u'0200'),
347.1.2 by Olivier Tilloy
Handle fractions in a transparent manner,
135
                   ('Xmp.exif.ExposureBiasValue', FRACTION, make_fraction(-13, 20)),
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
136
                   ('Xmp.exif.ExposureProgram', int, 4),
347.1.2 by Olivier Tilloy
Handle fractions in a transparent manner,
137
                   ('Xmp.exif.FNumber', FRACTION, make_fraction(3, 5)),
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
138
                   ('Xmp.exif.FileSource', int, 0),
139
                   ('Xmp.exif.FlashpixVersion', unicode, u'0100'),
347.1.2 by Olivier Tilloy
Handle fractions in a transparent manner,
140
                   ('Xmp.exif.FocalLength', FRACTION, make_fraction(0, 1)),
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
141
                   ('Xmp.exif.FocalPlaneResolutionUnit', int, 2),
347.1.2 by Olivier Tilloy
Handle fractions in a transparent manner,
142
                   ('Xmp.exif.FocalPlaneXResolution', FRACTION, make_fraction(3085, 256)),
143
                   ('Xmp.exif.FocalPlaneYResolution', FRACTION, make_fraction(3085, 256)),
270.2.2 by Mark Lee
Add an XMP metadata test.
144
                   ('Xmp.exif.GPSLatitude',
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
145
                    pyexiv2.utils.GPSCoordinate,
270.2.2 by Mark Lee
Add an XMP metadata test.
146
                    pyexiv2.utils.GPSCoordinate.from_string('54,59.380000N')),
147
                   ('Xmp.exif.GPSLongitude',
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
148
                    pyexiv2.utils.GPSCoordinate,
270.2.2 by Mark Lee
Add an XMP metadata test.
149
                    pyexiv2.utils.GPSCoordinate.from_string('1,54.850000W')),
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
150
                   ('Xmp.exif.GPSMapDatum', unicode, u'WGS84'),
270.2.2 by Mark Lee
Add an XMP metadata test.
151
                   ('Xmp.exif.GPSTimeStamp',
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
152
                    datetime.datetime,
270.2.2 by Mark Lee
Add an XMP metadata test.
153
                    datetime.datetime(2002, 7, 13, 14, 58, 24, tzinfo=pyexiv2.utils.FixedOffset())),
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
154
                   ('Xmp.exif.GPSVersionID', unicode, u'2.0.0.0'),
155
                   ('Xmp.exif.ISOSpeedRatings', list, [0]),
156
                   ('Xmp.exif.MeteringMode', int, 5),
157
                   ('Xmp.exif.PixelXDimension', int, 2400),
158
                   ('Xmp.exif.PixelYDimension', int, 1600),
159
                   ('Xmp.exif.SceneType', int, 0),
160
                   ('Xmp.exif.SensingMethod', int, 2),
347.1.2 by Olivier Tilloy
Handle fractions in a transparent manner,
161
                   ('Xmp.exif.ShutterSpeedValue', FRACTION, make_fraction(30827, 3245)),
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
162
                   ('Xmp.pdf.Keywords', unicode, u'Communications'),
163
                   ('Xmp.photoshop.AuthorsPosition', unicode, u'Photographer'),
164
                   ('Xmp.photoshop.CaptionWriter', unicode, u'Ian Britton'),
165
                   ('Xmp.photoshop.Category', unicode, u'BUS'),
166
                   ('Xmp.photoshop.City', unicode, u' '),
167
                   ('Xmp.photoshop.Country', unicode, u'Ubited Kingdom'),
168
                   ('Xmp.photoshop.Credit', unicode, u'Ian Britton'),
169
                   ('Xmp.photoshop.DateCreated', datetime.date, datetime.date(2002, 6, 20)),
170
                   ('Xmp.photoshop.Headline', unicode, u'Communications'),
171
                   ('Xmp.photoshop.State', unicode, u' '),
172
                   ('Xmp.photoshop.SupplementalCategories', list, [u'Communications']),
173
                   ('Xmp.photoshop.Urgency', int, 5),
174
                   ('Xmp.tiff.Artist', unicode, u'Ian Britton'),
175
                   ('Xmp.tiff.BitsPerSample', list, [8]),
176
                   ('Xmp.tiff.Compression', int, 6),
270.2.2 by Mark Lee
Add an XMP metadata test.
177
                   ('Xmp.tiff.Copyright',
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
178
                    dict,
270.2.2 by Mark Lee
Add an XMP metadata test.
179
                    {u'x-default': u'ian Britton - FreeFoto.com'}),
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
180
                   ('Xmp.tiff.ImageDescription', dict, {u'x-default': u'Communications'}),
181
                   ('Xmp.tiff.ImageLength', int, 400),
182
                   ('Xmp.tiff.ImageWidth', int, 600),
183
                   ('Xmp.tiff.Make', unicode, u'FUJIFILM'),
184
                   ('Xmp.tiff.Model', unicode, u'FinePixS1Pro'),
185
                   ('Xmp.tiff.Orientation', int, 1),
186
                   ('Xmp.tiff.ResolutionUnit', int, 2),
187
                   ('Xmp.tiff.Software', unicode, u'Adobe Photoshop 7.0'),
347.1.2 by Olivier Tilloy
Handle fractions in a transparent manner,
188
                   ('Xmp.tiff.XResolution', FRACTION, make_fraction(300, 1)),
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
189
                   ('Xmp.tiff.YCbCrPositioning', int, 2),
347.1.2 by Olivier Tilloy
Handle fractions in a transparent manner,
190
                   ('Xmp.tiff.YResolution', FRACTION, make_fraction(300, 1)),
270.2.2 by Mark Lee
Add an XMP metadata test.
191
                   ('Xmp.xmp.CreateDate',
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
192
                    datetime.datetime,
270.2.2 by Mark Lee
Add an XMP metadata test.
193
                    datetime.datetime(2002, 7, 13, 15, 58, 28, tzinfo=pyexiv2.utils.FixedOffset())),
194
                   ('Xmp.xmp.ModifyDate',
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
195
                    datetime.datetime,
270.2.2 by Mark Lee
Add an XMP metadata test.
196
                    datetime.datetime(2002, 7, 19, 13, 28, 10, tzinfo=pyexiv2.utils.FixedOffset())),
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
197
                   ('Xmp.xmpBJ.JobRef', list, []),
198
                   ('Xmp.xmpBJ.JobRef[1]', str, ''),
199
                   ('Xmp.xmpBJ.JobRef[1]/stJob:name', str, 'Photographer'),
270.2.2 by Mark Lee
Add an XMP metadata test.
200
                   ('Xmp.xmpMM.DocumentID',
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
201
                    str,
270.2.2 by Mark Lee
Add an XMP metadata test.
202
                    'adobe:docid:photoshop:84d4dba8-9b11-11d6-895d-c4d063a70fb0'),
270.2.3 by Mark Lee
XMP: Check the tag value types, not the tag type.
203
                   ('Xmp.xmpRights.Marked', bool, True),
204
                   ('Xmp.xmpRights.WebStatement', str, 'www.freefoto.com')]
270.2.6 by Olivier Tilloy
Consistent type and value(s) checks.
205
        self.assertEqual(image.xmp_keys, [tag[0] for tag in xmpTags])
206
        for key, ktype, value in xmpTags:
207
            self.check_type_and_value(image[key], ktype, value)
347.1.2 by Olivier Tilloy
Handle fractions in a transparent manner,
208