Bundle libOpenMPT as a dynamic framework, which should be safe once again, now that there is only one version to bundle. Also, now it is using the versions of libvorbisfile and libmpg123 that are bundled with the player, instead of compiling minimp3 and stbvorbis. Signed-off-by: Christopher Snowhill <kode54@gmail.com>
309 lines
6.5 KiB
C++
309 lines
6.5 KiB
C++
/*
|
|
* TestToolsLib.cpp
|
|
* ----------------
|
|
* Purpose: Unit test framework for libopenmpt.
|
|
* Notes : Currently somewhat unreadable :/
|
|
* Authors: OpenMPT Devs
|
|
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
|
*/
|
|
|
|
|
|
#include "stdafx.h"
|
|
#include "TestToolsLib.h"
|
|
|
|
|
|
#ifdef ENABLE_TESTS
|
|
#ifndef MODPLUG_TRACKER
|
|
|
|
|
|
#include <exception>
|
|
#include <iostream>
|
|
|
|
#include <cstdlib>
|
|
|
|
|
|
OPENMPT_NAMESPACE_BEGIN
|
|
|
|
|
|
namespace Test {
|
|
|
|
|
|
|
|
void mpt_test_reporter::case_run(const mpt::source_location& loc)
|
|
{
|
|
#if !MPT_OS_DJGPP
|
|
std::cout << "TEST..: " << MPT_AFORMAT("{}({}):")(loc.file_name() ? loc.file_name() : "", loc.line()) << ": " << std::endl;
|
|
#else
|
|
MPT_UNUSED(loc);
|
|
#endif
|
|
}
|
|
|
|
void mpt_test_reporter::case_run(const mpt::source_location& loc, const char* text_e)
|
|
{
|
|
#if !MPT_OS_DJGPP
|
|
std::cout << "TEST..: " << MPT_AFORMAT("{}({}): {}")(loc.file_name() ? loc.file_name() : "", loc.line(), text_e) << ": " << std::endl;
|
|
#else
|
|
MPT_UNUSED(loc);
|
|
MPT_UNUSED(text_e);
|
|
#endif
|
|
}
|
|
|
|
void mpt_test_reporter::case_run(const mpt::source_location& loc, const char* text_ex, const char* text_e)
|
|
{
|
|
if(text_ex)
|
|
{
|
|
#if !MPT_OS_DJGPP
|
|
std::cout << "TEST..: " << MPT_AFORMAT("{}({}): {} throws {}")(loc.file_name() ? loc.file_name() : "", loc.line(), text_e, text_ex) << ": " << std::endl;
|
|
#else
|
|
MPT_UNUSED(loc);
|
|
MPT_UNUSED(text_ex);
|
|
MPT_UNUSED(text_e);
|
|
#endif
|
|
} else
|
|
{
|
|
#if !MPT_OS_DJGPP
|
|
std::cout << "TEST..: " << MPT_AFORMAT("{}({}): {} throws")(loc.file_name() ? loc.file_name() : "", loc.line(), text_e) << ": " << std::endl;
|
|
#else
|
|
MPT_UNUSED(loc);
|
|
MPT_UNUSED(text_ex);
|
|
MPT_UNUSED(text_e);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void mpt_test_reporter::case_run(const mpt::source_location& loc, const char* text_a, const char* text_cmp, const char* text_b)
|
|
{
|
|
#if !MPT_OS_DJGPP
|
|
std::cout << "TEST..: " << MPT_AFORMAT("{}({}): {} {} {}")(loc.file_name() ? loc.file_name() : "", loc.line(), text_a, text_cmp, text_b) << ": " << std::endl;
|
|
#else
|
|
MPT_UNUSED(loc);
|
|
MPT_UNUSED(text_a);
|
|
MPT_UNUSED(text_cmp);
|
|
MPT_UNUSED(text_b);
|
|
#endif
|
|
}
|
|
|
|
void mpt_test_reporter::case_result(const mpt::source_location& loc, const mpt::test::result& result)
|
|
{
|
|
MPT_UNUSED(loc);
|
|
if(std::holds_alternative<mpt::test::result_success>(result.info))
|
|
{
|
|
#if !MPT_OS_DJGPP
|
|
std::cout << "RESULT: PASS" << std::endl;
|
|
#endif
|
|
} else if(std::holds_alternative<mpt::test::result_failure>(result.info))
|
|
{
|
|
fail_count++;
|
|
std::cout << "RESULT: FAIL" << std::endl;
|
|
std::cout.flush();
|
|
std::cerr << "FAIL: " << "FAILURE: " << std::get<mpt::test::result_failure>(result.info).text << std::endl;
|
|
std::cerr.flush();
|
|
} else if(std::holds_alternative<mpt::test::result_unexpected_exception>(result.info))
|
|
{
|
|
fail_count++;
|
|
std::cout << "RESULT: FAIL" << std::endl;
|
|
std::cout.flush();
|
|
std::cerr << "FAIL: " << "UNEXPECTED EXCEPTION: " << std::get<mpt::test::result_unexpected_exception>(result.info).text << std::endl;
|
|
std::cerr.flush();
|
|
} else
|
|
{
|
|
fail_count++;
|
|
std::cout << "RESULT: FAIL" << std::endl;
|
|
std::cout.flush();
|
|
std::cerr << "FAIL: " << "UNKOWN" << std::endl;
|
|
std::cerr.flush();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int fail_count = 0;
|
|
|
|
|
|
static std::string remove_newlines(std::string str)
|
|
{
|
|
return mpt::replace(mpt::replace(str, std::string("\n"), std::string(" ")), std::string("\r"), std::string(" "));
|
|
}
|
|
|
|
|
|
Testcase::Testcase(Fatality fatality, Verbosity verbosity, const char * const desc, const mpt::source_location &loc)
|
|
: fatality(fatality)
|
|
, verbosity(verbosity)
|
|
, desc(desc)
|
|
, loc(loc)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
std::string Testcase::AsString() const
|
|
{
|
|
return MPT_AFORMAT("{}({}): {}")(loc.file_name() ? loc.file_name() : "", loc.line(), remove_newlines(desc));
|
|
}
|
|
|
|
|
|
void Testcase::ShowStart() const
|
|
{
|
|
switch(verbosity)
|
|
{
|
|
case VerbosityQuiet:
|
|
break;
|
|
case VerbosityNormal:
|
|
#if !MPT_OS_DJGPP
|
|
std::cout << "TEST..: " << AsString() << ": " << std::endl;
|
|
#endif
|
|
break;
|
|
case VerbosityVerbose:
|
|
#if !MPT_OS_DJGPP
|
|
std::cout << "TEST..: " << AsString() << ": " << std::endl;
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void Testcase::ShowProgress(const char * text) const
|
|
{
|
|
switch(verbosity)
|
|
{
|
|
case VerbosityQuiet:
|
|
break;
|
|
case VerbosityNormal:
|
|
break;
|
|
case VerbosityVerbose:
|
|
#if !MPT_OS_DJGPP
|
|
std::cout << "TEST..: " << AsString() << ": " << text << std::endl;
|
|
#else
|
|
MPT_UNUSED_VARIABLE(text);
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void Testcase::ShowPass() const
|
|
{
|
|
switch(verbosity)
|
|
{
|
|
case VerbosityQuiet:
|
|
break;
|
|
case VerbosityNormal:
|
|
#if !MPT_OS_DJGPP
|
|
std::cout << "RESULT: PASS" << std::endl;
|
|
#endif
|
|
break;
|
|
case VerbosityVerbose:
|
|
#if !MPT_OS_DJGPP
|
|
std::cout << "PASS..: " << AsString() << std::endl;
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void Testcase::ShowFail(bool exception, const char * const text) const
|
|
{
|
|
switch(verbosity)
|
|
{
|
|
case VerbosityQuiet:
|
|
break;
|
|
case VerbosityNormal:
|
|
std::cout << "RESULT: FAIL" << std::endl;
|
|
break;
|
|
case VerbosityVerbose:
|
|
std::cout << "FAIL..: " << AsString() << std::endl;
|
|
break;
|
|
}
|
|
std::cout.flush();
|
|
if(!exception)
|
|
{
|
|
if(!text || (text && std::string(text).empty()))
|
|
{
|
|
std::cerr << "FAIL: " << AsString() << std::endl;
|
|
} else
|
|
{
|
|
std::cerr << "FAIL: " << AsString() << " : " << text << std::endl;
|
|
}
|
|
} else
|
|
{
|
|
if(!text || (text && std::string(text).empty()))
|
|
{
|
|
std::cerr << "FAIL: " << AsString() << " EXCEPTION!" << std::endl;
|
|
} else
|
|
{
|
|
std::cerr << "FAIL: " << AsString() << " EXCEPTION: " << text << std::endl;
|
|
}
|
|
}
|
|
std::cerr.flush();
|
|
}
|
|
|
|
|
|
void Testcase::ReportPassed()
|
|
{
|
|
ShowPass();
|
|
}
|
|
|
|
|
|
void Testcase::ReportFailed()
|
|
{
|
|
fail_count++;
|
|
ReportException();
|
|
}
|
|
|
|
|
|
void Testcase::ReportException()
|
|
{
|
|
try
|
|
{
|
|
throw; // get the exception
|
|
} catch(TestFailed & e)
|
|
{
|
|
ShowFail(false, e.values.c_str());
|
|
if(fatality == FatalityStop)
|
|
{
|
|
throw; // rethrow
|
|
}
|
|
} catch(std::exception & e)
|
|
{
|
|
ShowFail(true, e.what());
|
|
throw; // rethrow
|
|
} catch(...)
|
|
{
|
|
ShowFail(true);
|
|
throw; // rethrow
|
|
}
|
|
}
|
|
|
|
|
|
} // namespace Test
|
|
|
|
|
|
#if defined(MPT_ASSERT_HANDLER_NEEDED)
|
|
|
|
MPT_NOINLINE void AssertHandler(const mpt::source_location &loc, const char *expr, const char *msg)
|
|
{
|
|
Test::fail_count++;
|
|
if(msg)
|
|
{
|
|
mpt::log::GlobalLogger().SendLogMessage(loc, LogError, "ASSERT",
|
|
U_("ASSERTION FAILED: ") + mpt::ToUnicode(mpt::Charset::ASCII, msg) + U_(" (") + mpt::ToUnicode(mpt::Charset::ASCII, expr) + U_(")")
|
|
);
|
|
} else
|
|
{
|
|
mpt::log::GlobalLogger().SendLogMessage(loc, LogError, "ASSERT",
|
|
U_("ASSERTION FAILED: ") + mpt::ToUnicode(mpt::Charset::ASCII, expr)
|
|
);
|
|
}
|
|
#if defined(MPT_BUILD_FATAL_ASSERTS)
|
|
std::abort();
|
|
#endif // MPT_BUILD_FATAL_ASSERTS
|
|
}
|
|
|
|
#endif // MPT_ASSERT_HANDLER_NEEDED
|
|
|
|
|
|
OPENMPT_NAMESPACE_END
|
|
|
|
|
|
#endif // !MODPLUG_TRACKER
|
|
#endif // ENABLE_TESTS
|