1 #include <cppunit/extensions/HelperMacros.h>
6 #include <id3v2frame.h>
7 #include <uniquefileidentifierframe.h>
8 #include <textidentificationframe.h>
9 #include <attachedpictureframe.h>
10 #include <generalencapsulatedobjectframe.h>
11 #include <relativevolumeframe.h>
12 #include <urllinkframe.h>
16 using namespace TagLib;
18 class PublicFrame : public ID3v2::Frame
21 PublicFrame() : ID3v2::Frame(ByteVector("XXXX\0\0\0\0\0\0", 10)) {}
22 String readStringField(const ByteVector &data, String::Type encoding,
24 { return ID3v2::Frame::readStringField(data, encoding, positon); }
25 virtual String toString() const { return String::null; }
26 virtual void parseFields(const ByteVector &) {}
27 virtual ByteVector renderFields() const { return ByteVector::null; }
30 class TestID3v2 : public CppUnit::TestFixture
32 CPPUNIT_TEST_SUITE(TestID3v2);
33 CPPUNIT_TEST(testUnsynchDecode);
34 CPPUNIT_TEST(testUTF16BEDelimiter);
35 CPPUNIT_TEST(testUTF16Delimiter);
36 CPPUNIT_TEST(testReadStringField);
37 CPPUNIT_TEST(testParseAPIC);
38 CPPUNIT_TEST(testParseAPIC_UTF16_BOM);
39 CPPUNIT_TEST(testParseGEOB);
40 CPPUNIT_TEST(testParseRelativeVolumeFrame);
41 CPPUNIT_TEST(testParseUniqueFileIdentifierFrame);
42 CPPUNIT_TEST(testParseEmptyUniqueFileIdentifierFrame);
43 CPPUNIT_TEST(testBrokenFrame1);
44 CPPUNIT_TEST(testItunes24FrameSize);
45 CPPUNIT_TEST(testParseUrlLinkFrame);
46 CPPUNIT_TEST(testRenderUrlLinkFrame);
47 CPPUNIT_TEST(testParseUserUrlLinkFrame);
48 CPPUNIT_TEST(testRenderUserUrlLinkFrame);
49 CPPUNIT_TEST(testSaveUTF16Comment);
50 CPPUNIT_TEST_SUITE_END();
54 void testUnsynchDecode()
56 MPEG::File f("data/unsynch.id3", false);
57 CPPUNIT_ASSERT(f.tag());
58 CPPUNIT_ASSERT_EQUAL(String("My babe just cares for me"), f.tag()->title());
61 void testUTF16BEDelimiter()
63 ID3v2::TextIdentificationFrame f(ByteVector("TPE1"), String::UTF16BE);
68 CPPUNIT_ASSERT_EQUAL((unsigned int)(4+4+2+1+6+2+6), f.render().size());
71 void testUTF16Delimiter()
73 ID3v2::TextIdentificationFrame f(ByteVector("TPE1"), String::UTF16);
78 CPPUNIT_ASSERT_EQUAL((unsigned int)(4+4+2+1+8+2+8), f.render().size());
81 void testBrokenFrame1()
83 MPEG::File f("data/broken-tenc.id3", false);
84 CPPUNIT_ASSERT(f.tag());
85 CPPUNIT_ASSERT(!f.ID3v2Tag()->frameListMap().contains("TENC"));
88 void testReadStringField()
91 ByteVector data("abc\0", 4);
92 String str = f.readStringField(data, String::Latin1);
93 CPPUNIT_ASSERT_EQUAL(String("abc"), str);
96 // http://bugs.kde.org/show_bug.cgi?id=151078
99 ID3v2::AttachedPictureFrame f(ByteVector("APIC"
107 CPPUNIT_ASSERT_EQUAL(String("m"), f.mimeType());
108 CPPUNIT_ASSERT_EQUAL(ID3v2::AttachedPictureFrame::FileIcon, f.type());
109 CPPUNIT_ASSERT_EQUAL(String("d"), f.description());
112 void testParseAPIC_UTF16_BOM()
114 ID3v2::AttachedPictureFrame f(ByteVector(
115 "\x41\x50\x49\x43\x00\x02\x0c\x59\x00\x00\x01\x69\x6d\x61\x67\x65"
116 "\x2f\x6a\x70\x65\x67\x00\x00\xfe\xff\x00\x63\x00\x6f\x00\x76\x00"
117 "\x65\x00\x72\x00\x2e\x00\x6a\x00\x70\x00\x67\x00\x00\xff\xd8\xff",
119 CPPUNIT_ASSERT_EQUAL(String("image/jpeg"), f.mimeType());
120 CPPUNIT_ASSERT_EQUAL(ID3v2::AttachedPictureFrame::Other, f.type());
121 CPPUNIT_ASSERT_EQUAL(String("cover.jpg"), f.description());
122 CPPUNIT_ASSERT_EQUAL(ByteVector("\xff\xd8\xff", 3), f.picture());
125 // http://bugs.kde.org/show_bug.cgi?id=151078
128 ID3v2::GeneralEncapsulatedObjectFrame f(ByteVector("GEOB"
136 CPPUNIT_ASSERT_EQUAL(String("m"), f.mimeType());
137 CPPUNIT_ASSERT_EQUAL(String("f"), f.fileName());
138 CPPUNIT_ASSERT_EQUAL(String("d"), f.description());
141 // http://bugs.kde.org/show_bug.cgi?id=150481
142 void testParseRelativeVolumeFrame()
144 ID3v2::RelativeVolumeFrame f(
145 ByteVector("RVA2" // Frame ID
146 "\x00\x00\x00\x0B" // Frame size
147 "\x00\x00" // Frame flags
148 "ident\x00" // Identification
149 "\x02" // Type of channel
150 "\x00\x0F" // Volume adjustment
151 "\x08" // Bits representing peak
152 "\x45", 21)); // Peak volume
153 CPPUNIT_ASSERT_EQUAL(String("ident"), f.identification());
154 CPPUNIT_ASSERT_EQUAL(15.0f / 512.0f,
155 f.volumeAdjustment(ID3v2::RelativeVolumeFrame::FrontRight));
156 CPPUNIT_ASSERT_EQUAL((uchar)8,
157 f.peakVolume(ID3v2::RelativeVolumeFrame::FrontRight).bitsRepresentingPeak);
158 CPPUNIT_ASSERT_EQUAL(ByteVector("\x45"),
159 f.peakVolume(ID3v2::RelativeVolumeFrame::FrontRight).peakVolume);
162 void testParseUniqueFileIdentifierFrame()
164 ID3v2::UniqueFileIdentifierFrame f(
165 ByteVector("UFID" // Frame ID
166 "\x00\x00\x00\x09" // Frame size
167 "\x00\x00" // Frame flags
168 "owner\x00" // Owner identifier
169 "\x00\x01\x02", 19)); // Identifier
170 CPPUNIT_ASSERT_EQUAL(String("owner"),
172 CPPUNIT_ASSERT_EQUAL(ByteVector("\x00\x01\x02", 3),
176 void testParseEmptyUniqueFileIdentifierFrame()
178 ID3v2::UniqueFileIdentifierFrame f(
179 ByteVector("UFID" // Frame ID
180 "\x00\x00\x00\x01" // Frame size
181 "\x00\x00" // Frame flags
182 "\x00" // Owner identifier
183 "", 11)); // Identifier
184 CPPUNIT_ASSERT_EQUAL(String(),
186 CPPUNIT_ASSERT_EQUAL(ByteVector(),
190 void testParseUrlLinkFrame()
192 ID3v2::UrlLinkFrame f(
193 ByteVector("WOAF" // Frame ID
194 "\x00\x00\x00\x12" // Frame size
195 "\x00\x00" // Frame flags
196 "http://example.com", 28)); // URL
197 CPPUNIT_ASSERT_EQUAL(String("http://example.com"), f.url());
200 void testRenderUrlLinkFrame()
202 ID3v2::UrlLinkFrame f("WOAF");
203 f.setUrl("http://example.com");
204 CPPUNIT_ASSERT_EQUAL(
205 ByteVector("WOAF" // Frame ID
206 "\x00\x00\x00\x12" // Frame size
207 "\x00\x00" // Frame flags
208 "http://example.com", 28), // URL
212 void testParseUserUrlLinkFrame()
214 ID3v2::UserUrlLinkFrame f(
215 ByteVector("WXXX" // Frame ID
216 "\x00\x00\x00\x17" // Frame size
217 "\x00\x00" // Frame flags
218 "\x00" // Text encoding
219 "foo\x00" // Description
220 "http://example.com", 33)); // URL
221 CPPUNIT_ASSERT_EQUAL(String("foo"), f.description());
222 CPPUNIT_ASSERT_EQUAL(String("http://example.com"), f.url());
225 void testRenderUserUrlLinkFrame()
227 ID3v2::UserUrlLinkFrame f;
228 f.setDescription("foo");
229 f.setUrl("http://example.com");
230 CPPUNIT_ASSERT_EQUAL(
231 ByteVector("WXXX" // Frame ID
232 "\x00\x00\x00\x17" // Frame size
233 "\x00\x00" // Frame flags
234 "\x00" // Text encoding
235 "foo\x00" // Description
236 "http://example.com", 33), // URL
240 void testItunes24FrameSize()
242 MPEG::File f("data/005411.id3", false);
243 CPPUNIT_ASSERT(f.tag());
244 CPPUNIT_ASSERT(f.ID3v2Tag()->frameListMap().contains("TIT2"));
245 CPPUNIT_ASSERT_EQUAL(String("Sunshine Superman"), f.ID3v2Tag()->frameListMap()["TIT2"].front()->toString());
248 void testSaveUTF16Comment()
250 String::Type defaultEncoding = ID3v2::FrameFactory::instance()->defaultTextEncoding();
251 string newname = copyFile("xing", ".mp3");
252 ID3v2::FrameFactory::instance()->setDefaultTextEncoding(String::UTF16);
253 MPEG::File foo(newname.c_str());
255 foo.tag()->setComment("Test comment!");
257 MPEG::File bar(newname.c_str());
258 CPPUNIT_ASSERT_EQUAL(String("Test comment!"), bar.tag()->comment());
260 ID3v2::FrameFactory::instance()->setDefaultTextEncoding(defaultEncoding);
265 CPPUNIT_TEST_SUITE_REGISTRATION(TestID3v2);