Restructure unit-tests and tag #include directives so clang-tidy stops complaining.

Delete unused unit tests for classes that no longer exist.

Work #105 - Reorganize unit test directory to match the rest of the
source
This commit is contained in:
S David 2023-06-27 12:11:42 -04:00
parent f8ac7e1c76
commit 67afeebd80
10 changed files with 234 additions and 410 deletions

View File

@ -10,7 +10,7 @@ tests: $(check_PROGRAMS)
thirdparty_library_includes=-I ${srcdir}/third_party/FakeIt/include
thirdparty_library_includes+=-I ${srcdir}/third_party/FakeIt/config/catch
#
# Ignore errors that are usually coming from the testing frameworks themselves
test_disabled_warnings=-Wno-deprecated-declarations -Wno-defaulted-function-deleted\
-Wno-zero-length-array
@ -22,7 +22,8 @@ tests_addl_cflags+= $(thirdparty_library_includes)
game_tests_SOURCES=
game_tests_SOURCES+=src/tests/runtime.tests.cpp
game_tests_SOURCES+=src/tests/framework/core/components/PositionAttribute.test.cpp
include src/tests/framework/Makefile.am
game_tests_CPPFLAGS= $(AM_CPPFLAGS) $(PROJECT_INCLUDE_FLAGS)
game_tests_CPPFLAGS+= $(tests_addl_cflags)

View File

@ -0,0 +1,10 @@
pwd=src/tests/framework
core_sources=
core_sources+=$(pwd)/types/adapters/Sequential.test.cpp
core_sources+=$(pwd)/core/input/EventDispatcher.test.cpp
core_sources+=$(pwd)/core/input/InputMapper.test.cpp
core_sources+=$(pwd)/core/components/PositionAttribute.test.cpp
game_tests_SOURCES+=${core_sources}

View File

@ -17,7 +17,7 @@
///@todo: Replace the real component types here with types from
/// SomeCompoonent.hpp
#include "tests/common/SomeComponent.hpp"
#include "tests/runtime/SomeComponent.hpp"
BEGIN_TEST_SUITE("class::Entity")

View File

