Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fatal #586

Merged
merged 2 commits into from
Oct 5, 2023
Merged

Fatal #586

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -302,11 +302,11 @@ asserts: 4 | 0 passed | 4 failed

> Okay, but what about the case if my assertion is fatal.
> Meaning that the program will crash unless the processing will be terminated.
> Nothing easier, let's just add `>> fatal` after the expected expression to make it fatal.
> Nothing easier, let's just add `fatal` call to make the test fail immediately.

```cpp
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
```

```
Expand Down Expand Up @@ -354,7 +354,7 @@ asserts: 1 | 0 passed | 1 failed
> Yes, stream the `fatal`!

```cpp
expect(1 == 2_i) << "fatal assertion" << fatal;
expect(fatal(1 == 2_i) << "fatal assertion");
expect(1_i == 2);
```

Expand Down Expand Up @@ -449,14 +449,14 @@ int main() {
"[vector]"_test = [] {
std::vector<int> v(5);

expect((5_ul == std::size(v)) >> fatal);
expect(fatal(5_ul == std::size(v)));

should("resize bigger") = [v] { // or "resize bigger"_test
mut(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);
Expand All @@ -481,7 +481,7 @@ int main() {
"vector"_test = [] {
given("I have a vector") = [] {
std::vector<int> v(5);
expect((5_ul == std::size(v)) >> fatal);
expect(fatal(5_ul == std::size(v)));

when("I resize bigger") = [=] {
mut(v).resize(10);
Expand Down Expand Up @@ -509,7 +509,7 @@ int main() {
scenario("size") = [] {
given("I have a vector") = [] {
std::vector<int> v(5);
expect((5_ul == std::size(v)) >> fatal);
expect(fatal(5_ul == std::size(v)));

when("I resize bigger") = [=] {
mut(v).resize(10);
Expand Down Expand Up @@ -540,7 +540,7 @@ int main() {
steps.scenario("*") = [&] {
steps.given("I have a vector") = [&] {
std::vector<int> v(5);
expect((5_ul == std::size(v)) >> fatal);
expect(fatal(5_ul == std::size(v)));

steps.when("I resize bigger") = [&] {
v.resize(10);
Expand Down Expand Up @@ -577,7 +577,7 @@ All tests passed (2 asserts in 1 tests)
int main() {
describe("vector") = [] {
std::vector<int> 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);
Expand Down Expand Up @@ -816,14 +816,14 @@ All tests passed (1 asserts in 1 tests)
"[vector]"_test = [] {
std::vector<int> v(5);

expect((5_ul == std::size(v)) >> fatal);
expect(fatal(5_ul == std::size(v)));

should("resize bigger") = [=] { // or "resize bigger"_test
mut(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);
Expand Down Expand Up @@ -950,7 +950,7 @@ for (auto i : std::vector{1, 2, 3}) {

"args and types"_test =
[]<class TArg>(TArg arg) {
expect(std::is_integral_v<TArg> >> fatal);
expect(fatal(std::is_integral_v<TArg>));
expect(42_i == arg or "is true"_b == arg);
expect(type<TArg> == type<int> or type<TArg> == type<bool>);
}
Expand Down Expand Up @@ -1935,7 +1935,7 @@ int main() {
TEST("vector") {
std::vector<int> v(5);

EXPECT((5u == std::size(v)) >> fatal) << "fatal";
EXPECT(fatal(5u == std::size(v))) << "fatal";

TEST("resize bigger") {
v.resize(10);
Expand Down
8 changes: 4 additions & 4 deletions example/fatal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ int main() {
using boost::ut::expect;

std::optional<int> o{42};
expect(o.has_value() >> fatal) << "fatal assertion";
expect(fatal(o.has_value())) << "fatal assertion";
expect(*o == 42_i);
};

Expand All @@ -28,7 +28,7 @@ int main() {
using boost::ut::expect;

std::optional<int> o{42};
expect(o.has_value()) << "fatal assertion" << fatal;
expect(fatal(o.has_value())) << "fatal assertion";
expect(*o == 42_i);
};

Expand All @@ -38,7 +38,7 @@ int main() {
using boost::ut::that;

std::optional<int> o{42};
expect(that % o.has_value() >> fatal and that % *o == 42)
expect(fatal(that % o.has_value()) and that % *o == 42)
<< "fatal assertion";
};

Expand All @@ -53,6 +53,6 @@ int main() {
using boost::ut::expect;

std::vector v{1u};
expect((std::size(v) == 1_ul) >> fatal) << "fatal assertion";
expect(fatal(std::size(v) == 1_ul)) << "fatal assertion";
expect(v[0] == 1_u);
}
24 changes: 17 additions & 7 deletions include/boost/ut.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ export import std;
// library version to detect the support status.
//
// MSVC STL and libstdc++ provide __cpp_lib_format.
#if defined(__cpp_lib_format) or (defined(_LIBCPP_VERSION) and _LIBCPP_VERSION >= 170000)
#if defined(__cpp_lib_format) or \
(defined(_LIBCPP_VERSION) and _LIBCPP_VERSION >= 170000)
#define BOOST_UT_HAS_FORMAT
#endif

Expand Down Expand Up @@ -98,7 +99,7 @@ export import std;
#include <source_location>
#endif

struct unique_name_for_auto_detect_prefix_and_suffix_lenght_0123456789_struct {
struct _unique_name_for_auto_detect_prefix_and_suffix_lenght_0123456789_struct {
};

BOOST_UT_EXPORT
Expand Down Expand Up @@ -279,15 +280,15 @@ template <typename TargetType>

inline constexpr const std::string_view raw_type_name =
get_template_function_name_use_decay_type<
unique_name_for_auto_detect_prefix_and_suffix_lenght_0123456789_struct>();
_unique_name_for_auto_detect_prefix_and_suffix_lenght_0123456789_struct>();

inline constexpr const std::size_t raw_length = raw_type_name.length();
inline constexpr const std::string_view need_name =
#if defined(_MSC_VER) and not defined(__clang__)
"struct "
"unique_name_for_auto_detect_prefix_and_suffix_lenght_0123456789_struct";
"_unique_name_for_auto_detect_prefix_and_suffix_lenght_0123456789_struct";
#else
"unique_name_for_auto_detect_prefix_and_suffix_lenght_0123456789_struct";
"_unique_name_for_auto_detect_prefix_and_suffix_lenght_0123456789_struct";
#endif
inline constexpr const std::size_t need_length = need_name.length();
static_assert(need_length <= raw_length,
Expand Down Expand Up @@ -675,7 +676,16 @@ struct summary {};

namespace detail {
struct op {};
struct fatal {};

template <class>
struct fatal_;

struct fatal {
template <class T>
[[nodiscard]] inline auto operator()(const T& t) const {
return detail::fatal_{t};
}
};
struct cfg {
using value_ref = std::variant<std::monostate, std::reference_wrapper<bool>,
std::reference_wrapper<std::size_t>,
Expand Down Expand Up @@ -2020,7 +2030,7 @@ class runner {
}
}

if (!detail::cfg::query_pattern.empty()) { //
if (!detail::cfg::query_pattern.empty()) {
const static std::regex regex(detail::cfg::query_regex_pattern);
bool matches = std::regex_match(test.name.data(), regex);
for (const auto& tag2 : test.tag) {
Expand Down
19 changes: 15 additions & 4 deletions test/ut/ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1311,18 +1311,29 @@ int main() {
{
test_cfg = fake_cfg{};

"fatal assertions"_test = [] {
"fatal assertions via function"_test = [] {
expect(fatal(1_i == 1));
expect(fatal(2 != 2_i)) << "fatal";
};

"fatal assertions via operator"_test = [] {
expect((1_i == 1) >> fatal);
expect((2 != 2_i) >> fatal) << "fatal";
};

test_assert(1 == std::size(test_cfg.run_calls));
test_assert(2 == std::size(test_cfg.assertion_calls));
test_assert(2 == std::size(test_cfg.run_calls));
test_assert(4 == std::size(test_cfg.assertion_calls));
test_assert(test_cfg.assertion_calls[0].result);

test_assert("1 == 1" == test_cfg.assertion_calls[0].expr);
test_assert(not test_cfg.assertion_calls[1].result);
test_assert("2 != 2" == test_cfg.assertion_calls[1].expr);
test_assert(1 == test_cfg.fatal_assertion_calls);

test_assert("1 == 1" == test_cfg.assertion_calls[2].expr);
test_assert(not test_cfg.assertion_calls[3].result);
test_assert("2 != 2" == test_cfg.assertion_calls[3].expr);

test_assert(2 == test_cfg.fatal_assertion_calls);
test_assert(std::empty(test_cfg.log_calls));
}

Expand Down
2 changes: 0 additions & 2 deletions test/ut/win_compat_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,4 @@ namespace ut = boost::ut;
int main() {
using namespace ut;
expect(true);

return 0;
}