| @@ -24,87 +24,81 @@ | |||
| using namespace trompeloeil; | |||
| struct CallMock | |||
| namespace mock | |||
| { | |||
| MAKE_MOCK0(deleter, void()); | |||
| }; | |||
| struct CallMock | |||
| { | |||
| MAKE_MOCK0(deleter, void()); | |||
| }; | |||
| } | |||
| namespace | |||
| { | |||
| CallMock m; | |||
| mock::CallMock m; | |||
| void deleter() | |||
| { | |||
| m.deleter(); | |||
| } | |||
| void deleterThrow() | |||
| { | |||
| throw std::exception{}; | |||
| } | |||
| } | |||
| TEST_CASE("deleter called on destruction", "[ScopeGuard]") | |||
| { | |||
| { | |||
| REQUIRE_CALL(m, deleter()); | |||
| auto guard = sr::scope_guard(deleter); | |||
| static_cast<void>(guard); | |||
| } | |||
| REQUIRE_CALL(m, deleter()); | |||
| auto guard = sr::scope_guard(deleter); | |||
| static_cast<void>(guard); | |||
| } | |||
| TEST_CASE("deleter is not called if released", "[ScopeGuard]") | |||
| { | |||
| std::size_t calls{0}; | |||
| { | |||
| auto guard = sr::scope_guard([&calls] { ++calls; }); | |||
| guard.release(); | |||
| } | |||
| REQUIRE_CALL(m, deleter()).TIMES(0); | |||
| auto guard = sr::scope_guard(deleter); | |||
| guard.release(); | |||
| } | |||
| REQUIRE(calls == 0); | |||
| TEST_CASE("deleter lambda called on destruction", "[ScopeGuard]") | |||
| { | |||
| mock::CallMock cm; | |||
| REQUIRE_CALL(cm, deleter()); | |||
| auto guard = sr::scope_guard([&cm] { cm.deleter(); }); | |||
| static_cast<void>(guard); | |||
| } | |||
| TEST_CASE("move releases moved-from object", "[ScopeGuard]") | |||
| { | |||
| std::size_t calls{0}; | |||
| { | |||
| auto movedFrom = sr::scope_guard([&calls] { ++calls; }); | |||
| auto guard = std::move(movedFrom); | |||
| static_cast<void>(guard); | |||
| } | |||
| REQUIRE(calls == 1); | |||
| REQUIRE_CALL(m, deleter()); | |||
| auto movedFrom = sr::scope_guard(deleter); | |||
| auto guard = std::move(movedFrom); | |||
| static_cast<void>(guard); | |||
| } | |||
| TEST_CASE("move transfers state", "[ScopeGuard]") | |||
| { | |||
| std::size_t calls{0}; | |||
| { | |||
| auto movedFrom = sr::scope_guard([&calls] { ++calls; }); | |||
| auto guard = std::move(movedFrom); | |||
| static_cast<void>(guard); | |||
| } | |||
| REQUIRE(calls == 1); | |||
| REQUIRE_CALL(m, deleter()); | |||
| auto movedFrom = sr::scope_guard(deleter); | |||
| auto guard = std::move(movedFrom); | |||
| static_cast<void>(guard); | |||
| } | |||
| TEST_CASE("move transfers state if released", "[ScopeGuard]") | |||
| { | |||
| std::size_t calls{0}; | |||
| { | |||
| auto movedFrom = sr::scope_guard([&calls] { ++calls; }); | |||
| movedFrom.release(); | |||
| auto guard = std::move(movedFrom); | |||
| static_cast<void>(guard); | |||
| } | |||
| REQUIRE(calls == 0); | |||
| REQUIRE_CALL(m, deleter()).TIMES(0); | |||
| auto movedFrom = sr::scope_guard(deleter); | |||
| movedFrom.release(); | |||
| auto guard = std::move(movedFrom); | |||
| static_cast<void>(guard); | |||
| } | |||
| TEST_CASE("no exception propagation from deleter", "[ScopeGuard]") | |||
| { | |||
| REQUIRE_NOTHROW([] { | |||
| auto guard = sr::scope_guard([] { throw "Don't propagate this!"; }); | |||
| auto guard = sr::scope_guard(deleterThrow); | |||
| static_cast<void>(guard); | |||
| }()); | |||
| } | |||