Add a CppUnit-based test suite (only very few things is covered for now, but it's a start).

git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@734995 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
This commit is contained in:
Lukáš Lalinský 2007-11-10 16:46:04 +00:00
parent 2302f65964
commit db0be6b8c6
26 changed files with 811 additions and 270 deletions

View File

@ -14,7 +14,7 @@ set(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE
if (CMAKE_COMPILER_IS_GNUCXX)
if (CMAKE_SYSTEM_NAME MATCHES Linux)
set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-long-long -ansi -Wundef -Wcast-align -Werror-implicit-function-declaration -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -Wmissing-format-attribute -fno-common")
set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -fno-exceptions -fno-check-new -fno-common")
set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -fno-check-new -fno-common")
endif (CMAKE_SYSTEM_NAME MATCHES Linux)
endif (CMAKE_COMPILER_IS_GNUCXX)
if(MSVC)

View File

@ -19,3 +19,6 @@ IF(ZLIB_FOUND)
ELSE(ZLIB_FOUND)
SET(HAVE_ZLIB 0)
ENDIF(ZLIB_FOUND)
SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules)
FIND_PACKAGE(CppUnit)

View File

@ -0,0 +1,28 @@
INCLUDE(UsePkgConfig)
PKGCONFIG(cppunit _CppUnitIncDir _CppUnitLinkDir _CppUnitLinkFlags _CppUnitCflags)
FIND_PATH(CPPUNIT_INCLUDE_DIR cppunit/TestCase.h
${_CppUnitIncDir}
/usr/local/include
/usr/include
)
FIND_LIBRARY(CPPUNIT_LIBRARIES cppunit
${_CppUnitLinkDir}
/usr/local/lib
/usr/lib
)
IF (CPPUNIT_INCLUDE_DIR AND CPPUNIT_LIBRARIES)
SET(CPPUNIT_FOUND TRUE)
ENDIF (CPPUNIT_INCLUDE_DIR AND CPPUNIT_LIBRARIES)
IF (CPPUNIT_FOUND)
IF (NOT CppUnit_FIND_QUIETLY)
MESSAGE(STATUS "Found CppUnit: ${CPPUNIT_LIBRARIES}")
ENDIF (NOT CppUnit_FIND_QUIETLY)
ELSE (CPPUNIT_FOUND)
IF (CppUnit_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find CppUnit")
ENDIF (CppUnit_FIND_REQUIRED)
ENDIF (CPPUNIT_FOUND)

View File

@ -63,7 +63,7 @@ AC_CHECK_COMPILERS
dnl CXXFLAGS="$NOOPT_CXXFLAGS" dnl __kdevelop[noopt]__
dnl CFLAGS="$NOOPT_CFLAGS" dnl __kdevelop[noopt]__
dnl CXXFLAGS="$CXXFLAGS $USE_EXCEPTIONS" dnl __kdevelop[exc]__
CXXFLAGS="$CXXFLAGS $USE_EXCEPTIONS" dnl __kdevelop[exc]__
dnl create only shared libtool-libraries
AC_ENABLE_SHARED(yes)
@ -113,3 +113,21 @@ AC_DEFUN([AC_NO_ZLIB],
AC_CHECK_HEADER(zlib.h, AC_HAVE_ZLIB, AC_NO_ZLIB)
AM_CONDITIONAL(link_zlib, test x$have_zlib = xtrue)
AC_DEFUN([AC_HAVE_CPPUNIT],
[
AC_DEFINE(HAVE_CPPUNIT, 1, [have cppunit])
have_cppunit=true
])
AC_DEFUN([AC_NO_CPPUNIT],
[
AC_DEFINE(HAVE_CPPUNIT, 0, [have cppunit])
have_cppunit=false
])
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_CHECK_HEADER(cppunit/extensions/HelperMacros.h, AC_HAVE_CPPUNIT, AC_NO_CPPUNIT)
AC_LANG_RESTORE
AM_CONDITIONAL(build_tests, test x$have_cppunit = xtrue)

View File

@ -1,4 +1,4 @@
SUBDIRS = toolkit mpeg ogg flac ape mpc wavpack
SUBDIRS = toolkit mpeg ogg flac ape mpc wavpack speex
INCLUDES = \
-I$(top_srcdir)/taglib \

View File

@ -1,5 +1,6 @@
INCLUDES = \
-I$(top_srcdir)/taglib \
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/ogg \
$(all_includes)

View File

@ -1,16 +1,32 @@
if(BUILD_TESTS)
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/../taglib
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/toolkit
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpeg/id3v2 )
########### next target ###############
SET(toolkit-test_SRCS
toolkit-test.cpp
INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}/../taglib
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/toolkit
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpeg/id3v1
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpeg/id3v2
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpeg/id3v2/frames
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpeg
)
ADD_EXECUTABLE(toolkit-test ${toolkit-test_SRCS})
SET(test_runner_SRCS
main.cpp
test_list.cpp
test_map.cpp
test_synchdata.cpp
test_bytevector.cpp
test_string.cpp
test_fileref.cpp
test_id3v1.cpp
test_id3v2.cpp
)
ADD_EXECUTABLE(test_runner ${test_runner_SRCS})
TARGET_LINK_LIBRARIES(test_runner tag ${CPPUNIT_LIBRARIES})
ADD_CUSTOM_TARGET(check
./test_runner
DEPENDS test_runner
)
TARGET_LINK_LIBRARIES(toolkit-test tag )
endif(BUILD_TESTS)

View File

@ -1,10 +1,24 @@
INCLUDES = \
-I$(top_srcdir)/taglib\
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/mpeg/id3v2
-I$(top_srcdir)/taglib/mpeg \
-I$(top_srcdir)/taglib/mpeg/id3v1 \
-I$(top_srcdir)/taglib/mpeg/id3v2 \
-I$(top_srcdir)/taglib/mpeg/id3v2/frames
LDADD = ../taglib/libtag.la
test_runner_SOURCES = \
main.cpp \
test_list.cpp \
test_map.cpp \
test_synchdata.cpp \
test_bytevector.cpp \
test_string.cpp \
test_fileref.cpp \
test_id3v1.cpp \
test_id3v2.cpp
check_PROGRAMS = toolkit-test
toolkit_test_SOURCES = toolkit-test.cpp
if build_tests
TESTS = test_runner
check_PROGRAMS = test_runner
LDADD = ../taglib/libtag.la -lcppunit
endif

BIN
tests/data/broken-tenc.id3 Normal file

Binary file not shown.

BIN
tests/data/click.mpc Normal file

Binary file not shown.

BIN
tests/data/empty.ogg Normal file

Binary file not shown.

BIN
tests/data/empty.spx Normal file

Binary file not shown.

BIN
tests/data/no-tags.flac Normal file

Binary file not shown.

BIN
tests/data/unsynch.id3 Normal file

Binary file not shown.

BIN
tests/data/xing.mp3 Normal file

Binary file not shown.

46
tests/main.cpp Normal file
View File

@ -0,0 +1,46 @@
#include <stdexcept>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/TestRunner.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/BriefTestProgressListener.h>
#include <cppunit/CompilerOutputter.h>
int main(int argc, char* argv[])
{
std::string testPath = (argc > 1) ? std::string(argv[1]) : "";
// Create the event manager and test controller
CppUnit::TestResult controller;
// Add a listener that colllects test result
CppUnit::TestResultCollector result;
controller.addListener(&result);
// Add a listener that print dots as test run.
CppUnit::BriefTestProgressListener progress;
controller.addListener(&progress);
// Add the top suite to the test runner
CppUnit::TestRunner runner;
runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
try {
std::cout << "Running " << testPath;
runner.run(controller, testPath);
std::cerr << std::endl;
// Print test in a compiler compatible format.
CppUnit::CompilerOutputter outputter(&result, std::cerr);
outputter.write();
}
catch(std::invalid_argument &e){
std::cerr << std::endl
<< "ERROR: " << e.what()
<< std::endl;
return 0;
}
return result.wasSuccessful() ? 0 : 1;
}

169
tests/test_bytevector.cpp Normal file
View File

@ -0,0 +1,169 @@
/* Copyright (C) 2003 Scott Wheeler <wheeler@kde.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cppunit/extensions/HelperMacros.h>
#include <tbytevector.h>
#include <tbytevectorlist.h>
using namespace std;
using namespace TagLib;
class TestByteVector : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(TestByteVector);
CPPUNIT_TEST(testByteVector);
CPPUNIT_TEST(testFind1);
CPPUNIT_TEST(testRfind1);
CPPUNIT_TEST(testRfind2);
CPPUNIT_TEST_SUITE_END();
public:
void testConversion(unsigned int i, unsigned char a, unsigned char b, unsigned char c, unsigned char d)
{
ByteVector v(4, 0);
v[3] = a;
v[2] = b;
v[1] = c;
v[0] = d;
CPPUNIT_ASSERT(v.toUInt(false) == i);
v[0] = a;
v[1] = b;
v[2] = c;
v[3] = d;
CPPUNIT_ASSERT(v.toUInt() == i);
}
void testByteVector()
{
ByteVector v("foobar");
CPPUNIT_ASSERT(v.find("ob") == 2);
CPPUNIT_ASSERT(v.find('b') == 3);
ByteVector n(4, 0);
n[0] = 1;
CPPUNIT_ASSERT(n.toUInt(true) == 16777216);
CPPUNIT_ASSERT(n.toUInt(false) == 1);
CPPUNIT_ASSERT(ByteVector::fromUInt(16777216, true) == n);
CPPUNIT_ASSERT(ByteVector::fromUInt(1, false) == n);
CPPUNIT_ASSERT(ByteVector::fromUInt(0xa0).toUInt() == 0xa0);
testConversion(0x000000a0, 0x00, 0x00, 0x00, 0xa0);
testConversion(0xd50bf072, 0xd5, 0x0b, 0xf0, 0x72);
ByteVector intVector(2, 0);
intVector[0] = char(0xfc);
intVector[1] = char(0x00);
CPPUNIT_ASSERT(intVector.toShort() == -1024);
intVector[0] = char(0x04);
intVector[1] = char(0x00);
CPPUNIT_ASSERT(intVector.toShort() == 1024);
CPPUNIT_ASSERT(ByteVector::fromLongLong(1).toLongLong() == 1);
CPPUNIT_ASSERT(ByteVector::fromLongLong(0).toLongLong() == 0);
CPPUNIT_ASSERT(ByteVector::fromLongLong(0xffffffffffffffffLL).toLongLong() == -1);
CPPUNIT_ASSERT(ByteVector::fromLongLong(0xfffffffffffffffeLL).toLongLong() == -2);
CPPUNIT_ASSERT(ByteVector::fromLongLong(1024).toLongLong() == 1024);
ByteVector a1("foo");
a1.append("bar");
CPPUNIT_ASSERT(a1 == "foobar");
ByteVector a2("foo");
a2.append("b");
CPPUNIT_ASSERT(a2 == "foob");
ByteVector a3;
a3.append("b");
CPPUNIT_ASSERT(a3 == "b");
ByteVector s1("foo");
CPPUNIT_ASSERT(ByteVectorList::split(s1, " ").size() == 1);
ByteVector s2("f");
CPPUNIT_ASSERT(ByteVectorList::split(s2, " ").size() == 1);
CPPUNIT_ASSERT(ByteVector().size() == 0);
CPPUNIT_ASSERT(ByteVector("asdf").clear().size() == 0);
CPPUNIT_ASSERT(ByteVector("asdf").clear() == ByteVector());
}
void testFind1()
{
CPPUNIT_ASSERT_EQUAL(4, ByteVector("....SggO."). find("SggO"));
CPPUNIT_ASSERT_EQUAL(4, ByteVector("....SggO."). find("SggO", 0));
CPPUNIT_ASSERT_EQUAL(4, ByteVector("....SggO."). find("SggO", 1));
CPPUNIT_ASSERT_EQUAL(4, ByteVector("....SggO."). find("SggO", 2));
CPPUNIT_ASSERT_EQUAL(4, ByteVector("....SggO."). find("SggO", 3));
CPPUNIT_ASSERT_EQUAL(4, ByteVector("....SggO."). find("SggO", 4));
CPPUNIT_ASSERT_EQUAL(-1, ByteVector("....SggO."). find("SggO", 5));
CPPUNIT_ASSERT_EQUAL(-1, ByteVector("....SggO."). find("SggO", 6));
CPPUNIT_ASSERT_EQUAL(-1, ByteVector("....SggO."). find("SggO", 7));
CPPUNIT_ASSERT_EQUAL(-1, ByteVector("....SggO."). find("SggO", 8));
}
void testRfind1()
{
CPPUNIT_ASSERT_EQUAL(-1, ByteVector(".OggS....").rfind("OggS", 0));
CPPUNIT_ASSERT_EQUAL(1, ByteVector(".OggS....").rfind("OggS", 1));
CPPUNIT_ASSERT_EQUAL(1, ByteVector(".OggS....").rfind("OggS", 2));
CPPUNIT_ASSERT_EQUAL(1, ByteVector(".OggS....").rfind("OggS", 3));
CPPUNIT_ASSERT_EQUAL(1, ByteVector(".OggS....").rfind("OggS", 4));
CPPUNIT_ASSERT_EQUAL(1, ByteVector(".OggS....").rfind("OggS", 5));
CPPUNIT_ASSERT_EQUAL(1, ByteVector(".OggS....").rfind("OggS", 6));
CPPUNIT_ASSERT_EQUAL(1, ByteVector(".OggS....").rfind("OggS", 7));
CPPUNIT_ASSERT_EQUAL(1, ByteVector(".OggS....").rfind("OggS", 8));
CPPUNIT_ASSERT_EQUAL(1, ByteVector(".OggS....").rfind("OggS"));
}
void testRfind2()
{
ByteVector r0("**************");
ByteVector r1("OggS**********");
ByteVector r2("**********OggS");
ByteVector r3("OggS******OggS");
ByteVector r4("OggS*OggS*OggS");
CPPUNIT_ASSERT_EQUAL(-1, r0.find("OggS"));
CPPUNIT_ASSERT_EQUAL(-1, r0.rfind("OggS"));
CPPUNIT_ASSERT_EQUAL(0, r1.find("OggS"));
CPPUNIT_ASSERT_EQUAL(0, r1.rfind("OggS"));
CPPUNIT_ASSERT_EQUAL(10, r2.find("OggS"));
CPPUNIT_ASSERT_EQUAL(10, r2.rfind("OggS"));
CPPUNIT_ASSERT_EQUAL(0, r3.find("OggS"));
CPPUNIT_ASSERT_EQUAL(10, r3.rfind("OggS"));
CPPUNIT_ASSERT_EQUAL(10, r4.rfind("OggS"));
CPPUNIT_ASSERT_EQUAL(0, r4.rfind("OggS", 0));
CPPUNIT_ASSERT_EQUAL(5, r4.rfind("OggS", 7));
CPPUNIT_ASSERT_EQUAL(10, r4.rfind("OggS", 12));
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestByteVector);

95
tests/test_fileref.cpp Normal file
View File

@ -0,0 +1,95 @@
#include <cppunit/extensions/HelperMacros.h>
#include <string>
#include <stdio.h>
#include <tag.h>
#include <fileref.h>
#include "utils.h"
using namespace std;
using namespace TagLib;
class TestFileRef : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(TestFileRef);
CPPUNIT_TEST(testMusepack);
CPPUNIT_TEST(testVorbis);
CPPUNIT_TEST(testSpeex);
CPPUNIT_TEST(testFLAC);
CPPUNIT_TEST(testMP3);
CPPUNIT_TEST_SUITE_END();
public:
void fileRefSave(const string &filename, const string &ext)
{
string newname = copyFile(filename, ext);
FileRef *f = new FileRef(newname.c_str());
CPPUNIT_ASSERT(!f->isNull());
f->tag()->setArtist("test artist");
f->tag()->setTitle("test title");
f->tag()->setGenre("Test!");
f->tag()->setAlbum("albummmm");
f->tag()->setTrack(5);
f->tag()->setYear(2020);
f->save();
delete f;
f = new FileRef(newname.c_str());
CPPUNIT_ASSERT(!f->isNull());
CPPUNIT_ASSERT_EQUAL(f->tag()->artist(), String("test artist"));
CPPUNIT_ASSERT_EQUAL(f->tag()->title(), String("test title"));
CPPUNIT_ASSERT_EQUAL(f->tag()->genre(), String("Test!"));
CPPUNIT_ASSERT_EQUAL(f->tag()->album(), String("albummmm"));
CPPUNIT_ASSERT_EQUAL(f->tag()->track(), TagLib::uint(5));
CPPUNIT_ASSERT_EQUAL(f->tag()->year(), TagLib::uint(2020));
f->tag()->setArtist("ttest artist");
f->tag()->setTitle("ytest title");
f->tag()->setGenre("uTest!");
f->tag()->setAlbum("ialbummmm");
f->tag()->setTrack(7);
f->tag()->setYear(2080);
f->save();
delete f;
f = new FileRef(newname.c_str());
CPPUNIT_ASSERT(!f->isNull());
CPPUNIT_ASSERT_EQUAL(f->tag()->artist(), String("ttest artist"));
CPPUNIT_ASSERT_EQUAL(f->tag()->title(), String("ytest title"));
CPPUNIT_ASSERT_EQUAL(f->tag()->genre(), String("uTest!"));
CPPUNIT_ASSERT_EQUAL(f->tag()->album(), String("ialbummmm"));
CPPUNIT_ASSERT_EQUAL(f->tag()->track(), TagLib::uint(7));
CPPUNIT_ASSERT_EQUAL(f->tag()->year(), TagLib::uint(2080));
delete f;
deleteFile(newname);
}
void testMusepack()
{
fileRefSave("click", ".mpc");
}
void testVorbis()
{
fileRefSave("empty", ".ogg");
}
void testSpeex()
{
fileRefSave("empty", ".spx");
}
void testFLAC()
{
fileRefSave("no-tags", ".flac");
}
void testMP3()
{
fileRefSave("xing", ".mp3");
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestFileRef);

25
tests/test_id3v1.cpp Normal file
View File

@ -0,0 +1,25 @@
#include <cppunit/extensions/HelperMacros.h>
#include <string>
#include <stdio.h>
#include <id3v1tag.h>
using namespace std;
using namespace TagLib;
class TestID3v1 : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(TestID3v1);
CPPUNIT_TEST(testStripWhiteSpace);
CPPUNIT_TEST_SUITE_END();
public:
void testStripWhiteSpace()
{
ID3v1::StringHandler h;
CPPUNIT_ASSERT_EQUAL(String("Foo"), h.parse(ByteVector("Foo ")));
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestID3v1);

67
tests/test_id3v2.cpp Normal file
View File

@ -0,0 +1,67 @@
#include <cppunit/extensions/HelperMacros.h>
#include <string>
#include <stdio.h>
#include <id3v2tag.h>
#include <mpegfile.h>
#include <textidentificationframe.h>
using namespace std;
using namespace TagLib;
class TestID3v2 : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(TestID3v2);
CPPUNIT_TEST(testUnsynchDecode);
CPPUNIT_TEST(testUTF16BEDelimiter);
CPPUNIT_TEST(testUTF16Delimiter);
CPPUNIT_TEST(testBrokenFrame1);
//CPPUNIT_TEST(testItunes24FrameSize);
CPPUNIT_TEST_SUITE_END();
public:
void testUnsynchDecode()
{
MPEG::File f("data/unsynch.id3", false);
CPPUNIT_ASSERT(f.tag());
CPPUNIT_ASSERT_EQUAL(String("My babe just cares for me"), f.tag()->title());
}
void testUTF16BEDelimiter()
{
ID3v2::TextIdentificationFrame f(ByteVector("TPE1"), String::UTF16BE);
StringList sl;
sl.append("Foo");
sl.append("Bar");
f.setText(sl);
CPPUNIT_ASSERT_EQUAL((unsigned int)(4+4+2+1+6+2+6), f.render().size());
}
void testUTF16Delimiter()
{
ID3v2::TextIdentificationFrame f(ByteVector("TPE1"), String::UTF16);
StringList sl;
sl.append("Foo");
sl.append("Bar");
f.setText(sl);
CPPUNIT_ASSERT_EQUAL((unsigned int)(4+4+2+1+8+2+8), f.render().size());
}
void testBrokenFrame1()
{
MPEG::File f("data/broken-tenc.id3", false);
CPPUNIT_ASSERT(f.tag());
CPPUNIT_ASSERT(!f.ID3v2Tag()->frameListMap().contains("TENC"));
}
/*void testItunes24FrameSize()
{
MPEG::File f("data/005411.id3", false);
CPPUNIT_ASSERT(f.tag());
CPPUNIT_ASSERT(f.ID3v2Tag()->frameListMap().contains("TIT2"));
CPPUNIT_ASSERT_EQUAL(String("Sunshine Superman"), f.ID3v2Tag()->frameListMap()["TIT2"].front()->toString());
}*/
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestID3v2);

