implement methods in TempoMap for walking a given distance along a tempo map and...
[ardour.git] / libs / taglib / tests / test_id3v2.cpp
1 #include <cppunit/extensions/HelperMacros.h>
2 #include <string>
3 #include <stdio.h>
4 #include <id3v2tag.h>
5 #include <mpegfile.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>
13 #include "utils.h"
14
15 using namespace std;
16 using namespace TagLib;
17
18 class PublicFrame : public ID3v2::Frame
19 {
20   public:
21     PublicFrame() : ID3v2::Frame(ByteVector("XXXX\0\0\0\0\0\0", 10)) {}
22     String readStringField(const ByteVector &data, String::Type encoding,
23                            int *positon = 0)
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; }
28 };
29
30 class TestID3v2 : public CppUnit::TestFixture
31 {
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();
51
52 public:
53
54   void testUnsynchDecode()
55   {
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());
59   }
60
61   void testUTF16BEDelimiter()
62   {
63     ID3v2::TextIdentificationFrame f(ByteVector("TPE1"), String::UTF16BE);
64     StringList sl;
65     sl.append("Foo");
66     sl.append("Bar");
67     f.setText(sl);
68     CPPUNIT_ASSERT_EQUAL((unsigned int)(4+4+2+1+6+2+6), f.render().size());
69   }
70
71   void testUTF16Delimiter()
72   {
73     ID3v2::TextIdentificationFrame f(ByteVector("TPE1"), String::UTF16);
74     StringList sl;
75     sl.append("Foo");
76     sl.append("Bar");
77     f.setText(sl);
78     CPPUNIT_ASSERT_EQUAL((unsigned int)(4+4+2+1+8+2+8), f.render().size());
79   }
80
81   void testBrokenFrame1()
82   {
83     MPEG::File f("data/broken-tenc.id3", false);
84     CPPUNIT_ASSERT(f.tag());
85     CPPUNIT_ASSERT(!f.ID3v2Tag()->frameListMap().contains("TENC"));
86   }
87
88   void testReadStringField()
89   {
90     PublicFrame f;
91     ByteVector data("abc\0", 4);
92     String str = f.readStringField(data, String::Latin1);
93     CPPUNIT_ASSERT_EQUAL(String("abc"), str);
94   }
95
96   // http://bugs.kde.org/show_bug.cgi?id=151078
97   void testParseAPIC()
98   {
99     ID3v2::AttachedPictureFrame f(ByteVector("APIC"
100                                              "\x00\x00\x00\x07"
101                                              "\x00\x00"
102                                              "\x00"
103                                              "m\x00"
104                                              "\x01"
105                                              "d\x00"
106                                              "\x00", 17));
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());
110   }
111
112   void testParseAPIC_UTF16_BOM()
113   {
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",
118       16 * 3));
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());
123   }
124
125   // http://bugs.kde.org/show_bug.cgi?id=151078
126   void testParseGEOB()
127   {
128     ID3v2::GeneralEncapsulatedObjectFrame f(ByteVector("GEOB"
129                                              "\x00\x00\x00\x08"
130                                              "\x00\x00"
131                                              "\x00"
132                                              "m\x00"
133                                              "f\x00"
134                                              "d\x00"
135                                              "\x00", 18));
136     CPPUNIT_ASSERT_EQUAL(String("m"), f.mimeType());
137     CPPUNIT_ASSERT_EQUAL(String("f"), f.fileName());
138     CPPUNIT_ASSERT_EQUAL(String("d"), f.description());
139   }
140
141   // http://bugs.kde.org/show_bug.cgi?id=150481
142   void testParseRelativeVolumeFrame()
143   {
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);
160   }
161
162   void testParseUniqueFileIdentifierFrame()
163   {
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"),
171                          f.owner());
172     CPPUNIT_ASSERT_EQUAL(ByteVector("\x00\x01\x02", 3),
173                          f.identifier());
174   }
175
176   void testParseEmptyUniqueFileIdentifierFrame()
177   {
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(),
185                          f.owner());
186     CPPUNIT_ASSERT_EQUAL(ByteVector(),
187                          f.identifier());
188   }
189
190   void testParseUrlLinkFrame()
191   {
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());
198   }
199
200   void testRenderUrlLinkFrame()
201   {
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
209       f.render());
210   }
211
212   void testParseUserUrlLinkFrame()
213   {
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());
223   }
224
225   void testRenderUserUrlLinkFrame()
226   {
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
237       f.render());
238   }
239
240   void testItunes24FrameSize()
241   {
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());
246   }
247
248   void testSaveUTF16Comment()
249   {
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());
254     foo.strip();
255     foo.tag()->setComment("Test comment!");
256     foo.save();
257     MPEG::File bar(newname.c_str());
258     CPPUNIT_ASSERT_EQUAL(String("Test comment!"), bar.tag()->comment());
259     deleteFile(newname);
260     ID3v2::FrameFactory::instance()->setDefaultTextEncoding(defaultEncoding);
261   }
262
263 };
264
265 CPPUNIT_TEST_SUITE_REGISTRATION(TestID3v2);