No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

102 líneas
2.9KB

  1. // MIT License
  2. //
  3. // Copyright (c) 2017-2018 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_exit.h"
  23. #include "CallMocks.h"
  24. #include <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", "[ScopeExit]")
  36. {
  37. REQUIRE_CALL(m, deleter());
  38. [[maybe_unused]] auto guard = sr::scope_exit{deleter};
  39. }
  40. TEST_CASE("exit function lambda called on destruction", "[ScopeExit]")
  41. {
  42. CallMock cm;
  43. REQUIRE_CALL(cm, deleter());
  44. [[maybe_unused]] auto guard = sr::scope_exit{[&cm] { cm.deleter(); }};
  45. }
  46. TEST_CASE("exit function called and rethrow on copy exception", "[ScopeExit]")
  47. {
  48. REQUIRE_THROWS([] {
  49. const ThrowOnCopyMock noMove;
  50. REQUIRE_CALL(noMove, deleter());
  51. sr::scope_exit guard{noMove};
  52. }());
  53. }
  54. TEST_CASE("exit function is not called if released", "[ScopeExit]")
  55. {
  56. REQUIRE_CALL(m, deleter()).TIMES(0);
  57. auto guard = sr::scope_exit{deleter};
  58. guard.release();
  59. }
  60. TEST_CASE("move releases moved-from object", "[ScopeExit]")
  61. {
  62. REQUIRE_CALL(m, deleter());
  63. auto movedFrom = sr::scope_exit{deleter};
  64. [[maybe_unused]] auto guard = std::move(movedFrom);
  65. }
  66. TEST_CASE("move with copy init releases moved-from object", "[ScopeExit]")
  67. {
  68. CallMock mock;
  69. const NotNothrowMoveMock notNothrow{&mock};
  70. REQUIRE_CALL(mock, deleter());
  71. sr::scope_exit movedFrom{notNothrow};
  72. auto guard = std::move(movedFrom);
  73. }
  74. TEST_CASE("move transfers state", "[ScopeExit]")
  75. {
  76. REQUIRE_CALL(m, deleter());
  77. auto movedFrom = sr::scope_exit{deleter};
  78. [[maybe_unused]] auto guard = std::move(movedFrom);
  79. }
  80. TEST_CASE("move transfers state if released", "[ScopeExit]")
  81. {
  82. REQUIRE_CALL(m, deleter()).TIMES(0);
  83. auto movedFrom = sr::scope_exit{deleter};
  84. movedFrom.release();
  85. [[maybe_unused]] auto guard = std::move(movedFrom);
  86. }