diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 40cceb78e1e..a55b7a06523 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -9,21 +9,33 @@
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
CollectSourceFiles(
- ${CMAKE_CURRENT_SOURCE_DIR}/common
- COMMON_SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ TEST_SOURCES
)
-add_executable(tests-common ${COMMON_SOURCES})
+GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
-target_link_libraries(tests-common
+add_executable(tests ${TEST_SOURCES})
+
+target_link_libraries(tests
PRIVATE
trinity-core-interface
- common
+ game
Catch2::Catch2)
-catch_discover_tests(tests-common)
+CollectIncludeDirectories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ TEST_INCLUDES)
-set_target_properties(tests-common
+target_include_directories(tests
+ PUBLIC
+ ${TEST_INCLUDES}
+ PRIVATE
+ ${CMAKE_CURRENT_BINARY_DIR})
+
+catch_discover_tests(tests)
+
+set_target_properties(tests
PROPERTIES
FOLDER
"tests")
diff --git a/tests/common/test-EventMap.cpp b/tests/common/EventMap.cpp
similarity index 99%
rename from tests/common/test-EventMap.cpp
rename to tests/common/EventMap.cpp
index 31b27af5daa..1f3ff927fef 100644
--- a/tests/common/test-EventMap.cpp
+++ b/tests/common/EventMap.cpp
@@ -16,7 +16,7 @@
*/
#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
-#include "catch2/catch.hpp"
+#include "tc_catch2.h"
#include "EventMap.h"
diff --git a/tests/common/StringConvert.cpp b/tests/common/StringConvert.cpp
new file mode 100644
index 00000000000..d25e28f3d19
--- /dev/null
+++ b/tests/common/StringConvert.cpp
@@ -0,0 +1,131 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * 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; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+
+#include "tc_catch2.h"
+
+#include "StringConvert.h"
+
+TEST_CASE("String to uint32", "[StringConvert]")
+{
+ REQUIRE(Trinity::StringTo("42") == 42);
+ REQUIRE(Trinity::StringTo("42", 10) == 42);
+ REQUIRE(Trinity::StringTo(" 42") == std::nullopt);
+ REQUIRE(Trinity::StringTo("tail42") == std::nullopt);
+ REQUIRE(Trinity::StringTo("42tail") == std::nullopt);
+
+ REQUIRE(Trinity::StringTo("ff", 16) == 0xff);
+ REQUIRE(Trinity::StringTo("0xff") == std::nullopt);
+ REQUIRE(Trinity::StringTo("0xff", 0) == 0xff);
+
+ REQUIRE(Trinity::StringTo("101010", 2) == 0b101010);
+ REQUIRE(Trinity::StringTo("0b101010") == std::nullopt);
+ REQUIRE(Trinity::StringTo("0b101010", 0) == 0b101010);
+
+ REQUIRE(Trinity::StringTo("5000000000") == std::nullopt);
+ REQUIRE(Trinity::StringTo("100000000", 16) == std::nullopt);
+ REQUIRE(Trinity::StringTo("0x100000000", 0) == std::nullopt);
+ REQUIRE(Trinity::StringTo("0xffffffff", 0) == 0xffffffff);
+}
+
+TEST_CASE("String to uint64", "[StringConvert]")
+{
+ REQUIRE(Trinity::StringTo("42") == 42);
+ REQUIRE(Trinity::StringTo("42", 10) == 42);
+ REQUIRE(Trinity::StringTo(" 42") == std::nullopt);
+ REQUIRE(Trinity::StringTo("tail42") == std::nullopt);
+ REQUIRE(Trinity::StringTo("42tail") == std::nullopt);
+ REQUIRE(Trinity::StringTo("-1", 0) == std::nullopt);
+
+ REQUIRE(Trinity::StringTo("ff", 16) == 0xff);
+ REQUIRE(Trinity::StringTo("0xff") == std::nullopt);
+ REQUIRE(Trinity::StringTo("0xff", 0) == 0xff);
+
+ REQUIRE(Trinity::StringTo("101010", 2) == 0b101010);
+ REQUIRE(Trinity::StringTo("0b101010") == std::nullopt);
+ REQUIRE(Trinity::StringTo("0b101010", 0) == 0b101010);
+
+ REQUIRE(Trinity::StringTo("5000000000") == 5000000000ULL);
+ REQUIRE(Trinity::StringTo("100000000", 16) == 0x100000000ULL);
+
+ REQUIRE(Trinity::StringTo("20000000000000000000") == std::nullopt);
+ REQUIRE(Trinity::StringTo("10000000000000000", 16) == std::nullopt);
+ REQUIRE(Trinity::StringTo("0x10000000000000000", 0) == std::nullopt);
+ REQUIRE(Trinity::StringTo("0xFFFFFFFFFFFFFFFF", 0) == 0xffffffffffffffffULL);
+}
+
+TEST_CASE("String to int32", "[StringConvert]")
+{
+ REQUIRE(Trinity::StringTo("-42") == -42);
+ REQUIRE(Trinity::StringTo("42") == 42);
+ REQUIRE(Trinity::StringTo("+42") == std::nullopt);
+ REQUIRE(Trinity::StringTo("--42") == std::nullopt);
+ REQUIRE(Trinity::StringTo("~42") == std::nullopt);
+ REQUIRE(Trinity::StringTo("42-") == std::nullopt);
+
+ REQUIRE(Trinity::StringTo("-ffff", 16) == -0xffff);
+ REQUIRE(Trinity::StringTo("ffffffff", 16) == std::nullopt);
+ REQUIRE(Trinity::StringTo("7fffffff", 16) == 0x7fffffff);
+}
+
+TEST_CASE("String to int64", "[StringConvert]")
+{
+ REQUIRE(Trinity::StringTo("-42") == -42);
+ REQUIRE(Trinity::StringTo("42") == 42);
+ REQUIRE(Trinity::StringTo("+42") == std::nullopt);
+ REQUIRE(Trinity::StringTo("--42") == std::nullopt);
+ REQUIRE(Trinity::StringTo("~42") == std::nullopt);
+ REQUIRE(Trinity::StringTo("42-") == std::nullopt);
+
+ REQUIRE(Trinity::StringTo("-ffff", 16) == -0xffff);
+ REQUIRE(Trinity::StringTo("ffffffff", 16) == 0xffffffff);
+ REQUIRE(Trinity::StringTo("7fffffff", 16) == 0x7fffffff);
+
+ REQUIRE(Trinity::StringTo("ffffffffffffffff", 16) == std::nullopt);
+ REQUIRE(Trinity::StringTo("7fffffffffffffff", 16) == 0x7fffffffffffffffLL);
+
+ REQUIRE(Trinity::StringTo("-8500000000000000", 16) == std::nullopt);
+}
+
+TEST_CASE("String to smaller integer types", "[StringConvert]")
+{
+ REQUIRE(Trinity::StringTo("0xff", 0) == 0xff);
+ REQUIRE(Trinity::StringTo("0x1ff", 0) == std::nullopt);
+
+ REQUIRE(Trinity::StringTo("0xff", 0) == std::nullopt);
+ REQUIRE(Trinity::StringTo("0x7f", 0) == 0x7f);
+ REQUIRE(Trinity::StringTo("-7f", 16) == -0x7f);
+
+ REQUIRE(Trinity::StringTo("0x1ff", 0) == 0x1ff);
+ REQUIRE(Trinity::StringTo("0x1ffff", 0) == std::nullopt);
+ REQUIRE(Trinity::StringTo("-1", 0) == std::nullopt);
+
+ REQUIRE(Trinity::StringTo("0x1ff", 0) == 0x1ff);
+ REQUIRE(Trinity::StringTo("0xffff", 0) == std::nullopt);
+ REQUIRE(Trinity::StringTo("0x7fff", 0) == 0x7fff);
+ REQUIRE(Trinity::StringTo("-1", 0) == -1);
+}
+
+TEST_CASE("Test.String to boolean", "[StringConvert]")
+{
+ REQUIRE(Trinity::StringTo("true") == true);
+ REQUIRE(Trinity::StringTo("false") == false);
+ REQUIRE(Trinity::StringTo("ture") == std::nullopt);
+ REQUIRE(Trinity::StringTo("true", 10) == std::nullopt);
+ REQUIRE(Trinity::StringTo("1") == true);
+ REQUIRE(Trinity::StringTo("1", 10) == true);
+ REQUIRE(Trinity::StringTo("0", 10) == false);
+}
diff --git a/tests/common/test-Timer.cpp b/tests/common/Timer.cpp
similarity index 98%
rename from tests/common/test-Timer.cpp
rename to tests/common/Timer.cpp
index 76d02d51aa0..9117b1338a1 100644
--- a/tests/common/test-Timer.cpp
+++ b/tests/common/Timer.cpp
@@ -16,7 +16,7 @@
*/
#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
-#include "catch2/catch.hpp"
+#include "tc_catch2.h"
#include "Timer.h"
diff --git a/tests/game/ChatCommand.cpp b/tests/game/ChatCommand.cpp
new file mode 100644
index 00000000000..5aab641deba
--- /dev/null
+++ b/tests/game/ChatCommand.cpp
@@ -0,0 +1,64 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * 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; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+
+#include "tc_catch2.h"
+
+#include "ChatCommand.h"
+
+using namespace Trinity::ChatCommands;
+using namespace std::string_view_literals;
+
+template
+static void TestChatCommand(char const* c, F f, Optional expected = true)
+{
+ bool r = ChatCommand("", 0, false, +f, "")(nullptr, c);
+ if (expected)
+ ASSERT(r == *expected);
+}
+
+TEST_CASE("Command return pass-through", "[ChatCommand]")
+{
+ TestChatCommand("", [](ChatHandler*) { return true; }, true);
+ TestChatCommand("", [](ChatHandler*) { return false; }, false);
+}
+
+TEST_CASE("Command argument parsing", "[ChatCommand]")
+{
+ TestChatCommand("42", [](ChatHandler*, uint32 u)
+ {
+ REQUIRE(u == 42);
+ return true;
+ });
+
+ TestChatCommand("true", [](ChatHandler*, uint32) { return true; }, false);
+
+ TestChatCommand("1 2 3 4 5 6 7 8 9 10", [](ChatHandler*, std::vector v)
+ {
+ REQUIRE(v.size() == 10);
+ for (size_t i = 0; i < 10; ++i)
+ REQUIRE(v[i] == (i + 1));
+ return true;
+ });
+
+ TestChatCommand("|cffff0000|Hplayer:Test|h[Test]|h|r",
+ [](ChatHandler*, Hyperlink player)
+ {
+ REQUIRE("Test"sv == *player);
+ return true;
+ }
+ );
+}
diff --git a/tests/common/test-main.cpp b/tests/main.cpp
similarity index 100%
rename from tests/common/test-main.cpp
rename to tests/main.cpp
diff --git a/tests/tc_catch2.h b/tests/tc_catch2.h
new file mode 100644
index 00000000000..96fcdaf8c9e
--- /dev/null
+++ b/tests/tc_catch2.h
@@ -0,0 +1,44 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * 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; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+
+#ifndef TRINITY_CATCH2_H
+#define TRINITY_CATCH2_H
+
+#include "Optional.h"
+#include
+#include
+
+template
+std::ostream& operator<<(std::ostream& os, Optional const& value)
+{
+ os << "Opt";
+ if (value)
+ os << " { " << *value << " }";
+ else
+ os << " ()";
+ return os;
+}
+
+inline std::ostream& operator<<(std::ostream& os, std::nullopt_t)
+{
+ os << "";
+ return os;
+}
+
+#include "catch2/catch.hpp"
+
+#endif