選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

126 行
3.5KB

  1. // MIT License
  2. //
  3. // Copyright (c) 2017-2020 offa
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in all
  13. // copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21. // SOFTWARE.
  22. #include "scope_success.h"
  23. #include "CallMocks.h"
  24. #include <catch2/catch.hpp>
  25. using namespace mock;
  26. using namespace trompeloeil;
  27. namespace
  28. {
  29. CallMock m;
  30. void deleter()
  31. {
  32. m.deleter();
  33. }
  34. }
  35. TEST_CASE("exit function called on destruction", "[ScopeSuccess]")
  36. {
  37. REQUIRE_CALL(m, deleter());
  38. [[maybe_unused]] auto guard = sr::scope_success{deleter};
  39. }
  40. TEST_CASE("exit function lambda called on destruction", "[ScopeSuccess]")
  41. {
  42. CallMock cm;
  43. REQUIRE_CALL(cm, deleter());
  44. [[maybe_unused]] auto guard = sr::scope_success{[&cm] { cm.deleter(); }};
  45. }
  46. TEST_CASE("exit function not called and rethrow on copy exception", "[ScopeSuccess]")
  47. {
  48. REQUIRE_THROWS([] {
  49. const ThrowOnCopyMock noMove;
  50. REQUIRE_CALL(noMove, deleter());
  51. sr::scope_success guard{noMove};
  52. }());
  53. }
  54. TEST_CASE("exit function is not called if released", "[ScopeSuccess]")
  55. {
  56. REQUIRE_CALL(m, deleter()).TIMES(0);
  57. auto guard = sr::scope_success{deleter};
  58. guard.release();
  59. }
  60. TEST_CASE("move releases moved-from object", "[ScopeSuccess]")
  61. {
  62. REQUIRE_CALL(m, deleter());
  63. auto movedFrom = sr::scope_success{deleter};
  64. [[maybe_unused]] auto guard = std::move(movedFrom);
  65. }
  66. TEST_CASE("move with copy init releases moved-from object", "[ScopeSuccess]")
  67. {
  68. CallMock mock;
  69. const NotNothrowMoveMock notNothrow{&mock};
  70. REQUIRE_CALL(mock, deleter());
  71. sr::scope_success movedFrom{notNothrow};
  72. [[maybe_unused]] auto guard = std::move(movedFrom);
  73. }
  74. TEST_CASE("move transfers state", "[ScopeSuccess]")
  75. {
  76. REQUIRE_CALL(m, deleter());
  77. auto movedFrom = sr::scope_success{deleter};
  78. [[maybe_unused]] auto guard = std::move(movedFrom);
  79. }
  80. TEST_CASE("move transfers state if released", "[ScopeSuccess]")
  81. {
  82. REQUIRE_CALL(m, deleter()).TIMES(0);
  83. auto movedFrom = sr::scope_success{deleter};
  84. movedFrom.release();
  85. [[maybe_unused]] auto guard = std::move(movedFrom);
  86. }
  87. TEST_CASE("exit function not called on exception", "[ScopeFail]")
  88. {
  89. try
  90. {
  91. [[maybe_unused]] auto guard = sr::scope_success{deleter};
  92. throw std::exception{};
  93. }
  94. catch( ... )
  95. {
  96. }
  97. }
  98. TEST_CASE("exit function called on pending exception", "[ScopeFail]")
  99. {
  100. try
  101. {
  102. throw std::exception{};
  103. }
  104. catch( ... )
  105. {
  106. REQUIRE_CALL(m, deleter());
  107. [[maybe_unused]] auto guard = sr::scope_success{deleter};
  108. }
  109. }