@ -1,90 +0,0 @@
/* IterableView.test.cpp
* Copyright © 2021 Saul D. Beniquez
* License: Mozilla Public License v. 2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v.2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "test-includes.hpp"
#include "framework/core/BaseComponent.hpp"
#include "framework/core/LookupTable/IterableView.hpp"
#include "tests/common/SomeComponent.hpp"
#include <vector>
#include <algorithm>
using namespace QW;
using namespace QW::Core;
namespace {
const char* TEST_SUITE_NAME="[class:IterableView]";
struct TestComponent : public SomeComponent
{
TestComponent(BaseComponent::instance_id id) : SomeComponent(id),
instance_info({.id=id,.name=""})
{}
virtual ~TestComponent() = default;
const BaseComponent::TypeInfo& get_type() const override {
static TypeInfo typeInfo {
.id = "1838485393423492309",
.name = "TestComponent",
};
return typeInfo;
}
const InstanceInfo& GetInstanceInfo() override {
return instance_info;
}
void output(std::ostream & out) {
out << instance_info.id << " " << std::flush;
}
InstanceInfo instance_info;
};
}
TEST_CASE("can iterate using c++11 foreach syntax", TEST_SUITE_NAME)
{
std::vector<BaseComponent::instance_id> expected_results;
std::unordered_map<BaseComponent::instance_id, TestComponent> testDictionary;
for (auto i = 0; i < 200; ++i)
{
testDictionary.emplace(i,i);
}
// Iterate through the unordered_map and figure out whats supposed to
// happen
for (auto it = testDictionary.begin(); it != testDictionary.end(); ++it) {
expected_results.push_back(it->second.instance_info.id);
}
//
// Iterate thorugh the same object but through IterableView interface
IterableView<decltype(testDictionary)> iterableView(testDictionary);
for (auto& component : iterableView)
{
using instance_id = BaseComponent::instance_id;
auto id = component.GetInstanceInfo().id;
auto search_result =
std::find_if(expected_results.begin(), expected_results.end(),
[id](instance_id num) { return num == id ; });
REQUIRE(search_result != expected_results.end());
}
}
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

View File

@ -16,27 +16,27 @@
using namespace QW;
namespace {
const char* TEST_SUITE_NAME = "[class:EntityManager]";
// #region Test Fixtures
struct TestFixture
BEGIN_TEST_SUITE("class:EntityManager")
{
TestFixture() : registry(EntityManager::GetInstance())
// #region Test Fixtures
struct TestFixture
{
registry.RegisterPool(test_table);
registry.RegisterPool(test_table2);
test_table.emplace(0, 0);
}
virtual ~TestFixture()
{
registry.DeregisterPool<SomeComponent>();
registry.DeregisterPool<SomeOtherComponent>();
}
ComponentDictionary<SomeComponent> test_table;
ComponentDictionary<SomeOtherComponent> test_table2;
EntityManager& registry;
};
TestFixture() : registry(EntityManager::GetInstance())
{
registry.RegisterPool(test_table);
registry.RegisterPool(test_table2);
test_table.emplace(0, 0);
}
virtual ~TestFixture()
{
registry.DeregisterPool<SomeComponent>();
registry.DeregisterPool<SomeOtherComponent>();
}
ComponentDictionary<SomeComponent> test_table;
ComponentDictionary<SomeOtherComponent> test_table2;
EntityManager& registry;
};
} // #endregion
TEST_CASE("EntityManager::GetInstance", TEST_SUITE_NAME)

View File

@ -1,90 +0,0 @@
/* IterablePool.test.cpp
* Copyright © 2021 Saul D. Beniquez
* License: Mozilla Public License v. 2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v.2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "test-includes.hpp"
#include "framework/core/BaseComponent.hpp"
#include "framework/model/IterablePool.hpp"
#include "tests/common/SomeComponent.hpp"
#include <algorithm>
#include <vector>
using namespace QW;
using namespace QW::Model;
namespace {
const char* TEST_SUITE_NAME = "[class:IterablePool]";
template<typename TComponent>
using ComponentPool =
std::unordered_map<typename TComponent::instance_id, TComponent>;
struct TestComponent : public SomeComponent
{
TestComponent(BaseComponent::instance_id id)
: SomeComponent(id), instance_info({ .id = id, .name = "" })
{}
virtual ~TestComponent() = default;
const BaseComponent::TypeInfo& get_type() const override
{
static TypeInfo typeInfo{
.id = "1838485393423492309",
.name = "TestComponent",
};
return typeInfo;
}
const InstanceInfo& GetInstanceInfo() override { return instance_info; }
void output(std::ostream& out)
{
out << instance_info.id << " " << std::flush;
}
InstanceInfo instance_info;
};
}
TEST_CASE("can iterate using c++11 foreach syntax", TEST_SUITE_NAME)
{
std::vector<BaseComponent::instance_id> expected_results;
ComponentPool<TestComponent> somePool;
for (auto i = 0; i < 200; ++i) {
somePool.emplace(i, i);
}
// Iterate through the unordered_map and figure out whats supposed to
// happen
for (auto it = somePool.begin(); it != somePool.end(); ++it) {
expected_results.push_back(it->second.instance_info.id);
}
//
// Iterate thorugh the same object but through IterablePool interface
IterablePool<TestComponent> iterablePool(somePool);
// for (auto it = iterablePool.begin(); it != iterablePool.end(); ++it)
for (auto& component : iterablePool) {
using instance_id = BaseComponent::instance_id;
auto id = component.GetInstanceInfo().id;
auto search_result =
std::find_if(expected_results.begin(),
expected_results.end(),
[id](instance_id num) { return num == id; });
REQUIRE(search_result != expected_results.end());
}
}
// clang-format off
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :

View File

@ -13,7 +13,6 @@
#include <vector>
#include "SDL_keycode.h"
#include "framework/core/INonCopyable.hpp"
#include "framework/core/IObserver.hpp"
#include "framework/core/input/EventDispatcher.hpp"
@ -30,108 +29,106 @@ using QW::Core::Input::EventDispatcher;
using Sdl2Testing::Sdl2TestFixture;
using Sdl2Testing::SdlEventSimulator;
namespace {
const char* TEST_SUITE_NAME = "[class:EventDispatcher]";
class EventRecorder : public IObserver
{ // #region
public:
EventRecorder() : IObserver() {}
virtual void OnNotice(const Observable& sender, std::any message)
BEGIN_TEST_SUITE("class:EventDispatcher")
{
class EventRecorder : public IObserver // #region
{
auto event = std::any_cast<SDL_Event&>(message);
received.push_back(event);
}
virtual ~EventRecorder() = default;
std::vector<SDL_Event> received;
}; // #endregion
class EventDispatcherInspector : public EventDispatcher // #region
{
public:
explicit EventDispatcherInspector(EventDispatcher& other)
: EventDispatcher(other)
public:
EventRecorder() : IObserver() {}
virtual void OnNotice(const Observable& sender, std::any message)
{
auto event = std::any_cast<SDL_Event&>(message);
received.push_back(event);
}
virtual ~EventRecorder() = default;
std::vector<SDL_Event> received;
}; // #endregion
class EventDispatcherInspector : public EventDispatcher // #region
{
}
public:
explicit EventDispatcherInspector(EventDispatcher& other)
: EventDispatcher(other)
{
}
const std::queue<SDL_Event>& GetEventQueue() const
const std::queue<SDL_Event>& GetEventQueue() const
{
return this->getEventBuffer();
}
}; // #endregion
struct EventDispatcherFixture : public Sdl2TestFixture // #region
{
return this->getEventBuffer();
}
}; // #endregion
; // #endregion
struct EventDispatcherFixture : public Sdl2TestFixture // #region
{
EventDispatcherFixture() : Sdl2TestFixture(), eventSource(), recorder()
EventDispatcherFixture()
: Sdl2TestFixture(), eventSource(), recorder()
{
eventSource.RegisterObserver(recorder);
}
EventDispatcher eventSource;
EventRecorder recorder;
}; // #endregion
TEST_CASE("Fixtures work", TEST_SUITE_NAME)
{
eventSource.RegisterObserver(recorder);
REQUIRE_NOTHROW([]() { Sdl2TestFixture object; }());
REQUIRE_NOTHROW([]() { EventDispatcherFixture object2; }());
}
EventDispatcher eventSource;
EventRecorder recorder;
}; // #endregion
}
TEST_CASE("Fixtures work", TEST_SUITE_NAME)
{
REQUIRE_NOTHROW([]() { Sdl2TestFixture object; }());
REQUIRE_NOTHROW([]() { EventDispatcherFixture object2; }());
}
TEST_CASE_METHOD(EventDispatcherFixture,
"EventDispatcher::InitJoysticks() sanity check",
TEST_SUITE_NAME)
{
REQUIRE_NOTHROW([this]() { eventSource.InitJoysticks(); }());
}
TEST_CASE_METHOD(EventDispatcherFixture,
"EventDispatcher::Enqueue stores events in order",
TEST_SUITE_NAME)
{
const int MAX_EVENTS = 5;
SDL_Event testInput[MAX_EVENTS];
for (auto& input : testInput) {
input = SdlEventSimulator::randomArrowKey();
eventSource.Enqueue(input);
TEST_CASE_METHOD(EventDispatcherFixture,
"EventDispatcher::InitJoysticks() sanity check",
TEST_SUITE_NAME)
{
REQUIRE_NOTHROW([this]() { eventSource.InitJoysticks(); }());
}
EventDispatcherInspector subject(eventSource);
std::queue<SDL_Event> eventBuffer(subject.GetEventQueue());
FIXTURE_CASE(EventDispatcherFixture,
"EventDispatcher::Enqueue stores events in order")
{
const int MAX_EVENTS = 5;
SDL_Event testInput[MAX_EVENTS];
REQUIRE(eventBuffer.size() > 0);
for (auto& input : testInput) {
input = SdlEventSimulator::randomArrowKey();
eventSource.Enqueue(input);
}
for (unsigned i = 0; i < MAX_EVENTS; ++i) {
auto event = eventBuffer.front();
eventBuffer.pop();
EventDispatcherInspector subject(eventSource);
std::queue<SDL_Event> eventBuffer(subject.GetEventQueue());
REQUIRE(event.key.keysym.sym == testInput[i].key.keysym.sym);
REQUIRE(eventBuffer.size() > 0);
for (unsigned i = 0; i < MAX_EVENTS; ++i) {
auto event = eventBuffer.front();
eventBuffer.pop();
REQUIRE(event.key.keysym.sym ==
testInput[i].key.keysym.sym);
}
}
FIXTURE_CASE(EventDispatcherFixture,
"EventDispatcher::Notify sends out events in order")
{
const int MAX_EVENTS = 5;
SDL_Event testInput[MAX_EVENTS];
for (auto& input : testInput) {
input = SdlEventSimulator::randomArrowKey();
eventSource.Enqueue(input);
}
eventSource.Notify();
REQUIRE(recorder.received.size() > 0);
for (unsigned i = 0; i < MAX_EVENTS; ++i) {
auto& event = recorder.received[i];
REQUIRE(event.key.keysym.sym ==
testInput[i].key.keysym.sym);
}
}
}
TEST_CASE_METHOD(EventDispatcherFixture,
"EventDispatcher::Notify sends out events in order",
TEST_SUITE_NAME)
{
const int MAX_EVENTS = 5;
SDL_Event testInput[MAX_EVENTS];
for (auto& input : testInput) {
input = SdlEventSimulator::randomArrowKey();
eventSource.Enqueue(input);
}
eventSource.Notify();
REQUIRE(recorder.received.size() > 0);
for (unsigned i = 0; i < MAX_EVENTS; ++i) {
auto& event = recorder.received[i];
REQUIRE(event.key.keysym.sym == testInput[i].key.keysym.sym);
}
}
// clang-format off
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen:
// vim: set foldmethod=marker foldmarker=#region,#endregion textwidth=80
// ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen:

View File

@ -9,6 +9,8 @@
// #region #include directives
// #region system headers
#include <__iterator/access.h>
#include <iterator>
#include <stdexcept>
// #endregion
// #region project headers
@ -18,115 +20,112 @@
#include "SDL2.testing.hpp"
#include "framework/core/input/InputMapper.hpp"
// #endregion
// #endregion
// #region namespace aliasing
using QW::Core::Input::InputMapper;
using Sdl2Testing::Sdl2TestFixture;
using Sdl2Testing::SdlEventSimulator;
// #endregion
// #region Local Helper Classes
namespace { // #region (anonymous namespace)
const char* TEST_SUITE_NAME = "[class:InputMapper]";
struct TransparentInputMapper : public InputMapper
{
virtual std::unordered_map<SDL_Event, EventHandler>&
getEventHandlerMap() override
{
return InputMapper::getEventHandlerMap();
}
};
struct TestFixture : public Sdl2TestFixture
BEGIN_TEST_SUITE("class:InputMapper")
{
TestFixture()
: Sdl2TestFixture(), testSubject(), testInterface(testSubject)
struct TransparentInputMapper : public InputMapper // #region
{
virtual std::unordered_map<SDL_Event, EventHandler>&
getEventHandlerMap() override
{
return InputMapper::getEventHandlerMap();
}
}; // #endregion
struct TestFixture : public Sdl2TestFixture // #region
{
TestFixture()
: Sdl2TestFixture(), testSubject(), testInterface(testSubject)
{
}
TransparentInputMapper testSubject;
InputMapper& testInterface;
}; // #endregion
TEST_CASE("Allocation", TEST_SUITE_NAME)
{
REQUIRE_NOTHROW([]() {
InputMapper testSubject;
TestFixture fixture;
});
}
TransparentInputMapper testSubject;
InputMapper& testInterface;
};
} // #endregion
// #endregion
FIXTURE_CASE(TestFixture, "RegisterMapping from ScanCode")
{
const std::string expected_msg = "SDL_SCANCODE_A detected";
static std::stringstream output;
TEST_CASE("Allocation", TEST_SUITE_NAME)
{
auto handler = InputMapper::EventHandler([expected_msg]() {
output.str("");
output << expected_msg << std::flush;
});
testInterface.RegisterMapping(SDL_SCANCODE_A, handler);
REQUIRE_NOTHROW([]() {
InputMapper testSubject;
TestFixture fixture;
});
}
auto& handlerList = testSubject.getEventHandlerMap();
auto convertedKey =
SdlEventSimulator::eventFromScancode(SDL_SCANCODE_A);
auto resulting_handler = handlerList.at(convertedKey);
FIXTURE_CASE("RegisterMapping from ScanCode")
{
resulting_handler();
REQUIRE(output.str() == expected_msg);
}
const std::string expected_msg = "SDL_SCANCODE_A detected";
static std::stringstream output;
FIXTURE_CASE(TestFixture, "RegisterMapping from SDL_Event")
{
const std::string expected_msg = "SDL_SCANCODE_X detected";
const std::string doubled_msg =
"SDL_SCANCODE_X detectedSDL_SCANCODE_X detected";
static std::stringstream output;
auto handler = InputMapper::EventHandler([expected_msg]() {
output.str("");
output << expected_msg << std::flush;
});
testInterface.RegisterMapping(SDL_SCANCODE_A, handler);
auto handler = InputMapper::EventHandler(
[expected_msg]() { output << expected_msg << std::flush; });
auto event =
SdlEventSimulator::eventFromScancode(SDL_SCANCODE_X);
testInterface.RegisterMapping(event, handler);
auto& handlerList = testSubject.getEventHandlerMap();
auto convertedKey =
SdlEventSimulator::eventFromScancode(SDL_SCANCODE_A);
auto resulting_handler = handlerList.at(convertedKey);
auto& handlerList = testSubject.getEventHandlerMap();
auto resulting_handler = handlerList.at(event);
resulting_handler();
REQUIRE(output.str() == expected_msg);
}
resulting_handler();
REQUIRE(output.str() == expected_msg);
FIXTURE_CASE("RegisterMapping from SDL_Event")
{
// Test 2: Users can call the handler multiple times
// and the function calls should modify the state of the output
// buffer
resulting_handler();
REQUIRE(output.str() != expected_msg);
REQUIRE(output.str() == doubled_msg);
}
const std::string expected_msg = "SDL_SCANCODE_X detected";
const std::string doubled_msg =
"SDL_SCANCODE_X detectedSDL_SCANCODE_X detected";
static std::stringstream output;
FIXTURE_CASE(TestFixture, "Operator[]")
{
const std::string expected_msg = "SDL_SCANCODE_Y detected";
const std::string doubled_msg =
"SDL_SCANCODE_Y detectedSDL_SCANCODE_Y detected";
static std::stringstream output;
auto handler = InputMapper::EventHandler(
[expected_msg]() { output << expected_msg << std::flush; });
auto event = SdlEventSimulator::eventFromScancode(SDL_SCANCODE_X);
testInterface.RegisterMapping(event, handler);
auto handler = InputMapper::EventHandler(
[expected_msg]() { output << expected_msg << std::flush; });
auto event =
SdlEventSimulator::eventFromScancode(SDL_SCANCODE_X);
testInterface.RegisterMapping(event, handler);
auto& handlerList = testSubject.getEventHandlerMap();
auto resulting_handler = handlerList.at(event);
testInterface[event]();
resulting_handler();
REQUIRE(output.str() == expected_msg);
REQUIRE(output.str() == expected_msg);
// Test 2: Users can call the handler multiple times
// and the function calls should modify the state of the output buffer
resulting_handler();
REQUIRE(output.str() != expected_msg);
REQUIRE(output.str() == doubled_msg);
}
FIXTURE_CASE("Operator[]")
{
const std::string expected_msg = "SDL_SCANCODE_Y detected";
const std::string doubled_msg =
"SDL_SCANCODE_Y detectedSDL_SCANCODE_Y detected";
static std::stringstream output;
auto handler = InputMapper::EventHandler(
[expected_msg]() { output << expected_msg << std::flush; });
auto event = SdlEventSimulator::eventFromScancode(SDL_SCANCODE_X);
testInterface.RegisterMapping(event, handler);
testInterface[event]();
REQUIRE(output.str() == expected_msg);
testInterface[event]();
REQUIRE(output.str() != expected_msg);
REQUIRE(output.str() == doubled_msg);
testInterface[event]();
REQUIRE(output.str() != expected_msg);
REQUIRE(output.str() == doubled_msg);
}
}
// clang-format off

View File

@ -16,34 +16,33 @@
#include "framework/core/components/BaseComponent.hpp"
#include "framework/core/types/adapters/Sequential.hpp"
#include "tests/common/SomeComponent.hpp"
#include "tests/runtime/SomeComponent.hpp"
namespace {
using namespace QW;
using namespace QW::Core;
using namespace QW::Core::Components;
using namespace QW::Core::Types;
const char* TEST_SUITE_NAME = "[class:Adapter::Sequential]";
class TestComponent : public SomeComponent
BEGIN_TEST_SUITE("class:Adadpter::Sequential")
{
COMPONENT(TestComponent)
public:
TestComponent(InstanceId id) : SomeComponent(id) {}
virtual ~TestComponent() = default;
const InstanceInfo& GetInstanceInfo()
{
return this->component_info.instance;
}
void output(std::ostream& out)
{
out << this->component_info.instance.id << " " << std::flush;
}
};
using namespace QW;
using namespace QW::Core;
using namespace QW::Core::Components;
using namespace QW::Core::Types;
class TestComponent : public SomeComponent
{
COMPONENT(TestComponent)
public:
TestComponent(InstanceId id) : SomeComponent(id) {}
virtual ~TestComponent() = default;
const InstanceInfo& GetInstanceInfo()
{
return this->component_info.instance;
}
void output(std::ostream& out)
{
out << this->component_info.instance.id << " "
<< std::flush;
}
};
}
TEST_CASE("can iterate using c++11 foreach syntax", TEST_SUITE_NAME)

View File

@ -12,17 +12,15 @@
// IWYU pragma: begin_exports
#include <catch2/catch_test_macros.hpp>
#include <fakeit.hpp>
// IWYU pragma: end_exports
#define BEGIN_TEST_SUITE(name) \
namespace { \
const char* TEST_SUITE_NAME = "[" name "]";
static const char* TEST_SUITE_NAME = "[" name "]"; \
namespace
#define END_TEST_SUITE }
#define FIXTURE_CASE(TestFixture, testname) \
TEST_CASE_METHOD(TestFixture, #testname, TEST_SUITE_NAME)
#define FIXTURE_CASE(FixtureName, testname) \
TEST_CASE_METHOD(FixtureName, #testname, TEST_SUITE_NAME)
// IWYU pragma: end_exports
#ifdef VIM_COMPLETION
#define UNIT_TEST
#endif