#include #include #include #include #include #include #include #include using ::testing::Return; using ::testing::_; #include //using namespace ::entt::literals; class MockUpdateStrategy : public MM::UpdateStrategies::UpdateStrategy { public: MOCK_METHOD( bool, registerService, (const entt::id_type s_id, std::vector&& info), (override) ); // protected: MOCK_METHOD(void, doUpdate, (MM::Engine& engine), (override)); MOCK_METHOD(bool, enableService, (const entt::id_type s_id), (override)); MOCK_METHOD(bool, disableService, (const entt::id_type s_id), (override)); // public: MOCK_METHOD(bool, enable, (const MM::UpdateStrategies::update_key_t key), (override)); MOCK_METHOD(bool, disable, (const MM::UpdateStrategies::update_key_t key), (override)); MOCK_METHOD(bool, depend, (const MM::UpdateStrategies::update_key_t A, const MM::UpdateStrategies::update_key_t B), (override)); MOCK_METHOD(void, addDefered, (std::function function), (override)); }; class MockService : public MM::Services::Service { public: const char* name(void) override { return "MockService"; } MOCK_METHOD(bool, enable, (MM::Engine& engine), (override)); MOCK_METHOD(void, disable, (MM::Engine& engine), (override)); MOCK_METHOD(std::vector, registerUpdates, (), (override)); }; TEST(dependency_check_update_strategy, decoration_mock) { auto dep = std::make_unique>(); auto* mock = static_cast(dep.get()); EXPECT_CALL(*mock, registerService(_, _)) .Times(1); EXPECT_CALL(*mock, enableService(_)) .Times(1); EXPECT_CALL(*mock, disableService(_)) .Times(1); class TmpMockService : public MockService { public: TmpMockService(void) { EXPECT_CALL(*this, registerUpdates()) .Times(1); EXPECT_CALL(*this, enable(_)) .Times(1); ON_CALL(*this, enable(_)) .WillByDefault(Return(true)); EXPECT_CALL(*this, disable(_)) .Times(1); } }; { MM::Engine engine(std::move(dep)); engine.addService(); ASSERT_TRUE(engine.enableService()); engine.disableService(); } } TEST(dependency_check_update_strategy, simple_loop) { auto dep = std::make_unique>(); auto* mock = static_cast(dep.get()); EXPECT_CALL(*mock, registerService(_, _)) .Times(1); EXPECT_CALL(*mock, enableService(_)) .Times(1); //EXPECT_CALL(*mock, disableService(_)) //.Times(1); EXPECT_CALL(*mock, depend(_, _)) .Times(1); // the layer should catch the error before forwarding it class BonkersService : public MM::Services::Service { public: virtual ~BonkersService(void) {} const char* name(void) override { return "BonkersService"; } bool enable(MM::Engine& engine) override { engine.getUpdateStrategy().depend("BonkerA"_hs, "BonkerB"_hs); // maleformed: direct cycle engine.getUpdateStrategy().depend("BonkerB"_hs, "BonkerA"_hs); return true; } void disable(MM::Engine&) override {} std::vector registerUpdates(void) override { return { MM::UpdateStrategies::UpdateCreationInfo{ "BonkerA"_hs, "BonkerA", [](MM::Engine&) {} }, MM::UpdateStrategies::UpdateCreationInfo{ "BonkerB"_hs, "BonkerB", [](MM::Engine&) {} } }; } }; { MM::Engine engine(std::move(dep)); engine.addService(); ASSERT_THROW(engine.enableService(), std::logic_error); //engine.disableService(); } }