/* | |||||
* 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(); |