diff --git a/README.md b/README.md
index 4922563e..67e1e648 100644
--- a/README.md
+++ b/README.md
@@ -339,21 +339,23 @@ Completed =====================================================================
int main() {
using namespace boost::ut;
- expect((1 == 2_i) >> fatal); // fatal assertion
- expect(1_i == 2); // not executed
+ expect(fatal(1 == 2_i)); // fatal assertion
+ expect(1_i == 2); // not executed
}
```
```
UT starts =====================================================================
FAILED in: ...\example.cpp:6 - test condition: [1 == 2]
+=> terminated for the fatal issue
===============================================================================
Suite global
tests: 0 | 0 failed
asserts: 1 | 0 passed | 1 failed
+Completed =====================================================================
```
-> https://godbolt.org/z/6Mvex8TaT
+> https://godbolt.org/z/xohGacdWc
> But my expression is more complex than just simple comparisons.
> Not a problem, logic operators are also supported in the `expect` 👍.
@@ -425,6 +427,7 @@ int main() {
UT starts =====================================================================
Running test "lazy log"...
FAILED in: ...\example.cpp:8 - test condition: [false] lazy evaluated
+=> terminated for the fatal issue
===============================================================================
Suite global
tests: 1 | 1 failed
@@ -550,7 +553,7 @@ int main() {
"vector"_test = [] {
given("I have a vector") = [] {
std::vector v(5);
- expect((5_ul == std::size(v)) >> fatal);
+ expect(fatal(5_ul == std::size(v)));
when("I resize bigger") = [=] {
mut(v).resize(10);
@@ -570,7 +573,7 @@ Suite 'global': all tests passed (2 asserts in 1 tests)
Completed =====================================================================
```
-> https://godbolt.org/z/4YY7KzG64
+> https://godbolt.org/z/e73b7WTGE
> On top of that, `feature/scenario` aliases can be leveraged.
@@ -586,7 +589,7 @@ int main() {
scenario("size") = [] {
given("I have a vector") = [] {
std::vector v(5);
- expect((5_ul == std::size(v)) >> fatal);
+ expect(fatal(5_ul == std::size(v)));
when("I resize bigger") = [=] {
mut(v).resize(10);
@@ -607,7 +610,7 @@ Suite 'global': all tests passed (2 asserts in 1 tests)
Completed =====================================================================
```
-> https://godbolt.org/z/qxdrKxxqn
+> https://godbolt.org/z/nPcGqcn8f
> Can I use `Gherkin`?
> Yeah, let's rewrite the example using `Gherkin` specification
@@ -623,7 +626,7 @@ int main() {
steps.scenario("*") = [&] {
steps.given("I have a vector") = [&] {
std::vector v(5);
- expect((5_ul == std::size(v)) >> fatal);
+ expect(fatal(5_ul == std::size(v)));
steps.when("I resize bigger") = [&] { v.resize(10); };
steps.then("The size should increase") = [&] { expect(10_ul == std::size(v)); };
};
@@ -648,7 +651,7 @@ Suite 'global': all tests passed (2 asserts in 1 tests)
Completed =====================================================================
```
-> https://godbolt.org/z/nxW6dsPvj
+> https://godbolt.org/z/K69ha16rE
> Nice, is `Spec` notation supported as well?
@@ -662,7 +665,7 @@ int main() {
describe("vector") = [] {
std::vector v(5);
- expect((5_ul == std::size(v)) >> fatal);
+ expect(fatal(5_ul == std::size(v)));
it("should resize bigger") = [v] {
mut(v).resize(10);
@@ -678,7 +681,7 @@ Suite 'global': all tests passed (2 asserts in 1 tests)
Completed =====================================================================
```
-> https://godbolt.org/z/Y76sKKs4e
+> https://godbolt.org/z/5vbTs77ff
> That's great, but how can call the same tests with different arguments/types to be DRY (Don't Repeat Yourself)?
> Parameterized tests to the rescue!
@@ -935,14 +938,14 @@ int main() {
"[vector]"_test = [] {
std::vector v(5);
- expect((5_ul == std::size(v)) >> fatal);
+ expect(fatal(5_ul == std::size(v)));
should("resize bigger") = [=]() mutable { // or "resize bigger"_test
v.resize(10);
expect(10_ul == std::size(v));
};
- expect((5_ul == std::size(v)) >> fatal);
+ expect(fatal(5_ul == std::size(v)));
should("resize smaller") = [=]() mutable { // or "resize smaller"_test
v.resize(0);
@@ -958,7 +961,7 @@ Suite 'global': all tests passed (4 asserts in 1 tests)
Completed =====================================================================
```
-> https://godbolt.org/z/rez4qMhxE
+> https://godbolt.org/z/EjTEqMvzv
diff --git a/example/fatal.cpp b/example/fatal.cpp
index 2b6b2dea..de0e1375 100644
--- a/example/fatal.cpp
+++ b/example/fatal.cpp
@@ -19,7 +19,7 @@ int main() {
using boost::ut::expect;
std::optional o{42};
- expect(fatal(o.has_value())) << "fatal assertion";
+ expect(fatal(o.has_value()));
expect(*o == 42_i);
};
@@ -28,7 +28,7 @@ int main() {
using boost::ut::expect;
std::optional o{42};
- expect(fatal(o.has_value())) << "fatal assertion";
+ expect(o.has_value()) << "log messages...." << fatal;
expect(*o == 42_i);
};
@@ -38,21 +38,20 @@ int main() {
using boost::ut::that;
std::optional o{42};
- expect(fatal(that % o.has_value()) and that % *o == 42)
- << "fatal assertion";
+ expect(fatal(that % o.has_value()) and that % *o == 42);
};
"fatal terse"_test = [] {
using namespace boost::ut::operators::terse;
std::optional o{42};
- (o.has_value() >> fatal and *o == 42_i) << "fatal assertion";
+ (fatal(o.has_value()) and *o == 42_i);
};
using namespace boost::ut::operators;
using boost::ut::expect;
std::vector v{1u};
- expect(fatal(std::size(v) == 1_ul)) << "fatal assertion";
+ expect(fatal(std::size(v) == 1_ul));
expect(v[0] == 1_u);
}
diff --git a/include/boost/ut.hpp b/include/boost/ut.hpp
index 4785b405..5c020635 100644
--- a/include/boost/ut.hpp
+++ b/include/boost/ut.hpp
@@ -1653,8 +1653,10 @@ class reporter_junit {
? FAILED : (current_node_->skipped ? SKIPPED : PASSED);
auto parent = current_node_->parent;
if (parent != nullptr) {
- parent->n_tests += current_node_->n_tests;
- parent->fail_tests += current_node_->fail_tests;
+ parent->n_tests += 1LU;
+ if ((current_node_->fails > 0 || current_node_->fail_tests > 0)) {
+ parent->fail_tests++;
+ }
parent->assertions += current_node_->assertions;
parent->skipped += current_node_->skipped;
parent->fails += current_node_->fails;
@@ -1735,10 +1737,6 @@ class reporter_junit {
}
}
reset_printer();
- current_node_->n_tests = 1LU;
- if (current_node_->fails > 0 || current_node_->fail_tests > 0) {
- current_node_->fail_tests = 1LU;
- }
count_result();
}
@@ -1825,7 +1823,18 @@ class reporter_junit {
}
}
- auto on(const events::fatal_assertion&) -> void {}
+ auto on(const events::fatal_assertion&) -> void {
+ TPrinter ss{};
+ ss << ss_out_.str() << "\n=> " << color_.fail << "terminated for the fatal issue" << color_.none;
+ current_node_->report_string += ss.str();
+ reset_printer();
+ if (report_type_ == CONSOLE) {
+ lcout_ << ss.str();
+ }
+ while (current_node_->parent != nullptr) {
+ count_result();
+ }
+ }
auto on(events::summary) -> void {
std::cout.flush();
@@ -2102,10 +2111,7 @@ class runner {
#if defined(__cpp_exceptions)
try {
-#endif
test();
-#if defined(__cpp_exceptions)
- } catch (const events::fatal_assertion&) {
} catch (const std::exception& exception) {
++fails_;
reporter_.on(events::exception{exception.what()});
@@ -2154,19 +2160,7 @@ class runner {
auto on(events::fatal_assertion fatal_assertion) {
reporter_.on(fatal_assertion);
-
-#if defined(__cpp_exceptions)
- if (not level_) {
- report_summary();
- }
- throw fatal_assertion;
-#else
- if (level_) {
- reporter_.on(events::test_end{});
- }
- report_summary();
- std::abort();
-#endif
+ std::exit(-1);
}
template
diff --git a/test/ut/ut.cpp b/test/ut/ut.cpp
index a1546630..4111ef66 100644
--- a/test/ut/ut.cpp
+++ b/test/ut/ut.cpp
@@ -818,15 +818,6 @@ int main() { // NOLINT(readability-function-size)
test_assert(1 == reporter.tests_.skip);
run = options{};
- run.on(events::test{.type = "test",
- .name = "fatal",
- .location = {},
- .arg = none{},
- .run = test_assertions{run}});
- test_assert(5 == reporter.tests_.pass);
- test_assert(7 == reporter.tests_.fail);
- test_assert(1 == reporter.tests_.skip);
-
run.on(
events::test{.type = "test",
.name = "normal",
@@ -834,8 +825,17 @@ int main() { // NOLINT(readability-function-size)
.arg = none{},
.run = test_assertion_true{run}});
test_assert(6 == reporter.tests_.pass);
- test_assert(7 == reporter.tests_.fail);
+ test_assert(6 == reporter.tests_.fail);
test_assert(1 == reporter.tests_.skip);
+
+ /*run.on(events::test{.type = "test",
+ .name = "fatal",
+ .location = {},
+ .arg = none{},
+ .run = test_assertions{run}});
+ test_assert(6 == reporter.tests_.pass);
+ test_assert(7 == reporter.tests_.fail);
+ test_assert(1 == reporter.tests_.skip);*/
reporter = printer{};
}