Skip to content

Commit

Permalink
Refactor existing unit tests using Trompeloeil
Browse files Browse the repository at this point in the history
  • Loading branch information
ZombieRaccoon committed May 22, 2021
1 parent 1975953 commit 53e2f0c
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 72 deletions.
21 changes: 21 additions & 0 deletions Tests/Source/Common/Mocks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include <RmlUi/Core/EventListener.h>
#include <RmlUi/Core/EventListenerInstancer.h>

#include <doctest.h>
#include <doctest/trompeloeil.hpp>

class MockEventListener : public trompeloeil::mock_interface<Rml::EventListener>
{
public:
IMPLEMENT_MOCK1(OnAttach);
IMPLEMENT_MOCK1(OnDetach);
IMPLEMENT_MOCK1(ProcessEvent);
};

class MockEventListenerInstancer : public trompeloeil::mock_interface<Rml::EventListenerInstancer>
{
public:
IMPLEMENT_MOCK2(InstanceEventListener);
};
67 changes: 39 additions & 28 deletions Tests/Source/UnitTests/Element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
*
*/

#include "../Common/Mocks.h"
#include "../Common/TestsShell.h"
#include "FakeEventListenerInstancer.h"
#include <RmlUi/Core/Context.h>
#include <RmlUi/Core/Element.h>
#include <RmlUi/Core/ElementDocument.h>
Expand Down Expand Up @@ -67,7 +67,7 @@ static const String document_clone_rml = R"(
</rml>
)";

TEST_CASE("element")
TEST_CASE("Element")
{
Context* context = TestsShell::GetContext();
REQUIRE(context);
Expand All @@ -80,64 +80,75 @@ TEST_CASE("element")
context->Render();

TestsShell::RenderLoop();
SUBCASE("attribute")
SUBCASE("Attribute")
{
auto* button = document->AppendChild(document->CreateElement("button"));
SUBCASE("event listener")
SUBCASE("Event listener")
{
static constexpr auto CLICK_EVENT = "click";
namespace tl = trompeloeil;
static constexpr auto ON_CLICK_ATTRIBUTE = "onclick";
static constexpr auto ON_CLICK_VALUE = "moo";

FakeEventListenerInstancer eventListenerInstancer;
Factory::RegisterEventListenerInstancer(&eventListenerInstancer);
std::vector<UniquePtr<tl::expectation>> expectations;

REQUIRE(button->DispatchEvent(CLICK_EVENT, {}));
button->SetAttribute(ON_CLICK_ATTRIBUTE, ON_CLICK_VALUE);
REQUIRE_EQ(eventListenerInstancer.GetLastInstancedValue(), ON_CLICK_VALUE);
CHECK_FALSE(button->DispatchEvent(CLICK_EVENT, {}));

SUBCASE("removal")
UniquePtr<MockEventListener> mockEventListener;
const auto configureMockEventListener = [&]()
{
button->RemoveAttribute(ON_CLICK_ATTRIBUTE);
CHECK(button->DispatchEvent(CLICK_EVENT, {}));
}
mockEventListener.reset(new MockEventListener());
expectations.emplace_back(NAMED_ALLOW_CALL(*mockEventListener, OnAttach(button)));
expectations.emplace_back(NAMED_ALLOW_CALL(*mockEventListener, OnDetach(button))
.LR_SIDE_EFFECT(mockEventListener.reset()));
};

MockEventListenerInstancer mockEventListenerInstancer;
const auto configureMockEventListenerInstancer = [&](const auto value)
{
expectations.emplace_back(NAMED_REQUIRE_CALL(mockEventListenerInstancer, InstanceEventListener(value, button))
.LR_SIDE_EFFECT(configureMockEventListener())
.LR_RETURN(mockEventListener.get()));
};

SUBCASE("replacement")
Factory::RegisterEventListenerInstancer(&mockEventListenerInstancer);

configureMockEventListenerInstancer(ON_CLICK_VALUE);
button->SetAttribute(ON_CLICK_ATTRIBUTE, ON_CLICK_VALUE);

SUBCASE("Replacement")
{
static constexpr auto REPLACEMENT_ON_CLICK_VALUE = "boo";

configureMockEventListenerInstancer(REPLACEMENT_ON_CLICK_VALUE);
button->SetAttribute(ON_CLICK_ATTRIBUTE, REPLACEMENT_ON_CLICK_VALUE);
REQUIRE_EQ(eventListenerInstancer.GetLastInstancedValue(), REPLACEMENT_ON_CLICK_VALUE);
CHECK_FALSE(button->DispatchEvent(CLICK_EVENT, {}));
}

button->RemoveAttribute(ON_CLICK_ATTRIBUTE);
}

SUBCASE("simple")
SUBCASE("Simple")
{
static constexpr auto DISABLED_ATTRIBUTE = "disabled";

REQUIRE_FALSE(button->HasAttribute(DISABLED_ATTRIBUTE));
button->SetAttribute(DISABLED_ATTRIBUTE, "");
REQUIRE(button->HasAttribute(DISABLED_ATTRIBUTE));

SUBCASE("removal")
{
button->RemoveAttribute(DISABLED_ATTRIBUTE);
CHECK_FALSE(button->HasAttribute(DISABLED_ATTRIBUTE));
}

SUBCASE("replacement")
SUBCASE("Replacement")
{
static constexpr auto VALUE = "something";

button->SetAttribute(DISABLED_ATTRIBUTE, VALUE);
const auto* attributeValue = button->GetAttribute(DISABLED_ATTRIBUTE);
REQUIRE(attributeValue);
REQUIRE(attributeValue->GetType() == Variant::Type::STRING);
CHECK(attributeValue->Get<String>() == VALUE);
}

button->RemoveAttribute(DISABLED_ATTRIBUTE);
CHECK_FALSE(button->HasAttribute(DISABLED_ATTRIBUTE));
}
}

