/* 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 . */ #include "catch.hpp" #include "sizenotifiable.hpp" #include "sizeratio.hpp" #include #include 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, ¬if_a, ¬if_b, DeferredRegister()); REQUIRE( b.notif_b_called ); REQUIRE( not notif_a ); REQUIRE( notif_b ); } notif_a = notif_b = false; std::unique_ptr notifiable; try { notifiable.reset(new NotifiableB(true, ¬if_a, ¬if_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 ); } }