From bccf2c8a311e851cb57f4611b9a8257c0398e062 Mon Sep 17 00:00:00 2001 From: Corentin Schreiber Date: Thu, 22 Aug 2024 08:48:14 +0100 Subject: [PATCH] Fix #177 --- include/snitch/snitch_capture.hpp | 4 +--- src/snitch_capture.cpp | 13 +++++++++++ tests/runtime_tests/capture.cpp | 36 +++++++++++++++++++++++++++++++ tests/runtime_tests/section.cpp | 2 +- 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/include/snitch/snitch_capture.hpp b/include/snitch/snitch_capture.hpp index bfe2a96d..027d66a6 100644 --- a/include/snitch/snitch_capture.hpp +++ b/include/snitch/snitch_capture.hpp @@ -14,9 +14,7 @@ struct scoped_capture { capture_state& captures; std::size_t count = 0; - ~scoped_capture() { - captures.resize(captures.size() - count); - } + ~scoped_capture(); }; SNITCH_EXPORT std::string_view extract_next_name(std::string_view& names) noexcept; diff --git a/src/snitch_capture.cpp b/src/snitch_capture.cpp index e756325f..2d3f1b0d 100644 --- a/src/snitch_capture.cpp +++ b/src/snitch_capture.cpp @@ -20,6 +20,19 @@ void trim(std::string_view& str, std::string_view patterns) noexcept { } } // namespace +scoped_capture::~scoped_capture() { +#if SNITCH_WITH_EXCEPTIONS + if (std::uncaught_exceptions() > 0) { + // We are unwinding the stack because an exception has been thrown; + // avoid touching the capture state since we will want to preserve the information + // when reporting the exception. + return; + } +#endif + + captures.resize(captures.size() - count); +} + std::string_view extract_next_name(std::string_view& names) noexcept { std::string_view result; diff --git a/tests/runtime_tests/capture.cpp b/tests/runtime_tests/capture.cpp index eedbf46c..1368a4cf 100644 --- a/tests/runtime_tests/capture.cpp +++ b/tests/runtime_tests/capture.cpp @@ -171,6 +171,24 @@ TEST_CASE("capture", "[test macros]") { CHECK_CAPTURES_FOR_FAILURE(0u, "i := 1"); CHECK_CAPTURES_FOR_FAILURE(1u, "i := 1", "2 * i := 2"); } + +#if SNITCH_WITH_EXCEPTIONS + SECTION("with exception") { + framework.test_case.func = []() { + for (std::size_t i = 0; i < 5; ++i) { + SNITCH_CAPTURE(i); + + if (i % 2 == 1) { + throw std::runtime_error("bad"); + } + } + }; + + framework.run_test(); + REQUIRE(framework.get_num_failures() == 1u); + CHECK_CAPTURES_FOR_FAILURE(0u, "i := 1"); + } +#endif } TEST_CASE("info", "[test macros]") { @@ -324,6 +342,24 @@ TEST_CASE("info", "[test macros]") { framework.run_test(); CHECK_CAPTURES("1", "i := 1"); } + +#if SNITCH_WITH_EXCEPTIONS + SECTION("with exception") { + framework.test_case.func = []() { + for (std::size_t i = 0; i < 5; ++i) { + SNITCH_INFO(i); + + if (i % 2 == 1) { + throw std::runtime_error("bad"); + } + } + }; + + framework.run_test(); + REQUIRE(framework.get_num_failures() == 1u); + CHECK_CAPTURES_FOR_FAILURE(0u, "1"); + } +#endif } SNITCH_WARNING_POP diff --git a/tests/runtime_tests/section.cpp b/tests/runtime_tests/section.cpp index 8897e1e7..78bebc4e 100644 --- a/tests/runtime_tests/section.cpp +++ b/tests/runtime_tests/section.cpp @@ -354,7 +354,7 @@ TEST_CASE("section readme example", "[test macros]") { } }; - framework.registry.print_callback = print; + framework.registry.print_callback = print; framework.test_case.func = []() { auto& reg = snitch::impl::get_current_test().reg;