SUBCASE("clone")
SUBCASE("Clone")
{
// Simulate input for mouse click and drag
context->ProcessMouseMove(10, 10, 0);
Expand Down
37 changes: 27 additions & 10 deletions Tests/Source/UnitTests/ElementDocument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
*
*/

#include "../Common/Mocks.h"
#include "../Common/TestsShell.h"
#include "FakeEventListenerInstancer.h"
#include <RmlUi/Core/Context.h>
#include <RmlUi/Core/Element.h>
#include <RmlUi/Core/ElementDocument.h>
Expand Down Expand Up @@ -96,9 +96,9 @@ static const String document_focus_rml = R"(

static const String focus_forward = "p1 p2 p3 p5 p7 p9 p10 p11 p12 p13";

TEST_SUITE_BEGIN("elementdocument");
TEST_SUITE_BEGIN("ElementDocument");

TEST_CASE("focus")
TEST_CASE("Focus")
{
Context* context = TestsShell::GetContext();
REQUIRE(context);
Expand All @@ -111,14 +111,14 @@ TEST_CASE("focus")
context->Render();

TestsShell::RenderLoop();
SUBCASE("tab order")
SUBCASE("Tab order")
{
StringList ids;
StringUtilities::ExpandString(ids, focus_forward, ' ');
REQUIRE(!ids.empty());

document->Focus();
SUBCASE("forward")
SUBCASE("Forward")
{
for(const String& id : ids)
{
Expand All @@ -131,7 +131,7 @@ TEST_CASE("focus")
CHECK(context->GetFocusElement()->GetId() == ids[0]);
}

SUBCASE("reverse")
SUBCASE("Reverse")
{
std::reverse(ids.begin(), ids.end());
for (const String& id : ids)
Expand Down Expand Up @@ -241,17 +241,34 @@ TEST_CASE("focus")
TestsShell::ShutdownShell();
}

TEST_CASE("load")
TEST_CASE("Load")
{
namespace tl = trompeloeil;
constexpr auto BODY_TAG = "body";

Context* context = TestsShell::GetContext();
REQUIRE(context);

FakeEventListenerInstancer eventListenerInstancer;
Factory::RegisterEventListenerInstancer(&eventListenerInstancer);
MockEventListener mockEventListener;
MockEventListenerInstancer mockEventListenerInstancer;

tl::sequence sequence;
REQUIRE_CALL(mockEventListenerInstancer, InstanceEventListener("something", tl::_))
.WITH(_2->GetTagName() == BODY_TAG)
.IN_SEQUENCE(sequence)
.LR_RETURN(&mockEventListener);

ALLOW_CALL(mockEventListener, OnAttach(tl::_));
ALLOW_CALL(mockEventListener, OnDetach(tl::_));

REQUIRE_CALL(mockEventListener, ProcessEvent(tl::_))
.WITH(_1.GetId() == EventId::Load && _1.GetTargetElement()->GetTagName() == BODY_TAG)
.IN_SEQUENCE(sequence);

Factory::RegisterEventListenerInstancer(&mockEventListenerInstancer);

ElementDocument* document = context->LoadDocumentFromMemory(document_focus_rml);
REQUIRE(document);
CHECK_EQ(eventListenerInstancer.GetLastInstancedValue(), "something");

document->Close();
TestsShell::ShutdownShell();
Expand Down
34 changes: 0 additions & 34 deletions Tests/Source/UnitTests/FakeEventListenerInstancer.h

This file was deleted.

0 comments on commit 53e2f0c

Please sign in to comment.