mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2026-02-16 02:30:54 +00:00
start adding tests
This commit is contained in:
185
include/Common.h
185
include/Common.h
@@ -15,6 +15,8 @@ extern TSentry Sentry;
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
|
#include <doctest/doctest.h>
|
||||||
|
|
||||||
#include "Compat.h"
|
#include "Compat.h"
|
||||||
|
|
||||||
#include "TConsole.h"
|
#include "TConsole.h"
|
||||||
@@ -139,88 +141,115 @@ void RegisterThread(const std::string& str);
|
|||||||
#define _line std::to_string(__LINE__)
|
#define _line std::to_string(__LINE__)
|
||||||
#define _in_lambda (std::string(__func__) == "operator()")
|
#define _in_lambda (std::string(__func__) == "operator()")
|
||||||
|
|
||||||
// we would like the full function signature 'void a::foo() const'
|
|
||||||
// on windows this is __FUNCSIG__, on GCC it's __PRETTY_FUNCTION__,
|
|
||||||
// feel free to add more
|
|
||||||
#if defined(WIN32)
|
|
||||||
#define _function_name std::string(__FUNCSIG__)
|
|
||||||
#elif defined(__unix) || defined(__unix__)
|
|
||||||
#define _function_name std::string(__PRETTY_FUNCTION__)
|
|
||||||
#else
|
|
||||||
#define _function_name std::string(__func__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
#define DEBUG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(DEBUG)
|
|
||||||
|
|
||||||
// if this is defined, we will show the full function signature infront of
|
|
||||||
// each info/debug/warn... call instead of the 'filename:line' format.
|
|
||||||
#if defined(BMP_FULL_FUNCTION_NAMES)
|
|
||||||
#define _this_location (ThreadName() + _function_name + " ")
|
|
||||||
#else
|
|
||||||
#define _this_location (ThreadName() + _file_basename + ":" + _line + " ")
|
|
||||||
#endif
|
|
||||||
#define SU_RAW SSU_UNRAW
|
|
||||||
|
|
||||||
#else // !defined(DEBUG)
|
|
||||||
|
|
||||||
#define SU_RAW RAWIFY(SSU_UNRAW)
|
|
||||||
#define _this_location (ThreadName())
|
|
||||||
|
|
||||||
#endif // defined(DEBUG)
|
|
||||||
|
|
||||||
#define beammp_warn(x) Application::Console().Write(_this_location + std::string("[WARN] ") + (x))
|
|
||||||
#define beammp_info(x) Application::Console().Write(_this_location + std::string("[INFO] ") + (x))
|
|
||||||
#define beammp_error(x) \
|
|
||||||
do { \
|
|
||||||
Application::Console().Write(_this_location + std::string("[ERROR] ") + (x)); \
|
|
||||||
Sentry.AddErrorBreadcrumb((x), _file_basename, _line); \
|
|
||||||
} while (false)
|
|
||||||
#define beammp_lua_error(x) \
|
|
||||||
do { \
|
|
||||||
Application::Console().Write(_this_location + std::string("[LUA ERROR] ") + (x)); \
|
|
||||||
} while (false)
|
|
||||||
#define beammp_lua_warn(x) \
|
|
||||||
do { \
|
|
||||||
Application::Console().Write(_this_location + std::string("[LUA WARN] ") + (x)); \
|
|
||||||
} while (false)
|
|
||||||
#define luaprint(x) Application::Console().Write(_this_location + std::string("[LUA] ") + (x))
|
|
||||||
#define beammp_debug(x) \
|
|
||||||
do { \
|
|
||||||
if (Application::Settings.DebugModeEnabled) { \
|
|
||||||
Application::Console().Write(_this_location + std::string("[DEBUG] ") + (x)); \
|
|
||||||
} \
|
|
||||||
} while (false)
|
|
||||||
#define beammp_event(x) \
|
|
||||||
do { \
|
|
||||||
if (Application::Settings.DebugModeEnabled) { \
|
|
||||||
Application::Console().Write(_this_location + std::string("[EVENT] ") + (x)); \
|
|
||||||
} \
|
|
||||||
} while (false)
|
|
||||||
// for those times when you just need to ignore something :^)
|
// for those times when you just need to ignore something :^)
|
||||||
// explicity disables a [[nodiscard]] warning
|
// explicity disables a [[nodiscard]] warning
|
||||||
#define beammp_ignore(x) (void)x
|
#define beammp_ignore(x) (void)x
|
||||||
// trace() is a debug-build debug()
|
|
||||||
#if defined(DEBUG)
|
|
||||||
#define beammp_trace(x) \
|
|
||||||
do { \
|
|
||||||
if (Application::Settings.DebugModeEnabled) { \
|
|
||||||
Application::Console().Write(_this_location + std::string("[TRACE] ") + (x)); \
|
|
||||||
} \
|
|
||||||
} while (false)
|
|
||||||
#else
|
|
||||||
#define beammp_trace(x)
|
|
||||||
#endif // defined(DEBUG)
|
|
||||||
|
|
||||||
#define beammp_errorf(...) beammp_error(fmt::format(__VA_ARGS__))
|
// clang-format off
|
||||||
#define beammp_infof(...) beammp_info(fmt::format(__VA_ARGS__))
|
#ifdef DOCTEST_CONFIG_DISABLE
|
||||||
#define beammp_warnf(...) beammp_warn(fmt::format(__VA_ARGS__))
|
|
||||||
#define beammp_tracef(...) beammp_trace(fmt::format(__VA_ARGS__))
|
// we would like the full function signature 'void a::foo() const'
|
||||||
#define beammp_lua_errorf(...) beammp_lua_error(fmt::format(__VA_ARGS__))
|
// on windows this is __FUNCSIG__, on GCC it's __PRETTY_FUNCTION__,
|
||||||
#define beammp_lua_warnf(...) beammp_lua_warn(fmt::format(__VA_ARGS__))
|
// feel free to add more
|
||||||
|
#if defined(WIN32)
|
||||||
|
#define _function_name std::string(__FUNCSIG__)
|
||||||
|
#elif defined(__unix) || defined(__unix__)
|
||||||
|
#define _function_name std::string(__PRETTY_FUNCTION__)
|
||||||
|
#else
|
||||||
|
#define _function_name std::string(__func__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
#define DEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(DEBUG)
|
||||||
|
|
||||||
|
// if this is defined, we will show the full function signature infront of
|
||||||
|
// each info/debug/warn... call instead of the 'filename:line' format.
|
||||||
|
#if defined(BMP_FULL_FUNCTION_NAMES)
|
||||||
|
#define _this_location (ThreadName() + _function_name + " ")
|
||||||
|
#else
|
||||||
|
#define _this_location (ThreadName() + _file_basename + ":" + _line + " ")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // defined(DEBUG)
|
||||||
|
|
||||||
|
#define beammp_warn(x) Application::Console().Write(_this_location + std::string("[WARN] ") + (x))
|
||||||
|
#define beammp_info(x) Application::Console().Write(_this_location + std::string("[INFO] ") + (x))
|
||||||
|
#define beammp_error(x) \
|
||||||
|
do { \
|
||||||
|
Application::Console().Write(_this_location + std::string("[ERROR] ") + (x)); \
|
||||||
|
Sentry.AddErrorBreadcrumb((x), _file_basename, _line); \
|
||||||
|
} while (false)
|
||||||
|
#define beammp_lua_error(x) \
|
||||||
|
do { \
|
||||||
|
Application::Console().Write(_this_location + std::string("[LUA ERROR] ") + (x)); \
|
||||||
|
} while (false)
|
||||||
|
#define beammp_lua_warn(x) \
|
||||||
|
do { \
|
||||||
|
Application::Console().Write(_this_location + std::string("[LUA WARN] ") + (x)); \
|
||||||
|
} while (false)
|
||||||
|
#define luaprint(x) Application::Console().Write(_this_location + std::string("[LUA] ") + (x))
|
||||||
|
#define beammp_debug(x) \
|
||||||
|
do { \
|
||||||
|
if (Application::Settings.DebugModeEnabled) { \
|
||||||
|
Application::Console().Write(_this_location + std::string("[DEBUG] ") + (x)); \
|
||||||
|
} \
|
||||||
|
} while (false)
|
||||||
|
#define beammp_event(x) \
|
||||||
|
do { \
|
||||||
|
if (Application::Settings.DebugModeEnabled) { \
|
||||||
|
Application::Console().Write(_this_location + std::string("[EVENT] ") + (x)); \
|
||||||
|
} \
|
||||||
|
} while (false)
|
||||||
|
// trace() is a debug-build debug()
|
||||||
|
#if defined(DEBUG)
|
||||||
|
#define beammp_trace(x) \
|
||||||
|
do { \
|
||||||
|
if (Application::Settings.DebugModeEnabled) { \
|
||||||
|
Application::Console().Write(_this_location + std::string("[TRACE] ") + (x)); \
|
||||||
|
} \
|
||||||
|
} while (false)
|
||||||
|
#else
|
||||||
|
#define beammp_trace(x)
|
||||||
|
#endif // defined(DEBUG)
|
||||||
|
|
||||||
|
#define beammp_errorf(...) beammp_error(fmt::format(__VA_ARGS__))
|
||||||
|
#define beammp_infof(...) beammp_info(fmt::format(__VA_ARGS__))
|
||||||
|
#define beammp_warnf(...) beammp_warn(fmt::format(__VA_ARGS__))
|
||||||
|
#define beammp_tracef(...) beammp_trace(fmt::format(__VA_ARGS__))
|
||||||
|
#define beammp_lua_errorf(...) beammp_lua_error(fmt::format(__VA_ARGS__))
|
||||||
|
#define beammp_lua_warnf(...) beammp_lua_warn(fmt::format(__VA_ARGS__))
|
||||||
|
|
||||||
|
#else // DOCTEST_CONFIG_DISABLE
|
||||||
|
|
||||||
|
#define beammp_error(x) /* x */
|
||||||
|
#define beammp_lua_error(x) /* x */
|
||||||
|
#define beammp_warn(x) /* x */
|
||||||
|
#define beammp_lua_warn(x) /* x */
|
||||||
|
#define beammp_info(x) /* x */
|
||||||
|
#define beammp_event(x) /* x */
|
||||||
|
#define beammp_debug(x) /* x */
|
||||||
|
#define beammp_trace(x) /* x */
|
||||||
|
#define luaprint(x) /* x */
|
||||||
|
#define beammp_errorf(...) beammp_error(fmt::format(__VA_ARGS__))
|
||||||
|
#define beammp_infof(...) beammp_info(fmt::format(__VA_ARGS__))
|
||||||
|
#define beammp_warnf(...) beammp_warn(fmt::format(__VA_ARGS__))
|
||||||
|
#define beammp_tracef(...) beammp_trace(fmt::format(__VA_ARGS__))
|
||||||
|
#define beammp_lua_errorf(...) beammp_lua_error(fmt::format(__VA_ARGS__))
|
||||||
|
#define beammp_lua_warnf(...) beammp_lua_warn(fmt::format(__VA_ARGS__))
|
||||||
|
|
||||||
|
#endif // DOCTEST_CONFIG_DISABLE
|
||||||
|
|
||||||
|
#if defined(DEBUG)
|
||||||
|
#define SU_RAW SSU_UNRAW
|
||||||
|
#else
|
||||||
|
#define SU_RAW RAWIFY(SSU_UNRAW)
|
||||||
|
#define _this_location (ThreadName())
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
void LogChatMessage(const std::string& name, int id, const std::string& msg);
|
void LogChatMessage(const std::string& name, int id, const std::string& msg);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "ArgsParser.h"
|
#include "ArgsParser.h"
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <doctest/doctest.h>
|
||||||
|
|
||||||
void ArgsParser::Parse(const std::vector<std::string_view>& ArgList) {
|
void ArgsParser::Parse(const std::vector<std::string_view>& ArgList) {
|
||||||
for (const auto& Arg : ArgList) {
|
for (const auto& Arg : ArgList) {
|
||||||
@@ -92,3 +93,78 @@ void ArgsParser::ConsumeLongFlag(const std::string& Arg) {
|
|||||||
beammp_warn("Argument '" + Name + "' was supplied but isn't a known argument, so it is likely being ignored.");
|
beammp_warn("Argument '" + Name + "' was supplied but isn't a known argument, so it is likely being ignored.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ArgsParser") {
|
||||||
|
ArgsParser parser;
|
||||||
|
|
||||||
|
SUBCASE("Simple args") {
|
||||||
|
parser.RegisterArgument({ "a" }, ArgsParser::Flags::NONE);
|
||||||
|
parser.RegisterArgument({ "hello" }, ArgsParser::Flags::NONE);
|
||||||
|
parser.Parse({ "--a", "--hello" });
|
||||||
|
CHECK(parser.Verify());
|
||||||
|
CHECK(parser.FoundArgument({ "a" }));
|
||||||
|
CHECK(parser.FoundArgument({ "hello" }));
|
||||||
|
CHECK(parser.FoundArgument({ "a", "hello" }));
|
||||||
|
CHECK(!parser.FoundArgument({ "b" }));
|
||||||
|
CHECK(!parser.FoundArgument({ "goodbye" }));
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("No args") {
|
||||||
|
parser.RegisterArgument({ "a" }, ArgsParser::Flags::NONE);
|
||||||
|
parser.RegisterArgument({ "hello" }, ArgsParser::Flags::NONE);
|
||||||
|
parser.Parse({});
|
||||||
|
CHECK(parser.Verify());
|
||||||
|
CHECK(!parser.FoundArgument({ "a" }));
|
||||||
|
CHECK(!parser.FoundArgument({ "hello" }));
|
||||||
|
CHECK(!parser.FoundArgument({ "a", "hello" }));
|
||||||
|
CHECK(!parser.FoundArgument({ "b" }));
|
||||||
|
CHECK(!parser.FoundArgument({ "goodbye" }));
|
||||||
|
CHECK(!parser.FoundArgument({ "" }));
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("Value args") {
|
||||||
|
parser.RegisterArgument({ "a" }, ArgsParser::Flags::HAS_VALUE);
|
||||||
|
parser.RegisterArgument({ "hello" }, ArgsParser::Flags::HAS_VALUE);
|
||||||
|
parser.Parse({ "--a=5", "--hello=world" });
|
||||||
|
CHECK(parser.Verify());
|
||||||
|
REQUIRE(parser.FoundArgument({ "a" }));
|
||||||
|
REQUIRE(parser.FoundArgument({ "hello" }));
|
||||||
|
CHECK(parser.GetValueOfArgument({ "a" }).has_value());
|
||||||
|
CHECK(parser.GetValueOfArgument({ "a" }).value() == "5");
|
||||||
|
CHECK(parser.GetValueOfArgument({ "hello" }).has_value());
|
||||||
|
CHECK(parser.GetValueOfArgument({ "hello" }).value() == "world");
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("Mixed value & no-value args") {
|
||||||
|
parser.RegisterArgument({ "a" }, ArgsParser::Flags::HAS_VALUE);
|
||||||
|
parser.RegisterArgument({ "hello" }, ArgsParser::Flags::NONE);
|
||||||
|
parser.Parse({ "--a=5", "--hello" });
|
||||||
|
CHECK(parser.Verify());
|
||||||
|
REQUIRE(parser.FoundArgument({ "a" }));
|
||||||
|
REQUIRE(parser.FoundArgument({ "hello" }));
|
||||||
|
CHECK(parser.GetValueOfArgument({ "a" }).has_value());
|
||||||
|
CHECK(parser.GetValueOfArgument({ "a" }).value() == "5");
|
||||||
|
CHECK(!parser.GetValueOfArgument({ "hello" }).has_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("Required args") {
|
||||||
|
SUBCASE("Two required, two present") {
|
||||||
|
parser.RegisterArgument({ "a" }, ArgsParser::Flags::REQUIRED);
|
||||||
|
parser.RegisterArgument({ "hello" }, ArgsParser::Flags::REQUIRED);
|
||||||
|
parser.Parse({ "--a", "--hello" });
|
||||||
|
CHECK(parser.Verify());
|
||||||
|
}
|
||||||
|
SUBCASE("Two required, one present") {
|
||||||
|
parser.RegisterArgument({ "a" }, ArgsParser::Flags::REQUIRED);
|
||||||
|
parser.RegisterArgument({ "hello" }, ArgsParser::Flags::REQUIRED);
|
||||||
|
parser.Parse({ "--a" });
|
||||||
|
CHECK(!parser.Verify());
|
||||||
|
}
|
||||||
|
SUBCASE("Two required, none present") {
|
||||||
|
parser.RegisterArgument({ "a" }, ArgsParser::Flags::REQUIRED);
|
||||||
|
parser.RegisterArgument({ "hello" }, ArgsParser::Flags::REQUIRED);
|
||||||
|
parser.Parse({ "--b" });
|
||||||
|
CHECK(!parser.Verify());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
101
src/Common.cpp
101
src/Common.cpp
@@ -64,6 +64,23 @@ std::array<uint8_t, 3> Application::VersionStrToInts(const std::string& str) {
|
|||||||
return Version;
|
return Version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Application::VersionStrToInts") {
|
||||||
|
auto v = Application::VersionStrToInts("1.2.3");
|
||||||
|
CHECK(v[0] == 1);
|
||||||
|
CHECK(v[1] == 2);
|
||||||
|
CHECK(v[2] == 3);
|
||||||
|
|
||||||
|
v = Application::VersionStrToInts("10.20.30");
|
||||||
|
CHECK(v[0] == 10);
|
||||||
|
CHECK(v[1] == 20);
|
||||||
|
CHECK(v[2] == 30);
|
||||||
|
|
||||||
|
v = Application::VersionStrToInts("100.200.255");
|
||||||
|
CHECK(v[0] == 100);
|
||||||
|
CHECK(v[1] == 200);
|
||||||
|
CHECK(v[2] == 255);
|
||||||
|
}
|
||||||
|
|
||||||
bool Application::IsOutdated(const Version& Current, const Version& Newest) {
|
bool Application::IsOutdated(const Version& Current, const Version& Newest) {
|
||||||
if (Newest.major > Current.major) {
|
if (Newest.major > Current.major) {
|
||||||
return true;
|
return true;
|
||||||
@@ -76,6 +93,49 @@ bool Application::IsOutdated(const Version& Current, const Version& Newest) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Application::IsOutdated (version check)") {
|
||||||
|
SUBCASE("Same version") {
|
||||||
|
CHECK(!Application::IsOutdated({ 1, 2, 3 }, { 1, 2, 3 }));
|
||||||
|
}
|
||||||
|
// we need to use over 1-2 digits to test against lexical comparisons
|
||||||
|
SUBCASE("Patch outdated") {
|
||||||
|
for (size_t Patch = 0; Patch < 10; ++Patch) {
|
||||||
|
for (size_t Minor = 0; Minor < 10; ++Minor) {
|
||||||
|
for (size_t Major = 0; Major < 10; ++Major) {
|
||||||
|
CHECK(Application::IsOutdated({ Major, Minor, Patch }, { Major, Minor, Patch + 1 }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SUBCASE("Minor outdated") {
|
||||||
|
for (size_t Patch = 0; Patch < 10; ++Patch) {
|
||||||
|
for (size_t Minor = 0; Minor < 10; ++Minor) {
|
||||||
|
for (size_t Major = 0; Major < 10; ++Major) {
|
||||||
|
CHECK(Application::IsOutdated({ Major, Minor, Patch }, { Major, Minor + 1, Patch }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SUBCASE("Major outdated") {
|
||||||
|
for (size_t Patch = 0; Patch < 10; ++Patch) {
|
||||||
|
for (size_t Minor = 0; Minor < 10; ++Minor) {
|
||||||
|
for (size_t Major = 0; Major < 10; ++Major) {
|
||||||
|
CHECK(Application::IsOutdated({ Major, Minor, Patch }, { Major + 1, Minor, Patch }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SUBCASE("All outdated") {
|
||||||
|
for (size_t Patch = 0; Patch < 10; ++Patch) {
|
||||||
|
for (size_t Minor = 0; Minor < 10; ++Minor) {
|
||||||
|
for (size_t Major = 0; Major < 10; ++Major) {
|
||||||
|
CHECK(Application::IsOutdated({ Major, Minor, Patch }, { Major + 1, Minor + 1, Patch + 1 }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Application::SetSubsystemStatus(const std::string& Subsystem, Status status) {
|
void Application::SetSubsystemStatus(const std::string& Subsystem, Status status) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case Status::Good:
|
case Status::Good:
|
||||||
@@ -98,6 +158,15 @@ void Application::SetSubsystemStatus(const std::string& Subsystem, Status status
|
|||||||
mSystemStatusMap[Subsystem] = status;
|
mSystemStatusMap[Subsystem] = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Application::SetSubsystemStatus") {
|
||||||
|
Application::SetSubsystemStatus("Test", Application::Status::Good);
|
||||||
|
auto Map = Application::GetSubsystemStatuses();
|
||||||
|
CHECK(Map.at("Test") == Application::Status::Good);
|
||||||
|
Application::SetSubsystemStatus("Test", Application::Status::Bad);
|
||||||
|
Map = Application::GetSubsystemStatuses();
|
||||||
|
CHECK(Map.at("Test") == Application::Status::Bad);
|
||||||
|
}
|
||||||
|
|
||||||
void Application::CheckForUpdates() {
|
void Application::CheckForUpdates() {
|
||||||
Application::SetSubsystemStatus("UpdateCheck", Application::Status::Starting);
|
Application::SetSubsystemStatus("UpdateCheck", Application::Status::Starting);
|
||||||
static bool FirstTime = true;
|
static bool FirstTime = true;
|
||||||
@@ -155,6 +224,25 @@ std::string ThreadName(bool DebugModeOverride) {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ThreadName") {
|
||||||
|
RegisterThread("MyThread");
|
||||||
|
auto OrigDebug = Application::Settings.DebugModeEnabled;
|
||||||
|
|
||||||
|
// ThreadName adds a space at the end, legacy but we need it still
|
||||||
|
SUBCASE("Debug mode enabled") {
|
||||||
|
Application::Settings.DebugModeEnabled = true;
|
||||||
|
CHECK(ThreadName(true) == "MyThread ");
|
||||||
|
CHECK(ThreadName(false) == "MyThread ");
|
||||||
|
}
|
||||||
|
SUBCASE("Debug mode disabled") {
|
||||||
|
Application::Settings.DebugModeEnabled = false;
|
||||||
|
CHECK(ThreadName(true) == "MyThread ");
|
||||||
|
CHECK(ThreadName(false) == "");
|
||||||
|
}
|
||||||
|
// cleanup
|
||||||
|
Application::Settings.DebugModeEnabled = OrigDebug;
|
||||||
|
}
|
||||||
|
|
||||||
void RegisterThread(const std::string& str) {
|
void RegisterThread(const std::string& str) {
|
||||||
std::string ThreadId;
|
std::string ThreadId;
|
||||||
#ifdef BEAMMP_WINDOWS
|
#ifdef BEAMMP_WINDOWS
|
||||||
@@ -172,6 +260,11 @@ void RegisterThread(const std::string& str) {
|
|||||||
threadNameMap[std::this_thread::get_id()] = str;
|
threadNameMap[std::this_thread::get_id()] = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("RegisterThread") {
|
||||||
|
RegisterThread("MyThread");
|
||||||
|
CHECK(threadNameMap.at(std::this_thread::get_id()) == "MyThread");
|
||||||
|
}
|
||||||
|
|
||||||
Version::Version(uint8_t major, uint8_t minor, uint8_t patch)
|
Version::Version(uint8_t major, uint8_t minor, uint8_t patch)
|
||||||
: major(major)
|
: major(major)
|
||||||
, minor(minor)
|
, minor(minor)
|
||||||
@@ -185,6 +278,12 @@ std::string Version::AsString() {
|
|||||||
return fmt::format("{:d}.{:d}.{:d}", major, minor, patch);
|
return fmt::format("{:d}.{:d}.{:d}", major, minor, patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Version::AsString") {
|
||||||
|
CHECK(Version { 0, 0, 0 }.AsString() == "0.0.0");
|
||||||
|
CHECK(Version { 1, 2, 3 }.AsString() == "1.2.3");
|
||||||
|
CHECK(Version { 255, 255, 255 }.AsString() == "255.255.255");
|
||||||
|
}
|
||||||
|
|
||||||
void LogChatMessage(const std::string& name, int id, const std::string& msg) {
|
void LogChatMessage(const std::string& name, int id, const std::string& msg) {
|
||||||
if (Application::Settings.LogChat) {
|
if (Application::Settings.LogChat) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
@@ -196,7 +295,9 @@ void LogChatMessage(const std::string& name, int id, const std::string& msg) {
|
|||||||
ss << name << "";
|
ss << name << "";
|
||||||
}
|
}
|
||||||
ss << msg;
|
ss << msg;
|
||||||
|
#ifdef DOCTEST_CONFIG_DISABLE
|
||||||
Application::Console().Write(ss.str());
|
Application::Console().Write(ss.str());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -176,50 +176,57 @@ void LuaAPI::MP::Set(int ConfigID, sol::object NewValue) {
|
|||||||
if (NewValue.is<bool>()) {
|
if (NewValue.is<bool>()) {
|
||||||
Application::Settings.DebugModeEnabled = NewValue.as<bool>();
|
Application::Settings.DebugModeEnabled = NewValue.as<bool>();
|
||||||
beammp_info(std::string("Set `Debug` to ") + (Application::Settings.DebugModeEnabled ? "true" : "false"));
|
beammp_info(std::string("Set `Debug` to ") + (Application::Settings.DebugModeEnabled ? "true" : "false"));
|
||||||
} else
|
} else {
|
||||||
beammp_lua_error("set invalid argument [2] expected boolean");
|
beammp_lua_error("set invalid argument [2] expected boolean");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 1: // private
|
case 1: // private
|
||||||
if (NewValue.is<bool>()) {
|
if (NewValue.is<bool>()) {
|
||||||
Application::Settings.Private = NewValue.as<bool>();
|
Application::Settings.Private = NewValue.as<bool>();
|
||||||
beammp_info(std::string("Set `Private` to ") + (Application::Settings.Private ? "true" : "false"));
|
beammp_info(std::string("Set `Private` to ") + (Application::Settings.Private ? "true" : "false"));
|
||||||
} else
|
} else {
|
||||||
beammp_lua_error("set invalid argument [2] expected boolean");
|
beammp_lua_error("set invalid argument [2] expected boolean");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 2: // max cars
|
case 2: // max cars
|
||||||
if (NewValue.is<int>()) {
|
if (NewValue.is<int>()) {
|
||||||
Application::Settings.MaxCars = NewValue.as<int>();
|
Application::Settings.MaxCars = NewValue.as<int>();
|
||||||
beammp_info(std::string("Set `MaxCars` to ") + std::to_string(Application::Settings.MaxCars));
|
beammp_info(std::string("Set `MaxCars` to ") + std::to_string(Application::Settings.MaxCars));
|
||||||
} else
|
} else {
|
||||||
beammp_lua_error("set invalid argument [2] expected integer");
|
beammp_lua_error("set invalid argument [2] expected integer");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 3: // max players
|
case 3: // max players
|
||||||
if (NewValue.is<int>()) {
|
if (NewValue.is<int>()) {
|
||||||
Application::Settings.MaxPlayers = NewValue.as<int>();
|
Application::Settings.MaxPlayers = NewValue.as<int>();
|
||||||
beammp_info(std::string("Set `MaxPlayers` to ") + std::to_string(Application::Settings.MaxPlayers));
|
beammp_info(std::string("Set `MaxPlayers` to ") + std::to_string(Application::Settings.MaxPlayers));
|
||||||
} else
|
} else {
|
||||||
beammp_lua_error("set invalid argument [2] expected integer");
|
beammp_lua_error("set invalid argument [2] expected integer");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 4: // Map
|
case 4: // Map
|
||||||
if (NewValue.is<std::string>()) {
|
if (NewValue.is<std::string>()) {
|
||||||
Application::Settings.MapName = NewValue.as<std::string>();
|
Application::Settings.MapName = NewValue.as<std::string>();
|
||||||
beammp_info(std::string("Set `Map` to ") + Application::Settings.MapName);
|
beammp_info(std::string("Set `Map` to ") + Application::Settings.MapName);
|
||||||
} else
|
} else {
|
||||||
beammp_lua_error("set invalid argument [2] expected string");
|
beammp_lua_error("set invalid argument [2] expected string");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 5: // Name
|
case 5: // Name
|
||||||
if (NewValue.is<std::string>()) {
|
if (NewValue.is<std::string>()) {
|
||||||
Application::Settings.ServerName = NewValue.as<std::string>();
|
Application::Settings.ServerName = NewValue.as<std::string>();
|
||||||
beammp_info(std::string("Set `Name` to ") + Application::Settings.ServerName);
|
beammp_info(std::string("Set `Name` to ") + Application::Settings.ServerName);
|
||||||
} else
|
} else {
|
||||||
beammp_lua_error("set invalid argument [2] expected string");
|
beammp_lua_error("set invalid argument [2] expected string");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 6: // Desc
|
case 6: // Desc
|
||||||
if (NewValue.is<std::string>()) {
|
if (NewValue.is<std::string>()) {
|
||||||
Application::Settings.ServerDesc = NewValue.as<std::string>();
|
Application::Settings.ServerDesc = NewValue.as<std::string>();
|
||||||
beammp_info(std::string("Set `Description` to ") + Application::Settings.ServerDesc);
|
beammp_info(std::string("Set `Description` to ") + Application::Settings.ServerDesc);
|
||||||
} else
|
} else {
|
||||||
beammp_lua_error("set invalid argument [2] expected string");
|
beammp_lua_error("set invalid argument [2] expected string");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
beammp_warn("Invalid config ID \"" + std::to_string(ConfigID) + "\". Use `MP.Settings.*` enum for this.");
|
beammp_warn("Invalid config ID \"" + std::to_string(ConfigID) + "\". Use `MP.Settings.*` enum for this.");
|
||||||
@@ -255,7 +262,9 @@ void LuaAPI::MP::PrintRaw(sol::variadic_args Args) {
|
|||||||
ToPrint += LuaToString(static_cast<const sol::object>(Arg));
|
ToPrint += LuaToString(static_cast<const sol::object>(Arg));
|
||||||
ToPrint += "\t";
|
ToPrint += "\t";
|
||||||
}
|
}
|
||||||
|
#ifdef DOCTEST_CONFIG_DISABLE
|
||||||
Application::Console().WriteRaw(ToPrint);
|
Application::Console().WriteRaw(ToPrint);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int LuaAPI::PanicHandler(lua_State* State) {
|
int LuaAPI::PanicHandler(lua_State* State) {
|
||||||
|
|||||||
@@ -28,8 +28,9 @@ TResourceManager::TResourceManager() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mModsLoaded)
|
if (mModsLoaded) {
|
||||||
beammp_info("Loaded " + std::to_string(mModsLoaded) + " Mods");
|
beammp_info("Loaded " + std::to_string(mModsLoaded) + " Mods");
|
||||||
|
}
|
||||||
|
|
||||||
Application::SetSubsystemStatus("ResourceManager", Application::Status::Good);
|
Application::SetSubsystemStatus("ResourceManager", Application::Status::Good);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,22 @@
|
|||||||
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
|
#define DOCTEST_CONFIG_IMPLEMENT
|
||||||
#include <doctest/doctest.h>
|
#include <doctest/doctest.h>
|
||||||
|
|
||||||
|
#include <Common.h>
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
doctest::Context context;
|
||||||
|
|
||||||
|
Application::InitializeConsole();
|
||||||
|
|
||||||
|
context.applyCommandLine(argc, argv);
|
||||||
|
|
||||||
|
int res = context.run(); // run
|
||||||
|
|
||||||
|
if (context.shouldExit()) // important - query flags (and --exit) rely on the user doing this
|
||||||
|
return res; // propagate the result of the tests
|
||||||
|
|
||||||
|
int client_stuff_return_code = 0;
|
||||||
|
// your program - if the testing framework is integrated in your production code
|
||||||
|
|
||||||
|
return res + client_stuff_return_code; // the result from doctest is propagated here as well
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user