58
tests/test_list.cpp Normal file
View File

@ -0,0 +1,58 @@
/* Copyright (C) 2003 Scott Wheeler <wheeler@kde.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cppunit/extensions/HelperMacros.h>
#include <tlist.h>
using namespace std;
using namespace TagLib;
class TestList : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(TestList);
CPPUNIT_TEST(testList);
CPPUNIT_TEST_SUITE_END();
public:
void testList()
{
List<int> l1;
List<int> l2;
List<int> l3;
l1.append(2);
l2.append(3);
l2.append(4);
l1.append(l2);
l1.prepend(1);
l3.append(1);
l3.append(2);
l3.append(3);
l3.append(4);
CPPUNIT_ASSERT(l1 == l3);
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestList);

27
tests/test_map.cpp Normal file
View File

@ -0,0 +1,27 @@
#include <cppunit/extensions/HelperMacros.h>
#include <tstring.h>
#include <tmap.h>
using namespace std;
using namespace TagLib;
class TestMap : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(TestMap);
CPPUNIT_TEST(testInsert);
CPPUNIT_TEST_SUITE_END();
public:
void testInsert()
{
Map<String, int> m;
m.insert("foo", 3);
CPPUNIT_ASSERT_EQUAL(3, m["foo"]);
m.insert("foo", 7);
CPPUNIT_ASSERT_EQUAL(7, m["foo"]);
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestMap);

113
tests/test_string.cpp Normal file
View File

@ -0,0 +1,113 @@
/* Copyright (C) 2003 Scott Wheeler <wheeler@kde.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cppunit/extensions/HelperMacros.h>
#include <tstring.h>
using namespace std;
using namespace TagLib;
class TestString : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(TestString);
CPPUNIT_TEST(testString);
CPPUNIT_TEST(testUTF16Encode);
CPPUNIT_TEST(testUTF16Decode);
CPPUNIT_TEST_SUITE_END();
public:
void testString()
{
String s = "taglib string";
ByteVector v = "taglib string";
CPPUNIT_ASSERT(v == s.data(String::Latin1));
char str[] = "taglib string";
CPPUNIT_ASSERT(strcmp(s.toCString(), str) == 0);
String unicode("José Carlos", String::UTF8);
CPPUNIT_ASSERT(strcmp(unicode.toCString(), "Jos\xe9 Carlos") == 0);
String latin = "Jos\xe9 Carlos";
CPPUNIT_ASSERT(strcmp(latin.toCString(true), "José Carlos") == 0);
String unicode2(unicode.to8Bit(true), String::UTF8);
CPPUNIT_ASSERT(unicode == unicode2);
CPPUNIT_ASSERT(strcmp(String::number(0).toCString(), "0") == 0);
CPPUNIT_ASSERT(strcmp(String::number(12345678).toCString(), "12345678") == 0);
CPPUNIT_ASSERT(strcmp(String::number(-12345678).toCString(), "-12345678") == 0);
String n = "123";
CPPUNIT_ASSERT(n.toInt() == 123);
n = "-123";
CPPUNIT_ASSERT(n.toInt() == -123);
CPPUNIT_ASSERT(String("0").toInt() == 0);
CPPUNIT_ASSERT(String("1").toInt() == 1);
CPPUNIT_ASSERT(String(" foo ").stripWhiteSpace() == String("foo"));
CPPUNIT_ASSERT(String("foo ").stripWhiteSpace() == String("foo"));
CPPUNIT_ASSERT(String(" foo").stripWhiteSpace() == String("foo"));
CPPUNIT_ASSERT(memcmp(String("foo").data(String::Latin1).data(), "foo", 3) == 0);
CPPUNIT_ASSERT(memcmp(String("f").data(String::Latin1).data(), "f", 1) == 0);
ByteVector utf16 = unicode.data(String::UTF16);
// Check to make sure that the BOM is there and that the data size is correct
CPPUNIT_ASSERT(utf16.size() == 2 + (unicode.size() * 2));
CPPUNIT_ASSERT(unicode == String(utf16, String::UTF16));
}
void testUTF16Encode()
{
String a("foo");
ByteVector b("\0f\0o\0o", 6);
ByteVector c("f\0o\0o\0", 6);
ByteVector d("\377\376f\0o\0o\0", 8);
CPPUNIT_ASSERT(a.data(String::UTF16BE) != a.data(String::UTF16LE));
CPPUNIT_ASSERT(b == a.data(String::UTF16BE));
CPPUNIT_ASSERT(c == a.data(String::UTF16LE));
CPPUNIT_ASSERT_EQUAL(d, a.data(String::UTF16));
}
void testUTF16Decode()
{
String a("foo");
ByteVector b("\0f\0o\0o", 6);
ByteVector c("f\0o\0o\0", 6);
ByteVector d("\377\376f\0o\0o\0", 8);
CPPUNIT_ASSERT_EQUAL(a, String(b, String::UTF16BE));
CPPUNIT_ASSERT_EQUAL(a, String(c, String::UTF16LE));
CPPUNIT_ASSERT_EQUAL(a, String(d, String::UTF16));
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestString);

88
tests/test_synchdata.cpp Normal file
View File

@ -0,0 +1,88 @@
/* Copyright (C) 2003 Scott Wheeler <wheeler@kde.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cppunit/extensions/HelperMacros.h>
#include <id3v2synchdata.h>
using namespace std;
using namespace TagLib;
class TestID3v2SynchData : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(TestID3v2SynchData);
CPPUNIT_TEST(test1);
CPPUNIT_TEST(test2);
CPPUNIT_TEST(test3);
CPPUNIT_TEST(testDecode1);
CPPUNIT_TEST(testDecode2);
CPPUNIT_TEST_SUITE_END();
public:
void test1()
{
char data[] = { 0, 0, 0, 127 };
ByteVector v(data, 4);
CPPUNIT_ASSERT_EQUAL(ID3v2::SynchData::toUInt(v), TagLib::uint(127));
CPPUNIT_ASSERT_EQUAL(ID3v2::SynchData::fromUInt(127), v);
}
void test2()
{
char data[] = { 0, 0, 1, 0 };
ByteVector v(data, 4);
CPPUNIT_ASSERT_EQUAL(ID3v2::SynchData::toUInt(v), TagLib::uint(128));
CPPUNIT_ASSERT_EQUAL(ID3v2::SynchData::fromUInt(128), v);
}
void test3()
{
char data[] = { 0, 0, 1, 1 };
ByteVector v(data, 4);
CPPUNIT_ASSERT_EQUAL(ID3v2::SynchData::toUInt(v), TagLib::uint(129));
CPPUNIT_ASSERT_EQUAL(ID3v2::SynchData::fromUInt(129), v);
}
void testDecode1()
{
ByteVector a("\xff\x00\x00", 3);
ID3v2::SynchData::decode(a);
CPPUNIT_ASSERT_EQUAL((unsigned int)2, a.size());
CPPUNIT_ASSERT_EQUAL(ByteVector("\xff\x00", 2), a);
}
void testDecode2()
{
ByteVector a("\xff\x44", 2);
ID3v2::SynchData::decode(a);
CPPUNIT_ASSERT_EQUAL((unsigned int)2, a.size());
CPPUNIT_ASSERT_EQUAL(ByteVector("\xff\x44", 2), a);
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestID3v2SynchData);

View File

@ -1,252 +0,0 @@
/* Copyright (C) 2003 Scott Wheeler <wheeler@kde.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <iostream>
#include <string.h>
#include <tbytevector.h>
#include <tbytevectorlist.h>
#include <tstring.h>
#include <tlist.h>
#include <tdebug.h>
#include <id3v2synchdata.h>
using namespace TagLib;
using namespace std;
void testString();
void testByteVector();
void testSynchData();
void testList();
static int resultCount = 1;
int main()
{
testString();
resultCount = 1;
testByteVector();
resultCount = 1;
testSynchData();
resultCount = 1;
testList();
return 0;
}
void printResult(bool result)
{
if(result)
cout << "(" << resultCount << ")\tpass" << endl;
else
cout << "(" << resultCount << ")\tFAIL" << endl;
resultCount++;
}
void testString()
{
cout << "*** Testing TagLib::String ***" << endl;
String s = "taglib string";
ByteVector v = "taglib string";
printResult(v == s.data(String::Latin1));
char str[] = "taglib string";
printResult(strcmp(s.toCString(), str) == 0);
String unicode("José Carlos", String::UTF8);
printResult(strcmp(unicode.toCString(), "José Carlos") == 0);
String latin = "José Carlos";
printResult(strcmp(latin.toCString(true), "José Carlos") == 0);
String unicode2(unicode.to8Bit(true), String::UTF8);
printResult(unicode == unicode2);
printResult(strcmp(String::number(0).toCString(), "0") == 0);
printResult(strcmp(String::number(12345678).toCString(), "12345678") == 0);
printResult(strcmp(String::number(-12345678).toCString(), "-12345678") == 0);
String n = "123";
printResult(n.toInt() == 123);
n = "-123";
printResult(n.toInt() == -123);
printResult(String("0").toInt() == 0);
printResult(String("1").toInt() == 1);
printResult(String(" foo ").stripWhiteSpace() == String("foo"));
printResult(String("foo ").stripWhiteSpace() == String("foo"));
printResult(String(" foo").stripWhiteSpace() == String("foo"));
printResult(memcmp(String("foo").data(String::Latin1).data(), "foo", 3) == 0);
printResult(memcmp(String("f").data(String::Latin1).data(), "f", 1) == 0);
ByteVector utf16 = unicode.data(String::UTF16);
// Check to make sure that the BOM is there and that the data size is correct
printResult(utf16.size() == 2 + (unicode.size() * 2));
printResult(unicode == String(utf16, String::UTF16));
}
void testConversion(unsigned int i, unsigned char a, unsigned char b, unsigned char c, unsigned char d)
{
ByteVector v(4, 0);
v[3] = a;
v[2] = b;
v[1] = c;
v[0] = d;
printResult(v.toUInt(false) == i);
v[0] = a;
v[1] = b;
v[2] = c;
v[3] = d;
printResult(v.toUInt() == i);
}
void testByteVector()
{
cout << "*** Testing TagLib::ByteVector ***" << endl;
ByteVector v("foobar");
printResult(v.find("ob") == 2);
printResult(v.find('b') == 3);
ByteVector n(4, 0);
n[0] = 1;
printResult(n.toUInt(true) == 16777216);
printResult(n.toUInt(false) == 1);
printResult(ByteVector::fromUInt(16777216, true) == n);
printResult(ByteVector::fromUInt(1, false) == n);
printResult(ByteVector::fromUInt(0xa0).toUInt() == 0xa0);
testConversion(0x000000a0, 0x00, 0x00, 0x00, 0xa0);
testConversion(0xd50bf072, 0xd5, 0x0b, 0xf0, 0x72);
ByteVector intVector(2, 0);
intVector[0] = char(0xfc);
intVector[1] = char(0x00);
printResult(intVector.toShort() == -1024);
intVector[0] = char(0x04);
intVector[1] = char(0x00);
printResult(intVector.toShort() == 1024);
ByteVector r0("**************");
ByteVector r1("OggS**********");
ByteVector r2("**********OggS");
ByteVector r3("OggS******OggS");
ByteVector r4("OggS*OggS*OggS");
printResult(r0.find("OggS") == -1);
printResult(r0.rfind("OggS") == -1);
printResult(r1.find("OggS") == r1.rfind("OggS"));
printResult(r2.find("OggS") == r2.rfind("OggS"));
printResult(r3.find("OggS") == 0);
printResult(r3.rfind("OggS") == 10);
printResult(r4.rfind("OggS") == 10);
printResult(r4.rfind("OggS", 12) == 5);
printResult(ByteVector::fromLongLong(1).toLongLong() == 1);
printResult(ByteVector::fromLongLong(0).toLongLong() == 0);
printResult(ByteVector::fromLongLong(0xffffffffffffffffLL).toLongLong() == -1);
printResult(ByteVector::fromLongLong(0xfffffffffffffffeLL).toLongLong() == -2);
printResult(ByteVector::fromLongLong(1024).toLongLong() == 1024);
ByteVector a1("foo");
a1.append("bar");
printResult(a1 == "foobar");
ByteVector a2("foo");
a2.append("b");
printResult(a2 == "foob");
ByteVector a3;
a3.append("b");
printResult(a3 == "b");
ByteVector s1("foo");
printResult(ByteVectorList::split(s1, " ").size() == 1);
ByteVector s2("f");
printResult(ByteVectorList::split(s2, " ").size() == 1);
printResult(ByteVector().size() == 0);
printResult(ByteVector("asdf").clear().size() == 0);
printResult(ByteVector("asdf").clear() == ByteVector());
}
void testSynchData()
{
cout << "*** Testing TagLib::ID3v2::SynchData ***" << endl;
{ // test 1
char data[] = { 0, 0, 0, 127 };
ByteVector v(data, 4);
printResult(ID3v2::SynchData::toUInt(v) == 127);
printResult(ID3v2::SynchData::fromUInt(127) == v);
}
{ // test 2
char data[] = { 0, 0, 1, 0 };
ByteVector v(data, 4);
printResult(ID3v2::SynchData::toUInt(v) == 128);
printResult(ID3v2::SynchData::fromUInt(128) == v);
}
{ // test 3
char data[] = { 0, 0, 1, 1 };
ByteVector v(data, 4);
printResult(ID3v2::SynchData::toUInt(v) == 129);
printResult(ID3v2::SynchData::fromUInt(129) == v);
}
}
void testList()
{
cout << "*** Testing TagLib::List<T> ***" << endl;
List<int> l1;
List<int> l2;
List<int> l3;
l1.append(2);
l2.append(3);
l2.append(4);
l1.append(l2);
l1.prepend(1);
l3.append(1);
l3.append(2);
l3.append(3);
l3.append(4);
printResult(l1 == l3);
}

25
tests/utils.h Normal file
View File

@ -0,0 +1,25 @@
#include <string>
#include <stdio.h>
#include <sys/fcntl.h>
using namespace std;
inline string copyFile(const string &filename, const string &ext)
{
string newname = string(tempnam(NULL, NULL)) + ext;
string oldname = string("data/") + filename + ext;
char buffer[4096];
int bytes;
int inf = open(oldname.c_str(), O_RDONLY);
int outf = open(newname.c_str(), O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
while((bytes = read(inf, buffer, sizeof(buffer))) > 0)
write(outf, buffer, bytes);
close(outf);
close(inf);
return newname;
}
inline void deleteFile(const string &filename)
{
remove(filename.c_str());
}