Upgrade client active object mgr tests to Catch2

In addition to invoking Catch2's test runner after Minetest's homemade
runner, this refactors the tests to follow the DRY principle, and gives
them expressive names and clear assertions. Catch2 is already bundled
with Minetest, so there are no added dependencies.
This commit is contained in:
Josiah VanderZee 2023-06-19 10:40:59 -05:00
parent 1b89d4d541
commit a34eb196a9
6 changed files with 57 additions and 68 deletions

View File

@ -278,7 +278,7 @@ if(NOT USE_LUAJIT)
add_subdirectory(lib/bitop)
endif()
if(BUILD_BENCHMARKS)
if(BUILD_UNITTESTS OR BUILD_BENCHMARKS)
add_subdirectory(lib/catch2)
endif()

View File

@ -13,4 +13,5 @@
# + return os << std::fixed << duration.value() << ' ' << duration.unitsAsString();
add_library(catch2 INTERFACE)
target_include_directories(catch2 INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
add_library(Catch2::Catch2 ALIAS catch2)
target_include_directories(catch2 INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}")

View File

@ -614,8 +614,8 @@ if(BUILD_CLIENT)
if (USE_SPATIAL)
target_link_libraries(${PROJECT_NAME} ${SPATIAL_LIBRARY})
endif()
if(BUILD_BENCHMARKS)
target_link_libraries(${PROJECT_NAME} catch2)
if(BUILD_UNITTESTS OR BUILD_BENCHMARKS)
target_link_libraries(${PROJECT_NAME} Catch2::Catch2)
endif()
endif(BUILD_CLIENT)
@ -676,8 +676,8 @@ if(BUILD_SERVER)
${CURL_LIBRARY}
)
endif()
if(BUILD_BENCHMARKS)
target_link_libraries(${PROJECT_NAME}server catch2)
if(BUILD_UNITTESTS OR BUILD_BENCHMARKS)
target_link_libraries(${PROJECT_NAME}server Catch2::Catch2)
endif()
endif(BUILD_SERVER)

View File

@ -31,7 +31,6 @@ class TestServerActiveObjectMgr;
template <typename T>
class ActiveObjectMgr
{
friend class ::TestClientActiveObjectMgr;
friend class ::TestServerActiveObjectMgr;
public:

View File

@ -17,6 +17,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define CATCH_CONFIG_RUNNER
#include <catch.hpp>
#include "test.h"
#include "nodedef.h"
@ -248,7 +251,9 @@ bool run_tests()
<< num_total_tests_run << " failed individual tests)." << std::endl
<< " Testing took " << tdiff << "ms total." << std::endl
<< "++++++++++++++++++++++++++++++++++++++++"
<< "++++++++++++++++++++++++++++++++++++++++" << std::endl;
<< "++++++++++++++++++++++++++++++++++++++++" << std::endl
<< "Catch test results: " << std::endl;
Catch::Session().run();
return num_modules_failed == 0;
}

View File

@ -17,11 +17,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "client/activeobjectmgr.h"
#include <algorithm>
#include "test.h"
#include "profiler.h"
#include "client/activeobjectmgr.h"
#include <catch.hpp>
class TestClientActiveObject : public ClientActiveObject
{
@ -58,9 +58,6 @@ public:
void runTests(IGameDef *gamedef);
void testFreeID();
void testRegisterObject();
void testRemoveObject();
void testGetActiveSelectableObjects();
};
@ -68,75 +65,62 @@ static TestClientActiveObjectMgr g_test_instance;
void TestClientActiveObjectMgr::runTests(IGameDef *gamedef)
{
TEST(testFreeID);
TEST(testRegisterObject)
TEST(testRemoveObject)
TEST(testGetActiveSelectableObjects)
}
////////////////////////////////////////////////////////////////////////////////
void TestClientActiveObjectMgr::testFreeID()
TEST_CASE("test client active object manager")
{
client::ActiveObjectMgr caomgr;
std::vector<u16> aoids;
auto tcao1 = new TestClientActiveObject();
REQUIRE(caomgr.registerObject(tcao1) == true);
u16 aoid = caomgr.getFreeId();
// Ensure it's not the same id
UASSERT(caomgr.getFreeId() != aoid);
aoids.push_back(aoid);
// Register basic objects, ensure we never found
for (u8 i = 0; i < UINT8_MAX; i++) {
// Register an object
auto tcao_u = std::make_unique<TestClientActiveObject>();
auto tcao = tcao_u.get();
caomgr.registerObject(std::move(tcao_u));
aoids.push_back(tcao->getId());
// Ensure next id is not in registered list
UASSERT(std::find(aoids.begin(), aoids.end(), caomgr.getFreeId()) ==
aoids.end());
SECTION("When we register a client object, "
"then it should be assigned a unique ID.")
{
for (int i = 0; i < UINT8_MAX; ++i) {
auto other_tcao = new TestClientActiveObject();
REQUIRE(caomgr.registerObject(other_tcao) == true);
CHECK(other_tcao->getId() != tcao1->getId());
}
}
caomgr.clear();
}
SECTION("two registered objects")
{
auto tcao2 = new TestClientActiveObject();
REQUIRE(caomgr.registerObject(tcao2) == true);
auto tcao2_id = tcao2->getId();
void TestClientActiveObjectMgr::testRegisterObject()
{
client::ActiveObjectMgr caomgr;
auto tcao_u = std::make_unique<TestClientActiveObject>();
auto tcao = tcao_u.get();
UASSERT(caomgr.registerObject(std::move(tcao_u)));
auto obj1 = caomgr.getActiveObject(tcao1->getId());
REQUIRE(obj1 != nullptr);
u16 id = tcao->getId();
auto obj2 = caomgr.getActiveObject(tcao2_id);
REQUIRE(obj2 != nullptr);
auto tcaoToCompare = caomgr.getActiveObject(id);
UASSERT(tcaoToCompare->getId() == id);
UASSERT(tcaoToCompare == tcao);
SECTION("When we query an object by its ID, "
"then we should get back an object with that ID.")
{
CHECK(obj1->getId() == tcao1->getId());
CHECK(obj2->getId() == tcao2->getId());
}
tcao_u = std::make_unique<TestClientActiveObject>();
tcao = tcao_u.get();
UASSERT(caomgr.registerObject(std::move(tcao_u)));
UASSERT(caomgr.getActiveObject(tcao->getId()) == tcao);
UASSERT(caomgr.getActiveObject(tcao->getId()) != tcaoToCompare);
SECTION("When we register and query for an object, "
"its memory location should not have changed.")
{
CHECK(obj1 == tcao1);
CHECK(obj2 == tcao2);
}
}
caomgr.clear();
}
void TestClientActiveObjectMgr::testRemoveObject()
{
client::ActiveObjectMgr caomgr;
auto tcao_u = std::make_unique<TestClientActiveObject>();
auto tcao = tcao_u.get();
UASSERT(caomgr.registerObject(std::move(tcao_u)));
u16 id = tcao->getId();
UASSERT(caomgr.getActiveObject(id) != nullptr)
caomgr.removeObject(tcao->getId());
UASSERT(caomgr.getActiveObject(id) == nullptr)
SECTION("Given an object has been removed, "
"when we query for it, "
"then we should get nullptr.")
{
auto id = tcao1->getId();
caomgr.removeObject(tcao1->getId()); // may invalidate tcao1
CHECK(caomgr.getActiveObject(id) == nullptr);
}
caomgr.clear();
}