1 /*************************************************************************** 2 copyright : (C) 2007 by Lukas Lalinsky 3 email : lukas@oxygene.sk 4 ***************************************************************************/ 5 6 /*************************************************************************** 7 * This library is free software; you can redistribute it and/or modify * 8 * it under the terms of the GNU Lesser General Public License version * 9 * 2.1 as published by the Free Software Foundation. * 10 * * 11 * This library is distributed in the hope that it will be useful, but * 12 * WITHOUT ANY WARRANTY; without even the implied warranty of * 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 14 * Lesser General Public License for more details. * 15 * * 16 * You should have received a copy of the GNU Lesser General Public * 17 * License along with this library; if not, write to the Free Software * 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 19 * 02110-1301 USA * 20 * * 21 * Alternatively, this file is available under the Mozilla Public * 22 * License Version 1.1. You may obtain a copy of the License at * 23 * http://www.mozilla.org/MPL/ * 24 ***************************************************************************/ 25 26 #include <string> 27 #include <stdio.h> 28 #include <tag.h> 29 #include <fileref.h> 30 #include <oggflacfile.h> 31 #include <vorbisfile.h> 32 #include <mpegfile.h> 33 #include <mpcfile.h> 34 #include <asffile.h> 35 #include <speexfile.h> 36 #include <flacfile.h> 37 #include <trueaudiofile.h> 38 #include <mp4file.h> 39 #include <wavfile.h> 40 #include <apefile.h> 41 #include <aifffile.h> 42 #include <tfilestream.h> 43 #include <tbytevectorstream.h> 44 #include <cppunit/extensions/HelperMacros.h> 45 #include "utils.h" 46 47 using namespace std; 48 using namespace TagLib; 49 50 namespace 51 { 52 class DummyResolver : public FileRef::FileTypeResolver 53 { 54 public: createFile(FileName fileName,bool,AudioProperties::ReadStyle) const55 virtual File *createFile(FileName fileName, bool, AudioProperties::ReadStyle) const 56 { 57 return new Ogg::Vorbis::File(fileName); 58 } 59 }; 60 } 61 62 class TestFileRef : public CppUnit::TestFixture 63 { 64 CPPUNIT_TEST_SUITE(TestFileRef); 65 CPPUNIT_TEST(testASF); 66 CPPUNIT_TEST(testMusepack); 67 CPPUNIT_TEST(testVorbis); 68 CPPUNIT_TEST(testSpeex); 69 CPPUNIT_TEST(testFLAC); 70 CPPUNIT_TEST(testMP3); 71 CPPUNIT_TEST(testOGA_FLAC); 72 CPPUNIT_TEST(testOGA_Vorbis); 73 CPPUNIT_TEST(testMP4_1); 74 CPPUNIT_TEST(testMP4_2); 75 CPPUNIT_TEST(testMP4_3); 76 CPPUNIT_TEST(testMP4_4); 77 CPPUNIT_TEST(testTrueAudio); 78 CPPUNIT_TEST(testAPE); 79 CPPUNIT_TEST(testWav); 80 CPPUNIT_TEST(testAIFF_1); 81 CPPUNIT_TEST(testAIFF_2); 82 CPPUNIT_TEST(testUnsupported); 83 CPPUNIT_TEST(testCreate); 84 CPPUNIT_TEST(testFileResolver); 85 CPPUNIT_TEST_SUITE_END(); 86 87 public: 88 89 template <typename T> fileRefSave(const string & filename,const string & ext)90 void fileRefSave(const string &filename, const string &ext) 91 { 92 ScopedFileCopy copy(filename, ext); 93 string newname = copy.fileName(); 94 95 { 96 FileRef f(newname.c_str()); 97 CPPUNIT_ASSERT(dynamic_cast<T*>(f.file())); 98 CPPUNIT_ASSERT(!f.isNull()); 99 f.tag()->setArtist("test artist"); 100 f.tag()->setTitle("test title"); 101 f.tag()->setGenre("Test!"); 102 f.tag()->setAlbum("albummmm"); 103 f.tag()->setTrack(5); 104 f.tag()->setYear(2020); 105 f.save(); 106 } 107 { 108 FileRef f(newname.c_str()); 109 CPPUNIT_ASSERT(!f.isNull()); 110 CPPUNIT_ASSERT_EQUAL(f.tag()->artist(), String("test artist")); 111 CPPUNIT_ASSERT_EQUAL(f.tag()->title(), String("test title")); 112 CPPUNIT_ASSERT_EQUAL(f.tag()->genre(), String("Test!")); 113 CPPUNIT_ASSERT_EQUAL(f.tag()->album(), String("albummmm")); 114 CPPUNIT_ASSERT_EQUAL(f.tag()->track(), (unsigned int)5); 115 CPPUNIT_ASSERT_EQUAL(f.tag()->year(), (unsigned int)2020); 116 f.tag()->setArtist("ttest artist"); 117 f.tag()->setTitle("ytest title"); 118 f.tag()->setGenre("uTest!"); 119 f.tag()->setAlbum("ialbummmm"); 120 f.tag()->setTrack(7); 121 f.tag()->setYear(2080); 122 f.save(); 123 } 124 { 125 FileRef f(newname.c_str()); 126 CPPUNIT_ASSERT(!f.isNull()); 127 CPPUNIT_ASSERT_EQUAL(f.tag()->artist(), String("ttest artist")); 128 CPPUNIT_ASSERT_EQUAL(f.tag()->title(), String("ytest title")); 129 CPPUNIT_ASSERT_EQUAL(f.tag()->genre(), String("uTest!")); 130 CPPUNIT_ASSERT_EQUAL(f.tag()->album(), String("ialbummmm")); 131 CPPUNIT_ASSERT_EQUAL(f.tag()->track(), (unsigned int)7); 132 CPPUNIT_ASSERT_EQUAL(f.tag()->year(), (unsigned int)2080); 133 } 134 135 { 136 FileStream fs(newname.c_str()); 137 FileRef f(&fs); 138 CPPUNIT_ASSERT(dynamic_cast<T*>(f.file())); 139 CPPUNIT_ASSERT(!f.isNull()); 140 CPPUNIT_ASSERT_EQUAL(f.tag()->artist(), String("ttest artist")); 141 CPPUNIT_ASSERT_EQUAL(f.tag()->title(), String("ytest title")); 142 CPPUNIT_ASSERT_EQUAL(f.tag()->genre(), String("uTest!")); 143 CPPUNIT_ASSERT_EQUAL(f.tag()->album(), String("ialbummmm")); 144 CPPUNIT_ASSERT_EQUAL(f.tag()->track(), (unsigned int)7); 145 CPPUNIT_ASSERT_EQUAL(f.tag()->year(), (unsigned int)2080); 146 f.tag()->setArtist("test artist"); 147 f.tag()->setTitle("test title"); 148 f.tag()->setGenre("Test!"); 149 f.tag()->setAlbum("albummmm"); 150 f.tag()->setTrack(5); 151 f.tag()->setYear(2020); 152 f.save(); 153 } 154 155 ByteVector fileContent; 156 { 157 FileStream fs(newname.c_str()); 158 FileRef f(&fs); 159 CPPUNIT_ASSERT(dynamic_cast<T*>(f.file())); 160 CPPUNIT_ASSERT(!f.isNull()); 161 CPPUNIT_ASSERT_EQUAL(f.tag()->artist(), String("test artist")); 162 CPPUNIT_ASSERT_EQUAL(f.tag()->title(), String("test title")); 163 CPPUNIT_ASSERT_EQUAL(f.tag()->genre(), String("Test!")); 164 CPPUNIT_ASSERT_EQUAL(f.tag()->album(), String("albummmm")); 165 CPPUNIT_ASSERT_EQUAL(f.tag()->track(), (unsigned int)5); 166 CPPUNIT_ASSERT_EQUAL(f.tag()->year(), (unsigned int)2020); 167 168 fs.seek(0); 169 fileContent = fs.readBlock(fs.length()); 170 } 171 172 { 173 ByteVectorStream bs(fileContent); 174 FileRef f(&bs); 175 CPPUNIT_ASSERT(dynamic_cast<T*>(f.file())); 176 CPPUNIT_ASSERT(!f.isNull()); 177 CPPUNIT_ASSERT_EQUAL(f.tag()->artist(), String("test artist")); 178 CPPUNIT_ASSERT_EQUAL(f.tag()->title(), String("test title")); 179 CPPUNIT_ASSERT_EQUAL(f.tag()->genre(), String("Test!")); 180 CPPUNIT_ASSERT_EQUAL(f.tag()->album(), String("albummmm")); 181 CPPUNIT_ASSERT_EQUAL(f.tag()->track(), (unsigned int)5); 182 CPPUNIT_ASSERT_EQUAL(f.tag()->year(), (unsigned int)2020); 183 f.tag()->setArtist("ttest artist"); 184 f.tag()->setTitle("ytest title"); 185 f.tag()->setGenre("uTest!"); 186 f.tag()->setAlbum("ialbummmm"); 187 f.tag()->setTrack(7); 188 f.tag()->setYear(2080); 189 f.save(); 190 191 fileContent = *bs.data(); 192 } 193 { 194 ByteVectorStream bs(fileContent); 195 FileRef f(&bs); 196 CPPUNIT_ASSERT(dynamic_cast<T*>(f.file())); 197 CPPUNIT_ASSERT(!f.isNull()); 198 CPPUNIT_ASSERT_EQUAL(f.tag()->artist(), String("ttest artist")); 199 CPPUNIT_ASSERT_EQUAL(f.tag()->title(), String("ytest title")); 200 CPPUNIT_ASSERT_EQUAL(f.tag()->genre(), String("uTest!")); 201 CPPUNIT_ASSERT_EQUAL(f.tag()->album(), String("ialbummmm")); 202 CPPUNIT_ASSERT_EQUAL(f.tag()->track(), (unsigned int)7); 203 CPPUNIT_ASSERT_EQUAL(f.tag()->year(), (unsigned int)2080); 204 } 205 } 206 testMusepack()207 void testMusepack() 208 { 209 fileRefSave<MPC::File>("click", ".mpc"); 210 } 211 testASF()212 void testASF() 213 { 214 fileRefSave<ASF::File>("silence-1", ".wma"); 215 } 216 testVorbis()217 void testVorbis() 218 { 219 fileRefSave<Ogg::Vorbis::File>("empty", ".ogg"); 220 } 221 testSpeex()222 void testSpeex() 223 { 224 fileRefSave<Ogg::Speex::File>("empty", ".spx"); 225 } 226 testFLAC()227 void testFLAC() 228 { 229 fileRefSave<FLAC::File>("no-tags", ".flac"); 230 } 231 testMP3()232 void testMP3() 233 { 234 fileRefSave<MPEG::File>("xing", ".mp3"); 235 } 236 testTrueAudio()237 void testTrueAudio() 238 { 239 fileRefSave<TrueAudio::File>("empty", ".tta"); 240 } 241 testMP4_1()242 void testMP4_1() 243 { 244 fileRefSave<MP4::File>("has-tags", ".m4a"); 245 } 246 testMP4_2()247 void testMP4_2() 248 { 249 fileRefSave<MP4::File>("no-tags", ".m4a"); 250 } 251 testMP4_3()252 void testMP4_3() 253 { 254 fileRefSave<MP4::File>("no-tags", ".3g2"); 255 } 256 testMP4_4()257 void testMP4_4() 258 { 259 fileRefSave<MP4::File>("blank_video", ".m4v"); 260 } 261 testWav()262 void testWav() 263 { 264 fileRefSave<RIFF::WAV::File>("empty", ".wav"); 265 } 266 testOGA_FLAC()267 void testOGA_FLAC() 268 { 269 fileRefSave<Ogg::FLAC::File>("empty_flac", ".oga"); 270 } 271 testOGA_Vorbis()272 void testOGA_Vorbis() 273 { 274 fileRefSave<Ogg::Vorbis::File>("empty_vorbis", ".oga"); 275 } 276 testAPE()277 void testAPE() 278 { 279 fileRefSave<APE::File>("mac-399", ".ape"); 280 } 281 testAIFF_1()282 void testAIFF_1() 283 { 284 fileRefSave<RIFF::AIFF::File>("empty", ".aiff"); 285 } 286 testAIFF_2()287 void testAIFF_2() 288 { 289 fileRefSave<RIFF::AIFF::File>("alaw", ".aifc"); 290 } 291 testUnsupported()292 void testUnsupported() 293 { 294 FileRef f1(TEST_FILE_PATH_C("no-extension")); 295 CPPUNIT_ASSERT(f1.isNull()); 296 297 FileRef f2(TEST_FILE_PATH_C("unsupported-extension.xx")); 298 CPPUNIT_ASSERT(f2.isNull()); 299 } 300 testCreate()301 void testCreate() 302 { 303 // This is deprecated. But worth it to test. 304 305 File *f = FileRef::create(TEST_FILE_PATH_C("empty_vorbis.oga")); 306 CPPUNIT_ASSERT(dynamic_cast<Ogg::Vorbis::File*>(f)); 307 delete f; 308 309 f = FileRef::create(TEST_FILE_PATH_C("xing.mp3")); 310 CPPUNIT_ASSERT(dynamic_cast<MPEG::File*>(f)); 311 delete f; 312 } 313 testFileResolver()314 void testFileResolver() 315 { 316 { 317 FileRef f(TEST_FILE_PATH_C("xing.mp3")); 318 CPPUNIT_ASSERT(dynamic_cast<MPEG::File *>(f.file()) != NULL); 319 } 320 321 DummyResolver resolver; 322 FileRef::addFileTypeResolver(&resolver); 323 324 { 325 FileRef f(TEST_FILE_PATH_C("xing.mp3")); 326 CPPUNIT_ASSERT(dynamic_cast<Ogg::Vorbis::File *>(f.file()) != NULL); 327 } 328 } 329 330 }; 331 332 CPPUNIT_TEST_SUITE_REGISTRATION(TestFileRef); 333