Added tests and information about ignored id3 frames.

The ID3v2::toDict() function now has an optional
StringList* argument which will contain information
about frames that could not be converted to the dict
interface.
There are some dict tests for APE and FLAC now, and the
ID3v2 test was enlarged.
This commit is contained in:
Michael Helmling 2012-01-01 14:42:48 +01:00
parent 0eaf3a3fbd
commit c4cef55158
6 changed files with 57 additions and 7 deletions

View File

@ -197,6 +197,7 @@ void APE::Tag::fromDict(const TagDict &orig_dict)
{
TagDict dict(orig_dict); // make a local copy that can be modified
// see comment in toDict() about TRACKNUMBER and YEAR
if (dict.contains("TRACKNUMBER")) {
dict.insert("TRACK", dict["TRACKNUMBER"]);
dict.erase("TRACKNUMBER");

View File

@ -334,18 +334,22 @@ void ID3v2::Tag::removeFrames(const ByteVector &id)
removeFrame(*it, true);
}
TagDict ID3v2::Tag::toDict() const
TagDict ID3v2::Tag::toDict(StringList *ignoreInfo) const
{
TagDict dict;
FrameList::ConstIterator frameIt = frameList().begin();
for (; frameIt != frameList().end(); ++frameIt) {
ByteVector id = (*frameIt)->frameID();
if (ignored(id))
if (ignored(id)) {
debug("toDict() found ignored id3 frame: " + id);
else if (deprecated(id))
if (ignoreInfo)
ignoreInfo->append(String(id) + " frame is not supported");
} else if (deprecated(id)) {
debug("toDict() found deprecated id3 frame: " + id);
else {
if (ignoreInfo)
ignoreInfo->append(String(id) + " frame is deprecated");
} else {
// in the future, something like dict[frame->tagName()].append(frame->values())
// might replace the following lines.
KeyValuePair kvp = parseFrame(*frameIt);

View File

@ -264,8 +264,13 @@ namespace TagLib {
* Implements the unified tag dictionary interface -- export function.
* This function does some work to translate the hard-specified ID3v2
* frame types into a free-form string-to-stringlist dictionary.
*
* If the optional pointer to a StringList is given, that list will
* be filled with a descriptive text for each ID3v2 frame that could
* not be incorporated into the dict interface (binary data, unsupported
* frames, ...).
*/
TagDict toDict() const;
TagDict toDict(StringList *ignoredInfo = 0) const;
/*!
* Implements the unified tag dictionary interface -- import function.

View File

@ -15,6 +15,7 @@ class TestAPETag : public CppUnit::TestFixture
CPPUNIT_TEST_SUITE(TestAPETag);
CPPUNIT_TEST(testIsEmpty);
CPPUNIT_TEST(testIsEmpty2);
CPPUNIT_TEST(testDict);
CPPUNIT_TEST_SUITE_END();
public:
@ -35,6 +36,21 @@ public:
CPPUNIT_ASSERT(!tag.isEmpty());
}
void testDict()
{
APE::Tag tag;
TagDict dict = tag.toDict();
CPPUNIT_ASSERT(dict.isEmpty());
dict["ARTIST"] = String("artist 1");
dict["ARTIST"].append("artist 2");
dict["TRACKNUMBER"].append("17");
tag.fromDict(dict);
CPPUNIT_ASSERT_EQUAL(String("17"), tag.itemListMap()["TRACK"].values()[0]);
CPPUNIT_ASSERT_EQUAL(2u, tag.itemListMap()["ARTIST"].values().size());
CPPUNIT_ASSERT_EQUAL(String("artist 1"), tag.artist());
CPPUNIT_ASSERT_EQUAL(17u, tag.track());
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestAPETag);

View File

@ -22,6 +22,7 @@ class TestFLAC : public CppUnit::TestFixture
CPPUNIT_TEST(testRemoveAllPictures);
CPPUNIT_TEST(testRepeatedSave);
CPPUNIT_TEST(testSaveMultipleValues);
CPPUNIT_TEST(testDict);
CPPUNIT_TEST_SUITE_END();
public:
@ -208,6 +209,27 @@ public:
CPPUNIT_ASSERT_EQUAL(String("artist 2"), m["ARTIST"][1]);
}
void testDict()
{
// test unicode & multiple values with dict interface
ScopedFileCopy copy("silence-44-s", ".flac");
string newname = copy.fileName();
FLAC::File *f = new FLAC::File(newname.c_str());
TagDict dict;
dict["ARTIST"].append("artøst 1");
dict["ARTIST"].append("artöst 2");
f->fromDict(dict);
f->save();
delete f;
f = new FLAC::File(newname.c_str());
dict = f->toDict();
CPPUNIT_ASSERT_EQUAL(TagLib::uint(2), dict["ARTIST"].size());
CPPUNIT_ASSERT_EQUAL(String("artøst 1"), dict["ARTIST"][0]);
CPPUNIT_ASSERT_EQUAL(String("artöst 2"), dict["ARTIST"][1]);
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestFLAC);

View File

@ -553,20 +553,22 @@ public:
ScopedFileCopy copy("rare_frames", ".mp3");
string newname = copy.fileName();
MPEG::File f(newname.c_str());
TagDict dict = f.ID3v2Tag(false)->toDict();
StringList ignored;
TagDict dict = f.ID3v2Tag(false)->toDict(&ignored);
CPPUNIT_ASSERT_EQUAL(uint(6), dict.size());
CPPUNIT_ASSERT_EQUAL(String("userTextData1"), dict["USERTEXTDESCRIPTION1"][0]);
CPPUNIT_ASSERT_EQUAL(String("userTextData2"), dict["USERTEXTDESCRIPTION1"][1]);
CPPUNIT_ASSERT_EQUAL(String("userTextData1"), dict["USERTEXTDESCRIPTION2"][0]);
CPPUNIT_ASSERT_EQUAL(String("userTextData2"), dict["USERTEXTDESCRIPTION2"][1]);
CPPUNIT_ASSERT_EQUAL(String("Pop"), dict["GENRE"][0]);
CPPUNIT_ASSERT_EQUAL(String("Pop"), dict["GENRE"][0]);
CPPUNIT_ASSERT_EQUAL(String("http://a.user.url"), dict["USERURL"][0]);
CPPUNIT_ASSERT_EQUAL(String("http://a.user.url/with/empty/description"), dict["URL"][0]);
CPPUNIT_ASSERT_EQUAL(String("A COMMENT"), dict["COMMENT"][0]);
CPPUNIT_ASSERT_EQUAL(String("UFID frame is not supported"), ignored[0]);
CPPUNIT_ASSERT_EQUAL(1u, ignored.size());
}
};