Skip to main content

check_result Class

The result of one check, reported when destroyed. More...

Declaration​

class micro_os_plus::micro_test_plus::detail::check_result { ... }

Included Headers​

Public Constructors Index​

check_result (check_result &&)=delete

Deleted move constructor to prevent moving. More...

check_result (const check_result &)=delete

Deleted copy constructor to prevent copying. More...

check_result (void)

Constructs a result in the initial state. More...

Public Destructor Index​

~check_result ()

Destructor that reports the check. More...

Public Operators Index​

template <class T>
check_result &&operator<< (const T &msg) &&

Appends a message to the check. More...

check_result &operator= (check_result &&)=delete

Deleted move assignment operator to prevent moving. More...

check_result &operator= (const check_result &)=delete

Deleted copy assignment operator to prevent copying. More...

Public Member Functions Index​

template <class Expr_T>
voidinit (const Expr_T &expr, check_kind kind, const reflection::source_location &location, test_case &test_case, expression_formatter &expression, bool writes_passed)

Initialises the result with the check of an expression. More...

boolvalue (void) const &&noexcept

Retrieves the result value. More...

Private Member Functions Index​

voidstart (bool value, check_kind kind, bool has_expression, const reflection::source_location &location, test_case &test_case, bool writes_passed)

Starts the result of a check from its parts. More...

Private Member Attributes Index​

failure_infoinfo_

The details displayed when the check fails. More...

boolis_written_ = false

Whether the outcome of the check is written. More...

test_case *test_case_ = nullptr

Pointer to the test case invoking this check. More...

intuncaught_exceptions_ = 0

The number of uncaught exceptions when the check was created. More...

boolvalue_ = false

Stores the result value of the check. More...

Description​

The result of one check, reported when destroyed.

Created by the caller of expect() and require() as a temporary, the defaulted last argument of these functions, it lives until the end of the expression statement, and the functions return a reference to it, so that a result cannot be kept in a variable (auto r = t.expect (...) does not compile). The check is reported when the result is destroyed, at the end of the statement, in the order of the statements, and not later.

warning

The result must never be named: a reference bound to it (auto&& r = t.expect (...)) compiles, but dangles after the statement. The message operator and value() can be called only on a temporary, so the named result cannot be used, and forcing it with std::move() is undefined. The messages are appended in the same statement.

A result in the initial state, not yet initialised, reports nothing.

Its template function init() evaluates the expression and formats it, with the actual operand values, into the expression formatter of the reporter, which keeps the text for this check until it is reported, so that it can be displayed on failure. The messages passed via operator<<() are collected into a string. The destructor reports the outcome, updates the counters of the test case, and, after a failed require(), stops the test case.

A passed check whose line the reporter never writes (see reporter::writes_passed_checks()) formats neither its expression nor its messages; it is counted, and passed to reporter::pass_without_text(), which records only its test point.

Only the template function init() depends on the type of the expression; it delegates to a private non-template function, and the destructor, which does the reporting, is not a template either, so this code is compiled once, in src/check-result.cpp, not for each type of expression.

Definition at line 208 of file check-result.h.

Public Constructors​

check_result()​

micro_os_plus::micro_test_plus::detail::check_result::check_result (check_result &&)
delete

Deleted move constructor to prevent moving.

The instance is a temporary that lives only until the end of the expression statement; the functions that fill it return a reference to it, so that a result cannot be kept in a variable.

Definition at line 266 of file check-result.h.

Reference check_result.

check_result()​

micro_os_plus::micro_test_plus::detail::check_result::check_result (const check_result &)
delete

Deleted copy constructor to prevent copying.

Each instance reports exactly one check, from its destructor; a copy would report it twice.

Definition at line 256 of file check-result.h.

Reference check_result.

check_result()​

micro_os_plus::micro_test_plus::detail::check_result::check_result (void)

Constructs a result in the initial state.

Used for the temporary that the caller of expect() and require() creates as their defaulted argument; the result reports nothing unless it is initialised by init(). Defined in src/check-result.cpp, so that the call sites only call it.

The members have their initial values: the result is not initialised, has no test case, and its destructor reports nothing.

Definition at line 220 of file check-result.h.

Reference init.

Referenced by check_result, check_result, operator<<, operator= and operator=.

Public Destructor​

~check_result()​

micro_os_plus::micro_test_plus::detail::check_result::~check_result ()
noexcept(false)

Destructor that reports the check.

It may throw failed_requirement, after a failed require(), to stop the test case, hence noexcept (false).

The destructor reports the result of the check, at the end of the expression statement, after all the user messages were appended.

