| /* | |||||
| * Scope Guard | |||||
| * Copyright (C) 2017 offa | |||||
| * | |||||
| * This file is part of Scope Guard. | |||||
| * | |||||
| * Scope Guard 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. | |||||
| * | |||||
| * Scope Guard 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 Scope Guard. If not, see <http://www.gnu.org/licenses/>. | |||||
| */ | |||||
| #pragma once | |||||
| #include <trompeloeil.hpp> | |||||
| namespace | |||||
| { | |||||
| struct CallMock | |||||
| { | |||||
| MAKE_MOCK0(deleter, void()); | |||||
| }; | |||||
| struct ThrowOnCopyMock | |||||
| { | |||||
| ThrowOnCopyMock() { } | |||||
| ThrowOnCopyMock(const ThrowOnCopyMock&) | |||||
| { | |||||
| throw std::exception{}; | |||||
| } | |||||
| MAKE_CONST_MOCK0(deleter, void()); | |||||
| void operator()() const | |||||
| { | |||||
| this->deleter(); | |||||
| } | |||||
| ThrowOnCopyMock& operator=(const ThrowOnCopyMock&) | |||||
| { | |||||
| throw std::exception{}; | |||||
| } | |||||
| }; | |||||
| struct NotNothrowMoveMock | |||||
| { | |||||
| NotNothrowMoveMock(CallMock* m) : m_mock(m) { } | |||||
| NotNothrowMoveMock(const NotNothrowMoveMock& other) : m_mock(other.m_mock) { } | |||||
| NotNothrowMoveMock(NotNothrowMoveMock&& other) noexcept(false) : m_mock(other.m_mock) { } | |||||
| void operator()() const | |||||
| { | |||||
| m_mock->deleter(); | |||||
| } | |||||
| NotNothrowMoveMock& operator=(const NotNothrowMoveMock&) | |||||
| { | |||||
| throw "Not implemented"; | |||||
| } | |||||
| NotNothrowMoveMock& operator=(NotNothrowMoveMock&&) | |||||
| { | |||||
| throw "Not implemented"; | |||||
| } | |||||
| CallMock* m_mock; | |||||
| }; | |||||
| } | |||||
| */ | */ | ||||
| #include "scope_exit.h" | #include "scope_exit.h" | ||||
| #include "CallMocks.h" | |||||
| #include <catch.hpp> | #include <catch.hpp> | ||||
| #include <trompeloeil.hpp> | |||||
| using namespace trompeloeil; | using namespace trompeloeil; | ||||
| namespace | namespace | ||||
| { | { | ||||
| struct CallMock | |||||
| { | |||||
| MAKE_MOCK0(deleter, void()); | |||||
| }; | |||||
| struct ThrowOnCopyMock | |||||
| { | |||||
| ThrowOnCopyMock() { } | |||||
| ThrowOnCopyMock(const ThrowOnCopyMock&) | |||||
| { | |||||
| throw std::exception{}; | |||||
| } | |||||
| MAKE_CONST_MOCK0(deleter, void()); | |||||
| void operator()() const | |||||
| { | |||||
| this->deleter(); | |||||
| } | |||||
| ThrowOnCopyMock& operator=(const ThrowOnCopyMock&) | |||||
| { | |||||
| throw std::exception{}; | |||||
| } | |||||
| }; | |||||
| struct NotNothrowMoveMock | |||||
| { | |||||
| NotNothrowMoveMock(CallMock* m) : m_mock(m) { } | |||||
| NotNothrowMoveMock(const NotNothrowMoveMock& other) : m_mock(other.m_mock) { } | |||||
| NotNothrowMoveMock(NotNothrowMoveMock&& other) noexcept(false) : m_mock(other.m_mock) { } | |||||
| void operator()() const | |||||
| { | |||||
| m_mock->deleter(); | |||||
| } | |||||
| NotNothrowMoveMock& operator=(const NotNothrowMoveMock&) | |||||
| { | |||||
| throw "Not implemented"; | |||||
| } | |||||
| NotNothrowMoveMock& operator=(NotNothrowMoveMock&&) | |||||
| { | |||||
| throw "Not implemented"; | |||||
| } | |||||
| CallMock* m_mock; | |||||
| }; | |||||
| CallMock m; | CallMock m; | ||||
| void deleter() | void deleter() | ||||
| { | { | ||||
| m.deleter(); | m.deleter(); | ||||
| REQUIRE_CALL(noMove, deleter()); | REQUIRE_CALL(noMove, deleter()); | ||||
| sr::scope_exit<decltype(noMove)> guard{noMove}; | sr::scope_exit<decltype(noMove)> guard{noMove}; | ||||
| }()); | |||||
| }()); | |||||
| } | } | ||||
| TEST_CASE("exit function is not called if released", "[ScopeExit]") | TEST_CASE("exit function is not called if released", "[ScopeExit]") |
| */ | */ | ||||
| #include "scope_fail.h" | #include "scope_fail.h" | ||||
| #include "CallMocks.h" | |||||
| #include <catch.hpp> | #include <catch.hpp> | ||||
| #include <trompeloeil.hpp> | |||||
| using namespace trompeloeil; | using namespace trompeloeil; | ||||
| namespace | namespace | ||||
| { | { | ||||
| struct CallMock | |||||
| { | |||||
| MAKE_MOCK0(deleter, void()); | |||||
| }; | |||||
| struct ThrowOnCopyMock | |||||
| { | |||||
| ThrowOnCopyMock() { } | |||||
| ThrowOnCopyMock(const ThrowOnCopyMock&) | |||||
| { | |||||
| throw std::exception{}; | |||||
| } | |||||
| MAKE_CONST_MOCK0(deleter, void()); | |||||
| void operator()() const | |||||
| { | |||||
| this->deleter(); | |||||
| } | |||||
| ThrowOnCopyMock& operator=(const ThrowOnCopyMock&) | |||||
| { | |||||
| throw std::exception{}; | |||||
| } | |||||
| }; | |||||
| struct NotNothrowMoveMock | |||||
| { | |||||
| NotNothrowMoveMock(CallMock* m) : m_mock(m) { } | |||||
| NotNothrowMoveMock(const NotNothrowMoveMock& other) : m_mock(other.m_mock) { } | |||||
| NotNothrowMoveMock(NotNothrowMoveMock&& other) noexcept(false) : m_mock(other.m_mock) { } | |||||
| void operator()() const | |||||
| { | |||||
| m_mock->deleter(); | |||||
| } | |||||
| NotNothrowMoveMock& operator=(const NotNothrowMoveMock&) | |||||
| { | |||||
| throw "Not implemented"; | |||||
| } | |||||
| NotNothrowMoveMock& operator=(NotNothrowMoveMock&&) | |||||
| { | |||||
| throw "Not implemented"; | |||||
| } | |||||
| CallMock* m_mock; | |||||
| }; | |||||
| CallMock m; | CallMock m; | ||||
| void deleter() | void deleter() | ||||
| { | { | ||||
| m.deleter(); | m.deleter(); | ||||
| REQUIRE_CALL(noMove, deleter()); | REQUIRE_CALL(noMove, deleter()); | ||||
| sr::scope_fail<decltype(noMove)> guard{noMove}; | sr::scope_fail<decltype(noMove)> guard{noMove}; | ||||
| }()); | |||||
| }()); | |||||
| } | } | ||||
| TEST_CASE("exit function is not called if released", "[ScopeFail]") | TEST_CASE("exit function is not called if released", "[ScopeFail]") |
| */ | */ | ||||
| #include "scope_success.h" | #include "scope_success.h" | ||||
| #include "CallMocks.h" | |||||
| #include <catch.hpp> | #include <catch.hpp> | ||||
| #include <trompeloeil.hpp> | |||||
| using namespace trompeloeil; | using namespace trompeloeil; | ||||
| namespace | namespace | ||||
| { | { | ||||
| struct CallMock | |||||
| { | |||||
| MAKE_MOCK0(deleter, void()); | |||||
| }; | |||||
| struct ThrowOnCopyMock | |||||
| { | |||||
| ThrowOnCopyMock() { } | |||||
| ThrowOnCopyMock(const ThrowOnCopyMock&) | |||||
| { | |||||
| throw std::exception{}; | |||||
| } | |||||
| MAKE_CONST_MOCK0(deleter, void()); | |||||
| void operator()() const | |||||
| { | |||||
| this->deleter(); | |||||
| } | |||||
| ThrowOnCopyMock& operator=(const ThrowOnCopyMock&) | |||||
| { | |||||
| throw std::exception{}; | |||||
| } | |||||
| }; | |||||
| struct NotNothrowMoveMock | |||||
| { | |||||
| NotNothrowMoveMock(CallMock* m) : m_mock(m) { } | |||||
| NotNothrowMoveMock(const NotNothrowMoveMock& other) : m_mock(other.m_mock) { } | |||||
| NotNothrowMoveMock(NotNothrowMoveMock&& other) noexcept(false) : m_mock(other.m_mock) { } | |||||
| void operator()() const | |||||
| { | |||||
| m_mock->deleter(); | |||||
| } | |||||
| NotNothrowMoveMock& operator=(const NotNothrowMoveMock&) | |||||
| { | |||||
| throw "Not implemented"; | |||||
| } | |||||
| NotNothrowMoveMock& operator=(NotNothrowMoveMock&&) | |||||
| { | |||||
| throw "Not implemented"; | |||||
| } | |||||
| CallMock* m_mock; | |||||
| }; | |||||
| CallMock m; | CallMock m; | ||||
| void deleter() | void deleter() | ||||
| { | { | ||||
| m.deleter(); | m.deleter(); |