mirror of
https://github.com/taglib/taglib.git
synced 2025-05-27 21:20:26 -04:00
Merge pull request #990 from ufleisch/ufleisch/more-tests
More unit tests and bug fixes
This commit is contained in:
commit
f8d78a61f7
@ -215,7 +215,9 @@ namespace
|
||||
{"DATE", "YEAR" },
|
||||
{"ALBUMARTIST", "ALBUM ARTIST"},
|
||||
{"DISCNUMBER", "DISC" },
|
||||
{"REMIXER", "MIXARTIST" }};
|
||||
{"REMIXER", "MIXARTIST" },
|
||||
{"RELEASESTATUS", "MUSICBRAINZ_ALBUMSTATUS" },
|
||||
{"RELEASETYPE", "MUSICBRAINZ_ALBUMTYPE" }};
|
||||
const size_t keyConversionsSize = sizeof(keyConversions) / sizeof(keyConversions[0]);
|
||||
}
|
||||
|
||||
|
@ -216,7 +216,7 @@ namespace
|
||||
{ "WM/AlbumTitle", "ALBUM" },
|
||||
{ "WM/AlbumArtist", "ALBUMARTIST" },
|
||||
{ "WM/Composer", "COMPOSER" },
|
||||
{ "WM/Writer", "WRITER" },
|
||||
{ "WM/Writer", "LYRICIST" },
|
||||
{ "WM/Conductor", "CONDUCTOR" },
|
||||
{ "WM/ModifiedBy", "REMIXER" },
|
||||
{ "WM/Year", "DATE" },
|
||||
@ -243,11 +243,17 @@ namespace
|
||||
{ "WM/TitleSortOrder", "TITLESORT" },
|
||||
{ "WM/Script", "SCRIPT" },
|
||||
{ "WM/Language", "LANGUAGE" },
|
||||
{ "WM/ARTISTS", "ARTISTS" },
|
||||
{ "ASIN", "ASIN" },
|
||||
{ "MusicBrainz/Track Id", "MUSICBRAINZ_TRACKID" },
|
||||
{ "MusicBrainz/Artist Id", "MUSICBRAINZ_ARTISTID" },
|
||||
{ "MusicBrainz/Album Id", "MUSICBRAINZ_ALBUMID" },
|
||||
{ "MusicBrainz/Album Artist Id", "MUSICBRAINZ_ALBUMARTISTID" },
|
||||
{ "MusicBrainz/Album Release Country", "RELEASECOUNTRY" },
|
||||
{ "MusicBrainz/Album Status", "RELEASESTATUS" },
|
||||
{ "MusicBrainz/Album Type", "RELEASETYPE" },
|
||||
{ "MusicBrainz/Release Group Id", "MUSICBRAINZ_RELEASEGROUPID" },
|
||||
{ "MusicBrainz/Release Track Id", "MUSICBRAINZ_RELEASETRACKID" },
|
||||
{ "MusicBrainz/Work Id", "MUSICBRAINZ_WORKID" },
|
||||
{ "MusicIP/PUID", "MUSICIP_PUID" },
|
||||
{ "Acoustid/Id", "ACOUSTID_ID" },
|
||||
|
@ -366,6 +366,7 @@ StringList FileRef::defaultFileExtensions()
|
||||
l.append("ogg");
|
||||
l.append("flac");
|
||||
l.append("oga");
|
||||
l.append("opus");
|
||||
l.append("mp3");
|
||||
l.append("mpc");
|
||||
l.append("wv");
|
||||
@ -382,6 +383,8 @@ StringList FileRef::defaultFileExtensions()
|
||||
l.append("asf");
|
||||
l.append("aif");
|
||||
l.append("aiff");
|
||||
l.append("afc");
|
||||
l.append("aifc");
|
||||
l.append("wav");
|
||||
l.append("ape");
|
||||
l.append("mod");
|
||||
|
@ -895,6 +895,17 @@ namespace
|
||||
{ "soco", "COMPOSERSORT" },
|
||||
{ "sosn", "SHOWSORT" },
|
||||
{ "shwm", "SHOWWORKMOVEMENT" },
|
||||
{ "pgap", "GAPLESSPLAYBACK" },
|
||||
{ "pcst", "PODCAST" },
|
||||
{ "catg", "PODCASTCATEGORY" },
|
||||
{ "desc", "PODCASTDESC" },
|
||||
{ "egid", "PODCASTID" },
|
||||
{ "purl", "PODCASTURL" },
|
||||
{ "tves", "TVEPISODE" },
|
||||
{ "tven", "TVEPISODEID" },
|
||||
{ "tvnn", "TVNETWORK" },
|
||||
{ "tvsn", "TVSEASON" },
|
||||
{ "tvsh", "TVSHOW" },
|
||||
{ "\251wrk", "WORK" },
|
||||
{ "\251mvn", "MOVEMENTNAME" },
|
||||
{ "\251mvi", "MOVEMENTNUMBER" },
|
||||
@ -904,7 +915,13 @@ namespace
|
||||
{ "----:com.apple.iTunes:MusicBrainz Album Id", "MUSICBRAINZ_ALBUMID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Album Artist Id", "MUSICBRAINZ_ALBUMARTISTID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Release Group Id", "MUSICBRAINZ_RELEASEGROUPID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Release Track Id", "MUSICBRAINZ_RELEASETRACKID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Work Id", "MUSICBRAINZ_WORKID" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Album Release Country", "RELEASECOUNTRY" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Album Status", "RELEASESTATUS" },
|
||||
{ "----:com.apple.iTunes:MusicBrainz Album Type", "RELEASETYPE" },
|
||||
{ "----:com.apple.iTunes:ARTISTS", "ARTISTS" },
|
||||
{ "----:com.apple.iTunes:originaldate", "ORIGINALDATE" },
|
||||
{ "----:com.apple.iTunes:ASIN", "ASIN" },
|
||||
{ "----:com.apple.iTunes:LABEL", "LABEL" },
|
||||
{ "----:com.apple.iTunes:LYRICIST", "LYRICIST" },
|
||||
@ -952,10 +969,12 @@ PropertyMap MP4::Tag::properties() const
|
||||
}
|
||||
props[key] = value;
|
||||
}
|
||||
else if(key == "BPM" || key == "MOVEMENTNUMBER" || key == "MOVEMENTCOUNT") {
|
||||
else if(key == "BPM" || key == "MOVEMENTNUMBER" || key == "MOVEMENTCOUNT" ||
|
||||
key == "TVEPISODE" || key == "TVSEASON") {
|
||||
props[key] = String::number(it->second.toInt());
|
||||
}
|
||||
else if(key == "COMPILATION" || key == "SHOWWORKMOVEMENT") {
|
||||
else if(key == "COMPILATION" || key == "SHOWWORKMOVEMENT" ||
|
||||
key == "GAPLESSPLAYBACK" || key == "PODCAST") {
|
||||
props[key] = String::number(it->second.toBool());
|
||||
}
|
||||
else {
|
||||
@ -1007,11 +1026,15 @@ PropertyMap MP4::Tag::setProperties(const PropertyMap &props)
|
||||
d->items[name] = MP4::Item(first, second);
|
||||
}
|
||||
}
|
||||
else if((it->first == "BPM" || it->first == "MOVEMENTNUMBER" || it->first == "MOVEMENTCOUNT") && !it->second.isEmpty()) {
|
||||
else if((it->first == "BPM" || it->first == "MOVEMENTNUMBER" ||
|
||||
it->first == "MOVEMENTCOUNT" || it->first == "TVEPISODE" ||
|
||||
it->first == "TVSEASON") && !it->second.isEmpty()) {
|
||||
int value = it->second.front().toInt();
|
||||
d->items[name] = MP4::Item(value);
|
||||
}
|
||||
else if((it->first == "COMPILATION" || it->first == "SHOWWORKMOVEMENT") && !it->second.isEmpty()) {
|
||||
else if((it->first == "COMPILATION" || it->first == "SHOWWORKMOVEMENT" ||
|
||||
it->first == "GAPLESSPLAYBACK" || it->first == "PODCAST") &&
|
||||
!it->second.isEmpty()) {
|
||||
bool value = (it->second.front().toInt() != 0);
|
||||
d->items[name] = MP4::Item(value);
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "podcastframe.h"
|
||||
#include <tpropertymap.h>
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace ID3v2;
|
||||
@ -55,6 +56,13 @@ String PodcastFrame::toString() const
|
||||
return String();
|
||||
}
|
||||
|
||||
PropertyMap PodcastFrame::asProperties() const
|
||||
{
|
||||
PropertyMap map;
|
||||
map.insert("PODCAST", StringList());
|
||||
return map;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// protected members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -57,6 +57,8 @@ namespace TagLib {
|
||||
*/
|
||||
virtual String toString() const;
|
||||
|
||||
PropertyMap asProperties() const;
|
||||
|
||||
protected:
|
||||
// Reimplementations.
|
||||
|
||||
|
@ -55,7 +55,7 @@ PrivateFrame::PrivateFrame(const ByteVector &data) :
|
||||
Frame(data),
|
||||
d(new PrivateFramePrivate())
|
||||
{
|
||||
setData(data);
|
||||
Frame::setData(data);
|
||||
}
|
||||
|
||||
PrivateFrame::~PrivateFrame()
|
||||
|
@ -168,7 +168,8 @@ void TableOfContentsFrame::removeChildElement(const ByteVector &cE)
|
||||
if(it == d->childElements.end())
|
||||
it = d->childElements.find(cE + ByteVector("\0"));
|
||||
|
||||
d->childElements.erase(it);
|
||||
if(it != d->childElements.end())
|
||||
d->childElements.erase(it);
|
||||
}
|
||||
|
||||
const FrameListMap &TableOfContentsFrame::embeddedFrameListMap() const
|
||||
@ -196,11 +197,14 @@ void TableOfContentsFrame::removeEmbeddedFrame(Frame *frame, bool del)
|
||||
{
|
||||
// remove the frame from the frame list
|
||||
FrameList::Iterator it = d->embeddedFrameList.find(frame);
|
||||
d->embeddedFrameList.erase(it);
|
||||
if(it != d->embeddedFrameList.end())
|
||||
d->embeddedFrameList.erase(it);
|
||||
|
||||
// ...and from the frame list map
|
||||
it = d->embeddedFrameListMap[frame->frameID()].find(frame);
|
||||
d->embeddedFrameListMap[frame->frameID()].erase(it);
|
||||
FrameList &mappedList = d->embeddedFrameListMap[frame->frameID()];
|
||||
it = mappedList.find(frame);
|
||||
if(it != mappedList.end())
|
||||
mappedList.erase(it);
|
||||
|
||||
// ...and delete as desired
|
||||
if(del)
|
||||
|
@ -63,7 +63,10 @@ TextIdentificationFrame *TextIdentificationFrame::createTIPLFrame(const Property
|
||||
TextIdentificationFrame *frame = new TextIdentificationFrame("TIPL");
|
||||
StringList l;
|
||||
for(PropertyMap::ConstIterator it = properties.begin(); it != properties.end(); ++it){
|
||||
l.append(it->first);
|
||||
const String role = involvedPeopleMap()[it->first];
|
||||
if(role.isEmpty()) // should not happen
|
||||
continue;
|
||||
l.append(role);
|
||||
l.append(it->second.toString(",")); // comma-separated list of names
|
||||
}
|
||||
frame->setText(l);
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "frames/commentsframe.h"
|
||||
#include "frames/uniquefileidentifierframe.h"
|
||||
#include "frames/unknownframe.h"
|
||||
#include "frames/podcastframe.h"
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace ID3v2;
|
||||
@ -120,6 +121,8 @@ Frame *Frame::createTextualFrame(const String &key, const StringList &values) //
|
||||
UrlLinkFrame* frame = new UrlLinkFrame(frameID);
|
||||
frame->setUrl(values.front());
|
||||
return frame;
|
||||
} else if(frameID == "PCST") {
|
||||
return new PodcastFrame();
|
||||
}
|
||||
}
|
||||
if(key == "MUSICBRAINZ_TRACKID" && values.size() == 1) {
|
||||
@ -344,7 +347,7 @@ namespace
|
||||
{ "TEXT", "LYRICIST" },
|
||||
{ "TFLT", "FILETYPE" },
|
||||
//{ "TIPL", "INVOLVEDPEOPLE" }, handled separately
|
||||
{ "TIT1", "CONTENTGROUP" },
|
||||
{ "TIT1", "CONTENTGROUP" }, // 'Work' in iTunes
|
||||
{ "TIT2", "TITLE"},
|
||||
{ "TIT3", "SUBTITLE" },
|
||||
{ "TKEY", "INITIALKEY" },
|
||||
@ -369,6 +372,7 @@ namespace
|
||||
{ "TRSN", "RADIOSTATION" },
|
||||
{ "TRSO", "RADIOSTATIONOWNER" },
|
||||
{ "TSOA", "ALBUMSORT" },
|
||||
{ "TSOC", "COMPOSERSORT" },
|
||||
{ "TSOP", "ARTISTSORT" },
|
||||
{ "TSOT", "TITLESORT" },
|
||||
{ "TSO2", "ALBUMARTISTSORT" }, // non-standard, used by iTunes
|
||||
@ -402,7 +406,11 @@ namespace
|
||||
{ "MUSICBRAINZ ALBUM ID", "MUSICBRAINZ_ALBUMID" },
|
||||
{ "MUSICBRAINZ ARTIST ID", "MUSICBRAINZ_ARTISTID" },
|
||||
{ "MUSICBRAINZ ALBUM ARTIST ID", "MUSICBRAINZ_ALBUMARTISTID" },
|
||||
{ "MUSICBRAINZ ALBUM RELEASE COUNTRY", "RELEASECOUNTRY" },
|
||||
{ "MUSICBRAINZ ALBUM STATUS", "RELEASESTATUS" },
|
||||
{ "MUSICBRAINZ ALBUM TYPE", "RELEASETYPE" },
|
||||
{ "MUSICBRAINZ RELEASE GROUP ID", "MUSICBRAINZ_RELEASEGROUPID" },
|
||||
{ "MUSICBRAINZ RELEASE TRACK ID", "MUSICBRAINZ_RELEASETRACKID" },
|
||||
{ "MUSICBRAINZ WORK ID", "MUSICBRAINZ_WORKID" },
|
||||
{ "ACOUSTID ID", "ACOUSTID_ID" },
|
||||
{ "ACOUSTID FINGERPRINT", "ACOUSTID_FINGERPRINT" },
|
||||
@ -490,6 +498,8 @@ PropertyMap Frame::asProperties() const
|
||||
return dynamic_cast< const UnsynchronizedLyricsFrame* >(this)->asProperties();
|
||||
else if(id == "UFID")
|
||||
return dynamic_cast< const UniqueFileIdentifierFrame* >(this)->asProperties();
|
||||
else if(id == "PCST")
|
||||
return dynamic_cast< const PodcastFrame* >(this)->asProperties();
|
||||
PropertyMap m;
|
||||
m.unsupportedData().append(id);
|
||||
return m;
|
||||
|
@ -68,6 +68,7 @@ namespace TagLib {
|
||||
* - ALBUMSORT
|
||||
* - ARTISTSORT
|
||||
* - ALBUMARTISTSORT
|
||||
* - COMPOSERSORT
|
||||
*
|
||||
* Credits:
|
||||
*
|
||||
@ -90,12 +91,16 @@ namespace TagLib {
|
||||
* - LABEL
|
||||
* - CATALOGNUMBER
|
||||
* - BARCODE
|
||||
* - RELEASECOUNTRY
|
||||
* - RELEASESTATUS
|
||||
* - RELEASETYPE
|
||||
*
|
||||
* MusicBrainz identifiers:
|
||||
*
|
||||
* - MUSICBRAINZ_TRACKID
|
||||
* - MUSICBRAINZ_ALBUMID
|
||||
* - MUSICBRAINZ_RELEASEGROUPID
|
||||
* - MUSICBRAINZ_RELEASETRACKID
|
||||
* - MUSICBRAINZ_WORKID
|
||||
* - MUSICBRAINZ_ARTISTID
|
||||
* - MUSICBRAINZ_ALBUMARTISTID
|
||||
|
@ -263,7 +263,7 @@ void WavPack::File::read(bool readProperties)
|
||||
d->APELocation = d->APELocation + APE::Footer::size() - d->APESize;
|
||||
}
|
||||
|
||||
if(d->ID3v1Location >= 0)
|
||||
if(d->ID3v1Location < 0)
|
||||
APETag(true);
|
||||
|
||||
// Look for WavPack audio properties
|
||||
|
@ -155,6 +155,58 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void testProperties()
|
||||
{
|
||||
PropertyMap tags;
|
||||
tags["ALBUM"] = StringList("Album");
|
||||
tags["ALBUMARTIST"] = StringList("Album Artist");
|
||||
tags["ALBUMARTISTSORT"] = StringList("Album Artist Sort");
|
||||
tags["ALBUMSORT"] = StringList("Album Sort");
|
||||
tags["ARTIST"] = StringList("Artist");
|
||||
tags["ARTISTS"] = StringList("Artists");
|
||||
tags["ARTISTSORT"] = StringList("Artist Sort");
|
||||
tags["ASIN"] = StringList("ASIN");
|
||||
tags["BARCODE"] = StringList("Barcode");
|
||||
tags["CATALOGNUMBER"] = StringList("Catalog Number 1").append("Catalog Number 2");
|
||||
tags["COMMENT"] = StringList("Comment");
|
||||
tags["DATE"] = StringList("2021-01-10");
|
||||
tags["DISCNUMBER"] = StringList("3/5");
|
||||
tags["GENRE"] = StringList("Genre");
|
||||
tags["ISRC"] = StringList("UKAAA0500001");
|
||||
tags["LABEL"] = StringList("Label 1").append("Label 2");
|
||||
tags["MEDIA"] = StringList("Media");
|
||||
tags["MUSICBRAINZ_ALBUMARTISTID"] = StringList("MusicBrainz_AlbumartistID");
|
||||
tags["MUSICBRAINZ_ALBUMID"] = StringList("MusicBrainz_AlbumID");
|
||||
tags["MUSICBRAINZ_ARTISTID"] = StringList("MusicBrainz_ArtistID");
|
||||
tags["MUSICBRAINZ_RELEASEGROUPID"] = StringList("MusicBrainz_ReleasegroupID");
|
||||
tags["MUSICBRAINZ_RELEASETRACKID"] = StringList("MusicBrainz_ReleasetrackID");
|
||||
tags["MUSICBRAINZ_TRACKID"] = StringList("MusicBrainz_TrackID");
|
||||
tags["ORIGINALDATE"] = StringList("2021-01-09");
|
||||
tags["RELEASECOUNTRY"] = StringList("Release Country");
|
||||
tags["RELEASESTATUS"] = StringList("Release Status");
|
||||
tags["RELEASETYPE"] = StringList("Release Type");
|
||||
tags["SCRIPT"] = StringList("Script");
|
||||
tags["TITLE"] = StringList("Title");
|
||||
tags["TRACKNUMBER"] = StringList("2/3");
|
||||
|
||||
ScopedFileCopy copy("mac-399", ".ape");
|
||||
{
|
||||
APE::File f(copy.fileName().c_str());
|
||||
PropertyMap properties = f.properties();
|
||||
CPPUNIT_ASSERT(properties.isEmpty());
|
||||
f.setProperties(tags);
|
||||
f.save();
|
||||
}
|
||||
{
|
||||
const APE::File f(copy.fileName().c_str());
|
||||
PropertyMap properties = f.properties();
|
||||
if (tags != properties) {
|
||||
CPPUNIT_ASSERT_EQUAL(tags.toString(), properties.toString());
|
||||
}
|
||||
CPPUNIT_ASSERT(tags == properties);
|
||||
}
|
||||
}
|
||||
|
||||
void testRepeatedSave()
|
||||
{
|
||||
ScopedFileCopy copy("mac-399", ".ape");
|
||||
|
@ -79,6 +79,10 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(2u, tag.itemListMap()["ARTIST"].values().size());
|
||||
CPPUNIT_ASSERT_EQUAL(String("artist 1 artist 2"), tag.artist());
|
||||
CPPUNIT_ASSERT_EQUAL(17u, tag.track());
|
||||
const APE::Item &textItem = tag.itemListMap()["TRACK"];
|
||||
CPPUNIT_ASSERT_EQUAL(APE::Item::Text, textItem.type());
|
||||
CPPUNIT_ASSERT(!textItem.isEmpty());
|
||||
CPPUNIT_ASSERT_EQUAL(9 + 5 + 2, textItem.size());
|
||||
}
|
||||
|
||||
void testPropertyInterface2()
|
||||
@ -89,6 +93,8 @@ public:
|
||||
|
||||
APE::Item item2 = APE::Item();
|
||||
item2.setType(APE::Item::Binary);
|
||||
ByteVector binaryData1("first");
|
||||
item2.setBinaryData(binaryData1);
|
||||
tag.setItem("TESTBINARY", item2);
|
||||
|
||||
PropertyMap properties = tag.properties();
|
||||
@ -96,6 +102,16 @@ public:
|
||||
CPPUNIT_ASSERT(properties.contains("TRACKNUMBER"));
|
||||
CPPUNIT_ASSERT(!properties.contains("TRACK"));
|
||||
CPPUNIT_ASSERT(tag.itemListMap().contains("TESTBINARY"));
|
||||
CPPUNIT_ASSERT_EQUAL(binaryData1,
|
||||
tag.itemListMap()["TESTBINARY"].binaryData());
|
||||
ByteVector binaryData2("second");
|
||||
tag.setData("TESTBINARY", binaryData2);
|
||||
const APE::Item &binaryItem = tag.itemListMap()["TESTBINARY"];
|
||||
CPPUNIT_ASSERT_EQUAL(APE::Item::Binary, binaryItem.type());
|
||||
CPPUNIT_ASSERT(!binaryItem.isEmpty());
|
||||
CPPUNIT_ASSERT_EQUAL(9 + 10 + static_cast<int>(binaryData2.size()),
|
||||
binaryItem.size());
|
||||
CPPUNIT_ASSERT_EQUAL(binaryData2, binaryItem.binaryData());
|
||||
|
||||
tag.removeUnsupportedProperties(properties.unsupportedData());
|
||||
CPPUNIT_ASSERT(!tag.itemListMap().contains("TESTBINARY"));
|
||||
|
@ -50,6 +50,7 @@ class TestASF : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testSavePicture);
|
||||
CPPUNIT_TEST(testSaveMultiplePictures);
|
||||
CPPUNIT_TEST(testProperties);
|
||||
CPPUNIT_TEST(testPropertiesAllSupported);
|
||||
CPPUNIT_TEST(testRepeatedSave);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
@ -302,6 +303,84 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(StringList("3"), tags["DISCNUMBER"]);
|
||||
}
|
||||
|
||||
void testPropertiesAllSupported()
|
||||
{
|
||||
PropertyMap tags;
|
||||
tags["ACOUSTID_ID"] = StringList("Acoustid ID");
|
||||
tags["ACOUSTID_FINGERPRINT"] = StringList("Acoustid Fingerprint");
|
||||
tags["ALBUM"] = StringList("Album");
|
||||
tags["ALBUMARTIST"] = StringList("Album Artist");
|
||||
tags["ALBUMARTISTSORT"] = StringList("Album Artist Sort");
|
||||
tags["ALBUMSORT"] = StringList("Album Sort");
|
||||
tags["ARTIST"] = StringList("Artist");
|
||||
tags["ARTISTS"] = StringList("Artists");
|
||||
tags["ARTISTSORT"] = StringList("Artist Sort");
|
||||
tags["ASIN"] = StringList("ASIN");
|
||||
tags["BARCODE"] = StringList("Barcode");
|
||||
tags["BPM"] = StringList("123");
|
||||
tags["CATALOGNUMBER"] = StringList("Catalog Number");
|
||||
tags["COMMENT"] = StringList("Comment");
|
||||
tags["COMPOSER"] = StringList("Composer");
|
||||
tags["CONDUCTOR"] = StringList("Conductor");
|
||||
tags["COPYRIGHT"] = StringList("2021 Copyright");
|
||||
tags["DATE"] = StringList("2021-01-03 12:29:23");
|
||||
tags["DISCNUMBER"] = StringList("3/5");
|
||||
tags["DISCSUBTITLE"] = StringList("Disc Subtitle");
|
||||
tags["ENCODEDBY"] = StringList("Encoded by");
|
||||
tags["GENRE"] = StringList("Genre");
|
||||
tags["GROUPING"] = StringList("Grouping");
|
||||
tags["ISRC"] = StringList("UKAAA0500001");
|
||||
tags["LABEL"] = StringList("Label");
|
||||
tags["LANGUAGE"] = StringList("eng");
|
||||
tags["LYRICIST"] = StringList("Lyricist");
|
||||
tags["LYRICS"] = StringList("Lyrics");
|
||||
tags["MEDIA"] = StringList("Media");
|
||||
tags["MOOD"] = StringList("Mood");
|
||||
tags["MUSICBRAINZ_ALBUMARTISTID"] = StringList("MusicBrainz_AlbumartistID");
|
||||
tags["MUSICBRAINZ_ALBUMID"] = StringList("MusicBrainz_AlbumID");
|
||||
tags["MUSICBRAINZ_ARTISTID"] = StringList("MusicBrainz_ArtistID");
|
||||
tags["MUSICBRAINZ_RELEASEGROUPID"] = StringList("MusicBrainz_ReleasegroupID");
|
||||
tags["MUSICBRAINZ_RELEASETRACKID"] = StringList("MusicBrainz_ReleasetrackID");
|
||||
tags["MUSICBRAINZ_TRACKID"] = StringList("MusicBrainz_TrackID");
|
||||
tags["MUSICBRAINZ_WORKID"] = StringList("MusicBrainz_WorkID");
|
||||
tags["MUSICIP_PUID"] = StringList("MusicIP PUID");
|
||||
tags["ORIGINALDATE"] = StringList("2021-01-03 13:52:19");
|
||||
tags["PRODUCER"] = StringList("Producer");
|
||||
tags["RELEASECOUNTRY"] = StringList("Release Country");
|
||||
tags["RELEASESTATUS"] = StringList("Release Status");
|
||||
tags["RELEASETYPE"] = StringList("Release Type");
|
||||
tags["REMIXER"] = StringList("Remixer");
|
||||
tags["SCRIPT"] = StringList("Script");
|
||||
tags["SUBTITLE"] = StringList("Subtitle");
|
||||
tags["TITLE"] = StringList("Title");
|
||||
tags["TITLESORT"] = StringList("Title Sort");
|
||||
tags["TRACKNUMBER"] = StringList("2/4");
|
||||
|
||||
ScopedFileCopy copy("silence-1", ".wma");
|
||||
{
|
||||
ASF::File f(copy.fileName().c_str());
|
||||
ASF::Tag *asfTag = f.tag();
|
||||
asfTag->setTitle("");
|
||||
asfTag->attributeListMap().clear();
|
||||
f.save();
|
||||
}
|
||||
{
|
||||
ASF::File f(copy.fileName().c_str());
|
||||
PropertyMap properties = f.properties();
|
||||
CPPUNIT_ASSERT(properties.isEmpty());
|
||||
f.setProperties(tags);
|
||||
f.save();
|
||||
}
|
||||
{
|
||||
const ASF::File f(copy.fileName().c_str());
|
||||
PropertyMap properties = f.properties();
|
||||
if (tags != properties) {
|
||||
CPPUNIT_ASSERT_EQUAL(tags.toString(), properties.toString());
|
||||
}
|
||||
CPPUNIT_ASSERT(tags == properties);
|
||||
}
|
||||
}
|
||||
|
||||
void testRepeatedSave()
|
||||
{
|
||||
ScopedFileCopy copy("silence-1", ".wma");
|
||||
|
@ -39,6 +39,9 @@
|
||||
#include <wavfile.h>
|
||||
#include <apefile.h>
|
||||
#include <aifffile.h>
|
||||
#include <wavpackfile.h>
|
||||
#include <opusfile.h>
|
||||
#include <xmfile.h>
|
||||
#include <tfilestream.h>
|
||||
#include <tbytevectorstream.h>
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
@ -79,8 +82,12 @@ class TestFileRef : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testWav);
|
||||
CPPUNIT_TEST(testAIFF_1);
|
||||
CPPUNIT_TEST(testAIFF_2);
|
||||
CPPUNIT_TEST(testWavPack);
|
||||
CPPUNIT_TEST(testOpus);
|
||||
CPPUNIT_TEST(testUnsupported);
|
||||
CPPUNIT_TEST(testCreate);
|
||||
CPPUNIT_TEST(testAudioProperties);
|
||||
CPPUNIT_TEST(testDefaultFileExtensions);
|
||||
CPPUNIT_TEST(testFileResolver);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
@ -100,6 +107,7 @@ public:
|
||||
f.tag()->setTitle("test title");
|
||||
f.tag()->setGenre("Test!");
|
||||
f.tag()->setAlbum("albummmm");
|
||||
f.tag()->setComment("a comment");
|
||||
f.tag()->setTrack(5);
|
||||
f.tag()->setYear(2020);
|
||||
f.save();
|
||||
@ -111,12 +119,14 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->title(), String("test title"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->genre(), String("Test!"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->album(), String("albummmm"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->comment(), String("a comment"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->track(), (unsigned int)5);
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->year(), (unsigned int)2020);
|
||||
f.tag()->setArtist("ttest artist");
|
||||
f.tag()->setTitle("ytest title");
|
||||
f.tag()->setGenre("uTest!");
|
||||
f.tag()->setAlbum("ialbummmm");
|
||||
f.tag()->setComment("another comment");
|
||||
f.tag()->setTrack(7);
|
||||
f.tag()->setYear(2080);
|
||||
f.save();
|
||||
@ -128,6 +138,7 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->title(), String("ytest title"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->genre(), String("uTest!"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->album(), String("ialbummmm"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->comment(), String("another comment"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->track(), (unsigned int)7);
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->year(), (unsigned int)2080);
|
||||
}
|
||||
@ -141,12 +152,14 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->title(), String("ytest title"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->genre(), String("uTest!"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->album(), String("ialbummmm"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->comment(), String("another comment"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->track(), (unsigned int)7);
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->year(), (unsigned int)2080);
|
||||
f.tag()->setArtist("test artist");
|
||||
f.tag()->setTitle("test title");
|
||||
f.tag()->setGenre("Test!");
|
||||
f.tag()->setAlbum("albummmm");
|
||||
f.tag()->setComment("a comment");
|
||||
f.tag()->setTrack(5);
|
||||
f.tag()->setYear(2020);
|
||||
f.save();
|
||||
@ -162,6 +175,7 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->title(), String("test title"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->genre(), String("Test!"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->album(), String("albummmm"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->comment(), String("a comment"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->track(), (unsigned int)5);
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->year(), (unsigned int)2020);
|
||||
|
||||
@ -178,12 +192,14 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->title(), String("test title"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->genre(), String("Test!"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->album(), String("albummmm"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->comment(), String("a comment"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->track(), (unsigned int)5);
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->year(), (unsigned int)2020);
|
||||
f.tag()->setArtist("ttest artist");
|
||||
f.tag()->setTitle("ytest title");
|
||||
f.tag()->setGenre("uTest!");
|
||||
f.tag()->setAlbum("ialbummmm");
|
||||
f.tag()->setComment("another comment");
|
||||
f.tag()->setTrack(7);
|
||||
f.tag()->setYear(2080);
|
||||
f.save();
|
||||
@ -199,6 +215,7 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->title(), String("ytest title"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->genre(), String("uTest!"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->album(), String("ialbummmm"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->comment(), String("another comment"));
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->track(), (unsigned int)7);
|
||||
CPPUNIT_ASSERT_EQUAL(f.tag()->year(), (unsigned int)2080);
|
||||
}
|
||||
@ -289,6 +306,16 @@ public:
|
||||
fileRefSave<RIFF::AIFF::File>("alaw", ".aifc");
|
||||
}
|
||||
|
||||
void testWavPack()
|
||||
{
|
||||
fileRefSave<WavPack::File>("click", ".wv");
|
||||
}
|
||||
|
||||
void testOpus()
|
||||
{
|
||||
fileRefSave<Ogg::Opus::File>("correctness_gain_silent_output", ".opus");
|
||||
}
|
||||
|
||||
void testUnsupported()
|
||||
{
|
||||
FileRef f1(TEST_FILE_PATH_C("no-extension"));
|
||||
@ -309,6 +336,41 @@ public:
|
||||
f = FileRef::create(TEST_FILE_PATH_C("xing.mp3"));
|
||||
CPPUNIT_ASSERT(dynamic_cast<MPEG::File*>(f));
|
||||
delete f;
|
||||
|
||||
f = FileRef::create(TEST_FILE_PATH_C("test.xm"));
|
||||
CPPUNIT_ASSERT(dynamic_cast<XM::File*>(f));
|
||||
delete f;
|
||||
}
|
||||
|
||||
void testAudioProperties()
|
||||
{
|
||||
FileRef f(TEST_FILE_PATH_C("xing.mp3"));
|
||||
const AudioProperties *audioProperties = f.audioProperties();
|
||||
CPPUNIT_ASSERT_EQUAL(2, audioProperties->lengthInSeconds());
|
||||
CPPUNIT_ASSERT_EQUAL(2064, audioProperties->lengthInMilliseconds());
|
||||
}
|
||||
|
||||
void testDefaultFileExtensions()
|
||||
{
|
||||
const StringList extensions = FileRef::defaultFileExtensions();
|
||||
CPPUNIT_ASSERT(extensions.contains("mpc"));
|
||||
CPPUNIT_ASSERT(extensions.contains("wma"));
|
||||
CPPUNIT_ASSERT(extensions.contains("ogg"));
|
||||
CPPUNIT_ASSERT(extensions.contains("spx"));
|
||||
CPPUNIT_ASSERT(extensions.contains("flac"));
|
||||
CPPUNIT_ASSERT(extensions.contains("mp3"));
|
||||
CPPUNIT_ASSERT(extensions.contains("tta"));
|
||||
CPPUNIT_ASSERT(extensions.contains("m4a"));
|
||||
CPPUNIT_ASSERT(extensions.contains("3g2"));
|
||||
CPPUNIT_ASSERT(extensions.contains("m4v"));
|
||||
CPPUNIT_ASSERT(extensions.contains("wav"));
|
||||
CPPUNIT_ASSERT(extensions.contains("oga"));
|
||||
CPPUNIT_ASSERT(extensions.contains("ape"));
|
||||
CPPUNIT_ASSERT(extensions.contains("aiff"));
|
||||
CPPUNIT_ASSERT(extensions.contains("aifc"));
|
||||
CPPUNIT_ASSERT(extensions.contains("wv"));
|
||||
CPPUNIT_ASSERT(extensions.contains("opus"));
|
||||
CPPUNIT_ASSERT(extensions.contains("xm"));
|
||||
}
|
||||
|
||||
void testFileResolver()
|
||||
|
@ -54,6 +54,7 @@ class TestFLAC : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testRepeatedSave3);
|
||||
CPPUNIT_TEST(testSaveMultipleValues);
|
||||
CPPUNIT_TEST(testDict);
|
||||
CPPUNIT_TEST(testProperties);
|
||||
CPPUNIT_TEST(testInvalid);
|
||||
CPPUNIT_TEST(testAudioProperties);
|
||||
CPPUNIT_TEST(testZeroSizedPadding1);
|
||||
@ -313,6 +314,60 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void testProperties()
|
||||
{
|
||||
PropertyMap tags;
|
||||
tags["ALBUM"] = StringList("Album");
|
||||
tags["ALBUMARTIST"] = StringList("Album Artist");
|
||||
tags["ALBUMARTISTSORT"] = StringList("Album Artist Sort");
|
||||
tags["ALBUMSORT"] = StringList("Album Sort");
|
||||
tags["ARTIST"] = StringList("Artist");
|
||||
tags["ARTISTS"] = StringList("Artists");
|
||||
tags["ARTISTSORT"] = StringList("Artist Sort");
|
||||
tags["ASIN"] = StringList("ASIN");
|
||||
tags["BARCODE"] = StringList("Barcode");
|
||||
tags["CATALOGNUMBER"] = StringList("Catalog Number 1").append("Catalog Number 2");
|
||||
tags["COMMENT"] = StringList("Comment");
|
||||
tags["DATE"] = StringList("2021-01-10");
|
||||
tags["DISCNUMBER"] = StringList("3");
|
||||
tags["DISCTOTAL"] = StringList("5");
|
||||
tags["GENRE"] = StringList("Genre");
|
||||
tags["ISRC"] = StringList("UKAAA0500001");
|
||||
tags["LABEL"] = StringList("Label 1").append("Label 2");
|
||||
tags["MEDIA"] = StringList("Media");
|
||||
tags["MUSICBRAINZ_ALBUMARTISTID"] = StringList("MusicBrainz_AlbumartistID");
|
||||
tags["MUSICBRAINZ_ALBUMID"] = StringList("MusicBrainz_AlbumID");
|
||||
tags["MUSICBRAINZ_ARTISTID"] = StringList("MusicBrainz_ArtistID");
|
||||
tags["MUSICBRAINZ_RELEASEGROUPID"] = StringList("MusicBrainz_ReleasegroupID");
|
||||
tags["MUSICBRAINZ_RELEASETRACKID"] = StringList("MusicBrainz_ReleasetrackID");
|
||||
tags["MUSICBRAINZ_TRACKID"] = StringList("MusicBrainz_TrackID");
|
||||
tags["ORIGINALDATE"] = StringList("2021-01-09");
|
||||
tags["RELEASECOUNTRY"] = StringList("Release Country");
|
||||
tags["RELEASESTATUS"] = StringList("Release Status");
|
||||
tags["RELEASETYPE"] = StringList("Release Type");
|
||||
tags["SCRIPT"] = StringList("Script");
|
||||
tags["TITLE"] = StringList("Title");
|
||||
tags["TRACKNUMBER"] = StringList("2");
|
||||
tags["TRACKTOTAL"] = StringList("4");
|
||||
|
||||
ScopedFileCopy copy("no-tags", ".flac");
|
||||
{
|
||||
FLAC::File f(copy.fileName().c_str());
|
||||
PropertyMap properties = f.properties();
|
||||
CPPUNIT_ASSERT(properties.isEmpty());
|
||||
f.setProperties(tags);
|
||||
f.save();
|
||||
}
|
||||
{
|
||||
const FLAC::File f(copy.fileName().c_str());
|
||||
PropertyMap properties = f.properties();
|
||||
if (tags != properties) {
|
||||
CPPUNIT_ASSERT_EQUAL(tags.toString(), properties.toString());
|
||||
}
|
||||
CPPUNIT_ASSERT(tags == properties);
|
||||
}
|
||||
}
|
||||
|
||||
void testInvalid()
|
||||
{
|
||||
ScopedFileCopy copy("silence-44-s", ".flac");
|
||||
|
@ -67,6 +67,8 @@ public:
|
||||
{
|
||||
CPPUNIT_ASSERT_EQUAL(String("Darkwave"), ID3v1::genre(50));
|
||||
CPPUNIT_ASSERT_EQUAL(100, ID3v1::genreIndex("Humour"));
|
||||
CPPUNIT_ASSERT(ID3v1::genreList().contains("Heavy Metal"));
|
||||
CPPUNIT_ASSERT_EQUAL(79, ID3v1::genreMap()["Hard Rock"]);
|
||||
}
|
||||
|
||||
void testRenamedGenres()
|
||||
|
@ -42,6 +42,9 @@
|
||||
#include <unknownframe.h>
|
||||
#include <chapterframe.h>
|
||||
#include <tableofcontentsframe.h>
|
||||
#include <commentsframe.h>
|
||||
#include <podcastframe.h>
|
||||
#include <privateframe.h>
|
||||
#include <tdebug.h>
|
||||
#include <tpropertymap.h>
|
||||
#include <tzlib.h>
|
||||
@ -76,16 +79,20 @@ class TestID3v2 : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testParseAPIC);
|
||||
CPPUNIT_TEST(testParseAPIC_UTF16_BOM);
|
||||
CPPUNIT_TEST(testParseAPICv22);
|
||||
CPPUNIT_TEST(testRenderAPIC);
|
||||
CPPUNIT_TEST(testDontRender22);
|
||||
CPPUNIT_TEST(testParseGEOB);
|
||||
CPPUNIT_TEST(testRenderGEOB);
|
||||
CPPUNIT_TEST(testPOPMtoString);
|
||||
CPPUNIT_TEST(testParsePOPM);
|
||||
CPPUNIT_TEST(testParsePOPMWithoutCounter);
|
||||
CPPUNIT_TEST(testRenderPOPM);
|
||||
CPPUNIT_TEST(testPOPMFromFile);
|
||||
CPPUNIT_TEST(testParseRelativeVolumeFrame);
|
||||
CPPUNIT_TEST(testRenderRelativeVolumeFrame);
|
||||
CPPUNIT_TEST(testParseUniqueFileIdentifierFrame);
|
||||
CPPUNIT_TEST(testParseEmptyUniqueFileIdentifierFrame);
|
||||
CPPUNIT_TEST(testRenderUniqueFileIdentifierFrame);
|
||||
CPPUNIT_TEST(testBrokenFrame1);
|
||||
CPPUNIT_TEST(testItunes24FrameSize);
|
||||
CPPUNIT_TEST(testParseUrlLinkFrame);
|
||||
@ -99,6 +106,12 @@ class TestID3v2 : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testRenderSynchronizedLyricsFrame);
|
||||
CPPUNIT_TEST(testParseEventTimingCodesFrame);
|
||||
CPPUNIT_TEST(testRenderEventTimingCodesFrame);
|
||||
CPPUNIT_TEST(testParseCommentsFrame);
|
||||
CPPUNIT_TEST(testRenderCommentsFrame);
|
||||
CPPUNIT_TEST(testParsePodcastFrame);
|
||||
CPPUNIT_TEST(testRenderPodcastFrame);
|
||||
CPPUNIT_TEST(testParsePrivateFrame);
|
||||
CPPUNIT_TEST(testRenderPrivateFrame);
|
||||
CPPUNIT_TEST(testSaveUTF16Comment);
|
||||
CPPUNIT_TEST(testUpdateGenre23_1);
|
||||
CPPUNIT_TEST(testUpdateGenre23_2);
|
||||
@ -266,6 +279,26 @@ public:
|
||||
delete frame;
|
||||
}
|
||||
|
||||
void testRenderAPIC()
|
||||
{
|
||||
ID3v2::AttachedPictureFrame f;
|
||||
f.setTextEncoding(String::UTF8);
|
||||
f.setMimeType("image/png");
|
||||
f.setType(ID3v2::AttachedPictureFrame::BackCover);
|
||||
f.setDescription("Description");
|
||||
f.setPicture("PNG data");
|
||||
CPPUNIT_ASSERT_EQUAL(
|
||||
ByteVector("APIC"
|
||||
"\x00\x00\x00\x20"
|
||||
"\x00\x00"
|
||||
"\x03"
|
||||
"image/png\x00"
|
||||
"\x04"
|
||||
"Description\x00"
|
||||
"PNG data", 42),
|
||||
f.render());
|
||||
}
|
||||
|
||||
void testDontRender22()
|
||||
{
|
||||
ID3v2::FrameFactory *factory = ID3v2::FrameFactory::instance();
|
||||
@ -304,6 +337,26 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(String("d"), f.description());
|
||||
}
|
||||
|
||||
void testRenderGEOB()
|
||||
{
|
||||
ID3v2::GeneralEncapsulatedObjectFrame f;
|
||||
f.setTextEncoding(String::Latin1);
|
||||
f.setMimeType("application/octet-stream");
|
||||
f.setFileName("test.bin");
|
||||
f.setDescription("Description");
|
||||
f.setObject(ByteVector(3, '\x01'));
|
||||
CPPUNIT_ASSERT_EQUAL(
|
||||
ByteVector("GEOB"
|
||||
"\x00\x00\x00\x32"
|
||||
"\x00\x00"
|
||||
"\x00"
|
||||
"application/octet-stream\x00"
|
||||
"test.bin\x00"
|
||||
"Description\x00"
|
||||
"\x01\x01\x01", 60),
|
||||
f.render());
|
||||
}
|
||||
|
||||
void testParsePOPM()
|
||||
{
|
||||
ID3v2::PopularimeterFrame f(ByteVector("POPM"
|
||||
@ -392,10 +445,36 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(String("ident"), f.identification());
|
||||
CPPUNIT_ASSERT_EQUAL(15.0f / 512.0f,
|
||||
f.volumeAdjustment(ID3v2::RelativeVolumeFrame::FrontRight));
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<short>(15),
|
||||
f.volumeAdjustmentIndex(ID3v2::RelativeVolumeFrame::FrontRight));
|
||||
CPPUNIT_ASSERT_EQUAL((unsigned char)8,
|
||||
f.peakVolume(ID3v2::RelativeVolumeFrame::FrontRight).bitsRepresentingPeak);
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("\x45"),
|
||||
f.peakVolume(ID3v2::RelativeVolumeFrame::FrontRight).peakVolume);
|
||||
const List<ID3v2::RelativeVolumeFrame::ChannelType> channels = f.channels();
|
||||
CPPUNIT_ASSERT_EQUAL(1U, channels.size());
|
||||
CPPUNIT_ASSERT_EQUAL(ID3v2::RelativeVolumeFrame::FrontRight, channels[0]);
|
||||
}
|
||||
|
||||
void testRenderRelativeVolumeFrame()
|
||||
{
|
||||
ID3v2::RelativeVolumeFrame f;
|
||||
f.setIdentification("ident");
|
||||
f.setVolumeAdjustment(15.0f / 512.0f, ID3v2::RelativeVolumeFrame::FrontRight);
|
||||
ID3v2::RelativeVolumeFrame::PeakVolume peakVolume;
|
||||
peakVolume.bitsRepresentingPeak = 8;
|
||||
peakVolume.peakVolume.setData("\x45");
|
||||
f.setPeakVolume(peakVolume, ID3v2::RelativeVolumeFrame::FrontRight);
|
||||
CPPUNIT_ASSERT_EQUAL(
|
||||
ByteVector("RVA2"
|
||||
"\x00\x00\x00\x0B"
|
||||
"\x00\x00"
|
||||
"ident\x00"
|
||||
"\x02"
|
||||
"\x00\x0F"
|
||||
"\x08"
|
||||
"\x45", 21),
|
||||
f.render());
|
||||
}
|
||||
|
||||
void testParseUniqueFileIdentifierFrame()
|
||||
@ -426,6 +505,18 @@ public:
|
||||
f.identifier());
|
||||
}
|
||||
|
||||
void testRenderUniqueFileIdentifierFrame()
|
||||
{
|
||||
ID3v2::UniqueFileIdentifierFrame f("owner", "\x01\x02\x03");
|
||||
CPPUNIT_ASSERT_EQUAL(
|
||||
ByteVector("UFID"
|
||||
"\x00\x00\x00\x09"
|
||||
"\x00\x00"
|
||||
"owner\x00"
|
||||
"\x01\x02\x03", 19),
|
||||
f.render());
|
||||
}
|
||||
|
||||
void testParseUrlLinkFrame()
|
||||
{
|
||||
ID3v2::UrlLinkFrame f(
|
||||
@ -635,6 +726,89 @@ public:
|
||||
f.render());
|
||||
}
|
||||
|
||||
void testParseCommentsFrame()
|
||||
{
|
||||
ID3v2::CommentsFrame f(
|
||||
ByteVector("COMM"
|
||||
"\x00\x00\x00\x14"
|
||||
"\x00\x00"
|
||||
"\x03"
|
||||
"deu"
|
||||
"Description\x00"
|
||||
"Text", 30));
|
||||
CPPUNIT_ASSERT_EQUAL(String::UTF8, f.textEncoding());
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("deu"), f.language());
|
||||
CPPUNIT_ASSERT_EQUAL(String("Description"), f.description());
|
||||
CPPUNIT_ASSERT_EQUAL(String("Text"), f.text());
|
||||
}
|
||||
|
||||
void testRenderCommentsFrame()
|
||||
{
|
||||
ID3v2::CommentsFrame f;
|
||||
f.setTextEncoding(String::UTF16);
|
||||
f.setLanguage("eng");
|
||||
f.setDescription("Description");
|
||||
f.setText("Text");
|
||||
CPPUNIT_ASSERT_EQUAL(
|
||||
ByteVector("COMM"
|
||||
"\x00\x00\x00\x28"
|
||||
"\x00\x00"
|
||||
"\x01"
|
||||
"eng"
|
||||
"\xff\xfe" "D\0e\0s\0c\0r\0i\0p\0t\0i\0o\0n\0" "\x00\x00"
|
||||
"\xff\xfe" "T\0e\0x\0t\0", 50),
|
||||
f.render());
|
||||
}
|
||||
|
||||
void testParsePodcastFrame()
|
||||
{
|
||||
ID3v2::FrameFactory *factory = ID3v2::FrameFactory::instance();
|
||||
ByteVector data = ByteVector("PCST"
|
||||
"\x00\x00\x00\x04"
|
||||
"\x00\x00"
|
||||
"\x00\x00\x00\x00", 14);
|
||||
const ID3v2::Header header;
|
||||
CPPUNIT_ASSERT(dynamic_cast<ID3v2::PodcastFrame *>(
|
||||
factory->createFrame(data, &header)));
|
||||
}
|
||||
|
||||
void testRenderPodcastFrame()
|
||||
{
|
||||
ID3v2::PodcastFrame f;
|
||||
CPPUNIT_ASSERT_EQUAL(
|
||||
ByteVector("PCST"
|
||||
"\x00\x00\x00\x04"
|
||||
"\x00\x00"
|
||||
"\x00\x00\x00\x00", 14),
|
||||
f.render());
|
||||
}
|
||||
|
||||
void testParsePrivateFrame()
|
||||
{
|
||||
ID3v2::PrivateFrame f(
|
||||
ByteVector("PRIV"
|
||||
"\x00\x00\x00\x0e"
|
||||
"\x00\x00"
|
||||
"WM/Provider\x00"
|
||||
"TL", 24));
|
||||
CPPUNIT_ASSERT_EQUAL(String("WM/Provider"), f.owner());
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("TL"), f.data());
|
||||
}
|
||||
|
||||
void testRenderPrivateFrame()
|
||||
{
|
||||
ID3v2::PrivateFrame f;
|
||||
f.setOwner("WM/Provider");
|
||||
f.setData("TL");
|
||||
CPPUNIT_ASSERT_EQUAL(
|
||||
ByteVector("PRIV"
|
||||
"\x00\x00\x00\x0e"
|
||||
"\x00\x00"
|
||||
"WM/Provider\x00"
|
||||
"TL", 24),
|
||||
f.render());
|
||||
}
|
||||
|
||||
void testItunes24FrameSize()
|
||||
{
|
||||
MPEG::File f(TEST_FILE_PATH_C("005411.id3"), false);
|
||||
@ -1246,6 +1420,16 @@ public:
|
||||
CPPUNIT_ASSERT((unsigned int)0x01 == f.embeddedFrameList().size());
|
||||
CPPUNIT_ASSERT(f.embeddedFrameList("TIT2").size() == 1);
|
||||
CPPUNIT_ASSERT(f.embeddedFrameList("TIT2")[0]->toString() == "TC1");
|
||||
|
||||
f.removeChildElement("E"); // not existing
|
||||
CPPUNIT_ASSERT_EQUAL(2U, f.entryCount());
|
||||
f.removeChildElement("C");
|
||||
CPPUNIT_ASSERT_EQUAL(1U, f.entryCount());
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("D"), f.childElements()[0]);
|
||||
|
||||
ID3v2::Frame *frame = f.embeddedFrameList("TIT2")[0];
|
||||
f.removeEmbeddedFrame(frame);
|
||||
CPPUNIT_ASSERT(f.embeddedFrameList("TIT2").isEmpty());
|
||||
}
|
||||
|
||||
void testRenderTableOfContentsFrame()
|
||||
|
@ -59,6 +59,7 @@ class TestMP4 : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testCovrWrite);
|
||||
CPPUNIT_TEST(testCovrRead2);
|
||||
CPPUNIT_TEST(testProperties);
|
||||
CPPUNIT_TEST(testPropertiesAllSupported);
|
||||
CPPUNIT_TEST(testPropertiesMovement);
|
||||
CPPUNIT_TEST(testFuzzedFile);
|
||||
CPPUNIT_TEST(testRepeatedSave);
|
||||
@ -426,6 +427,97 @@ public:
|
||||
f.setProperties(tags);
|
||||
}
|
||||
|
||||
void testPropertiesAllSupported()
|
||||
{
|
||||
PropertyMap tags;
|
||||
tags["ALBUM"] = StringList("Album");
|
||||
tags["ALBUMARTIST"] = StringList("Album Artist");
|
||||
tags["ALBUMARTISTSORT"] = StringList("Album Artist Sort");
|
||||
tags["ALBUMSORT"] = StringList("Album Sort");
|
||||
tags["ARTIST"] = StringList("Artist");
|
||||
tags["ARTISTS"] = StringList("Artists");
|
||||
tags["ARTISTSORT"] = StringList("Artist Sort");
|
||||
tags["ASIN"] = StringList("ASIN");
|
||||
tags["BARCODE"] = StringList("Barcode");
|
||||
tags["BPM"] = StringList("123");
|
||||
tags["CATALOGNUMBER"] = StringList("Catalog Number");
|
||||
tags["COMMENT"] = StringList("Comment");
|
||||
tags["COMPILATION"] = StringList("1");
|
||||
tags["COMPOSER"] = StringList("Composer");
|
||||
tags["COMPOSERSORT"] = StringList("Composer Sort");
|
||||
tags["CONDUCTOR"] = StringList("Conductor");
|
||||
tags["COPYRIGHT"] = StringList("2021 Copyright");
|
||||
tags["DATE"] = StringList("2021-01-03 12:29:23");
|
||||
tags["DISCNUMBER"] = StringList("3/5");
|
||||
tags["DISCSUBTITLE"] = StringList("Disc Subtitle");
|
||||
tags["DJMIXER"] = StringList("DJ Mixer");
|
||||
tags["ENCODEDBY"] = StringList("Encoded by");
|
||||
tags["ENGINEER"] = StringList("Engineer");
|
||||
tags["GAPLESSPLAYBACK"] = StringList("1");
|
||||
tags["GENRE"] = StringList("Genre");
|
||||
tags["GROUPING"] = StringList("Grouping");
|
||||
tags["ISRC"] = StringList("UKAAA0500001");
|
||||
tags["LABEL"] = StringList("Label");
|
||||
tags["LANGUAGE"] = StringList("eng");
|
||||
tags["LICENSE"] = StringList("License");
|
||||
tags["LYRICIST"] = StringList("Lyricist");
|
||||
tags["LYRICS"] = StringList("Lyrics");
|
||||
tags["MEDIA"] = StringList("Media");
|
||||
tags["MIXER"] = StringList("Mixer");
|
||||
tags["MOOD"] = StringList("Mood");
|
||||
tags["MOVEMENTCOUNT"] = StringList("3");
|
||||
tags["MOVEMENTNAME"] = StringList("Movement Name");
|
||||
tags["MOVEMENTNUMBER"] = StringList("2");
|
||||
tags["MUSICBRAINZ_ALBUMARTISTID"] = StringList("MusicBrainz_AlbumartistID");
|
||||
tags["MUSICBRAINZ_ALBUMID"] = StringList("MusicBrainz_AlbumID");
|
||||
tags["MUSICBRAINZ_ARTISTID"] = StringList("MusicBrainz_ArtistID");
|
||||
tags["MUSICBRAINZ_RELEASEGROUPID"] = StringList("MusicBrainz_ReleasegroupID");
|
||||
tags["MUSICBRAINZ_RELEASETRACKID"] = StringList("MusicBrainz_ReleasetrackID");
|
||||
tags["MUSICBRAINZ_TRACKID"] = StringList("MusicBrainz_TrackID");
|
||||
tags["MUSICBRAINZ_WORKID"] = StringList("MusicBrainz_WorkID");
|
||||
tags["ORIGINALDATE"] = StringList("2021-01-03 13:52:19");
|
||||
tags["PODCAST"] = StringList("1");
|
||||
tags["PODCASTCATEGORY"] = StringList("Podcast Category");
|
||||
tags["PODCASTDESC"] = StringList("Podcast Description");
|
||||
tags["PODCASTID"] = StringList("Podcast ID");
|
||||
tags["PODCASTURL"] = StringList("Podcast URL");
|
||||
tags["PRODUCER"] = StringList("Producer");
|
||||
tags["RELEASECOUNTRY"] = StringList("Release Country");
|
||||
tags["RELEASESTATUS"] = StringList("Release Status");
|
||||
tags["RELEASETYPE"] = StringList("Release Type");
|
||||
tags["REMIXER"] = StringList("Remixer");
|
||||
tags["SCRIPT"] = StringList("Script");
|
||||
tags["SHOWSORT"] = StringList("Show Sort");
|
||||
tags["SHOWWORKMOVEMENT"] = StringList("1");
|
||||
tags["SUBTITLE"] = StringList("Subtitle");
|
||||
tags["TITLE"] = StringList("Title");
|
||||
tags["TITLESORT"] = StringList("Title Sort");
|
||||
tags["TRACKNUMBER"] = StringList("2/4");
|
||||
tags["TVEPISODE"] = StringList("3");
|
||||
tags["TVEPISODEID"] = StringList("TV Episode ID");
|
||||
tags["TVNETWORK"] = StringList("TV Network");
|
||||
tags["TVSEASON"] = StringList("2");
|
||||
tags["TVSHOW"] = StringList("TV Show");
|
||||
tags["WORK"] = StringList("Work");
|
||||
|
||||
ScopedFileCopy copy("no-tags", ".m4a");
|
||||
{
|
||||
MP4::File f(copy.fileName().c_str());
|
||||
PropertyMap properties = f.properties();
|
||||
CPPUNIT_ASSERT(properties.isEmpty());
|
||||
f.setProperties(tags);
|
||||
f.save();
|
||||
}
|
||||
{
|
||||
const MP4::File f(copy.fileName().c_str());
|
||||
PropertyMap properties = f.properties();
|
||||
if (tags != properties) {
|
||||
CPPUNIT_ASSERT_EQUAL(tags.toString(), properties.toString());
|
||||
}
|
||||
CPPUNIT_ASSERT(tags == properties);
|
||||
}
|
||||
}
|
||||
|
||||
void testPropertiesMovement()
|
||||
{
|
||||
MP4::File f(TEST_FILE_PATH_C("has-tags.m4a"));
|
||||
|
@ -58,6 +58,7 @@ class TestMPEG : public CppUnit::TestFixture
|
||||
CPPUNIT_TEST(testFuzzedFile);
|
||||
CPPUNIT_TEST(testFrameOffset);
|
||||
CPPUNIT_TEST(testStripAndProperties);
|
||||
CPPUNIT_TEST(testProperties);
|
||||
CPPUNIT_TEST(testRepeatedSave1);
|
||||
CPPUNIT_TEST(testRepeatedSave2);
|
||||
CPPUNIT_TEST(testRepeatedSave3);
|
||||
@ -295,6 +296,109 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void testProperties()
|
||||
{
|
||||
PropertyMap tags;
|
||||
tags["ALBUM"] = StringList("Album");
|
||||
tags["ALBUMARTIST"] = StringList("Album Artist");
|
||||
tags["ALBUMARTISTSORT"] = StringList("Album Artist Sort");
|
||||
tags["ALBUMSORT"] = StringList("Album Sort");
|
||||
tags["ARRANGER"] = StringList("Arranger");
|
||||
tags["ARTIST"] = StringList("Artist");
|
||||
tags["ARTISTSORT"] = StringList("Artist Sort");
|
||||
tags["ARTISTWEBPAGE"] = StringList("Artist Web Page");
|
||||
tags["ASIN"] = StringList("ASIN");
|
||||
tags["AUDIOSOURCEWEBPAGE"] = StringList("Audio Source Web Page");
|
||||
tags["BARCODE"] = StringList("Barcode");
|
||||
tags["BPM"] = StringList("123");
|
||||
tags["CATALOGNUMBER"] = StringList("Catalog Number");
|
||||
tags["COMMENT"] = StringList("Comment");
|
||||
tags["COMMENT:CDESC"] = StringList("Comment with Description");
|
||||
tags["COMPOSER"] = StringList("Composer");
|
||||
tags["COMPOSERSORT"] = StringList("Composer Sort");
|
||||
tags["CONDUCTOR"] = StringList("Conductor");
|
||||
tags["CONTENTGROUP"] = StringList("Content Group");
|
||||
tags["COPYRIGHT"] = StringList("2021 Copyright");
|
||||
tags["COPYRIGHTURL"] = StringList("Copyright URL");
|
||||
tags["DATE"] = StringList("2021-01-03 12:29:23");
|
||||
tags["DISCNUMBER"] = StringList("3/5");
|
||||
tags["DJMIXER"] = StringList("DJ Mixer");
|
||||
tags["ENCODEDBY"] = StringList("Encoded by");
|
||||
tags["ENCODING"] = StringList("Encoding");
|
||||
tags["ENCODINGTIME"] = StringList("2021-01-03 13:48:44");
|
||||
tags["ENGINEER"] = StringList("Engineer");
|
||||
tags["FILETYPE"] = StringList("File Type");
|
||||
tags["FILEWEBPAGE"] = StringList("File Web Page");
|
||||
tags["GENRE"] = StringList("Genre");
|
||||
tags["GROUPING"] = StringList("Grouping");
|
||||
tags["INITIALKEY"] = StringList("Dbm");
|
||||
tags["ISRC"] = StringList("UKAAA0500001");
|
||||
tags["LABEL"] = StringList("Label");
|
||||
tags["LANGUAGE"] = StringList("eng");
|
||||
tags["LENGTH"] = StringList("1234");
|
||||
tags["LYRICIST"] = StringList("Lyricist");
|
||||
tags["LYRICS:LDESC"] = StringList("Lyrics");
|
||||
tags["MEDIA"] = StringList("Media");
|
||||
tags["MIXER"] = StringList("Mixer");
|
||||
tags["MOOD"] = StringList("Mood");
|
||||
tags["MOVEMENTNAME"] = StringList("Movement Name");
|
||||
tags["MOVEMENTNUMBER"] = StringList("2");
|
||||
tags["MUSICBRAINZ_ALBUMID"] = StringList("MusicBrainz_AlbumID");
|
||||
tags["MUSICBRAINZ_ALBUMARTISTID"] = StringList("MusicBrainz_AlbumartistID");
|
||||
tags["MUSICBRAINZ_ARTISTID"] = StringList("MusicBrainz_ArtistID");
|
||||
tags["MUSICBRAINZ_RELEASEGROUPID"] = StringList("MusicBrainz_ReleasegroupID");
|
||||
tags["MUSICBRAINZ_RELEASETRACKID"] = StringList("MusicBrainz_ReleasetrackID");
|
||||
tags["MUSICBRAINZ_TRACKID"] = StringList("MusicBrainz_TrackID");
|
||||
tags["MUSICBRAINZ_WORKID"] = StringList("MusicBrainz_WorkID");
|
||||
tags["ORIGINALALBUM"] = StringList("Original Album");
|
||||
tags["ORIGINALARTIST"] = StringList("Original Artist");
|
||||
tags["ORIGINALDATE"] = StringList("2021-01-03 13:52:19");
|
||||
tags["ORIGINALFILENAME"] = StringList("Original Filename");
|
||||
tags["ORIGINALLYRICIST"] = StringList("Original Lyricist");
|
||||
tags["OWNER"] = StringList("Owner");
|
||||
tags["PAYMENTWEBPAGE"] = StringList("Payment Web Page");
|
||||
tags["PERFORMER:DRUMS"] = StringList("Drummer");
|
||||
tags["PERFORMER:GUITAR"] = StringList("Guitarist");
|
||||
tags["PLAYLISTDELAY"] = StringList("10");
|
||||
tags["PODCAST"] = StringList();
|
||||
tags["PODCASTCATEGORY"] = StringList("Podcast Category");
|
||||
tags["PODCASTDESC"] = StringList("Podcast Description");
|
||||
tags["PODCASTID"] = StringList("Podcast ID");
|
||||
tags["PODCASTURL"] = StringList("Podcast URL");
|
||||
tags["PRODUCEDNOTICE"] = StringList("2021 Produced Notice");
|
||||
tags["PRODUCER"] = StringList("Producer");
|
||||
tags["PUBLISHERWEBPAGE"] = StringList("Publisher Web Page");
|
||||
tags["RADIOSTATION"] = StringList("Radio Station");
|
||||
tags["RADIOSTATIONOWNER"] = StringList("Radio Station Owner");
|
||||
tags["RELEASECOUNTRY"] = StringList("Release Country");
|
||||
tags["RELEASESTATUS"] = StringList("Release Status");
|
||||
tags["RELEASETYPE"] = StringList("Release Type");
|
||||
tags["REMIXER"] = StringList("Remixer");
|
||||
tags["SCRIPT"] = StringList("Script");
|
||||
tags["SUBTITLE"] = StringList("Subtitle");
|
||||
tags["TITLE"] = StringList("Title");
|
||||
tags["TITLESORT"] = StringList("Title Sort");
|
||||
tags["TRACKNUMBER"] = StringList("2/4");
|
||||
tags["URL:UDESC"] = StringList("URL");
|
||||
|
||||
ScopedFileCopy copy("xing", ".mp3");
|
||||
{
|
||||
MPEG::File f(copy.fileName().c_str());
|
||||
PropertyMap properties = f.properties();
|
||||
CPPUNIT_ASSERT(properties.isEmpty());
|
||||
f.setProperties(tags);
|
||||
f.save();
|
||||
}
|
||||
{
|
||||
const MPEG::File f(copy.fileName().c_str());
|
||||
PropertyMap properties = f.properties();
|
||||
if (tags != properties) {
|
||||
CPPUNIT_ASSERT_EQUAL(tags.toString(), properties.toString());
|
||||
}
|
||||
CPPUNIT_ASSERT(tags == properties);
|
||||
}
|
||||
}
|
||||
|
||||
void testRepeatedSave1()
|
||||
{
|
||||
ScopedFileCopy copy("xing", ".mp3");
|
||||
|
Loading…
Reference in New Issue
Block a user