Unit tests + cleanup

This commit is contained in:
KimLS 2013-02-17 13:36:39 -08:00
parent a192e726d4
commit 53d6e4000c
30 changed files with 3321 additions and 2 deletions

View File

@ -154,5 +154,5 @@ IF(EQEMU_BUILD_AZONE OR EQEMU_BUILD_CLEANIPC)
ENDIF(EQEMU_BUILD_AZONE OR EQEMU_BUILD_CLEANIPC)
IF(EQEMU_BUILD_TESTS)
#ADD_SUBDIRECTORY(tests)
ADD_SUBDIRECTORY(tests)
ENDIF(EQEMU_BUILD_TESTS)

View File

@ -8,4 +8,4 @@ StackWalker - New BSD License
ZLib - ZLib License
MySQL - GPL
Perl - GPL / ActiveState (under the assumption that this is a free project).
Google Test - New BSD License
CPPUnit - GLP

37
tests/CMakeLists.txt Normal file
View File

@ -0,0 +1,37 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
ADD_SUBDIRECTORY(cppunit)
SET(tests_sources
main.cpp
)
SET(tests_headers
memory_mapped_file_test.h
ipc_mutex_test.h
fixed_memory_test.h
)
ADD_EXECUTABLE(tests ${tests_sources} ${tests_headers})
TARGET_LINK_LIBRARIES(tests Common cppunit)
IF(MSVC)
SET_TARGET_PROPERTIES(tests PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
TARGET_LINK_LIBRARIES(tests "Ws2_32.lib")
ENDIF(MSVC)
IF(MINGW)
TARGET_LINK_LIBRARIES(tests "WS2_32")
ENDIF(MINGW)
IF(UNIX)
TARGET_LINK_LIBRARIES(tests "dl")
TARGET_LINK_LIBRARIES(tests "z")
TARGET_LINK_LIBRARIES(tests "m")
TARGET_LINK_LIBRARIES(tests "rt")
TARGET_LINK_LIBRARIES(tests "pthread")
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(EXECUTABLE_OUTPUT_PATH ../Bin)

View File

@ -0,0 +1,38 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(cppunit_sources
collectoroutput.cpp
compileroutput.cpp
htmloutput.cpp
missing.cpp
source.cpp
suite.cpp
textoutput.cpp
time.cpp
utils.cpp
)
SET(cppunit_headers
cpptest-assert.h
cpptest-collectoroutput.h
cpptest-compileroutput.h
cpptest-htmloutput.h
cpptest-output.h
cpptest-source.h
cpptest-suite.h
cpptest-textoutput.h
cpptest-time.h
cpptest.h
missing.h
utils.h
winconfig.h
)
ADD_LIBRARY(cppunit ${cppunit_sources} ${cppunit_headers})
IF(UNIX)
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(LIBRARY_OUTPUT_PATH ../../Bin)

View File

@ -0,0 +1,106 @@
// ---
//
// $Id: collectoroutput.cpp,v 1.4 2008/07/15 20:33:31 hartwork Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
#if (defined(__WIN32__) || defined(WIN32))
# include "winconfig.h"
#else
# include "config.h"
#endif
#include "cpptest-collectoroutput.h"
using namespace std;
namespace Test
{
CollectorOutput::TestInfo::TestInfo(const string name)
: _name(name)
{}
CollectorOutput::SuiteInfo::SuiteInfo(const string& name, int tests)
: _name(name),
_errors(0)
{
_tests.reserve(tests);
}
/// Constructs a collector object.
///
CollectorOutput::CollectorOutput()
: Output(),
_total_errors(0)
{}
void
CollectorOutput::finished(int tests, const Time& time)
{
_total_tests = tests;
_total_time = time;
}
void
CollectorOutput::suite_start(int tests, const string& name)
{
if (tests > 0)
{
_suites.push_back(SuiteInfo(name, tests));
_cur_suite = &_suites.back();
}
}
void
CollectorOutput::suite_end(int tests, const string&, const Time& time)
{
if (tests > 0)
{
_cur_suite->_time = time;
_total_errors += _cur_suite->_errors;
}
}
void
CollectorOutput::test_start(const string& name)
{
_cur_suite->_tests.push_back(TestInfo(name));
_cur_test = &_cur_suite->_tests.back();
}
void
CollectorOutput::test_end(const string&, bool ok, const Time& time)
{
if (!(_cur_test->_success = ok))
++_cur_suite->_errors;
_cur_test->_time = time;
}
void
CollectorOutput::assertment(const Source& s)
{
_cur_test->_sources.push_back(s);
}
} // namespace Test

View File

@ -0,0 +1,133 @@
// ---
//
// $Id: compileroutput.cpp,v 1.3 2005/06/08 08:08:06 nilu Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
#include <cstring>
#include <sstream>
#include "cpptest-compileroutput.h"
#include "cpptest-source.h"
using namespace std;
namespace Test
{
namespace
{
// Checks for output format modifiers.
//
bool
check_format(const string& format,
string::size_type& pos,
const string& mod,
int& mod_cnt)
{
if (format.compare(pos, mod.size(), mod) == 0)
{
if (++mod_cnt > 1)
throw Test::CompilerOutput::InvalidFormat(format);
pos += mod.size();
return true;
}
return false;
}
} // anonymous namespace
/// Constructs a compiler output handler.
///
/// \param format Pre-defined compiler output format.
/// \param stream Stream to output to.
///
CompilerOutput::CompilerOutput(Format format, ostream& stream)
: Output(),
_stream(stream)
{
static const char* table[] =
{
"%file:%line: %text", // Generic
"Error cpptest %file %line: %text", // BCC
"%file:%line: %text", // GCC
"%file(%line) : %text" // MSVC
};
_format = table[format];
}
/// Constructs a compiler output handler.
///
/// \param format %Output format to use.
/// \param stream Stream to output to.
///
/// \exception InvalidFormat Invalid format specified.
///
CompilerOutput::CompilerOutput(const string& format, ostream& stream)
: Output(),
_format(format),
_stream(stream)
{
int expr(0), file(0), line(0);
for (string::size_type pos = 0;
(pos = _format.find_first_of('%', pos)) != string::npos; )
{
++pos;
if (check_format(_format, pos, "expr", expr)) ;
else if (check_format(_format, pos, "file", file)) ;
else if (check_format(_format, pos, "line", line)) ;
else
throw InvalidFormat(format);
}
if (!expr && !file && !line)
throw InvalidFormat(format);
}
void
CompilerOutput::assertment(const Source& s)
{
string fmt(_format);
string::size_type pos;
fmt.reserve(fmt.size() + 128);
if ((pos = fmt.find("%file")) != string::npos)
fmt.replace(pos, 5, s.file());
if ((pos = fmt.find("%text")) != string::npos)
fmt.replace(pos, 5, s.message());
if ((pos = fmt.find("%line")) != string::npos)
{
ostringstream ss;
ss << s.line();
fmt.replace(pos, 5, ss.str());
}
_stream << fmt << endl;
}
} // namespace Test

View File

@ -0,0 +1,424 @@
// ---
//
// $Id: cpptest-assert.h,v 1.3 2005/06/08 08:08:06 nilu Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
// Copyright (c) 2010 Nate Gallaher
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
/** \file */
#ifndef CPPTEST_ASSERT_H
#define CPPTEST_ASSERT_H
#include <sstream>
/// Unconditional failure.
///
/// Used in conjunction with Test::Suite.
///
/// \param msg Provided message.
///
/// \par Example:
/// \code
/// void MySuite::test()
/// {
/// // ...
///
/// switch (flag)
/// {
/// // handling valid cases ...
///
/// default:
/// TEST_FAIL("This should not happen")
/// }
/// }
/// \endcode
///
/// For a description of all asserts, see \ref asserts.
///
#define TEST_FAIL(msg) \
{ \
assertment(::Test::Source(__FILE__, __LINE__, (msg) != 0 ? #msg : "")); \
if (!continue_after_failure()) return; \
}
/// Verify an expression and issues an assertment if it fails.
///
/// Used in conjunction with Test::Suite.
///
/// \param expr Expression to test.
///
/// \see TEST_ASSERT_MSG(expr, msg)
///
/// \par Example:
/// \code
/// void MySuite::test()
/// {
/// int i;
///
/// // ...
///
/// TEST_ASSERT(i == 13)
/// }
/// \endcode
///
/// For a description of all asserts, see \ref asserts.
///
#define TEST_ASSERT(expr) \
{ \
if (!(expr)) \
{ \
assertment(::Test::Source(__FILE__, __LINE__, #expr)); \
if (!continue_after_failure()) return; \
} \
}
/// Verify an expression and issues an assertment if it fails.
///
/// Used in conjunction with Test::Suite.
///
/// \param expr Expression to test.
/// \param msg User message.
///
/// \see TEST_ASSERT(expr)
///
/// For a description of all asserts, see \ref asserts.
///
#define TEST_ASSERT_MSG(expr, msg) \
{ \
if (!(expr)) \
{ \
assertment(::Test::Source(__FILE__, __LINE__, msg)); \
if (!continue_after_failure()) return; \
} \
}
/// Verify that two expressions are equal, issues an
/// assertment if it fails. Requires the output operator (<<)
/// to be defined for both expected and got.
///
/// If the output operator is not available, you should use
/// TEST_ASSERT_EQUALS_OBJ(expected, got).
///
/// Used in conjunction with Test::Suite.
///
/// \param expected Expected value.
/// \param got Value to test against expected value.
///
/// \see TEST_ASSERT_EQUALS_MSG(expected, got, msg)
/// \see TEST_ASSERT_EQUALS_OBJ(expected, got)
///
/// For a description of all asserts, see \ref asserts.
///
#define TEST_ASSERT_EQUALS(expected, got) \
{ \
if (!((got) == (expected))) \
{ \
std::stringstream tmpstream; \
tmpstream << "Got " << (got) << ", expected " << (expected);\
assertment(::Test::Source(__FILE__, __LINE__, \
tmpstream.str().c_str())); \
if (!continue_after_failure()) return; \
} \
}
/// Verify that two expressions are equal, issues an
/// assertment if it fails.
///
/// If the output operator is defined for the objects being compared
/// you should use TEST_ASSERT_EQUALS(expected, got) instead for
/// more useful failure messages.
///
/// Used in conjunction with Test::Suite.
///
/// \param expected Expected value.
/// \param got Value to test against expected value.
///
/// \see TEST_ASSERT_EQUALS(expected, got)
/// \see TEST_ASSERT_EQUALS_MSG(expected, got, msg)
///
/// For a description of all asserts, see \ref asserts.
///
#define TEST_ASSERT_EQUALS_OBJ(expected, got) \
{ \
if (!((got) == (expected))) \
{ \
std::stringstream tmpstream; \
tmpstream << #expected << " object not equal to "; \
tmpstream << #got << " object."; \
assertment(::Test::Source(__FILE__, __LINE__, \
tmpstream.str().c_str())); \
if (!continue_after_failure()) return; \
} \
}
/// Verify that two expressions are equal, issues an
/// assertment if it fails. The output operator (<<) must be defined for the
/// object under test. If the output operator is not available, you
/// should use TEST_ASSERT_EQUALS_OBJ(expected, got) instead.
///
/// Used in conjunction with Test::Suite.
///
/// \param expected Expected value.
/// \param got Value to test against expected value.
/// \param msg User message to print out on failure.
///
/// \see TEST_ASSERT_EQUALS(expected, got)
/// \see TEST_ASSERT_EQUALS_OBJ(expected, got)
///
/// For a description of all asserts, see \ref asserts.
#define TEST_ASSERT_EQUALS_MSG(expected, got, msg) \
{ \
if (!((got) == (expected))) \
{ \
std::stringstream tmpstream; \
tmpstream << (msg) << ": "; \
tmpstream << "Got " << (got) << ", expected " << (expected);\
assertment(::Test::Source(__FILE__, __LINE__, \
tmpstream.str().c_str())); \
if (!continue_after_failure()) return; \
} \
}
/// Verify that two expressions are equal up to a constant, issues an
/// assertment if it fails.
///
/// Used in conjunction with Test::Suite.
///
/// \param a First expression to test.
/// \param b Second expression to test.
/// \param delta Constant.
///
/// \see TEST_ASSERT_DELTA_MSG(a, b, delta, msg)
///
/// For a description of all asserts, see \ref asserts.
///
#define TEST_ASSERT_DELTA(a, b, delta) \
{ \
if (((b) < (a) - (delta)) || ((b) > (a) + (delta))) \
{ \
assertment(::Test::Source(__FILE__, __LINE__, \
"delta(" #a ", " #b ", " #delta ")" )); \
if (!continue_after_failure()) return; \
} \
}
/// Verify that two expressions are equal up to a constant, issues an
/// assertment if it fails.
///
/// Used in conjunction with Test::Suite.
///
/// \param a First expression to test.
/// \param b Second expression to test.
/// \param delta Constant.
/// \param msg User message.
///
/// \see TEST_ASSERT_DELTA(a, b, delta)
///
/// For a description of all asserts, see \ref asserts.
///
#define TEST_ASSERT_DELTA_MSG(a, b, delta, msg) \
{ \
if (((b) < (a) - (delta)) || ((b) > (a) + (delta))) \
{ \
assertment(::Test::Source(__FILE__, __LINE__, msg)); \
if (!continue_after_failure()) return; \
} \
}
/// Verify an expression and expects an exception in return.
/// An assertment is issued if the exception is not thrown.
///
/// Used in conjunction with Test::Suite.
///
/// \param expr Expression to test.
/// \param x Expected exception.
///
/// \see TEST_THROWS_MSG(expr, x, msg)
///
/// For a description of all asserts, see \ref asserts.
///
#define TEST_THROWS(expr, x) \
{ \
bool __expected = false; \
try { expr; } \
catch (x) { __expected = true; } \
catch (...) {} \
if (!__expected) \
{ \
assertment(::Test::Source(__FILE__, __LINE__, #expr)); \
if (!continue_after_failure()) return; \
} \
}
/// Verify an expression and expects an exception in return.
/// An assertment is issued if the exception is not thrown.
///
/// Used in conjunction with Test::Suite.
///
/// \param expr Expression to test.
/// \param x Expected exception.
/// \param msg User message.
///
/// \see TEST_THROWS(expr, x)
///
/// For a description of all asserts, see \ref asserts.
///
#define TEST_THROWS_MSG(expr, x, msg) \
{ \
bool __expected = false; \
try { expr; } \
catch (x) { __expected = true; } \
catch (...) {} \
if (!__expected) \
{ \
assertment(::Test::Source(__FILE__, __LINE__, msg)); \
if (!continue_after_failure()) return; \
} \
}
/// Verify an expression and expects any exception in return.
/// An assertment is issued if no exception is thrown.
///
/// Used in conjunction with Test::Suite.
///
/// \param expr Expression to test.
///
/// \see TEST_THROWS_ANYTHING_MSG(expr, msg)
///
/// For a description of all asserts, see \ref asserts.
///
#define TEST_THROWS_ANYTHING(expr) \
{ \
bool __expected = false; \
try { expr; } \
catch (...) { __expected = true; } \
if (!__expected) \
{ \
assertment(::Test::Source(__FILE__, __LINE__, #expr)); \
if (!continue_after_failure()) return; \
} \
}
/// Verify an expression and expects any exception in return.
/// An assertment is issued if no exception is thrown.
///
/// Used in conjunction with Test::Suite.
///
/// \param expr Expression to test.
/// \param msg User message.
///
/// \see TEST_THROWS_ANYTHING(expr)
///
/// For a description of all asserts, see \ref asserts.
///
#define TEST_THROWS_ANYTHING_MSG(expr, msg) \
{ \
bool __expected = false; \
try { expr; } \
catch (...) { __expected = true; } \
if (!__expected) \
{ \
assertment(::Test::Source(__FILE__, __LINE__, msg)); \
if (!continue_after_failure()) return; \
} \
}
/// Verify an expression and expects no exception in return.
/// An assertment is issued if any exception is thrown.
///
/// Used in conjunction with Test::Suite.
///
/// \param expr Expression to test.
///
/// \see TEST_THROWS_NOTHING_MSG(expr, msg)
///
/// For a description of all asserts, see \ref asserts.
///
#define TEST_THROWS_NOTHING(expr) \
{ \
bool __expected = true; \
try { expr; } \
catch (...) { __expected = false; } \
if (!__expected) \
{ \
assertment(::Test::Source(__FILE__, __LINE__, #expr)); \
if (!continue_after_failure()) return; \
} \
}
/// Verify an expression and expects no exception in return.
/// An assertment is issued if any exception is thrown.
///
/// Used in conjunction with Test::Suite.
///
/// \param expr Expression to test.
/// \param msg User message.
///
/// \see TEST_THROWS_NOTHING(expr)
///
/// For a description of all asserts, see \ref asserts.
///
#define TEST_THROWS_NOTHING_MSG(expr, msg) \
{ \
bool __expected = true; \
try { expr; } \
catch (...) { __expected = false; } \
if (!__expected) \
{ \
assertment(::Test::Source(__FILE__, __LINE__, msg)); \
if (!continue_after_failure()) return; \
} \
}
/// \page asserts Available asserts
///
/// Normally, assert macros issues an assert if the given expression, if any,
/// fails (as defined by the macro). Assertments include information about the
/// current test suite, test function, source file, source file line, and a
/// message. The message is normally the offending expression, however, for
/// macros ending in _MSG it is possibly to supply a user defined message.
///
/// <b>General asserts</b>
/// - TEST_FAIL(msg)
///
/// <b>Comparision asserts</b>
/// - TEST_ASSERT(expr)
/// - TEST_ASSERT_MSG(expr, msg)
/// - TEST_ASSERT_EQUALS(expected, got)
/// - TEST_ASSERT_EQUALS_MSG(expected, got, msg)
/// - TEST_ASSERT_EQUALS_OBJ(expected, got)
/// - TEST_ASSERT_DELTA(a, b, delta)
/// - TEST_ASSERT_DELTA_MSG(a, b, delta, msg)
///
/// <b>Exception asserts</b>
/// - TEST_THROWS(expr, x)
/// - TEST_THROWS_MSG(expr, x, msg)
/// - TEST_THROWS_ANYTHING(expr)
/// - TEST_THROWS_ANYTHING_MSG(expr, msg)
/// - TEST_THROWS_NOTHING(expr)
/// - TEST_THROWS_NOTHING_MSG(expr, msg)
///
#endif // #ifndef CPPTEST_ASSERT_H

View File

@ -0,0 +1,106 @@
// ---
//
// $Id: cpptest-collectoroutput.h,v 1.3 2005/06/08 08:08:06 nilu Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
/** \file */
#ifndef CPPTEST_COLLECTOROUTPUT_H
#define CPPTEST_COLLECTOROUTPUT_H
#include <list>
#include <string>
#include <vector>
#include "cpptest-output.h"
#include "cpptest-source.h"
#include "cpptest-time.h"
namespace Test
{
/// \brief Collector output.
///
/// Base class for output handlers that need to report status when all
/// tests have executed.
///
class CollectorOutput : public Output
{
public:
virtual void finished(int tests, const Time& time);
virtual void suite_start(int tests, const std::string& name);
virtual void suite_end(int tests, const std::string& name,
const Time& time);
virtual void test_start(const std::string& name);
virtual void test_end(const std::string& name, bool ok,
const Time& time);
virtual void assertment(const Source& s);
protected:
struct OutputSuiteInfo;
struct OutputTestInfo;
struct OutputErrorTestInfo;
typedef std::list<Source> Sources;
struct TestInfo
{
std::string _name;
Time _time;
bool _success : 1;
Sources _sources;
explicit TestInfo(const std::string name);
};
typedef std::vector<TestInfo> Tests;
struct SuiteInfo
{
std::string _name;
int _errors;
Tests _tests;
Time _time;
SuiteInfo(const std::string& name, int tests);
};
typedef std::list<SuiteInfo> Suites;
Suites _suites;
int _total_errors;
int _total_tests;
Time _total_time;
CollectorOutput();
private:
SuiteInfo* _cur_suite;
TestInfo* _cur_test;
};
} // namespace Test
#endif // #ifndef CPPTEST_COLLECTOROUTPUT_H

View File

@ -0,0 +1,112 @@
// ---
//
// $Id: cpptest-compileroutput.h,v 1.3 2005/06/08 08:08:06 nilu Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
/** \file */
#ifndef CPPTEST_COMPILEROUTPUT_H
#define CPPTEST_COMPILEROUTPUT_H
#include <iostream>
#include <stdexcept>
#include "cpptest-output.h"
namespace Test
{
/// \brief Compiler-like output handler.
///
/// %Test suite output handler that only outputs failures in compiler
/// warning/error format. This way, you can use your IDE to browse between
/// failures.
///
/// The output format is configurable to be able to emulate different
/// compiler outputs. The following modifiers exist:
/// - \e %file Outputs the file containing the test function.
/// - \e %line Line number for the the test function.
/// - \e %text Expression (or message) that caused the assertment.
/// Note that each modifier can only be specified once.
///
class CompilerOutput : public Output
{
public:
/// \brief Compiler output exception.
///
/// Indicates that an invalid message format was given when creating
/// a compiler output. The failing format may be retrieved using the
/// what() method.
///
class InvalidFormat : public std::logic_error
{
public:
InvalidFormat(const std::string& what)
: std::logic_error(what) {}
};
/// Pre-defined compiler output formats.
///
enum Format
{
/// Generic compiler format, which equals:
/// <tt>%%file:%%line: %%text</tt>
///
Generic,
/// <a href="http://www.borland.com/products/downloads/download_cbuilder.html">
/// Borland C++ Compiler</a> (BCC) format, which equals:
/// <tt>Error cpptest %%file %%line: %%text</tt>.
///
BCC,
/// <a href="http://gcc.gnu.org">GNU Compiler Collection</a>
/// (GCC) format, which equals:
/// <tt>%%file:%%line: %%text</tt>
///
GCC,
/// <a href="http://www.microsoft.com">Microsoft Visual C++</a>
/// (MSVC) format, which equals:
/// <tt>%%file(%%line) : %%text</tt>
///
MSVC
};
explicit CompilerOutput(Format format = Generic,
std::ostream& stream = std::cout);
explicit CompilerOutput(const std::string& format,
std::ostream& stream = std::cout);
virtual void assertment(const Source& s);
private:
std::string _format;
std::ostream& _stream;
};
} // namespace Test
#endif // #ifndef CPPTEST_COMPILEROUTPUT_H

View File

@ -0,0 +1,64 @@
// ---
//
// $Id: cpptest-htmloutput.h,v 1.3 2005/06/08 08:08:06 nilu Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
/** \file */
#ifndef CPPTEST_HTMLOUTPUT_H
#define CPPTEST_HTMLOUTPUT_H
#include <iostream>
#include <string>
#include "cpptest-collectoroutput.h"
namespace Test
{
/// \brief HTML output.
///
/// %Output handler that creates a HTML table with detailed information
/// about all tests.
///
class HtmlOutput : public CollectorOutput
{
public:
void generate(std::ostream& os, bool incl_ok_tests = true,
const std::string& name = "");
private:
struct SuiteRow;
struct TestRow;
struct TestSuiteRow;
struct TestResult;
struct TestResultAll;
struct SuiteTestResult;
friend struct TestSuiteRow;
};
} // namespace Test
#endif // #ifndef CPPTEST_HTMLOUTPUT_H

View File

@ -0,0 +1,152 @@
// ---
//
// $Id: cpptest-output.h,v 1.7 2008/07/15 21:20:26 hartwork Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
/** \file */
#ifndef CPPTEST_OUTPUT_H
#define CPPTEST_OUTPUT_H
#include <string>
#ifdef _MSC_VER
# define CPPTEST_UNUSED(x)
#else
# define CPPTEST_UNUSED(x) (void)x
#endif
namespace Test
{
class Source;
class Time;
/// \brief %Test suite output handler.
///
/// Abstract base class for all suite output handlers. Derive from this
/// class to create real output handlers that creates arbitrary complex
/// output handlers.
///
/// All parts of testing is reported (test start/stop, suite start/stop,
/// individual test start/stop, and assertments), thus giving maximum
/// flexibility for derived classes.
///
class Output
{
public:
/// Empty destructor.
///
virtual ~Output() {}
/// Called when testing is started.
///
/// \param tests Total number of tests in all suites.
///
virtual void initialize(int tests)
{
CPPTEST_UNUSED(tests);
}
/// Called when testing is finished.
///
/// \param tests Total number of tests in all suites.
/// \param time Total elapsed time for all tests.
///
virtual void finished(int tests, const Time& time)
{
CPPTEST_UNUSED(tests);
CPPTEST_UNUSED(time);
}
/// Called when a suite is entered.
///
/// \param tests Number of tests in this suite.
/// \param name Name of the suite.
///
virtual void suite_start(int tests, const std::string& name)
{
CPPTEST_UNUSED(tests);
CPPTEST_UNUSED(name);
}
/// Called when a suite is finished.
///
/// \param tests Number of tests in this suite.
/// \param name Name of the suite.
/// \param time Total elapsed time for all tests in this suite.
///
virtual void suite_end(int tests, const std::string& name,
const Time& time)
{
CPPTEST_UNUSED(tests);
CPPTEST_UNUSED(name);
CPPTEST_UNUSED(time);
}
/// Called when a tests is executed.
///
/// \param name Name of the test function.
///
virtual void test_start(const std::string& name)
{
CPPTEST_UNUSED(name);
}
/// Called when a test if finished, regardless if an assertment was
/// issued.
///
/// \param name Name of the test function.
/// \param ok True if the test was successful; false otherwise.
/// \param time Execution time.
///
virtual void test_end(const std::string& name, bool ok,
const Time& time)
{
CPPTEST_UNUSED(name);
CPPTEST_UNUSED(ok);
CPPTEST_UNUSED(time);
}
/// Called when an assertment is issued.
///
/// \param s Assert point information.
///
virtual void assertment(const Source& s)
{
CPPTEST_UNUSED(s);
}
protected:
/// Empty constructor.
///
Output() {}
private:
Output(const Output&);
Output& operator=(const Output&);
};
} // namespace Test
#endif // #ifndef CPPTEST_OUTPUT_H

View File

@ -0,0 +1,67 @@
// ---
//
// $Id: cpptest-source.h,v 1.3 2005/06/08 08:08:06 nilu Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
/** \file */
#ifndef CPPTEST_SOURCE_H
#define CPPTEST_SOURCE_H
#include <string>
namespace Test
{
class Suite;
/// \brief Assertment source information.
///
/// Contains information about an assertment point.
///
class Source
{
friend class Suite;
public:
Source();
Source(const char* file, unsigned int line, const char* msg);
const std::string& file() const;
unsigned int line() const;
const std::string& message() const;
const std::string& suite() const;
const std::string& test() const;
private:
unsigned int _line;
std::string _file;
std::string _msg;
std::string _suite;
std::string _test;
};
} // namespace Test
#endif // #ifndef CPPTEST_SOURCE_H

View File

@ -0,0 +1,140 @@
// ---
//
// $Id: cpptest-suite.h,v 1.4 2010/03/26 04:45:14 hartwork Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
/** \file */
#ifndef CPPTEST_SUITE_H
#define CPPTEST_SUITE_H
#include <list>
#include <memory>
#include <string>
#include "cpptest-time.h"
#include "cpptest-source.h"
namespace Test
{
class Output;
/// \brief Unit testing suite.
///
/// Base class for all suites. Derive from this class to create own
/// test suites.
///
/// %Test functions in derived classes are registered as tests using the
/// TEST_ADD(func). Testing is started by run(). Note that suites may be
/// embedded in other suites using add().
///
class Suite
{
public:
Suite();
virtual ~Suite();
void add(std::auto_ptr<Suite> suite);
bool run(Output& output, bool cont_after_fail = true);
protected:
/// Pointer to a test function.
///
typedef void (Suite::*Func)();
bool continue_after_failure() const { return _continue; }
virtual void setup() {}
virtual void tear_down() {}
void register_test(Func func, const std::string& name);
void assertment(Source s);
private:
struct DoRun;
struct ExecTests;
struct SubSuiteTests;
struct SuiteTime;
struct SubSuiteTime;
friend struct DoRun;
friend struct ExecTests;
friend struct SubSuiteTests;
friend struct SubSuiteTime;
struct Data
{
Func _func;
std::string _name;
Time _time;
Data(Func func, const std::string& name)
: _func(func), _name(name) {}
};
typedef std::list<Data> Tests;
typedef std::list<Suite*> Suites;
std::string _name; // Suite name
const std::string* _cur_test; // Current test func name
Suites _suites; // External test suites
Tests _tests; // All tests
Output* _output; // Output handler
bool _result : 1; // Test result
bool _success : 1; // Set if no test failed
bool _continue : 1; // Continue func after failures
void do_run(Output* os, bool cont_after_fail);
int total_tests() const;
Time total_time(bool recursive) const;
// Disable
//
Suite(const Suite&);
Suite& operator=(const Suite&);
};
/// Adds a test function to the enclosing suite. Note that test functions
/// should be added in the suites constructor.
///
/// \param func Function to add, must be of type Suite::Func.
///
/// \par Example:
/// \code
/// MySuite::MySuite()
/// {
/// TEST_ADD(&MySuite::test_1)
/// TEST_ADD(&MySuite::test_2)
/// ...
/// }
/// \endcode
///
#define TEST_ADD(func)\
register_test(static_cast<Func>(&func), #func);
} // namespace Test
#endif // #ifndef CPPTEST_SUITE_H

View File

@ -0,0 +1,88 @@
// ---
//
// $Id: cpptest-textoutput.h,v 1.3 2005/06/08 08:08:06 nilu Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
/** \file */
#ifndef CPPTEST_TEXTOUTPUT_H
#define CPPTEST_TEXTOUTPUT_H
#include <iostream>
#include <list>
#include "cpptest-source.h"
#include "cpptest-output.h"
namespace Test
{
/// \brief Text output handler that outputs to the a stream.
///
/// %Test suite output handler that writes its information as text to a
/// a stream. It it possible to select between two different operational
/// modes that controls the detail level, see Mode.
///
class TextOutput : public Output
{
public:
/// Output mode.
///
enum Mode
{
/// Terse output mode, which only shows the number of correct tests.
///
Terse,
/// Verbose output mode, which also shows extended assert
/// information for each test that failed.
///
Verbose
};
TextOutput(Mode mode, std::ostream& stream = std::cout);
virtual void finished(int tests, const Time& time);
virtual void suite_start(int tests, const std::string& name);
virtual void suite_end(int tests, const std::string& name,
const Time& time);
virtual void test_end(const std::string& name, bool ok,
const Time& time);
virtual void assertment(const Source& s);
private:
typedef std::list<Source> ErrorList;
Mode _mode;
std::ostream& _stream;
ErrorList _suite_error_list;
std::string _suite_name;
int _suite_errors;
int _suite_tests;
int _suite_total_tests;
int _total_errors;
};
} // namespace Test
#endif // #ifndef CPPTEST_TEXTOUTPUT_H

View File

@ -0,0 +1,66 @@
// ---
//
// $Id: cpptest-time.h,v 1.3 2005/06/08 08:08:06 nilu Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
/** \file */
#ifndef CPPTEST_TIME_H
#define CPPTEST_TIME_H
#include <iostream>
#include <string>
namespace Test
{
/// \brief %Time representation.
///
/// Encapsulates a time value with microsecond resolution. It is possible
/// to retrieve the current time, add and subtract time values, and output
/// the time to an output stream.
///
class Time
{
public:
Time();
Time(unsigned int sec, unsigned int usec);
unsigned int seconds() const;
unsigned int microseconds() const;
static Time current();
friend Time operator+(const Time& t1, const Time& t2);
friend Time operator-(const Time& t1, const Time& t2);
friend std::ostream& operator<<(std::ostream& os, const Time& t);
private:
unsigned int _sec;
unsigned int _usec;
};
} // namespace Test
#endif // #ifndef CPPTEST_TIME_H

42
tests/cppunit/cpptest.h Normal file
View File

@ -0,0 +1,42 @@
// ---
//
// $Id: cpptest.h,v 1.3 2005/06/08 08:08:06 nilu Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
/** \file */
#ifndef CPPTEST_H
#define CPPTEST_H
#include "cpptest-assert.h"
#include "cpptest-source.h"
#include "cpptest-suite.h"
#include "cpptest-time.h"
#include "cpptest-compileroutput.h"
#include "cpptest-htmloutput.h"
#include "cpptest-textoutput.h"
#endif // #ifndef CPPTEST_H

View File

@ -0,0 +1,453 @@
// ---
//
// $Id: htmloutput.cpp,v 1.7 2008/07/15 20:33:31 hartwork Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
#include <algorithm>
#include <sstream>
#if (defined(__WIN32__) || defined(WIN32))
# include "winconfig.h"
#else
# include "config.h"
#endif
#include "cpptest-htmloutput.h"
#include "utils.h"
using namespace std;
namespace Test
{
namespace
{
void
strreplace(string &value, char search, const string &replace)
{
string::size_type idx = 0;
while((idx = value.find(search, idx)) != string::npos)
{
value.replace(idx, 1, replace);
idx += replace.size();
}
}
string
escape(string value)
{
strreplace(value, '&', "&amp;");
strreplace(value, '<', "&lt;");
strreplace(value, '>', "&gt;");
strreplace(value, '"', "&quot;");
strreplace(value, '\'', "&#39;");
return value;
}
void
header(ostream& os, string name)
{
if (!name.empty())
name += " ";
name = escape(name);
os <<
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"
"<head>\n"
" <meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n"
" <meta name=\"generator\" content=\"CppTest - http://cpptest.sourceforge.net\" />\n"
" \n"
" <title>" << name << "Unit Tests Results</title>\n"
" \n"
" <style type=\"text/css\" media=\"screen\">\n"
" <!--\n"
" hr {\n"
" width: 100%;\n"
" border-width: 0px;\n"
" height: 1px;\n"
" color: #cccccc;\n"
" background-color: #cccccc;\n"
" padding: 0px;\n"
" }\n"
" \n"
" table {\n"
" width:100%;\n"
" border-collapse:separate;\n"
" border-spacing: 2px;\n"
" border:0px;\n"
" }\n"
" tr {\n"
" margin:0px;\n"
" padding:0px;\n"
" }\n"
" td {\n"
" margin:0px;\n"
" padding:1px;\n"
" }\n"
" .table_summary {\n"
" }\n"
" .table_suites {\n"
" }\n"
" .table_suite {\n"
" }\n"
" .table_result {\n"
" margin: 0px 0px 1em 0px;\n"
" }\n"
" .tablecell_title {\n"
" background-color: #a5cef7;\n"
" font-weight: bold;\n"
" }\n"
" \n"
" .tablecell_success {\n"
" background-color: #efefe7;\n"
" }\n"
" \n"
" .tablecell_error {\n"
" color: #ff0808;\n"
" background-color: #efefe7;\n"
" font-weight: bold;\n"
" }\n"
" p.spaced {\n"
" margin: 0px;\n"
" padding: 1em 0px 2em 0px;\n"
" }\n"
" p.unspaced {\n"
" margin: 0px;\n"
" padding: 0px 0px 2em 0px;\n"
" }\n"
" -->\n"
" </style>\n"
"</head>\n"
"\n"
"<body>\n"
"\n"
"<h1><a name=\"top\"></a>" << name << "Unit Tests Results</h1>\n"
"\n"
"<div style=\"text-align:right\">\n"
"Designed by <a href=\"http://cpptest.sourceforge.net\">CppTest</a>\n"
"</div>\n"
"<hr />\n"
"\n";
}
void
footer(ostream& os)
{
os <<
"\n"
"<p>\n"
" <a href=\"http://validator.w3.org/#validate-by-upload\">\n"
" Valid XHTML 1.0 Strict\n"
" </a>\n"
"</p>\n"
"</body>\n</html>\n";
}
void
back_ref(ostream& os, const string& ref, bool prepend_newline = true)
{
os << "<p class=\"" << (prepend_newline ? "spaced" : "unspaced") << "\"><a href=\"#" << ref
<< "\">Back to " << escape(ref) << "</a>\n</p>\n";
}
void
sub_title(ostream& os, const string& title, int size)
{
ostringstream h;
h << "h" << size;
os << "<" << h.str() << ">" << escape(title) << "</" << h.str() << ">\n";
}
void
sub_title(ostream& os, const string& title, int size, const string& mark)
{
ostringstream h;
h << "h" << size;
os << "<" << h.str() << "><a name=\"" << mark << "\"></a>" << escape(title) << "</" << h.str() << ">\n";
}
enum ClassTableType { TableClass_Summary, TableClass_Suites, TableClass_Suite, TableClass_Result };
void
table_header(ostream& os, ClassTableType type, const string &summary = "")
{
static const char* class_tabletypes[] = { "summary", "suites", "suite", "result" };
os << "<table summary=\"" << escape(summary) << "\" class=\"table_" << class_tabletypes[type] << "\">\n";
}
void
table_footer(ostream& os)
{
os << "</table>\n";
}
void
table_tr_header(ostream& os)
{
os << " <tr>\n";
}
void
table_tr_footer(ostream& os)
{
os << " </tr>\n";
}
enum ClassType { Title, Success, Error };
void
table_entry(ostream& os, ClassType type, const string& s,
int width = 0, const string& link = "")
{
static const char* class_types[] = { "title", "success", "error" };
os << " <td";
if (width)
os << " style=\"width:" << width << "%\"";
if (!link.empty())
os << " class=\"tablecell_" << class_types[type] << "\"><a href=\"#" << link << "\">" << escape(s) << "</a>";
else
os << " class=\"tablecell_" << class_types[type] << "\">" << escape(s);
os << "</td>\n";
}
} // anonymous namespace
// Test suite table
//
struct HtmlOutput::SuiteRow
{
ostream& _os;
SuiteRow(ostream& os) : _os(os) {}
void operator()(const SuiteInfo& si)
{
ClassType type(si._errors > 0 ? Error : Success);
ostringstream ss;
table_tr_header(_os);
table_entry(_os, type, si._name, 0, si._name);
ss.str(""), ss << si._tests.size();
table_entry(_os, type, ss.str(), 10);
ss.str(""), ss << si._errors;
table_entry(_os, type, ss.str(), 10);
ss.str(""), ss << correct(si._tests.size(), si._errors) << "%";
table_entry(_os, type, ss.str(), 10);
ss.str(""), ss << si._time;
table_entry(_os, type, ss.str(), 10);
table_tr_footer(_os);
}
};
// Individual tests tables, tests
//
struct HtmlOutput::TestRow
{
bool _incl_ok_tests;
ostream& _os;
TestRow(ostream& os, bool incl_ok_tests)
: _incl_ok_tests(incl_ok_tests), _os(os) {}
void operator()(const TestInfo& ti)
{
if (!ti._success || _incl_ok_tests)
{
string link = ti._success ? string(""):
ti._sources.front().suite() + "_" + ti._name;
ClassType type(ti._success ? Success : Error);
ostringstream ss;
table_tr_header(_os);
table_entry(_os, type, ti._name, 0, link);
ss.str(""), ss << ti._sources.size();
table_entry(_os, type, ss.str());
table_entry(_os, type, ti._success ? "true" : "false");
ss.str(""), ss << ti._time;
table_entry(_os, type, ss.str());
table_tr_footer(_os);
}
}
};
// Individual tests tables, header
//
struct HtmlOutput::TestSuiteRow
{
bool _incl_ok_tests;
ostream& _os;
TestSuiteRow(ostream& os, bool incl_ok_tests)
: _incl_ok_tests(incl_ok_tests), _os(os) {}
void operator()(const SuiteInfo& si)
{
ostringstream ss;
sub_title(_os, "Suite: " + si._name, 3, si._name);
table_header(_os, TableClass_Suite, "Details for suite " + si._name);
table_tr_header(_os);
table_entry(_os, Title, "Name");
table_entry(_os, Title, "Errors", 10);
table_entry(_os, Title, "Success", 10);
table_entry(_os, Title, "Time (s)", 10);
table_tr_footer(_os);
for_each(si._tests.begin(), si._tests.end(),
TestRow(_os, _incl_ok_tests));
table_footer(_os);
back_ref(_os, "top");
}
};
// Individual tests result tables
//
struct HtmlOutput::TestResult
{
ostream& _os;
TestResult(ostream& os) : _os(os) {}
void operator()(const Source& s)
{
const int TitleSize = 15;
ostringstream ss;
table_header(_os, TableClass_Result, "Test Failure");
table_tr_header(_os);
table_entry(_os, Title, "Test", TitleSize);
table_entry(_os, Success, s.suite() + "::" + s.test());
table_tr_footer(_os);
table_tr_header(_os);
table_entry(_os, Title, "File", TitleSize);
ss << s.file() << ":" << s.line();
table_entry(_os, Success, ss.str());
table_tr_footer(_os);
table_tr_header(_os);
table_entry(_os, Title, "Message", TitleSize);
table_entry(_os, Success, s.message());
table_tr_footer(_os);
table_footer(_os);
}
};
// All tests result tables
//
struct HtmlOutput::TestResultAll
{
ostream& _os;
TestResultAll(ostream& os) : _os(os) {}
void operator()(const TestInfo& ti)
{
if (!ti._success)
{
const string& suite = ti._sources.front().suite();
sub_title(_os, suite + "::" + ti._name, 3, suite + "_" + ti._name);
for_each(ti._sources.begin(), ti._sources.end(), TestResult(_os));
back_ref(_os, suite, false);
}
}
};
// Individual tests result tables, iterator
//
struct HtmlOutput::SuiteTestResult
{
ostream& _os;
SuiteTestResult(ostream& os) : _os(os) {}
void operator()(const SuiteInfo& si)
{
for_each(si._tests.begin(), si._tests.end(), TestResultAll(_os));
}
};
/// Generates the HTML table. This function should only be called after
/// run(), when all tests have been executed.
///
/// \param os Output stream.
/// \param incl_ok_tests Set if successful tests should be shown;
/// false otherwise.
/// \param name Name of generated report.
///
void
HtmlOutput::generate(ostream& os, bool incl_ok_tests, const string& name)
{
ClassType type(_total_errors > 0 ? Error : Success);
ostringstream ss;
header(os, name);
// Table: Summary
//
sub_title(os, "Summary", 2);
table_header(os, TableClass_Summary, "Summary of test results");
table_tr_header(os);
table_entry(os, Title, "Tests", 30);
table_entry(os, Title, "Errors", 30);
table_entry(os, Title, "Success", 30);
table_entry(os, Title, "Time (s)", 10);
table_tr_footer(os);
table_tr_header(os);
ss.str(""), ss << _total_tests;
table_entry(os, type, ss.str(), 30);
ss.str(""), ss << _total_errors;
table_entry(os, type, ss.str(), 30);
ss.str(""), ss << correct(_total_tests, _total_errors) << "%";
table_entry(os, type, ss.str(), 30);
ss.str(""), ss << _total_time;
table_entry(os, type, ss.str(), 10);
table_tr_footer(os);
table_footer(os);
os << "<hr />\n\n";
// Table: Test suites
//
sub_title(os, "Test suites", 2);
table_header(os, TableClass_Suites, "Test Suites");
table_tr_header(os);
table_entry(os, Title, "Name");
table_entry(os, Title, "Tests", 10);
table_entry(os, Title, "Errors", 10);
table_entry(os, Title, "Success", 10);
table_entry(os, Title, "Time (s)", 10);
table_tr_footer(os);
for_each(_suites.begin(), _suites.end(), SuiteRow(os));
table_footer(os);
os << "<hr />\n\n";
// Individual tests tables
//
for_each(_suites.begin(), _suites.end(), TestSuiteRow(os, incl_ok_tests));
os << "<hr />\n\n";
// Individual tests result tables
//
if(_total_errors != 0)
{
sub_title(os, "Test results", 2);
for_each(_suites.begin(), _suites.end(), SuiteTestResult(os));
os << "<hr />\n\n";
}
// EOF
//
footer(os);
}
} // namespace Test

80
tests/cppunit/missing.cpp Normal file
View File

@ -0,0 +1,80 @@
// ---
//
// $Id: missing.cpp,v 1.4 2008/07/15 20:33:31 hartwork Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
#if (defined(__WIN32__) || defined(WIN32))
# include "winconfig.h"
#else
# include "config.h"
#endif
#include "missing.h"
#ifdef HAVE_GETTICKCOUNT
#include <windows.h>
#endif
#ifndef __BORLANDC__
#include <cmath>
#else
#include <math.h>
#endif
#include <cassert>
#include <ctime>
namespace Test
{
#ifndef HAVE_GETTIMEOFDAY
int
gettimeofday(timeval* tv, void*)
{
assert(tv);
#ifdef HAVE_GETTICKCOUNT
long now = GetTickCount();
tv->tv_sec = now / 1000;
tv->tv_usec = (now % 1000) * 1000;
#else
tv->tv_sec = time(0);
tv->tv_usec = 0;
#endif // #ifdef HAVE_GETTICKCOUNT
return 0;
}
#endif // #ifndef HAVE_GETTIMEOFDAY
#ifndef HAVE_ROUND
double
round(double d)
{
return d > 0.0 ? floor(d + 0.5) : ceil(d - 0.5);
}
#endif
} // namespace Test

56
tests/cppunit/missing.h Normal file
View File

@ -0,0 +1,56 @@
// ---
//
// $Id: missing.h,v 1.4 2008/07/15 20:33:31 hartwork Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
#ifndef CPPTEST_MISSING_H
#define CPPTEST_MISSING_H
#if (defined(__WIN32__) || defined(WIN32))
# include "winconfig.h"
#else
# include "config.h"
#endif
namespace Test
{
#ifndef HAVE_GETTIMEOFDAY
struct timeval
{
long tv_sec;
long tv_usec;
};
extern int gettimeofday(timeval* tv, void*);
#endif // #ifndef HAVE_GETTIMEOFDAY
#ifndef HAVE_ROUND
extern double round(double d);
#endif
} // namespace Test
#endif // #ifndef CPPTEST_MISSING_H

93
tests/cppunit/source.cpp Normal file
View File

@ -0,0 +1,93 @@
// ---
//
// $Id: source.cpp,v 1.4 2005/06/08 09:25:09 nilu Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
#include "cpptest-source.h"
using namespace std;
namespace Test
{
/// Constructs an invalid source object, which filename and message are
/// empty strings and the line equals zero.
///
Source::Source()
: _line(0)
{}
/// Constructs a source object.
///
/// \param file Name of the file containing the failing function.
/// \param line Line where the function starts.
/// \param msg Expression (or message) that caused the failure.
///
Source::Source(const char* file, unsigned int line, const char* msg)
: _line(line),
_file(file ? file : ""),
_msg(msg ? msg : "")
{}
/// \return Name of the file containing the failing function.
///
const string&
Source::file() const
{
return _file;
}
/// \return Line where the function starts.
///
unsigned int
Source::line() const
{
return _line;
}
/// \return Descriptive message.
///
const string&
Source::message() const
{
return _msg;
}
/// \return Name of the suite, which the test belongs to.
///
const string&
Source::suite() const
{
return _suite;
}
/// \return Name of failing test.
///
const string&
Source::test() const
{
return _test;
}
} // namespace Test

281
tests/cppunit/suite.cpp Normal file
View File

@ -0,0 +1,281 @@
// ---
//
// $Id: suite.cpp,v 1.7 2010/03/26 04:38:25 hartwork Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
#include <algorithm>
#include <cassert>
#include <cstring>
#include <functional>
#include <numeric>
#if (defined(__WIN32__) || defined(WIN32))
# include "winconfig.h"
#else
# include "config.h"
#endif
#include "cpptest-output.h"
#include "cpptest-source.h"
#include "cpptest-suite.h"
using namespace std;
namespace Test
{
namespace
{
// Destroys all dynamically allocated objects within the given range.
//
template <class FwdIter>
void
destroy_range(FwdIter first, FwdIter last)
{
while (first != last)
delete *first++;
}
} // anonymous namespace
/// Constructs an empty test suite.
///
Suite::Suite()
: _cur_test(0),
_output(0),
_success(true)
{}
/// Destroys this suite object.
///
Suite::~Suite()
{
destroy_range(_suites.begin(), _suites.end());
}
/// Starts the testing. All tests in this suite and embedded suites will
/// be executed.
///
/// \param output Progress report destination.
/// \param cont_after_fail Continue functions despite failures.
///
/// \return True if no test failed; false otherwise.
///
bool
Suite::run(Output& output, bool cont_after_fail)
{
int ntests = total_tests();
output.initialize(ntests);
do_run(&output, cont_after_fail);
output.finished(ntests, total_time(true));
return _success;
}
/// \fn void Suite::setup()
///
/// Setups a test fixture. This function is called before each test,
/// in this suite, is executed.
///
/// This function should be overloaded by derived classes to provide
/// specialized behavior.
///
/// \see tear_down()
/// \fn void Suite::tear_down()
///
/// Tears down a test fixture. This function is called after each test,
/// in this suite, have been executed.
///
/// This function should be overloaded by derived classes to provide
/// specialized behavior.
///
/// \see setup()
/// Adds a suite to this suite. Tests in added suites will be executed
/// when run() of the top-level suite is called.
///
/// \param suite %Test suite to add.
///
void
Suite::add(auto_ptr<Suite> suite)
{
_suites.push_back(suite.release());
}
/// Registers a test function.
///
/// \b Note: Do not call this function directly, use the TEST_ADD(func)
/// macro instead.
///
/// \param func Pointer to a test function.
/// \param name Class and function name of the function. The format \b must
/// equal \e class::func.
///
void
Suite::register_test(Func func, const string& name)
{
string::size_type pos = name.find_first_of(':');
assert(!name.empty() && name[pos + 1] == ':' && name[pos + 2] != '\0');
_name.assign(name, 0, pos);
_tests.push_back(Data(func, name.substr(pos + 2)));
}
/// Issues an assertment to the output handler.
///
/// Do not call this function directly, use one of the available assertment
/// macros instead, see \ref asserts.
///
/// \param s Assert point information.
///
void
Suite::assertment(Source s)
{
s._suite = _name;
s._test = *_cur_test;
_output->assertment(s);
_result = _success = false;
}
// Functor to execute tests for the given suite.
//
struct Suite::ExecTests
{
Suite& _suite;
ExecTests(Suite& s) : _suite(s) {}
void operator()(Data& data)
{
_suite._cur_test = &data._name;
_suite._result = true; // assume success, assert will set to false
_suite._output->test_start(data._name);
_suite.setup();
Time start(Time::current());
// FIXME Also feedback exception to user
try
{
(_suite.*data._func)();
} catch (...) {
_suite._result = _suite._success = false;
}
Time end(Time::current());
_suite.tear_down();
data._time = end - start;
_suite._output->test_end(data._name, _suite._result, data._time);
}
};
// Functor to execute a suite.
//
struct Suite::DoRun
{
bool _continue;
Output* _output;
DoRun(Output* output, bool cont) : _continue(cont), _output(output) {}
void operator()(Suite* suite) { suite->do_run(_output, _continue); }
};
// Execute all tests in this and added suites.
//
void
Suite::do_run(Output* os, bool cont_after_fail)
{
_continue = cont_after_fail;
_output = os;
_output->suite_start(_tests.size(), _name);
for_each(_tests.begin(), _tests.end(), ExecTests(*this));
_output->suite_end(_tests.size(), _name, total_time(false));
for_each(_suites.begin(), _suites.end(), DoRun(_output, _continue));
// FIXME Find a cleaner way
Suites::const_iterator iter = _suites.begin();
while (iter != _suites.end())
{
if (!(*iter)->_success)
{
_success = false;
break;
}
iter++;
}
}
// Functor to count all tests in a suite.
//
struct Suite::SubSuiteTests
{
int operator()(size_t value, const Suite* s) const
{
return value + s->total_tests();
}
};
// Counts all tests in this and all its embedded suites.
//
int
Suite::total_tests() const
{
return accumulate(_suites.begin(), _suites.end(),
_tests.size(), SubSuiteTests());
}
// Functor to accumulate execution time for tests.
//
struct Suite::SuiteTime
{
Time operator()(const Time& time, const Data& data)
{
return time + data._time;
}
};
// Functor to accumulate execution time for suites.
//
struct Suite::SubSuiteTime
{
Time operator()(Time time, const Suite* s) const
{
return time + s->total_time(true);
}
};
// Counts time accumulated execution time for all tests in this and all
// its embedded suites.
//
Time
Suite::total_time(bool recursive) const
{
Time time = accumulate(_tests.begin(), _tests.end(),
Time(), SuiteTime());
return !recursive ? time : accumulate(_suites.begin(), _suites.end(),
time, SubSuiteTime());
}
} // namespace Test

View File

@ -0,0 +1,132 @@
// ---
//
// $Id: textoutput.cpp,v 1.4 2008/07/15 20:33:31 hartwork Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
#include <algorithm>
#if (defined(__WIN32__) || defined(WIN32))
# include "winconfig.h"
#else
# include "config.h"
#endif
#include "cpptest-textoutput.h"
#include "cpptest-time.h"
#include "utils.h"
using namespace std;
namespace Test
{
namespace
{
// Outputs detailed assert source information. Used in verbose mode.
//
struct ShowSource
{
ostream& _stream;
ShowSource(ostream& stream) : _stream(stream) {}
void operator()(const Source& s)
{
_stream << "\tTest: " << s.test() << endl
<< "\tSuite: " << s.suite() << endl
<< "\tFile: " << s.file() << endl
<< "\tLine: " << s.line() << endl
<< "\tMessage: " << s.message() << endl << endl;
}
};
} // anonymous namespace
/// Constructs a text output handler.
///
/// \param mode Output mode.
/// \param stream Stream to output to.
///
TextOutput::TextOutput(Mode mode, ostream& stream)
: _mode(mode),
_stream(stream),
_total_errors(0)
{}
void
TextOutput::finished(int tests, const Time& time)
{
_stream << "Total: " << tests << " tests, "
<< correct(tests, _total_errors) << "% correct"
<< " in " << time << " seconds" << endl;
}
void
TextOutput::suite_start(int tests, const string& name)
{
if (tests > 0)
{
_suite_name = name;
_suite_tests = _suite_errors = 0;
_suite_total_tests = tests;
_suite_error_list.clear();
_stream << _suite_name << ": "
<< "0/" << _suite_total_tests
<< "\r" << flush;
}
}
void
TextOutput::suite_end(int tests, const string& name, const Time& time)
{
if (tests > 0)
{
_stream << name << ": " << tests << "/" << tests << ", "
<< correct(tests, _suite_errors) << "% correct"
<< " in " << time << " seconds" << endl;
if (_mode == Verbose && _suite_errors)
for_each(_suite_error_list.begin(), _suite_error_list.end(),
ShowSource(_stream));
_total_errors += _suite_errors;
}
}
void
TextOutput::test_end(const string&, bool ok, const Time&)
{
_stream << _suite_name << ": "
<< ++_suite_tests << "/" << _suite_total_tests
<< "\r" << flush;
if (!ok)
++_suite_errors;
}
void
TextOutput::assertment(const Source& s)
{
_suite_error_list.push_back(s);
}
} // namespace Test

176
tests/cppunit/time.cpp Normal file
View File

@ -0,0 +1,176 @@
// ---
//
// $Id: time.cpp,v 1.4 2008/07/15 20:33:31 hartwork Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
#if (defined(__WIN32__) || defined(WIN32))
# include "winconfig.h"
#else
# include "config.h"
#endif
#include "missing.h"
#include "cpptest-time.h"
#ifdef HAVE_GETTIMEOFDAY
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#else
#include <time.h>
#endif
#endif
using namespace std;
namespace Test
{
namespace
{
const unsigned int UsecPerSec = 1000000;
} // anonymous namespace
/// Constructs a time object with zeroed time.
///
Time::Time()
: _sec(0),
_usec(0)
{}
/// Constructs a time object.
///
/// \param sec Seconds.
/// \param usec Micro-seconds.
///
Time::Time(unsigned int sec, unsigned int usec)
: _sec(sec),
_usec(usec)
{}
/// \return Seconds.
///
unsigned int
Time::seconds() const
{
return _sec;
}
/// \return Micro-seconds.
///
unsigned int
Time::microseconds() const
{
return _usec;
}
/// \return The current time.
///
Time
Time::current()
{
struct timeval tv;
gettimeofday(&tv, 0);
return Time(tv.tv_sec, tv.tv_usec);
}
/// \relates Time
///
/// Computes the time elapsed between two time values.
///
/// \param t1 Left-hand time, should be greater than \a t2.
/// \param t2 Right-hand time, should be less than \a t1.
///
/// \return Computed time value.
///
Time
operator-(const Time& t1, const Time& t2)
{
if (t2._sec > t1._sec || (t2._sec == t1._sec && t2._usec > t1._usec))
return Time();
unsigned int sec = t1._sec - t2._sec;
unsigned int usec;
if (t2._usec > t1._usec)
{
--sec;
usec = UsecPerSec - (t2._usec - t1._usec);
}
else
usec = t1._usec - t2._usec;
return Time(sec, usec);
}
/// \relates Time
///
/// Adds two time values.
///
/// \param t1 Left-hand time.
/// \param t2 Right-hand time.
///
/// \return Computed time value.
///
Time
operator+(const Time& t1, const Time& t2)
{
unsigned int sec = t1._sec + t2._sec;
unsigned int usec = t1._usec + t2._usec;
if (usec > UsecPerSec)
{
++sec;
usec -= UsecPerSec;
}
return Time(sec, usec);
}
/// \relates Time
///
/// Outputs a time to an output stream.
///
/// \param os Output stream to write to.
/// \param t %Time to output.
///
/// \return A reference to the given output stream.
///
ostream&
operator<<(ostream& os, const Time& t)
{
int old_fill(os.fill());
int old_width(os.width());
os << t.seconds() << '.';
os.fill('0');
os.width(6);
os << t.microseconds();
os.fill(old_fill);
os.width(old_width);
return os;
}
} // namespace Test

50
tests/cppunit/utils.cpp Normal file
View File

@ -0,0 +1,50 @@
// ---
//
// $Id: utils.cpp,v 1.5 2008/07/15 20:33:31 hartwork Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
#if (defined(__WIN32__) || defined(WIN32))
# include "winconfig.h"
#else
# include "config.h"
#endif
#include "missing.h"
#include "utils.h"
namespace Test
{
// Computes the procentage of correct tests.
//
int
correct(int tests, int errors)
{
if ((errors == 0) || (tests == 0))
return 100;
return (tests - errors) * 100 / tests;
}
} // namespace Test

36
tests/cppunit/utils.h Normal file
View File

@ -0,0 +1,36 @@
// ---
//
// $Id: utils.h,v 1.3 2005/06/08 08:08:06 nilu Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
#ifndef CPPTEST_UTILS_H
#define CPPTEST_UTILS_H
namespace Test
{
extern int correct(int tests, int errors);
} // namespace Test
#endif // #ifndef CPPTEST_UTILS_H

44
tests/cppunit/winconfig.h Normal file
View File

@ -0,0 +1,44 @@
// ---
//
// $Id: winconfig.h,v 1.1 2008/07/15 20:33:31 hartwork Exp $
//
// CppTest - A C++ Unit Testing Framework
// Copyright (c) 2003 Niklas Lundell
//
// ---
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// ---
#ifndef TEST_CONFIG_H
#define TEST_CONFIG_H
// Capabilities
//
#define HAVE_GETTICKCOUNT
// Compiler specific stuff
//
#if _MSC_VER == 1200 // MS Visual C++ 6.0
#pragma warning (disable: 4786)
#endif
#if _MSC_VER > 1300 // MS Visual C++ .NET 2002 and above
#pragma warning (disable: 4267)
#endif
#endif // #ifndef TEST_CONFIG_H

150
tests/fixed_memory_test.h Normal file
View File

@ -0,0 +1,150 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2006 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __EQEMU_TESTS_FIXED_MEMORY_H
#define __EQEMU_TESTS_FIXED_MEMORY_H
#include "cppunit/cpptest.h"
#include "../common/fixed_memory_hash_set.h"
#include "../common/Item.h"
class FixedMemoryHashTest : public Test::Suite {
typedef void(FixedMemoryHashTest::*TestFunction)(void);
public:
FixedMemoryHashTest() {
size_ = EQEmu::FixedMemoryHashSet<Item_Struct>::estimated_size(72000, 190000);
data_ = new uint8[size_];
memset(data_, 0, size_);
TEST_ADD(FixedMemoryHashTest::InitTest);
TEST_ADD(FixedMemoryHashTest::LoadTest);
TEST_ADD(FixedMemoryHashTest::InsertTest);
TEST_ADD(FixedMemoryHashTest::RetrieveTest);
TEST_ADD(FixedMemoryHashTest::OverwriteTest);
TEST_ADD(FixedMemoryHashTest::OverwriteRetrieveTest);
TEST_ADD(FixedMemoryHashTest::InsertAgainTest);
TEST_ADD(FixedMemoryHashTest::RetrieveAgainTest);
}
~FixedMemoryHashTest() {
delete[] data_;
}
void InitTest() {
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_, 72000, 190000);
TEST_ASSERT(!hash.exists(1001));
TEST_ASSERT(hash.size() == 0);
TEST_ASSERT(hash.max_size() == 72000);
TEST_ASSERT(hash.empty());
}
void LoadTest() {
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_);
TEST_ASSERT(!hash.exists(1001));
TEST_ASSERT(hash.size() == 0);
TEST_ASSERT(hash.max_size() == 72000);
TEST_ASSERT(hash.empty());
}
void InsertTest() {
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_);
Item_Struct item;
memset(&item, 0, sizeof(item));
strcpy(item.Name, "Iron Sword");
item.ID = 1001;
hash.insert(1001, item);
TEST_ASSERT(hash.exists(1001));
TEST_ASSERT(hash.size() == 1);
TEST_ASSERT(hash.max_size() == 72000);
TEST_ASSERT(!hash.empty());
}
void RetrieveTest() {
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_);
TEST_ASSERT(hash.exists(1001));
TEST_ASSERT(hash.size() == 1);
TEST_ASSERT(hash.max_size() == 72000);
TEST_ASSERT(!hash.empty());
Item_Struct item = hash[1001];
TEST_ASSERT(strcmp(item.Name, "Iron Sword") == 0);
TEST_ASSERT(item.ID == 1001);
}
void OverwriteTest() {
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_);
Item_Struct item;
memset(&item, 0, sizeof(item));
strcpy(item.Name, "Steel Sword");
item.ID = 1001;
hash.insert(1001, item);
TEST_ASSERT(hash.exists(1001));
TEST_ASSERT(hash.size() == 1);
TEST_ASSERT(hash.max_size() == 72000);
TEST_ASSERT(!hash.empty());
}
void OverwriteRetrieveTest() {
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_);
TEST_ASSERT(hash.exists(1001));
TEST_ASSERT(hash.size() == 1);
TEST_ASSERT((hash.max_size() == 72000));
TEST_ASSERT(!hash.empty());
Item_Struct item = hash[1001];
TEST_ASSERT(strcmp(item.Name, "Steel Sword") == 0);
TEST_ASSERT(item.ID == 1001);
}
void InsertAgainTest() {
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_);
Item_Struct item;
memset(&item, 0, sizeof(item));
strcpy(item.Name, "Iron Sword");
item.ID = 1000;
hash.insert(1000, item);
TEST_ASSERT(hash.exists(1000));
TEST_ASSERT(hash.exists(1001));
TEST_ASSERT(hash.size() == 2);
TEST_ASSERT(hash.max_size() == 72000);
TEST_ASSERT(!hash.empty());
}
void RetrieveAgainTest() {
EQEmu::FixedMemoryHashSet<Item_Struct> hash(data_, size_);
TEST_ASSERT(hash.exists(1000));
TEST_ASSERT(hash.exists(1001));
TEST_ASSERT(hash.size() == 2);
TEST_ASSERT(hash.max_size() == 72000);
TEST_ASSERT(!hash.empty());
Item_Struct item = hash[1000];
TEST_ASSERT(strcmp(item.Name, "Iron Sword") == 0);
TEST_ASSERT(item.ID == 1000);
item = hash[1001];
TEST_ASSERT(strcmp(item.Name, "Steel Sword") == 0);
TEST_ASSERT(item.ID == 1001);
}
private:
uint8 *data_;
size_t size_;
};
#endif

63
tests/ipc_mutex_test.h Normal file
View File

@ -0,0 +1,63 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2006 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __EQEMU_TESTS_IPC_MUTEX_H
#define __EQEMU_TESTS_IPC_MUTEX_H
#include "cppunit/cpptest.h"
#include "../common/ipc_mutex.h"
class IPCMutexTest : public Test::Suite {
typedef void(IPCMutexTest::*TestFunction)(void);
public:
IPCMutexTest() {
TEST_ADD(IPCMutexTest::LockMutexTest);
TEST_ADD(IPCMutexTest::UnlockMutexTest);
TEST_ADD(IPCMutexTest::DoubleLockMutexTest);
TEST_ADD(IPCMutexTest::DoubleUnlockMutexTest);
}
~IPCMutexTest() {
}
void LockMutexTest() {
EQEmu::IPCMutex mutex("TestMutex1");
TEST_ASSERT(mutex.Lock());
TEST_ASSERT(mutex.Unlock());
}
void UnlockMutexTest() {
EQEmu::IPCMutex mutex("TestMutex2");
TEST_ASSERT(!mutex.Unlock());
}
void DoubleLockMutexTest() {
EQEmu::IPCMutex mutex("TestMutex3");
TEST_ASSERT(mutex.Lock());
TEST_ASSERT(!mutex.Lock());
}
void DoubleUnlockMutexTest() {
EQEmu::IPCMutex mutex("TestMutex4");
TEST_ASSERT(mutex.Lock());
TEST_ASSERT(mutex.Unlock());
TEST_ASSERT(!mutex.Unlock());
}
};
#endif

64
tests/main.cpp Normal file
View File

@ -0,0 +1,64 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2006 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2006 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <iostream>
#include <fstream>
#include <memory>
#include "memory_mapped_file_test.h"
#include "ipc_mutex_test.h"
#include "fixed_memory_test.h"
int main() {
try {
std::unique_ptr<Test::Output> output(new Test::HtmlOutput);
Test::Suite tests;
tests.add(std::auto_ptr<MemoryMappedFileTest>(new MemoryMappedFileTest()));
tests.add(std::auto_ptr<IPCMutexTest>(new IPCMutexTest()));
tests.add(std::auto_ptr<FixedMemoryHashTest>(new FixedMemoryHashTest()));
tests.run(*output, true);
std::ofstream outfile("tests.html");
Test::HtmlOutput* const html = dynamic_cast<Test::HtmlOutput*>(output.get());
if(html)
html->generate(outfile, true, "EQEmuTests");
outfile.close();
} catch(...) {
getchar();
return -1;
}
getchar();
return 0;
}

View File

@ -0,0 +1,66 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2006 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __EQEMU_TESTS_MEMORY_MAPPED_FILE_H
#define __EQEMU_TESTS_MEMORY_MAPPED_FILE_H
#include "cppunit/cpptest.h"
#include "../common/memory_mapped_file.h"
class MemoryMappedFileTest : public Test::Suite {
typedef void(MemoryMappedFileTest::*TestFunction)(void);
public:
MemoryMappedFileTest() {
TEST_ADD(MemoryMappedFileTest::LoadAndZeroMMF)
TEST_ADD(MemoryMappedFileTest::LoadExistingMMF)
}
~MemoryMappedFileTest() {
}
private:
void LoadAndZeroMMF() {
EQEmu::MemoryMappedFile mmf("testfile.txt", 512);
mmf.ZeroFile();
TEST_ASSERT(!mmf.Loaded());
TEST_ASSERT(mmf.Size() == 512);
unsigned char *data = reinterpret_cast<unsigned char*>(mmf.Get());
TEST_ASSERT(data != NULL);
*reinterpret_cast<uint32*>(data) = 562;
mmf.SetLoaded();
TEST_ASSERT(mmf.Loaded());
}
void LoadExistingMMF() {
EQEmu::MemoryMappedFile mmf("testfile.txt");
TEST_ASSERT(mmf.Size() == 512);
TEST_ASSERT(mmf.Loaded());
unsigned char *data = reinterpret_cast<unsigned char*>(mmf.Get());
TEST_ASSERT(data != NULL);
uint32 val = *reinterpret_cast<uint32*>(data);
TEST_ASSERT(val == 562);
}
};
#endif