Merge branch 'master' into merge-master-to-taglib2

Conflicts:
	ConfigureChecks.cmake
	taglib/CMakeLists.txt
	taglib/riff/aiff/aiffproperties.cpp
	taglib/toolkit/tbytevector.cpp
	taglib/toolkit/tbytevector.h
	taglib/toolkit/tfilestream.cpp
	taglib/toolkit/tstring.cpp
	taglib/toolkit/tutils.h
	tests/test_apetag.cpp
	tests/test_bytevector.cpp
	tests/test_flac.cpp
	tests/test_id3v2.cpp
	tests/test_propertymap.cpp
This commit is contained in:
Tsuda Kageyu
2014-07-24 09:39:08 +09:00
32 changed files with 2030 additions and 581 deletions

View File

@ -51,8 +51,8 @@ public:
dict["TRACKNUMBER"].append("17");
tag.setProperties(dict);
CPPUNIT_ASSERT_EQUAL(String("17"), tag.itemListMap()["TRACK"].values()[0]);
CPPUNIT_ASSERT_EQUAL((size_t)2u, tag.itemListMap()["ARTIST"].values().size());
CPPUNIT_ASSERT_EQUAL(String("artist 1"), tag.artist());
CPPUNIT_ASSERT_EQUAL((size_t)2, tag.itemListMap()["ARTIST"].values().size());
CPPUNIT_ASSERT_EQUAL(String("artist 1 artist 2"), tag.artist());
CPPUNIT_ASSERT_EQUAL(17u, tag.track());
}
@ -98,19 +98,19 @@ public:
CPPUNIT_ASSERT(unsuccessful.contains("A"));
CPPUNIT_ASSERT(unsuccessful.contains("MP+"));
}
void testTextBinary()
{
APE::Item item = APE::Item("DUMMY", "Test Text");
CPPUNIT_ASSERT_EQUAL(String("Test Text"), item.toString());
CPPUNIT_ASSERT_EQUAL(ByteVector::null, item.binaryData());
ByteVector data("Test Data");
item.setBinaryData(data);
CPPUNIT_ASSERT(item.values().isEmpty());
CPPUNIT_ASSERT_EQUAL(String::null, item.toString());
CPPUNIT_ASSERT_EQUAL(data, item.binaryData());
item.setValue("Test Text 2");
CPPUNIT_ASSERT_EQUAL(String("Test Text 2"), item.toString());
CPPUNIT_ASSERT_EQUAL(ByteVector::null, item.binaryData());

View File

@ -22,6 +22,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cstring>
#include <tbytevector.h>
#include <tbytevectorlist.h>
#include <cppunit/extensions/HelperMacros.h>
@ -79,7 +80,7 @@ public:
CPPUNIT_ASSERT(i.containsAt(j, 6, 1));
CPPUNIT_ASSERT(i.containsAt(j, 6, 1, 3));
}
void testFind1()
{
CPPUNIT_ASSERT_EQUAL((size_t)4, ByteVector("....SggO."). find("SggO"));
@ -92,6 +93,12 @@ public:
CPPUNIT_ASSERT_EQUAL(ByteVector::npos, ByteVector("....SggO."). find("SggO", 6));
CPPUNIT_ASSERT_EQUAL(ByteVector::npos, ByteVector("....SggO."). find("SggO", 7));
CPPUNIT_ASSERT_EQUAL(ByteVector::npos, ByteVector("....SggO."). find("SggO", 8));
// Intentional out-of-bounds access.
ByteVector v("0123456789x");
v.resize(10);
v.data()[10] = 'x';
CPPUNIT_ASSERT_EQUAL(ByteVector::npos, v.find("789x", 7));
}
void testFind2()
@ -147,6 +154,7 @@ public:
void testNumericCoversion()
{
// n = { 0x00, 0x88, 0x11, 0x99, ..., 0x77, 0xFF }
ByteVector n(16, 0);
for(size_t i = 0; i < 8; ++i) {
n[i * 2 ] = static_cast<unsigned char>(0x11 * i);
@ -167,7 +175,7 @@ public:
CPPUNIT_ASSERT(n.toInt64BE(3) == -7412174897536512939ll);
CPPUNIT_ASSERT(n.toInt64LE(6) == -1268082884489200845ll);
CPPUNIT_ASSERT(n.toInt64BE(4) == 2497865822736504285ll);
CPPUNIT_ASSERT(ByteVector::fromUInt16LE(n.toInt16LE(5)) == n.mid(5, 2));
CPPUNIT_ASSERT(ByteVector::fromUInt16BE(n.toInt16BE(9)) == n.mid(9, 2));
CPPUNIT_ASSERT(ByteVector::fromUInt32LE(n.toUInt32LE(4)) == n.mid(4, 4));
@ -179,18 +187,42 @@ public:
CPPUNIT_ASSERT(ByteVector::fromUInt32LE(287454020) == ByteVector::fromUInt32BE(1144201745));
CPPUNIT_ASSERT(ByteVector::fromUInt64LE(1234605615291183940) == ByteVector::fromUInt64BE(4914309075945333265));
const uchar PI32[] = { 0x00, 0x40, 0x49, 0x0f, 0xdb };
const uchar PI64[] = { 0x00, 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18 };
const uchar PI80[] = { 0x00, 0x40, 0x00, 0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc0, 0x00 };
const uchar PI32LE[] = { 0x00, 0xdb, 0x0f, 0x49, 0x40 };
const uchar PI32BE[] = { 0x00, 0x40, 0x49, 0x0f, 0xdb };
const uchar PI64LE[] = { 0x00, 0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40 };
const uchar PI64BE[] = { 0x00, 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18 };
const uchar PI80LE[] = { 0x00, 0x00, 0xc0, 0x68, 0x21, 0xa2, 0xda, 0x0f, 0xc9, 0x00, 0x40 };
const uchar PI80BE[] = { 0x00, 0x40, 0x00, 0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc0, 0x00 };
ByteVector pi32(reinterpret_cast<const char*>(PI32), 5);
CPPUNIT_ASSERT_EQUAL(31415, static_cast<int>(pi32.toFloat32BE(1) * 10000));
ByteVector pi32le(reinterpret_cast<const char*>(PI32LE), 5);
CPPUNIT_ASSERT_EQUAL(31415, static_cast<int>(pi32le.toFloat32LE(1) * 10000));
ByteVector pi64(reinterpret_cast<const char*>(PI64), 9);
CPPUNIT_ASSERT_EQUAL(31415, static_cast<int>(pi64.toFloat64BE(1) * 10000));
ByteVector pi32be(reinterpret_cast<const char*>(PI32BE), 5);
CPPUNIT_ASSERT_EQUAL(31415, static_cast<int>(pi32be.toFloat32BE(1) * 10000));
ByteVector pi80(reinterpret_cast<const char*>(PI80), 11);
CPPUNIT_ASSERT_EQUAL(31415, static_cast<int>(pi80.toFloat80BE(1) * 10000));
ByteVector pi64le(reinterpret_cast<const char*>(PI64LE), 9);
CPPUNIT_ASSERT_EQUAL(31415, static_cast<int>(pi64le.toFloat64LE(1) * 10000));
ByteVector pi64be(reinterpret_cast<const char*>(PI64BE), 9);
CPPUNIT_ASSERT_EQUAL(31415, static_cast<int>(pi64be.toFloat64BE(1) * 10000));
ByteVector pi80le(reinterpret_cast<const char*>(PI80LE), 11);
CPPUNIT_ASSERT_EQUAL(31415, static_cast<int>(pi80le.toFloat80LE(1) * 10000));
ByteVector pi80be(reinterpret_cast<const char*>(PI80BE), 11);
CPPUNIT_ASSERT_EQUAL(31415, static_cast<int>(pi80be.toFloat80BE(1) * 10000));
ByteVector pi32le2 = ByteVector::fromFloat32LE(pi32le.toFloat32LE(1));
CPPUNIT_ASSERT(memcmp(pi32le.data() + 1, pi32le2.data(), 4) == 0);
ByteVector pi32be2 = ByteVector::fromFloat32BE(pi32be.toFloat32BE(1));
CPPUNIT_ASSERT(memcmp(pi32be.data() + 1, pi32be2.data(), 4) == 0);
ByteVector pi64le2 = ByteVector::fromFloat64LE(pi64le.toFloat64LE(1));
CPPUNIT_ASSERT(memcmp(pi64le.data() + 1, pi64le2.data(), 8) == 0);
ByteVector pi64be2 = ByteVector::fromFloat64BE(pi64be.toFloat64BE(1));
CPPUNIT_ASSERT(memcmp(pi64be.data() + 1, pi64be2.data(), 8) == 0);
}
void testReplace()

View File

@ -91,6 +91,7 @@ public:
newpic->setData("JPEG data");
f->addPicture(newpic);
f->save();
delete f;
f = new FLAC::File(newname.c_str());
lst = f->pictureList();
@ -115,6 +116,7 @@ public:
CPPUNIT_ASSERT_EQUAL(String("image/jpeg"), pic->mimeType());
CPPUNIT_ASSERT_EQUAL(String("new image"), pic->description());
CPPUNIT_ASSERT_EQUAL(ByteVector("JPEG data"), pic->data());
delete f;
}
void testReplacePicture()
@ -138,6 +140,7 @@ public:
f->removePictures();
f->addPicture(newpic);
f->save();
delete f;
f = new FLAC::File(newname.c_str());
lst = f->pictureList();
@ -152,6 +155,7 @@ public:
CPPUNIT_ASSERT_EQUAL(String("image/jpeg"), pic->mimeType());
CPPUNIT_ASSERT_EQUAL(String("new image"), pic->description());
CPPUNIT_ASSERT_EQUAL(ByteVector("JPEG data"), pic->data());
delete f;
}
void testRemoveAllPictures()
@ -165,10 +169,12 @@ public:
f->removePictures();
f->save();
delete f;
f = new FLAC::File(newname.c_str());
lst = f->pictureList();
CPPUNIT_ASSERT_EQUAL(size_t(0), lst.size());
delete f;
}
void testRepeatedSave()
@ -185,10 +191,12 @@ public:
tag->setTitle("NEW TITLE 2");
f->save();
CPPUNIT_ASSERT_EQUAL(String("NEW TITLE 2"), tag->title());
delete f;
f = new FLAC::File(newname.c_str());
tag = f->tag();
CPPUNIT_ASSERT_EQUAL(String("NEW TITLE 2"), tag->title());
delete f;
}
void testSaveMultipleValues()
@ -209,6 +217,7 @@ public:
CPPUNIT_ASSERT_EQUAL(size_t(2), m["ARTIST"].size());
CPPUNIT_ASSERT_EQUAL(String("artist 1"), m["ARTIST"][0]);
CPPUNIT_ASSERT_EQUAL(String("artist 2"), m["ARTIST"][1]);
delete f;
}
void testDict()
@ -230,13 +239,14 @@ public:
CPPUNIT_ASSERT_EQUAL(size_t(2), dict["ARTIST"].size());
CPPUNIT_ASSERT_EQUAL(String("artøst 1"), dict["ARTIST"][0]);
CPPUNIT_ASSERT_EQUAL(String("artöst 2"), dict["ARTIST"][1]);
delete f;
}
void testInvalid()
{
ScopedFileCopy copy("silence-44-s", ".flac");
PropertyMap map;
map["H\xc4\xd6"] = String("bla");
map[L"H\x00c4\x00d6"] = String("bla");
FLAC::File f(copy.fileName().c_str());
PropertyMap invalid = f.setProperties(map);
CPPUNIT_ASSERT_EQUAL(size_t(1), invalid.size());

View File

@ -4,12 +4,9 @@
#include <string>
#include <stdio.h>
// so evil :(
#define protected public
#include <id3v2tag.h>
#include <mpegfile.h>
#include <id3v2frame.h>
#undef protected
#include <uniquefileidentifierframe.h>
#include <textidentificationframe.h>
#include <attachedpictureframe.h>
@ -22,6 +19,8 @@
#include <urllinkframe.h>
#include <ownershipframe.h>
#include <unknownframe.h>
#include <chapterframe.h>
#include <tableofcontentsframe.h>
#include <tdebug.h>
#include <tpropertymap.h>
#include <cppunit/extensions/HelperMacros.h>
@ -36,8 +35,8 @@ class PublicFrame : public ID3v2::Frame
PublicFrame() : ID3v2::Frame(ByteVector("XXXX\0\0\0\0\0\0", 10)) {}
String readStringField(const ByteVector &data, String::Type encoding)
{
size_t position = 0;
return ID3v2::Frame::readStringField(data, encoding, position);
size_t position = 0;
return ID3v2::Frame::readStringField(data, encoding, position);
}
virtual String toString() const { return String::null; }
virtual void parseFields(const ByteVector &) {}
@ -90,6 +89,10 @@ class TestID3v2 : public CppUnit::TestFixture
CPPUNIT_TEST(testPropertyInterface2);
CPPUNIT_TEST(testDeleteFrame);
CPPUNIT_TEST(testSaveAndStripID3v1ShouldNotAddFrameFromID3v1ToId3v2);
CPPUNIT_TEST(testParseChapterFrame);
CPPUNIT_TEST(testRenderChapterFrame);
CPPUNIT_TEST(testParseTableOfContentsFrame);
CPPUNIT_TEST(testRenderTableOfContentsFrame);
CPPUNIT_TEST_SUITE_END();
public:
@ -103,13 +106,23 @@ public:
void testDowngradeUTF8ForID3v23()
{
ID3v2::TextIdentificationFrame f(ByteVector("TPE1"), String::UTF8);
ScopedFileCopy copy("xing", ".mp3");
string newname = copy.fileName();
ID3v2::TextIdentificationFrame *f
= new ID3v2::TextIdentificationFrame(ByteVector("TPE1"), String::UTF8);
StringList sl;
sl.append("Foo");
f.setText(sl);
f.header()->setVersion(3);
ByteVector data = f.render();
f->setText(sl);
MPEG::File file(newname.c_str());
file.ID3v2Tag(true)->addFrame(f);
file.save(MPEG::File::ID3v2, true, 3);
CPPUNIT_ASSERT_EQUAL(true, file.hasID3v2Tag());
ByteVector data = f->render();
CPPUNIT_ASSERT_EQUAL((size_t)(4+4+2+1+6+2), data.size());
ID3v2::TextIdentificationFrame f2(data);
CPPUNIT_ASSERT_EQUAL(sl, f2.fieldList());
CPPUNIT_ASSERT_EQUAL(String::UTF16, f2.textEncoding());
@ -295,13 +308,16 @@ public:
f->setRating(200);
f->setCounter(3);
MPEG::File foo(newname.c_str());
foo.ID3v2Tag()->addFrame(f);
foo.save();
MPEG::File bar(newname.c_str());
CPPUNIT_ASSERT_EQUAL(String("email@example.com"), dynamic_cast<ID3v2::PopularimeterFrame *>(bar.ID3v2Tag()->frameList("POPM").front())->email());
CPPUNIT_ASSERT_EQUAL(200, dynamic_cast<ID3v2::PopularimeterFrame *>(bar.ID3v2Tag()->frameList("POPM").front())->rating());
{
MPEG::File foo(newname.c_str());
foo.ID3v2Tag()->addFrame(f);
foo.save();
}
{
MPEG::File bar(newname.c_str());
CPPUNIT_ASSERT_EQUAL(String("email@example.com"), dynamic_cast<ID3v2::PopularimeterFrame *>(bar.ID3v2Tag()->frameList("POPM").front())->email());
CPPUNIT_ASSERT_EQUAL(200, dynamic_cast<ID3v2::PopularimeterFrame *>(bar.ID3v2Tag()->frameList("POPM").front())->rating());
}
}
// http://bugs.kde.org/show_bug.cgi?id=150481
@ -402,7 +418,7 @@ public:
"http://example.com", 33), // URL
f.render());
}
void testParseOwnershipFrame()
{
ID3v2::OwnershipFrame f(
@ -547,13 +563,17 @@ public:
ScopedFileCopy copy("xing", ".mp3");
string newname = copy.fileName();
ID3v2::FrameFactory::instance()->setDefaultTextEncoding(String::UTF16);
MPEG::File foo(newname.c_str());
foo.strip();
foo.tag()->setComment("Test comment!");
foo.save();
MPEG::File bar(newname.c_str());
CPPUNIT_ASSERT_EQUAL(String("Test comment!"), bar.tag()->comment());
ID3v2::FrameFactory::instance()->setDefaultTextEncoding(defaultEncoding);
{
MPEG::File foo(newname.c_str());
foo.strip();
foo.tag()->setComment("Test comment!");
foo.save();
}
{
MPEG::File bar(newname.c_str());
CPPUNIT_ASSERT_EQUAL(String("Test comment!"), bar.tag()->comment());
ID3v2::FrameFactory::instance()->setDefaultTextEncoding(defaultEncoding);
}
}
void testUpdateGenre23_1()
@ -634,57 +654,60 @@ public:
string newname = copy.fileName();
ID3v2::TextIdentificationFrame *tf;
MPEG::File foo(newname.c_str());
tf = new ID3v2::TextIdentificationFrame("TDOR", String::Latin1);
tf->setText("2011-03-16");
foo.ID3v2Tag()->addFrame(tf);
tf = new ID3v2::TextIdentificationFrame("TDRC", String::Latin1);
tf->setText("2012-04-17T12:01");
foo.ID3v2Tag()->addFrame(tf);
tf = new ID3v2::TextIdentificationFrame("TMCL", String::Latin1);
tf->setText(StringList().append("Guitar").append("Artist 1").append("Drums").append("Artist 2"));
foo.ID3v2Tag()->addFrame(tf);
tf = new ID3v2::TextIdentificationFrame("TIPL", String::Latin1);
tf->setText(StringList().append("Producer").append("Artist 3").append("Mastering").append("Artist 4"));
foo.ID3v2Tag()->addFrame(tf);
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TDRL", String::Latin1));
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TDTG", String::Latin1));
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TMOO", String::Latin1));
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TPRO", String::Latin1));
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TSOA", String::Latin1));
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TSOT", String::Latin1));
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TSST", String::Latin1));
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TSOP", String::Latin1));
foo.save(MPEG::File::AllTags, true, 3);
MPEG::File bar(newname.c_str());
tf = static_cast<ID3v2::TextIdentificationFrame *>(bar.ID3v2Tag()->frameList("TDOR").front());
CPPUNIT_ASSERT(tf);
CPPUNIT_ASSERT_EQUAL(size_t(1), tf->fieldList().size());
CPPUNIT_ASSERT_EQUAL(String("2011"), tf->fieldList().front());
tf = static_cast<ID3v2::TextIdentificationFrame *>(bar.ID3v2Tag()->frameList("TDRC").front());
CPPUNIT_ASSERT(tf);
CPPUNIT_ASSERT_EQUAL(size_t(1), tf->fieldList().size());
CPPUNIT_ASSERT_EQUAL(String("2012"), tf->fieldList().front());
tf = dynamic_cast<ID3v2::TextIdentificationFrame *>(bar.ID3v2Tag()->frameList("TIPL").front());
CPPUNIT_ASSERT(tf);
CPPUNIT_ASSERT_EQUAL(size_t(8), tf->fieldList().size());
CPPUNIT_ASSERT_EQUAL(String("Guitar"), tf->fieldList()[0]);
CPPUNIT_ASSERT_EQUAL(String("Artist 1"), tf->fieldList()[1]);
CPPUNIT_ASSERT_EQUAL(String("Drums"), tf->fieldList()[2]);
CPPUNIT_ASSERT_EQUAL(String("Artist 2"), tf->fieldList()[3]);
CPPUNIT_ASSERT_EQUAL(String("Producer"), tf->fieldList()[4]);
CPPUNIT_ASSERT_EQUAL(String("Artist 3"), tf->fieldList()[5]);
CPPUNIT_ASSERT_EQUAL(String("Mastering"), tf->fieldList()[6]);
CPPUNIT_ASSERT_EQUAL(String("Artist 4"), tf->fieldList()[7]);
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TDRL"));
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TDTG"));
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TMOO"));
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TPRO"));
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TSOA"));
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TSOT"));
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TSST"));
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TSOP"));
{
MPEG::File foo(newname.c_str());
tf = new ID3v2::TextIdentificationFrame("TDOR", String::Latin1);
tf->setText("2011-03-16");
foo.ID3v2Tag()->addFrame(tf);
tf = new ID3v2::TextIdentificationFrame("TDRC", String::Latin1);
tf->setText("2012-04-17T12:01");
foo.ID3v2Tag()->addFrame(tf);
tf = new ID3v2::TextIdentificationFrame("TMCL", String::Latin1);
tf->setText(StringList().append("Guitar").append("Artist 1").append("Drums").append("Artist 2"));
foo.ID3v2Tag()->addFrame(tf);
tf = new ID3v2::TextIdentificationFrame("TIPL", String::Latin1);
tf->setText(StringList().append("Producer").append("Artist 3").append("Mastering").append("Artist 4"));
foo.ID3v2Tag()->addFrame(tf);
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TDRL", String::Latin1));
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TDTG", String::Latin1));
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TMOO", String::Latin1));
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TPRO", String::Latin1));
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TSOA", String::Latin1));
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TSOT", String::Latin1));
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TSST", String::Latin1));
foo.ID3v2Tag()->addFrame(new ID3v2::TextIdentificationFrame("TSOP", String::Latin1));
foo.save(MPEG::File::AllTags, true, 3);
}
{
MPEG::File bar(newname.c_str());
tf = static_cast<ID3v2::TextIdentificationFrame *>(bar.ID3v2Tag()->frameList("TDOR").front());
CPPUNIT_ASSERT(tf);
CPPUNIT_ASSERT_EQUAL(size_t(1), tf->fieldList().size());
CPPUNIT_ASSERT_EQUAL(String("2011"), tf->fieldList().front());
tf = static_cast<ID3v2::TextIdentificationFrame *>(bar.ID3v2Tag()->frameList("TDRC").front());
CPPUNIT_ASSERT(tf);
CPPUNIT_ASSERT_EQUAL(size_t(1), tf->fieldList().size());
CPPUNIT_ASSERT_EQUAL(String("2012"), tf->fieldList().front());
tf = dynamic_cast<ID3v2::TextIdentificationFrame *>(bar.ID3v2Tag()->frameList("TIPL").front());
CPPUNIT_ASSERT(tf);
CPPUNIT_ASSERT_EQUAL(size_t(8), tf->fieldList().size());
CPPUNIT_ASSERT_EQUAL(String("Guitar"), tf->fieldList()[0]);
CPPUNIT_ASSERT_EQUAL(String("Artist 1"), tf->fieldList()[1]);
CPPUNIT_ASSERT_EQUAL(String("Drums"), tf->fieldList()[2]);
CPPUNIT_ASSERT_EQUAL(String("Artist 2"), tf->fieldList()[3]);
CPPUNIT_ASSERT_EQUAL(String("Producer"), tf->fieldList()[4]);
CPPUNIT_ASSERT_EQUAL(String("Artist 3"), tf->fieldList()[5]);
CPPUNIT_ASSERT_EQUAL(String("Mastering"), tf->fieldList()[6]);
CPPUNIT_ASSERT_EQUAL(String("Artist 4"), tf->fieldList()[7]);
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TDRL"));
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TDTG"));
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TMOO"));
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TPRO"));
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TSOA"));
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TSOT"));
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TSST"));
CPPUNIT_ASSERT(!bar.ID3v2Tag()->frameListMap().contains("TSOP"));
}
}
void testCompressedFrameWithBrokenLength()
@ -694,7 +717,7 @@ public:
#ifdef HAVE_ZLIB
ID3v2::AttachedPictureFrame *frame
ID3v2::AttachedPictureFrame *frame
= dynamic_cast<TagLib::ID3v2::AttachedPictureFrame*>(f.ID3v2Tag()->frameListMap()["APIC"].front());
CPPUNIT_ASSERT(frame);
CPPUNIT_ASSERT_EQUAL(String("image/bmp"), frame->mimeType());
@ -707,13 +730,13 @@ public:
// Skip the test if ZLIB is not installed.
// The message "Compressed frames are currently not supported." will be displayed.
ID3v2::UnknownFrame *frame
ID3v2::UnknownFrame *frame
= dynamic_cast<TagLib::ID3v2::UnknownFrame*>(f.ID3v2Tag()->frameListMap()["APIC"].front());
CPPUNIT_ASSERT(frame);
#endif
}
void testW000()
{
MPEG::File f(TEST_FILE_PATH_C("w000.mp3"), false);
@ -825,40 +848,157 @@ public:
{
ScopedFileCopy copy("rare_frames", ".mp3");
string newname = copy.fileName();
MPEG::File f(newname.c_str());
ID3v2::Tag *t = f.ID3v2Tag();
ID3v2::Frame *frame = t->frameList("TCON")[0];
CPPUNIT_ASSERT_EQUAL((size_t)1u, t->frameList("TCON").size());
t->removeFrame(frame, true);
f.save(MPEG::File::ID3v2);
MPEG::File f2(newname.c_str());
t = f2.ID3v2Tag();
CPPUNIT_ASSERT(t->frameList("TCON").isEmpty());
{
MPEG::File f(newname.c_str());
ID3v2::Tag *t = f.ID3v2Tag();
ID3v2::Frame *frame = t->frameList("TCON")[0];
CPPUNIT_ASSERT_EQUAL(size_t(1), t->frameList("TCON").size());
t->removeFrame(frame, true);
f.save(MPEG::File::ID3v2);
}
{
MPEG::File f2(newname.c_str());
ID3v2::Tag *t = f2.ID3v2Tag();
CPPUNIT_ASSERT(t->frameList("TCON").isEmpty());
}
}
void testSaveAndStripID3v1ShouldNotAddFrameFromID3v1ToId3v2()
{
ScopedFileCopy copy("xing", ".mp3");
string newname = copy.fileName();
{
MPEG::File foo(newname.c_str());
foo.tag()->setArtist("Artist");
foo.save(MPEG::File::ID3v1 | MPEG::File::ID3v2);
}
{
MPEG::File bar(newname.c_str());
bar.ID3v2Tag()->removeFrames("TPE1");
// Should strip ID3v1 here and not add old values to ID3v2 again
bar.save(MPEG::File::ID3v2, true);
}
MPEG::File f(newname.c_str());
CPPUNIT_ASSERT(!f.ID3v2Tag()->frameListMap().contains("TPE1"));
}
void testParseChapterFrame()
{
ID3v2::ChapterFrame f(
ByteVector("CHAP" // Frame ID
"\x00\x00\x00\x20" // Frame size
"\x00\x00" // Frame flags
"\x43\x00" // Element ID
"\x00\x00\x00\x03" // Start time
"\x00\x00\x00\x05" // End time
"\x00\x00\x00\x02" // Start offset
"\x00\x00\x00\x03" // End offset
"TIT2" // Embedded frame ID
"\x00\x00\x00\x04" // Embedded frame size
"\x00\x00" // Embedded frame flags
"\x00" // TIT2 frame text encoding
"CH1", 42)); // Chapter title
CPPUNIT_ASSERT_EQUAL(ByteVector("\x43\x00", 2),
f.elementID());
CPPUNIT_ASSERT((uint)0x03 == f.startTime());
CPPUNIT_ASSERT((uint)0x05 == f.endTime());
CPPUNIT_ASSERT((uint)0x02 == f.startOffset());
CPPUNIT_ASSERT((uint)0x03 == f.endOffset());
CPPUNIT_ASSERT((uint)0x01 == f.embeddedFrameList().size());
CPPUNIT_ASSERT(f.embeddedFrameList("TIT2").size() == 1);
CPPUNIT_ASSERT(f.embeddedFrameList("TIT2")[0]->toString() == "CH1");
}
void testRenderChapterFrame()
{
ID3v2::ChapterFrame f("CHAP");
f.setElementID(ByteVector("\x43\x00", 2));
f.setStartTime(3);
f.setEndTime(5);
f.setStartOffset(2);
f.setEndOffset(3);
ID3v2::TextIdentificationFrame eF("TIT2");
eF.setText("CH1");
f.addEmbeddedFrame(&eF);
CPPUNIT_ASSERT_EQUAL(
ByteVector("CHAP" // Frame ID
"\x00\x00\x00\x20" // Frame size
"\x00\x00" // Frame flags
"\x43\x00" // Element ID
"\x00\x00\x00\x03" // Start time
"\x00\x00\x00\x05" // End time
"\x00\x00\x00\x02" // Start offset
"\x00\x00\x00\x03" // End offset
"TIT2" // Embedded frame ID
"\x00\x00\x00\x04" // Embedded frame size
"\x00\x00" // Embedded frame flags
"\x00" // TIT2 frame text encoding
"CH1", 42), // Chapter title
f.render());
}
void testParseTableOfContentsFrame()
{
ID3v2::TableOfContentsFrame f(
ByteVector("CTOC" // Frame ID
"\x00\x00\x00\x16" // Frame size
"\x00\x00" // Frame flags
"\x54\x00" // Element ID
"\x01" // CTOC flags
"\x02" // Entry count
"\x43\x00" // First entry
"\x44\x00" // Second entry
"TIT2" // Embedded frame ID
"\x00\x00\x00\x04" // Embedded frame size
"\x00\x00" // Embedded frame flags
"\x00" // TIT2 frame text encoding
"TC1", 32)); // Table of contents title
CPPUNIT_ASSERT_EQUAL(ByteVector("\x54\x00", 2),
f.elementID());
CPPUNIT_ASSERT(!f.isTopLevel());
CPPUNIT_ASSERT(f.isOrdered());
CPPUNIT_ASSERT((uint)0x02 == f.entryCount());
CPPUNIT_ASSERT_EQUAL(ByteVector("\x43\x00", 2),
f.childElements()[0]);
CPPUNIT_ASSERT_EQUAL(ByteVector("\x44\x00", 2),
f.childElements()[1]);
CPPUNIT_ASSERT((uint)0x01 == f.embeddedFrameList().size());
CPPUNIT_ASSERT(f.embeddedFrameList("TIT2").size() == 1);
CPPUNIT_ASSERT(f.embeddedFrameList("TIT2")[0]->toString() == "TC1");
}
void testRenderTableOfContentsFrame()
{
ID3v2::TableOfContentsFrame f("CTOC");
f.setElementID(ByteVector("\x54\x00", 2));
f.setIsTopLevel(false);
f.setIsOrdered(true);
f.addChildElement(ByteVector("\x43\x00", 2));
f.addChildElement(ByteVector("\x44\x00", 2));
ID3v2::TextIdentificationFrame eF("TIT2");
eF.setText("TC1");
f.addEmbeddedFrame(&eF);
CPPUNIT_ASSERT_EQUAL(
ByteVector("CTOC" // Frame ID
"\x00\x00\x00\x16" // Frame size
"\x00\x00" // Frame flags
"\x54\x00" // Element ID
"\x01" // CTOC flags
"\x02" // Entry count
"\x43\x00" // First entry
"\x44\x00" // Second entry
"TIT2" // Embedded frame ID
"\x00\x00\x00\x04" // Embedded frame size
"\x00\x00" // Embedded frame flags
"\x00" // TIT2 frame text encoding
"TC1", 32), // Table of contents title
f.render());
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestID3v2);

View File

@ -18,85 +18,90 @@ class TestMatroska : public CppUnit::TestFixture
CPPUNIT_TEST(testInsertAndExtract);
CPPUNIT_TEST(testAudioProperties);
CPPUNIT_TEST_SUITE_END();
public:
void testPredefined()
{
ScopedFileCopy copy("matroska", ".mka");
string filename = copy.fileName();
EBML::Matroska::File f(filename.c_str());
CPPUNIT_ASSERT(f.isValid());
PropertyMap pm = f.properties();
PropertyMap::Iterator i = pm.find("ENCODER");
CPPUNIT_ASSERT(i != f.properties().end());
CPPUNIT_ASSERT(i != pm.end());
CPPUNIT_ASSERT_EQUAL(String("Lavf54.63.104"), i->second.front());
}
void testInsertAndExtract()
{
ScopedFileCopy copy("matroska", ".mka");
string filename = copy.fileName();
EBML::Matroska::File f1(filename.c_str());
CPPUNIT_ASSERT(f1.isValid());
Tag* t = f1.tag();
CPPUNIT_ASSERT(t != 0);
t->setTitle("Seconds of Silence");
t->setArtist("Nobody");
t->setAlbum("TagLib Test Suite");
t->setComment("Well, there's nothing to say - a few special signs: ©’…ä–€ſ");
t->setGenre("Air");
t->setYear(2013);
t->setTrack(15);
CPPUNIT_ASSERT(f1.save());
EBML::Matroska::File f2(filename.c_str());
CPPUNIT_ASSERT(f2.isValid());
t = f2.tag();
CPPUNIT_ASSERT(t != 0);
CPPUNIT_ASSERT_EQUAL(String("Seconds of Silence"), t->title());
CPPUNIT_ASSERT_EQUAL(String("Nobody"), t->artist());
CPPUNIT_ASSERT_EQUAL(String("TagLib Test Suite"), t->album());
CPPUNIT_ASSERT_EQUAL(String("Well, there's nothing to say - a few special signs: ©’…ä–€ſ"), t->comment());
CPPUNIT_ASSERT_EQUAL(String("Air"), t->genre());
CPPUNIT_ASSERT_EQUAL(2013u, t->year());
CPPUNIT_ASSERT_EQUAL(15u, t->track());
PropertyMap pm = f2.properties();
pm.erase("COMMENT");
f2.setProperties(pm);
CPPUNIT_ASSERT(f2.save());
EBML::Matroska::File f3(filename.c_str());
CPPUNIT_ASSERT(f3.isValid());
pm = f3.properties();
PropertyMap::Iterator i = pm.find("GENRE");
CPPUNIT_ASSERT(i != pm.end());
CPPUNIT_ASSERT_EQUAL(String("Air"), i->second.front());
{
EBML::Matroska::File f1(filename.c_str());
CPPUNIT_ASSERT(f1.isValid());
Tag* t = f1.tag();
CPPUNIT_ASSERT(t != 0);
t->setTitle("Seconds of Silence");
t->setArtist("Nobody");
t->setAlbum("TagLib Test Suite");
t->setComment("Well, there's nothing to say - a few special signs: ©’…ä–€ſ");
t->setGenre("Air");
t->setYear(2013);
t->setTrack(15);
CPPUNIT_ASSERT(f1.save());
}
{
EBML::Matroska::File f2(filename.c_str());
CPPUNIT_ASSERT(f2.isValid());
Tag* t = f2.tag();
CPPUNIT_ASSERT(t != 0);
CPPUNIT_ASSERT_EQUAL(String("Seconds of Silence"), t->title());
CPPUNIT_ASSERT_EQUAL(String("Nobody"), t->artist());
CPPUNIT_ASSERT_EQUAL(String("TagLib Test Suite"), t->album());
CPPUNIT_ASSERT_EQUAL(String("Well, there's nothing to say - a few special signs: ©’…ä–€ſ"), t->comment());
CPPUNIT_ASSERT_EQUAL(String("Air"), t->genre());
CPPUNIT_ASSERT_EQUAL(2013u, t->year());
CPPUNIT_ASSERT_EQUAL(15u, t->track());
PropertyMap pm = f2.properties();
pm.erase("COMMENT");
f2.setProperties(pm);
CPPUNIT_ASSERT(f2.save());
}
{
EBML::Matroska::File f3(filename.c_str());
CPPUNIT_ASSERT(f3.isValid());
PropertyMap pm = f3.properties();
PropertyMap::Iterator i = pm.find("GENRE");
CPPUNIT_ASSERT(i != pm.end());
CPPUNIT_ASSERT_EQUAL(String("Air"), i->second.front());
}
}
void testAudioProperties()
{
ScopedFileCopy copy("matroska", ".mka");
string filename = copy.fileName();
EBML::Matroska::File f(filename.c_str());
CPPUNIT_ASSERT(f.isValid());
AudioProperties* a = f.audioProperties();
CPPUNIT_ASSERT(a != 0);
// Not a very nice assertion...
CPPUNIT_ASSERT_EQUAL(a->length(), 0);
// Bitrate is not nice and thus not tested.

View File

@ -158,6 +158,7 @@ public:
f->tag()->itemListMap()["pgap"] = true;
f->save();
delete f;
f = new MP4::File(filename.c_str());
CPPUNIT_ASSERT_EQUAL(true, f->tag()->itemListMap()["cpil"].toBool());
@ -167,6 +168,7 @@ public:
moov = atoms->atoms[0];
// original size + 'pgap' size + padding
CPPUNIT_ASSERT_EQUAL(long(77 + 25 + 974), moov->length);
delete f;
}
void testGnre()
@ -231,7 +233,7 @@ public:
void testProperties()
{
MP4::File f(TEST_FILE_PATH_C("has-tags.m4a"));
PropertyMap tags = f.properties();
CPPUNIT_ASSERT_EQUAL(StringList("Test Artist"), tags["ARTIST"]);

View File

@ -32,18 +32,21 @@ public:
string newname = copy.fileName();
String xxx = ByteVector(254, 'X');
MPEG::File f(newname.c_str());
CPPUNIT_ASSERT_EQUAL(false, f.hasID3v2Tag());
{
MPEG::File f(newname.c_str());
CPPUNIT_ASSERT_EQUAL(false, f.hasID3v2Tag());
f.tag()->setTitle(xxx);
f.tag()->setArtist("Artist A");
f.save(MPEG::File::AllTags, true, 4);
CPPUNIT_ASSERT_EQUAL(true, f.hasID3v2Tag());
MPEG::File f2(newname.c_str());
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4), f2.ID3v2Tag()->header()->majorVersion());
CPPUNIT_ASSERT_EQUAL(String("Artist A"), f2.tag()->artist());
CPPUNIT_ASSERT_EQUAL(xxx, f2.tag()->title());
f.tag()->setTitle(xxx);
f.tag()->setArtist("Artist A");
f.save(MPEG::File::AllTags, true, 4);
CPPUNIT_ASSERT_EQUAL(true, f.hasID3v2Tag());
}
{
MPEG::File f2(newname.c_str());
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4), f2.ID3v2Tag()->header()->majorVersion());
CPPUNIT_ASSERT_EQUAL(String("Artist A"), f2.tag()->artist());
CPPUNIT_ASSERT_EQUAL(xxx, f2.tag()->title());
}
}
void testSaveID3v24WrongParam()
@ -52,15 +55,18 @@ public:
string newname = copy.fileName();
String xxx = ByteVector(254, 'X');
MPEG::File f(newname.c_str());
f.tag()->setTitle(xxx);
f.tag()->setArtist("Artist A");
f.save(MPEG::File::AllTags, true, 8);
MPEG::File f2(newname.c_str());
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4), f2.ID3v2Tag()->header()->majorVersion());
CPPUNIT_ASSERT_EQUAL(String("Artist A"), f2.tag()->artist());
CPPUNIT_ASSERT_EQUAL(xxx, f2.tag()->title());
{
MPEG::File f(newname.c_str());
f.tag()->setTitle(xxx);
f.tag()->setArtist("Artist A");
f.save(MPEG::File::AllTags, true, 8);
}
{
MPEG::File f2(newname.c_str());
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4), f2.ID3v2Tag()->header()->majorVersion());
CPPUNIT_ASSERT_EQUAL(String("Artist A"), f2.tag()->artist());
CPPUNIT_ASSERT_EQUAL(xxx, f2.tag()->title());
}
}
void testSaveID3v23()
@ -69,18 +75,21 @@ public:
string newname = copy.fileName();
String xxx = ByteVector(254, 'X');
MPEG::File f(newname.c_str());
CPPUNIT_ASSERT_EQUAL(false, f.hasID3v2Tag());
{
MPEG::File f(newname.c_str());
CPPUNIT_ASSERT_EQUAL(false, f.hasID3v2Tag());
f.tag()->setTitle(xxx);
f.tag()->setArtist("Artist A");
f.save(MPEG::File::AllTags, true, 3);
CPPUNIT_ASSERT_EQUAL(true, f.hasID3v2Tag());
MPEG::File f2(newname.c_str());
CPPUNIT_ASSERT_EQUAL(TagLib::uint(3), f2.ID3v2Tag()->header()->majorVersion());
CPPUNIT_ASSERT_EQUAL(String("Artist A"), f2.tag()->artist());
CPPUNIT_ASSERT_EQUAL(xxx, f2.tag()->title());
f.tag()->setTitle(xxx);
f.tag()->setArtist("Artist A");
f.save(MPEG::File::AllTags, true, 3);
CPPUNIT_ASSERT_EQUAL(true, f.hasID3v2Tag());
}
{
MPEG::File f2(newname.c_str());
CPPUNIT_ASSERT_EQUAL(TagLib::uint(3), f2.ID3v2Tag()->header()->majorVersion());
CPPUNIT_ASSERT_EQUAL(String("Artist A"), f2.tag()->artist());
CPPUNIT_ASSERT_EQUAL(xxx, f2.tag()->title());
}
}
};

