Skip to content

Commit d8f5011

Browse files
committed
fix reported failure location
1 parent 56c99de commit d8f5011

File tree

9 files changed

+51
-32
lines changed

9 files changed

+51
-32
lines changed

example/always_passes.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33

44
namespace demo {
55
auto zoinks() {
6-
ASSERT(false, "oh no");
6+
bool x = true;
7+
ASSERT(x == false);
78
}
89

910
[[= rsl::test]] void always_passes() {

include/rsl/testing/annotations.hpp

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,32 +30,33 @@ struct Skip {
3030
bool (*value)() = &_testing_impl::constant_predicate<true>;
3131
};
3232

33-
34-
namespace _impl {
35-
template <typename T, bool T::*condition>
33+
namespace _impl {
34+
template <typename T, bool T::* condition>
3635
bool wrap_cli_nsdm() {
3736
return T::get().*condition;
3837
}
39-
}
38+
} // namespace _impl
4039

4140
struct SkipIf {
4241
static consteval Skip operator()(bool condition) {
4342
return {extract<bool (*)()>(
44-
substitute(^^_testing_impl::constant_predicate, {std::meta::reflect_constant(condition)}))};
43+
substitute(^^_testing_impl::constant_predicate, {std::meta::reflect_constant(condition)}))};
44+
}
45+
46+
static consteval Skip operator()(bool (*condition)()) { return {condition}; }
47+
48+
template <typename T>
49+
requires requires {
50+
{ T::get() } -> std::same_as<T&>;
4551
}
46-
47-
static consteval Skip operator()(bool (*condition)()) { return {condition}; }
48-
49-
template <typename T>
50-
requires requires { T::get(); }
51-
static consteval Skip operator()(bool T::* condition) {
52-
return {extract<bool (*)()>(
52+
static consteval Skip operator()(bool T::* condition) {
53+
return {extract<bool (*)()>(
5354
substitute(^^_impl::wrap_cli_nsdm, {^^T, std::meta::reflect_constant(condition)}))};
54-
}
55-
};
56-
57-
struct Rename {
58-
rsl::string_view value;
55+
}
56+
};
57+
58+
struct Rename {
59+
rsl::string_view value;
5960

6061
static consteval Rename operator()(std::string_view new_name) {
6162
return Rename(define_static_string(new_name));

include/rsl/testing/assert.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
11
#pragma once
22
#include <cstddef>
3+
#include <exception>
34
#include <vector>
45
#include <string_view>
56

7+
#include <rsl/source_location>
8+
69
namespace rsl::testing {
10+
11+
struct assertion_failure : std::exception {
12+
std::string message;
13+
rsl::source_location sloc;
14+
15+
assertion_failure(std::string_view message, rsl::source_location sloc)
16+
: message(std::string(message))
17+
, sloc(sloc) {}
18+
};
19+
720
struct AssertionInfo {
821
std::string_view raw;
922
std::string_view expanded;

include/rsl/testing/test.hpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,9 @@
1717

1818
#include <rsl/testing/assert.hpp>
1919

20-
namespace rsl::testing {
21-
struct assertion_failure : std::runtime_error {
22-
using std::runtime_error::runtime_error;
23-
};
2420

21+
namespace rsl::testing {
22+
2523
class Test {
2624
using runner_type = std::vector<TestCase> (Test::*)() const;
2725
runner_type get_tests_impl;
@@ -30,6 +28,7 @@ class Test {
3028
std::vector<TestCase> expand_test() const {
3129
return _testing_impl::Expand<R, Ann>{this}.runs;
3230
}
31+
3332
public:
3433
std::source_location sloc;
3534
std::string_view name; // raw name

include/rsl/testing/test_case.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ struct TestResult {
1818
TestOutcome outcome;
1919
double duration_ms;
2020

21-
std::string failure;
21+
std::optional<assertion_failure> failure;
2222
std::string exception;
2323
std::string stdout;
2424
std::string stderr;

src/main/reporters/catch2xml.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,11 @@ class[[= rename("xml")]] Catch2XmlReporter : public Reporter::Registrar<Catch2Xm
202202
using enum TestOutcome;
203203
case PASS: ++section->results.successes; break;
204204
case FAIL:
205-
section->failure = {.value = result.failure};
205+
if (result.failure.has_value()) {
206+
section->failure = Failure{.filename = std::string(result.failure->sloc.file),
207+
.line = result.failure->sloc.line,
208+
.value = result.failure->message};
209+
}
206210
++section->results.failures;
207211
break;
208212
case SKIP:

src/main/reporters/terminal.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class [[=rename("plain")]] ConsoleReporter : public Reporter::Registrar<ConsoleR
2626
reset,
2727
result.name,
2828
result.duration_ms);
29-
std::print("{}ERROR{}: {}\n", color[1], reset, result.failure);
29+
std::print("{}ERROR{}: {}\n", color[1], reset, result.failure->message);
3030
std::print("==== {}stdout{} ====\n{}\n", color[1], reset, result.stdout);
3131
std::print("==== {}stderr{} ====\n{}\n", color[1], reset, result.stderr);
3232
}

src/main/reporters/xml.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class [[=rename("junit")]] JUnitXmlReporter : public Reporter::Registrar<JUnitXm
2323
void after_test(TestResult const& result) override {
2424
auto node = testcase{.name=std::string(result.name), .time=result.duration_ms / 1000.};
2525
if (result.outcome == TestOutcome::FAIL) {
26-
node.failure = result.failure + "\n";
26+
node.failure = result.failure->message + "\n";
2727
}
2828
suite.tests.push_back(node);
2929
}

src/test.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <print>
44
#include <chrono>
55

6+
#include <rsl/source_location>
67
#include <rsl/testing/assert.hpp>
78
#include <rsl/testing/test.hpp>
89
#include <rsl/testing/output.hpp>
@@ -43,7 +44,7 @@ void failure_handler(libassert::assertion_info const& info) {
4344
auto trace = info.get_stacktrace();
4445
cleanup_frames(trace, rsl::testing::_testing_impl::assertion_counter().test_name);
4546
message += trace.to_string(Colorize);
46-
throw rsl::testing::assertion_failure(message);
47+
throw rsl::testing::assertion_failure(message, rsl::source_location(info.file_name, info.function, info.line));
4748
}
4849

4950
namespace rsl::testing {
@@ -101,7 +102,7 @@ bool TestNamespace::run(Reporter* reporter) {
101102
reporter->before_test(TestCase{&test, +[]{}, std::string(test.name)});
102103

103104
// TODO stringify skipped tests properly
104-
auto result = TestResult{&test, std::string(test.name) + "(...)", TestOutcome::PASS};
105+
auto result = TestResult{&test, std::string(test.name) + "(...)", TestOutcome::SKIP};
105106
reporter->after_test(result);
106107
results.push_back(result);
107108
}
@@ -128,15 +129,15 @@ TestResult TestCase::run() const {
128129
ret.duration_ms = std::chrono::duration<double, std::milli>(t1 - t0).count();
129130
return ret;
130131
} catch (assertion_failure const& failure) {
131-
ret.failure += failure.what();
132+
ret.failure = failure;
132133
} catch (std::exception const& exc) { //
133134
ret.exception += exc.what();
134135
} catch (std::string const& msg) { //
135-
ret.failure += msg;
136+
ret.exception += msg;
136137
} catch (std::string_view msg) { //
137-
ret.failure += msg;
138+
ret.exception += msg;
138139
} catch (char const* msg) { //
139-
ret.failure += msg;
140+
ret.exception += msg;
140141
} catch (...) { ret.exception += "unknown exception thrown"; }
141142

142143
ret.outcome = TestOutcome(test->expect_failure);

0 commit comments

Comments
 (0)