mirror of
https://github.com/fergalmoran/picard.git
synced 2026-01-06 08:34:01 +00:00
191 lines
6.8 KiB
Python
191 lines
6.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
#
|
|
# Picard, the next-generation MusicBrainz tagger
|
|
#
|
|
# Copyright (C) 2019-2020 Philipp Wolfer
|
|
#
|
|
# 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 2
|
|
# 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, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
|
from mutagen.asf import ASFByteArrayAttribute
|
|
|
|
from test.picardtestcase import (
|
|
PicardTestCase,
|
|
create_fake_png,
|
|
)
|
|
|
|
from picard.formats import (
|
|
asf,
|
|
ext_to_format,
|
|
)
|
|
|
|
from .common import (
|
|
CommonTests,
|
|
load_metadata,
|
|
load_raw,
|
|
save_metadata,
|
|
save_raw,
|
|
skipUnlessTestfile,
|
|
)
|
|
from .coverart import CommonCoverArtTests
|
|
|
|
|
|
# prevent unittest to run tests in those classes
|
|
class CommonAsfTests:
|
|
|
|
class AsfTestCase(CommonTests.TagFormatsTestCase):
|
|
|
|
def test_supports_tag(self):
|
|
fmt = ext_to_format(self.testfile_ext[1:])
|
|
self.assertTrue(fmt.supports_tag('copyright'))
|
|
self.assertTrue(fmt.supports_tag('compilation'))
|
|
self.assertTrue(fmt.supports_tag('bpm'))
|
|
self.assertTrue(fmt.supports_tag('djmixer'))
|
|
self.assertTrue(fmt.supports_tag('discnumber'))
|
|
self.assertTrue(fmt.supports_tag('lyrics:lead'))
|
|
self.assertTrue(fmt.supports_tag('~length'))
|
|
for tag in self.replaygain_tags.keys():
|
|
self.assertTrue(fmt.supports_tag(tag))
|
|
|
|
@skipUnlessTestfile
|
|
def test_ci_tags_preserve_case(self):
|
|
# Ensure values are not duplicated on repeated save and are saved
|
|
# case preserving.
|
|
tags = {
|
|
'Replaygain_Album_Peak': '-6.48 dB'
|
|
}
|
|
save_raw(self.filename, tags)
|
|
loaded_metadata = load_metadata(self.filename)
|
|
loaded_metadata['replaygain_album_peak'] = '1.0'
|
|
save_metadata(self.filename, loaded_metadata)
|
|
raw_metadata = load_raw(self.filename)
|
|
self.assertIn('Replaygain_Album_Peak', raw_metadata)
|
|
self.assertEqual(raw_metadata['Replaygain_Album_Peak'][0], loaded_metadata['replaygain_album_peak'])
|
|
self.assertEqual(1, len(raw_metadata['Replaygain_Album_Peak']))
|
|
self.assertNotIn('REPLAYGAIN_ALBUM_PEAK', raw_metadata)
|
|
|
|
def _test_invalid_picture(self, invalid_picture_data):
|
|
png_data = create_fake_png(b'x')
|
|
tags = {
|
|
'WM/Picture': [
|
|
ASFByteArrayAttribute(invalid_picture_data),
|
|
ASFByteArrayAttribute(
|
|
asf.pack_image("image/png", png_data)
|
|
)
|
|
]
|
|
}
|
|
save_raw(self.filename, tags)
|
|
metadata = load_metadata(self.filename)
|
|
self.assertEqual(1, len(metadata.images))
|
|
self.assertEqual(png_data, metadata.images[0].data)
|
|
|
|
@skipUnlessTestfile
|
|
def test_ignore_invalid_wm_picture(self):
|
|
# A picture that cannot be unpacked
|
|
self._test_invalid_picture(b'notapicture')
|
|
|
|
|
|
class ASFTest(CommonAsfTests.AsfTestCase):
|
|
testfile = 'test.asf'
|
|
supports_ratings = True
|
|
expected_info = {
|
|
'length': 92,
|
|
'~channels': '2',
|
|
'~sample_rate': '44100',
|
|
'~bitrate': '128.0',
|
|
}
|
|
|
|
|
|
class WMATest(CommonAsfTests.AsfTestCase):
|
|
testfile = 'test.wma'
|
|
supports_ratings = True
|
|
expected_info = {
|
|
'length': 139,
|
|
'~channels': '2',
|
|
'~sample_rate': '44100',
|
|
'~bitrate': '64.0',
|
|
}
|
|
unexpected_info = ['~video']
|
|
|
|
|
|
class WMVTest(CommonAsfTests.AsfTestCase):
|
|
testfile = 'test.wmv'
|
|
supports_ratings = True
|
|
expected_info = {
|
|
'length': 565,
|
|
'~channels': '2',
|
|
'~sample_rate': '44100',
|
|
'~bitrate': '128.0',
|
|
'~video': '1',
|
|
}
|
|
|
|
|
|
class AsfUtilTest(PicardTestCase):
|
|
test_cases = [
|
|
# Empty MIME, description and data
|
|
(('', b'', 2, ''), b'\x02\x00\x00\x00\x00\x00\x00\x00\x00'),
|
|
# MIME, description set, 1 byte data
|
|
(('M', b'x', 2, 'D'), b'\x02\x01\x00\x00\x00M\x00\x00\x00D\x00\x00\x00x'),
|
|
# Empty MIME and description, 3 byte data
|
|
(('', b'abc', 0, ''), b'\x00\x03\x00\x00\x00\x00\x00\x00\x00abc'),
|
|
]
|
|
|
|
def test_pack_and_unpack_image(self):
|
|
mime = 'image/png'
|
|
image_data = create_fake_png(b'x')
|
|
image_type = 4
|
|
description = 'testing'
|
|
tag_data = asf.pack_image(mime, image_data, image_type, description)
|
|
expected_length = 5 + 2 * len(mime) + 2 + 2 * len(description) + 2 + len(image_data)
|
|
self.assertEqual(tag_data[0], image_type)
|
|
self.assertEqual(len(tag_data), expected_length)
|
|
self.assertEqual(image_data, tag_data[-len(image_data):])
|
|
|
|
unpacked = asf.unpack_image(tag_data)
|
|
self.assertEqual(mime, unpacked[0])
|
|
self.assertEqual(image_data, unpacked[1])
|
|
self.assertEqual(image_type, unpacked[2])
|
|
self.assertEqual(description, unpacked[3])
|
|
|
|
def test_pack_image(self):
|
|
for args, expected in self.test_cases:
|
|
self.assertEqual(expected, asf.pack_image(*args))
|
|
|
|
def test_unpack_image(self):
|
|
for expected, packed in self.test_cases:
|
|
self.assertEqual(expected, asf.unpack_image(packed))
|
|
|
|
def test_unpack_image_value_errors(self):
|
|
self.assertRaisesRegex(ValueError, "unpack_from requires a buffer of at least 5 bytes",
|
|
asf.unpack_image, b'')
|
|
self.assertRaisesRegex(ValueError, "unpack_from requires a buffer of at least 5 bytes",
|
|
asf.unpack_image, b'\x02\x01\x00\x00')
|
|
self.assertRaisesRegex(ValueError, "mime: missing data",
|
|
asf.unpack_image, b'\x00\x00\x00\x00\x00')
|
|
self.assertRaisesRegex(ValueError, "mime: missing data",
|
|
asf.unpack_image, b'\x04\x19\x00\x00\x00a\x00')
|
|
self.assertRaisesRegex(ValueError, "desc: missing data",
|
|
asf.unpack_image, b'\x04\x19\x00\x00\x00a\x00\x00\x00a\x00')
|
|
self.assertRaisesRegex(ValueError, "image data size mismatch",
|
|
asf.unpack_image, b'\x04\x19\x00\x00\x00a\x00\x00\x00a\x00\x00\x00x')
|
|
|
|
|
|
class AsfCoverArtTest(CommonCoverArtTests.CoverArtTestCase):
|
|
testfile = 'test.asf'
|
|
|
|
|
|
class WmaCoverArtTest(CommonCoverArtTests.CoverArtTestCase):
|
|
testfile = 'test.wma'
|