View File

@ -11,11 +11,11 @@ public:
{
TagLib::PropertyMap map1;
CPPUNIT_ASSERT(map1.isEmpty());
map1["\xc4\xd6\xdc"].append("test");
CPPUNIT_ASSERT_EQUAL(map1.size(), (size_t)1u);
map1[L"\x00c4\x00d6\x00dc"].append("test");
CPPUNIT_ASSERT_EQUAL(map1.size(), (size_t)1);
TagLib::PropertyMap map2;
map2["\xc4\xd6\xdc"].append("test");
map2[L"\x00c4\x00d6\x00dc"].append("test");
CPPUNIT_ASSERT(map1 == map2);
CPPUNIT_ASSERT(map1.contains(map2));
@ -24,6 +24,7 @@ public:
CPPUNIT_ASSERT(map2.contains(map1));
map2["\xc4\xd6\xdc"].append("test 2");
map2[L"\x00c4\x00d6\x00dc"].append("test 2");
CPPUNIT_ASSERT(!map2.contains(map1));
}

View File

@ -99,7 +99,7 @@ public:
String unicode6(L"\u65e5\u672c\u8a9e", String::UTF16LE);
CPPUNIT_ASSERT(unicode6[1] == (littleEndian ? L'\u672c' : L'\u2c67'));
wstring stduni = L"\u65e5\u672c\u8a9e";
std::wstring stduni = L"\u65e5\u672c\u8a9e";
String unicode7(stduni);
CPPUNIT_ASSERT(unicode7[1] == L'\u672c');

View File

@ -29,8 +29,8 @@ inline string copyFile(const string &filename, const string &ext)
string newname = string(tempnam(NULL, NULL)) + ext;
string oldname = testFilePath(filename) + ext;
#ifdef _WIN32
CopyFile(oldname.c_str(), newname.c_str(), FALSE);
SetFileAttributes(newname.c_str(), GetFileAttributes(newname.c_str()) & ~FILE_ATTRIBUTE_READONLY);
CopyFileA(oldname.c_str(), newname.c_str(), FALSE);
SetFileAttributesA(newname.c_str(), GetFileAttributesA(newname.c_str()) & ~FILE_ATTRIBUTE_READONLY);
#else
char buffer[4096];
int bytes;