The test point number of the test case is advanced first, so that the check numbers follow the order in which the checks are reported (the first check is reported as check #1), also when a check is reported after checks that began later, such as those made by a function called in its arguments.

If the evaluated expression is true, the reporter records a successful outcome along with any accumulated message, or, if it does not write the passed checks, only the test point, with reporter::pass_without_text(), and the passed checks counter of the test case is incremented. If the expression is false, the reporter records a failure, with the failure details (the kind of the check, the message, and the source location) and the expression, and the failed checks counter is incremented.

The expression text is obtained from the expression formatter with check_text(), which returns the text of this check even if later checks used the formatter, and is released with end_check().

If the check is a require() and the test expression has failed, the test case is stopped: when exceptions are enabled, by throwing failed_requirement, caught by test_case::run(), as the fatal assertions of most C++ test frameworks do; the run then continues with the next test case. If the destructor runs during stack unwinding (caused by an exception thrown while the rest of the statement is evaluated, such as by the argument of a message), it does not throw, since the test case is already being stopped.

Without exceptions, the test execution is aborted via the runner, whose reporter writes the buffered test output, in place of the end_test_case() that is never reached (see runner::abort()).

Declaration at line 295 of file check-result.h, definition at line 139 of file check-result.cpp.

139 check_result::~check_result () noexcept (false)
140 {
141#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
142 trace::printf ("%s\n", __PRETTY_FUNCTION__);
143#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
144
145 // A result that was not initialised, such as a default argument
146 // whose function did not run, reports nothing.
147 if (test_case_ == nullptr) [[unlikely]]
148 {
149 return;
150 }
151
152 // The index starts at 0; it must be incremented before the check is
153 // reported, so that the first check is reported as check #1.
155
156 // The text formatted by this check, even if the formatter was used by
157 // other checks in the meantime (when this result was kept).
158 auto& expression = test_case_->test_reporter ().expression_;
159 const std::string& expression_str = expression.check_text (this);
160
161 if (value_) [[likely]]
162 {
163 if (is_written_)
164 {
165 test_case_->test_reporter ().pass (info_.message, expression_str,
166 *test_case_);
167 }
168 else
169 {
171 }
173 }
174 else
175 {
176 test_case_->test_reporter ().fail (info_, expression_str,
177 *test_case_);
179 }
180
181 expression.end_check (this);
182
183 if (info_.kind == check_kind::requirement && !value_) [[unlikely]]
184 {
185#if defined(__cpp_exceptions)
186 if (std::uncaught_exceptions () <= uncaught_exceptions_)
187 {
188 throw failed_requirement{};
189 }
190#else
192#endif // defined(__cpp_exceptions)
193 }
194 }

References micro_os_plus::micro_test_plus::detail::runnable_base::abort, micro_os_plus::micro_test_plus::detail::expression_formatter::check_text, micro_os_plus::micro_test_plus::detail::reporter::expression_, micro_os_plus::micro_test_plus::detail::reporter::fail, micro_os_plus::micro_test_plus::counters::increment_failed_checks, micro_os_plus::micro_test_plus::counters::increment_passed_checks, info_, is_written_, micro_os_plus::micro_test_plus::detail::failure_info::kind, micro_os_plus::micro_test_plus::detail::failure_info::location, micro_os_plus::micro_test_plus::detail::failure_info::message, micro_os_plus::micro_test_plus::detail::runnable_base::next_test_point_number, micro_os_plus::micro_test_plus::detail::reporter::pass, micro_os_plus::micro_test_plus::detail::reporter::pass_without_text, micro_os_plus::micro_test_plus::detail::requirement, test_case_, micro_os_plus::micro_test_plus::detail::runnable_base::test_reporter, micro_os_plus::micro_test_plus::detail::runnable_base::totals_, uncaught_exceptions_ and value_.

Public Operators​

operator<<()​

template <class T>
check_result && micro_os_plus::micro_test_plus::detail::check_result::operator<< (const T & msg)

Appends a message to the check.

Callable only on a temporary, like the result of expect() and require(), which is destroyed at the end of the statement: a result bound to a name (auto&& r = t.expect (...)) is not usable, since it would refer to a destroyed object after the statement.

Template Parameters
T

The type of the message to append: a value that the formatter can write, or a callable object that returns one (see detail::message_argument); any other argument is rejected at compile time, with a message that states what is accepted.

Parameters
msg

The message to append, or the callable object that returns it, called only if the check fails.

Returns

The current check result, as an rvalue reference, so that further messages can be appended in the same expression.

This operator overload enables the check result to accumulate expectation messages by appending the provided value to the internal message string.

The value is written by the same operator<< overloads as the operands of the expressions, so that both accept the same types, including the application types with an operator<< for the formatter. The message is moved into a local formatter in the plain mode, which writes the numbers without the type suffixes, and the strings and the char values without quotes, with only the control characters that can change the state of a terminal escaped, and is moved back after the value is appended, so that no other buffer is allocated. The formatter of the reporter is not used, since it may hold the expression of this check, or of a pending one.

When the outcome of the check is not written, the message is not needed, and the value is not formatted.

A callable object (see detail::lazy_message) is called only if the check failed, and its result is appended as a value; after a success, even if the outcome is written, it appends nothing, since its purpose is to describe a failure with values that may not be valid otherwise, like the error of a std::expected that holds a value. Being a class type, a lambda without captures is called too, although it is also printable, as a bool.

Declaration at line 319 of file check-result.h, definition at line 178 of file check-result-inlines.h.

178 check_result::operator<<(const T& msg) &&
179 {
180 if constexpr (detail::lazy_message<T>)
181 {
182 if (value_)
183 {
184 return std::move (*this);
185 }
186 }
187 else
188 {
189 if (!is_written_)
190 {
191 return std::move (*this);
192 }
193 }
194
195 expression_formatter formatter{ std::move (info_.message) };
196 if constexpr (detail::lazy_message<T>)
197 {
198 formatter << std::invoke (msg);
199 }
200 else
201 {
202 formatter << msg;
203 }
204 info_.message = std::move (formatter.buffer_);
205 return std::move (*this);
206 }

References check_result, micro_os_plus::micro_test_plus::detail::expression_formatter::buffer_, info_, is_written_ and value_.

operator=()​

check_result & micro_os_plus::micro_test_plus::detail::check_result::operator= (check_result &&)
delete

Deleted move assignment operator to prevent moving.

Each instance reports exactly one check, from its destructor.

Definition at line 285 of file check-result.h.

References check_result, start and value.

operator=()​

check_result & micro_os_plus::micro_test_plus::detail::check_result::operator= (const check_result &)
delete

Deleted copy assignment operator to prevent copying.

Each instance reports exactly one check, from its destructor.

Definition at line 275 of file check-result.h.

Reference check_result.

Public Member Functions​

init()​

template <class Expr_T>
void micro_os_plus::micro_test_plus::detail::check_result::init (const Expr_T & expr, check_kind kind, const reflection::source_location & location, test_case & test_case, expression_formatter & expression, bool writes_passed)

Initialises the result with the check of an expression.

The expression is evaluated, and, if the outcome is written, formatted into the expression formatter.

Template Parameters
Expr_T

The type of the expression.

Parameters
expr

The expression under evaluation.

kind

The kind of the check, check_kind::requirement for require(), whose failure stops the test case.

location

The source location of the check.

test_case

The test case that owns this check.

expression

The expression formatter to format the expression text.

writes_passed

Whether the reporter writes the passed checks; if not, a passed check is not formatted.

Returns

Nothing.

The expression is evaluated, and the result is passed, together with the kind of the check and whether the expression is a framework comparator, to the non-template start(), which also stores the source location and the test case. The kind, check_kind::requirement for require(), determines whether the test case is stopped if the check fails.

The expression formatter of the reporter, which is shared by all checks, is then assigned to this check by begin_check(), which sets aside the text of a previous check not yet reported, if any. The expression is formatted into it only when the outcome is written: on failure, or, if writes_passed, also on success. Otherwise the text of this check stays empty, and the operands, which may be application types with an expensive operator<<, are not formatted.

An expression that is only explicitly convertible to bool, such as a std::optional or a std::unique_ptr, is written as the result of the conversion, true or false, since that is what the check tested; its own value (the contents of a std::optional<bool>, for example) could contradict the outcome, and many such types cannot be formatted at all.

The decision is taken here, while the operands are alive.

Declaration at line 245 of file check-result.h, definition at line 102 of file check-result-inlines.h.

102 check_result::init (const Expr_T& expr, check_kind kind,
103 const reflection::source_location& location,
105 bool writes_passed)
106 {
107 start (static_cast<bool> (expr), kind, extension::is_op<Expr_T>,
108 location, test_case, writes_passed);
109
110#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
111 trace::printf ("%s\n", __PRETTY_FUNCTION__);
112#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
113
114 // The same address is used by the destructor, to retrieve the text,
115 // even if other checks used the formatter in the meantime.
116 expression.begin_check (this);
117
118 if (is_written_)
119 {
120 if constexpr (extension::is_op<Expr_T>
121 or std::convertible_to<Expr_T, bool>)
122 {
123 expression << expr;
124 }
125 else
126 {
127 expression << static_cast<bool> (expr);
128 }
129 }
130 }

References micro_os_plus::micro_test_plus::detail::expression_formatter::begin_check, is_written_ and start.

Referenced by check_result, micro_os_plus::micro_test_plus::test_case::expect, micro_os_plus::micro_test_plus::test_case::report_rejected_test and micro_os_plus::micro_test_plus::test_case::require.

value()​

bool micro_os_plus::micro_test_plus::detail::check_result::value (void)
inline nodiscard noexcept

Retrieves the result value.

Callable only on a temporary, for the reason given for operator<<().

Parameters

None.

Return Values
true

The checked condition was met.

false

The checked condition was not met.

Returns the result value stored in value_.

Declaration at line 356 of file check-result.h, definition at line 139 of file check-result-inlines.h.

139 check_result::value (void) const&& noexcept
140 {
141 return value_;
142 }

Reference value_.

Referenced by operator= and start.

Private Member Functions​

start()​

void micro_os_plus::micro_test_plus::detail::check_result::start (bool value, check_kind kind, bool has_expression, const reflection::source_location & location, test_case & test_case, bool writes_passed)

Starts the result of a check from its parts.

The non-template part of the initialisation, shared by all the instantiations of the template function init(), which calls it. Marks the result as initialised, so that the destructor reports it.

Parameters
value

The result of the evaluated expression.

kind

The kind of the check.

has_expression

Indicates whether the expression is a framework comparator, whose text is displayed on failure.

location

The source location of the check.

test_case

The test case that owns this check.

writes_passed

Whether the reporter writes the passed checks.

Returns

Nothing.

Stores the evaluated Boolean value, and, in the failure details, the kind of the check, the has_expression flag, and the location identifying the source line of the check, with an empty message; it also stores a pointer to the owning test_case, which marks the result as initialised. The outcome is written when the check failed, or when the reporter writes the passed checks (writes_passed). The check number is assigned later, by the destructor, when the check is reported.

When exceptions are enabled, the number of uncaught exceptions is also stored, so that the destructor can tell whether it runs during stack unwinding.

Declaration at line 379 of file check-result.h, definition at line 89 of file check-result.cpp.

89 check_result::start (bool value, check_kind kind, bool has_expression,
90 const reflection::source_location& location,
91 test_case& test_case, bool writes_passed)
92 {
94 is_written_ = !value || writes_passed;
95 info_ = failure_info{ kind, {}, has_expression, location };
97#if defined(__cpp_exceptions)
98 uncaught_exceptions_ = std::uncaught_exceptions ();
99#endif // defined(__cpp_exceptions)
100 }

References info_, is_written_, test_case_, uncaught_exceptions_, value and value_.

Referenced by init and operator=.

Private Member Attributes​

info_​

failure_info micro_os_plus::micro_test_plus::detail::check_result::info_

The details displayed when the check fails.

The kind, the expression flag, and the location are set by start(); the message is collected via operator<<(). Passed to the reporter by the destructor; the message is also displayed when the check passes.

Definition at line 412 of file check-result.h.

Referenced by ~check_result, operator<< and start.

is_written_​

bool micro_os_plus::micro_test_plus::detail::check_result::is_written_ = false

Whether the outcome of the check is written.

Set by start() for a failed check, and for a passed one when the reporter writes the passed checks. When not set, the expression and the messages are not formatted, and the destructor only updates the counters.

Definition at line 401 of file check-result.h.

401 bool is_written_ = false;

Referenced by ~check_result, init, operator<< and start.

test_case_​

test_case* micro_os_plus::micro_test_plus::detail::check_result::test_case_ = nullptr

Pointer to the test case invoking this check.

Provides access to the reporter and to the totals to be updated. Null in the initial state, which marks a result that was not initialised and reports nothing.

Definition at line 436 of file check-result.h.

Referenced by ~check_result and start.

uncaught_exceptions_​

int micro_os_plus::micro_test_plus::detail::check_result::uncaught_exceptions_ = 0

The number of uncaught exceptions when the check was created.

If the destructor finds more, it runs during stack unwinding (an exception was thrown while the rest of the statement was evaluated, for example by the argument of a message), and must not throw. Present only when exceptions are enabled.

Definition at line 425 of file check-result.h.

Referenced by ~check_result and start.

value_​

bool micro_os_plus::micro_test_plus::detail::check_result::value_ = false

Stores the result value of the check.

The boolean value of the checked expression, computed by the template function init().

Definition at line 390 of file check-result.h.

390 bool value_ = false;

Referenced by ~check_result, operator<<, start and value.


The documentation for this class was generated from the following files:


Generated via doxygen2docusaurus 2.2.8 by Doxygen 1.18.0.