Skip to content

Commit 0de0abb

Browse files
committed
filtered stack traces
1 parent a72f6a2 commit 0de0abb

File tree

5 files changed

+69
-52
lines changed

5 files changed

+69
-52
lines changed

example/always_passes.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@
22
#include <iostream>
33

44
namespace demo {
5+
template <typename T= void>
6+
auto zoinks() -> T {
7+
ASSERT(false, "oh no");
8+
}
59

6-
[[= rsl::test]]
7-
void always_passes() {
10+
[[= rsl::test]] void always_passes() {
811
std::cout << "foo\n";
912
std::cerr << "bar\n";
10-
ASSERT(false, "testing");
13+
zoinks();
1114
}
1215

13-
[[ = rsl::test, = rsl::expect_failure ]]
14-
void always_fails() {
15-
ASSERT(false, "oh no");
16+
[[ = rsl::test, = rsl::expect_failure ]] void always_fails() {
1617
ASSERT(false, "oh no");
1718
}
1819
} // namespace demo

include/rsl/testing/assert.hpp

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,34 @@ struct AssertionInfo {
99
std::string_view expanded;
1010
bool success;
1111
};
12-
std::vector<AssertionInfo>* assertion_counter(std::vector<AssertionInfo>* new_counter = nullptr);
12+
13+
struct AssertionTracker {
14+
std::vector<AssertionInfo> assertions;
15+
std::string test_name;
16+
};
17+
18+
AssertionTracker& assertion_counter();
1319
} // namespace rsl::testing::_testing_impl
1420

15-
#define LIBASSERT_ASSERT_MAIN_BODY(expr, \
16-
name, \
17-
type, \
18-
failaction, \
19-
decomposer_name, \
20-
condition_value, \
21-
pretty_function_arg, \
22-
...) \
23-
if (auto* ac = rsl::testing::_testing_impl::assertion_counter(); ac) { \
24-
ac->emplace_back(#expr, "", (condition_value)); \
25-
} \
26-
if (LIBASSERT_STRONG_EXPECT(!(condition_value), 0)) { \
27-
libassert::ERROR_ASSERTION_FAILURE_IN_CONSTEXPR_CONTEXT(); \
28-
LIBASSERT_BREAKPOINT_IF_DEBUGGING_ON_FAIL(); \
29-
failaction; \
30-
LIBASSERT_STATIC_DATA(name, libassert::assert_type::type, #expr, __VA_ARGS__) \
31-
libassert::detail::process_assert_fail(decomposer_name, \
32-
libassert_params LIBASSERT_VA_ARGS(__VA_ARGS__) \
33-
pretty_function_arg); \
21+
#define LIBASSERT_ASSERT_MAIN_BODY(expr, \
22+
name, \
23+
type, \
24+
failaction, \
25+
decomposer_name, \
26+
condition_value, \
27+
pretty_function_arg, \
28+
...) \
29+
rsl::testing::_testing_impl::assertion_counter().assertions.emplace_back(#expr, \
30+
"", \
31+
(condition_value)); \
32+
if (LIBASSERT_STRONG_EXPECT(!(condition_value), 0)) { \
33+
libassert::ERROR_ASSERTION_FAILURE_IN_CONSTEXPR_CONTEXT(); \
34+
LIBASSERT_BREAKPOINT_IF_DEBUGGING_ON_FAIL(); \
35+
failaction; \
36+
LIBASSERT_STATIC_DATA(name, libassert::assert_type::type, #expr, __VA_ARGS__) \
37+
libassert::detail::process_assert_fail(decomposer_name, \
38+
libassert_params LIBASSERT_VA_ARGS(__VA_ARGS__) \
39+
pretty_function_arg); \
3440
}
3541

3642
#include <libassert/assert.hpp>

include/rsl/testing/util.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <vector>
33
#include <tuple>
44
#include <ranges>
5+
#include <numeric>
56

67
namespace rsl {
78
template <typename... Ts>
@@ -35,4 +36,11 @@ template <typename... Ts>
3536
constexpr std::vector<std::tuple<Ts...>> cartesian_product(std::initializer_list<Ts> const&... vs) {
3637
return cartesian_product(std::vector(vs)...);
3738
}
39+
40+
template <std::ranges::range R>
41+
std::string join_str(R&& values, std::string_view delimiter) {
42+
auto fold = [&](std::string a, auto b) { return std::move(a) + delimiter + b; };
43+
44+
return std::accumulate(std::next(values.begin()), values.end(), std::string(values[0]), fold);
45+
}
3846
} // namespace rsl

src/main/main.cpp

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,14 @@
33
#define RSLTEST_SKIP
44
#include <memory>
55
#include <rsl/test>
6-
7-
#include <regex>
8-
9-
#include <numeric>
10-
#include <ranges>
116
#include <string_view>
127
#include <string>
138

149
#include <rsl/config>
10+
#include <rsl/testing/util.hpp>
1511
#include <rsl/testing/_testing_impl/factory.hpp>
1612
#include "output.hpp"
1713

18-
namespace {
19-
template <std::ranges::range R>
20-
std::string join(R&& values, std::string_view delimiter) {
21-
auto fold = [&](std::string a, auto b) { return std::move(a) + delimiter + b; };
22-
23-
return std::accumulate(std::next(values.begin()), values.end(), std::string(values[0]), fold);
24-
}
25-
26-
} // namespace
27-
2814
class[[= rsl::cli::description("rsl::test (in Catch2 v3.8.1 compatibility mode)")]] TestConfig : public rsl::cli {
2915
rsl::testing::TestRoot tree;
3016
std::vector<std::string> sections;
@@ -69,7 +55,7 @@ class[[= rsl::cli::description("rsl::test (in Catch2 v3.8.1 compatibility mode)"
6955
rsl::testing::TestRoot new_tree;
7056
// rebuild the test tree with filters applied
7157
for (auto&& test : tree) {
72-
auto full_name = join(test.full_name, "::");
58+
auto full_name = rsl::join_str(test.full_name, "::");
7359

7460
for (auto const& name : names) {
7561
if (name == full_name || name == test.name || name == test.full_name[0]) {

src/test.cpp

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,25 @@
55
#include <rsl/testing/assert.hpp>
66
#include <rsl/testing/test.hpp>
77
#include <rsl/testing/output.hpp>
8+
#include <rsl/testing/util.hpp>
89
#include <rsl/testing/_testing_impl/discovery.hpp>
910

1011
#include "capture.hpp"
1112

13+
#include <cpptrace/basic.hpp>
14+
#include <cpptrace/utils.hpp>
15+
16+
void cleanup_frames(cpptrace::stacktrace& trace, std::string_view test_name) {
17+
std::vector<cpptrace::stacktrace_frame> frames;
18+
for (auto const& frame : trace.frames | std::views::drop(1)) {
19+
frames.push_back(frame);
20+
if (cpptrace::prune_symbol(frame.symbol) == test_name) {
21+
break;
22+
}
23+
}
24+
trace.frames = frames;
25+
}
26+
1227
void failure_handler(libassert::assertion_info const& info) {
1328
// libassert::enable_virtual_terminal_processing_if_needed(); // for terminal colors on windows
1429
constexpr bool Colorize = true;
@@ -20,7 +35,11 @@ void failure_handler(libassert::assertion_info const& info) {
2035
}
2136
message += "\n";
2237
message += info.statement(scheme) + info.print_binary_diagnostics(width, scheme) +
23-
info.print_extra_diagnostics(width, scheme);
38+
info.print_extra_diagnostics(width, scheme);// + info.print_stacktrace(width, scheme);
39+
40+
auto trace = info.get_stacktrace();
41+
cleanup_frames(trace, rsl::testing::_testing_impl::assertion_counter().test_name);
42+
message += trace.to_string(true);
2443
throw rsl::testing::assertion_failure(message);
2544
}
2645

@@ -31,11 +50,8 @@ std::set<TestDef>& registry() {
3150
return data;
3251
}
3352

34-
std::vector<AssertionInfo>* assertion_counter(std::vector<AssertionInfo>* new_counter) {
35-
static std::vector<AssertionInfo>* counter = nullptr;
36-
if (new_counter != nullptr) {
37-
counter = new_counter;
38-
}
53+
AssertionTracker& assertion_counter() {
54+
static AssertionTracker counter{};
3955
return counter;
4056
}
4157
} // namespace _testing_impl
@@ -66,15 +82,15 @@ bool TestNamespace::run(Reporter* reporter) {
6682

6783
std::vector<TestResult> results;
6884
for (auto const& test_run : test.get_tests()) {
69-
std::vector<_testing_impl::AssertionInfo> assertions;
70-
_testing_impl::assertion_counter(&assertions);
85+
auto& tracker = _testing_impl::assertion_counter();
86+
tracker.assertions = {};
87+
tracker.test_name = join_str(test.full_name, "::");
7188

7289
reporter->before_test(test_run);
7390
auto result = test_run.run();
7491
reporter->after_test(result);
7592

76-
_testing_impl::assertion_counter(nullptr);
77-
std::println("assertion count: {}", assertions.size());
93+
std::println("assertion count: {}", tracker.assertions.size());
7894
results.push_back(result);
7995
}
8096

0 commit comments

Comments
 (0)