clooneljump/test/unit/deferred_virtual_call.cpp

126 lines
3.2 KiB
C++
Raw Normal View History

/*
Copyright 2014-2016 Michele "King_DuckZ" Santullo
This file is part of CloonelJump.
CloonelJump 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 3 of the License, or
(at your option) any later version.
CloonelJump 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 CloonelJump. If not, see <http://www.gnu.org/licenses/>.
*/
#include "catch.hpp"
#include "sizenotifiable.hpp"
#include "sizeratio.hpp"
#include <exception>
#include <memory>
class DummyRegister {
public:
enum { SDLMAIN_NEEDED = false };
DummyRegister() = default;
void Register (cloonel::SizeNotifiableBase* parNotifiable) {
using cloonel::SizeRatio;
using cloonel::float2;
float2 orig(1024.0f, 768.0f);
float2 size(123.0f, 456.0f);
parNotifiable->NotifyResChanged(SizeRatio(orig, size));
}
void Unregister() {}
};
class NotifiableA : public cloonel::SizeNotifiable<::DummyRegister> {
public:
typedef cloonel::SizeNotifiable<::DummyRegister> BaseClass;
NotifiableA (bool parThrow, bool* parOut, const cloonel::DeferredRegister& parDeferred) :
BaseClass(parDeferred),
notif_a_called(false),
m_out_a(parOut)
{
if (parThrow)
throw std::runtime_error("Throwing exception because parThrow=true");
}
bool notif_a_called;
private:
bool* m_out_a;
virtual void OnResChanged (const cloonel::SizeRatio&) override {
notif_a_called = true;
if (m_out_a)
*m_out_a = true;
}
};
class NotifiableB : public NotifiableA {
public:
NotifiableB (bool parThrow, bool* parOutA, bool* parOutB, const cloonel::DeferredRegister& parDeferred) :
NotifiableA(parThrow, parOutA, parDeferred),
notif_b_called(false),
m_out_b(parOutB)
{}
bool notif_b_called;
private:
bool* m_out_b;
virtual void OnResChanged (const cloonel::SizeRatio&) override {
notif_b_called = true;
if (m_out_b)
*m_out_b = true;
}
};
TEST_CASE ("Check the deferred virtual call mechanism in SizeNotifiable", "[core]") {
using cloonel::DeferredRegister;
{
NotifiableB b(false, nullptr, nullptr, DeferredRegister());
REQUIRE( b.notif_b_called );
REQUIRE( !b.notif_a_called );
}
{
NotifiableA a(false, nullptr, DeferredRegister());
REQUIRE( a.notif_a_called );
}
{
bool notif_a = false;
bool notif_b = false;
//Check that the test mechanism works (sets the bool pointers)
{
NotifiableB b(false, &notif_a, &notif_b, DeferredRegister());
REQUIRE( b.notif_b_called );
REQUIRE( not notif_a );
REQUIRE( notif_b );
}
notif_a = notif_b = false;
std::unique_ptr<NotifiableB> notifiable;
try {
notifiable.reset(new NotifiableB(true, &notif_a, &notif_b, DeferredRegister()));
REQUIRE( false ); //not reached, constructor should throw
}
catch (const std::runtime_error& e) {
REQUIRE( e.what() == std::string("Throwing exception because parThrow=true") );
}
REQUIRE( not notif_a );
REQUIRE( not notif_b );
}
}