38#if __has_include("micro-os-plus/diag/trace.h")
39#include "micro-os-plus/diag/trace.h"
51#pragma clang diagnostic ignored "-Wunknown-warning-option"
52#pragma clang diagnostic ignored "-Wc++98-compat"
53#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
54#pragma clang diagnostic ignored "-Wc++20-compat"
55#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
57#pragma GCC diagnostic ignored "-Wredundant-tags"
58#pragma GCC diagnostic ignored "-Wsuggest-final-types"
59#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
65#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_ENABLED)
82 const auto is_control = [] (
char c)
84 const auto unit =
static_cast<unsigned char> (c);
85 return (unit < 0x20 && c !=
'\t') || unit == 0x7F;
88 std::size_t first = 0;
89 while (first < name.size () && !is_control (name[first]))
93 if (first == name.size ())
98 std::string escaped (name, 0, first);
99 escaped.reserve (name.size () + 8);
100 for (std::size_t i = first; i < name.size (); ++i)
102 if (is_control (name[i]))
108 escaped.push_back (name[i]);
111 name = std::move (escaped);
130#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
144#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
145 trace::printf (
"%s '%s'\n", __PRETTY_FUNCTION__,
name_);
168 return runner_.running_test_case_;
190 return runner_.options_.list_tests;
200 const suite& target)
const noexcept
203 return running !=
nullptr && &running->
parent_suite_ == ⌖
215 runner_.running_suite_ = running;
253 std::string message{
"test case '" };
255 message.append (
"' started on suite '");
256 message.append (target.
name ());
257 message.append (
"', which is not running");
291 std::string message{
"unexpected exception in the body of suite '" };
292 message.append (
name_);
293 message.append (
"'");
408#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
409 trace::printf (
"%s test case '%s' executed one more test case\n",
410 __PRETTY_FUNCTION__,
name ());
423#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
424 trace::printf (
"%s suite '%s' totals\n", __PRETTY_FUNCTION__,
450 std::string message{
"[check on test case '" };
451 message.append (
name ());
452 message.append (
"' while '");
453 message.append (running.
name ());
454 message.append (
"' runs] ");
456 result.init (
false, kind, sl, running,
460 return std::move (std::move (result) << message);
476 std::string message{
"[test case '" };
478 message.append (
"' started on test case '");
479 message.append (this->name ());
480 message.append (
"' while '");
481 message.append (running.
name ());
482 message.append (
"' runs]");
500 std::move (result) << message;
514#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
515 trace::printf (
"%s '%s'\n", __PRETTY_FUNCTION__,
name_);
519#if defined(__cpp_exceptions)
540 .message =
"unexpected exception",
541 .has_expression =
false,
550 failure.
message.append (
" of unknown type");
553 const std::string expression{};
569#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
570 trace::printf (
"%s '%s'\n", __PRETTY_FUNCTION__,
name_);
606#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED)
607 trace::printf (
"%s '%s'\n", __PRETTY_FUNCTION__,
name_);
629#if defined(__cpp_exceptions)
653#if defined(__cpp_exceptions)
659 catch (
const std::exception& e)
686#if defined(__cpp_exceptions)
705 std::string message{
"unexpected exception" };
708 message.append (
" in the suite body: ");
709 message.append (what);
713 message.append (
" of unknown type in the suite body");
740#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED)
741 trace::printf (
"%s '%s'\n", __PRETTY_FUNCTION__,
name_);
747 while (*slot !=
nullptr && std::strcmp ((*slot)->name_,
name_) <= 0)
749 slot = &(*slot)->
next_;
762 for (
suite** slot = &
first_; *slot !=
nullptr; slot = &(*slot)->next_)
786#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
787 trace::printf (
"%s '%s'\n", __PRETTY_FUNCTION__,
name);
801#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
802 trace::printf (
"%s '%s'\n", __PRETTY_FUNCTION__,
name_);
827#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
828 trace::printf (
"%s '%s'\n", __PRETTY_FUNCTION__,
name_);
void increment_skipped_test_cases(size_t count=1) noexcept
Increments the skipped test cases counter.
bool passed(void) const noexcept
Checks whether all executed checks and test cases were successful.
void increment_executed_test_cases(size_t count=1) noexcept
Increments the executed test cases counter.
void increment_failed_test_cases(size_t count=1) noexcept
Increments the failed test cases counter.
void increment_failed_checks(size_t count=1) noexcept
Increments the failed-checks counter.
The result of one check, reported when destroyed.
void 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.
Abstract base class for the reporters that display test results, including operand values for failure...
bool writes_passed_checks(void) const noexcept
Returns whether the passed checks are written anywhere.
virtual void skip_test_case(const test_case &test_case)=0
Reports a test case skipped by the filter.
virtual void fail_suite(const std::string &message, const suite &suite)=0
Reports a failure of a test suite outside its test cases.
void fail(const failure_info &failure, const std::string &expression, const test_case &test_case)
Reports a failed condition.
virtual void end_suite(const suite &suite)=0
Marks the end of a test suite.
expression_formatter expression_
Expression formatter for pass and fail reporting.
virtual void begin_suite(const suite &suite)=0
Marks the beginning of a test suite.
runner & test_runner(void) const noexcept
Returns the test runner that owns this test runnable.
size_t next_test_point_number(void) noexcept
Advances to the next child test point, and returns its number.
virtual ~runnable_base()
Virtual destructor.
void reject_body_exception(void)
Reports the exception that escaped the body of a suite while the test cases are listed,...
void after_test_case_create(class test_case &test_case, suite &suite)
Counts a newly constructed child test case and executes it immediately.
class test_case * running_test_case(void) const noexcept
Returns the innermost test case being run by the owning runner, if any.
bool is_listing(void) const noexcept
Checks whether the owning runner lists the test cases instead of running them.
bool accepts_test_case(const suite &target, const located_name &name)
Checks whether a test case can be created on a suite.
void abort(const reflection::source_location &sl=reflection::source_location::current()) const
Aborts test execution via the owning runner, for a failed requirement.
friend class micro_test_plus::runner
The runner, which numbers and runs the suites.
size_t own_index_
The test index, counting from 1.
const char * name(void) const noexcept
Returns the node name.
suite * exchange_running_suite(suite *running) noexcept
Replaces the suite whose body is running in the owning runner, and returns the previous one.
class reporter & test_reporter(void) const noexcept
Returns the test reporter associated with this test runnable.
counters totals_
Totals for the node.
size_t own_index(void) const noexcept
Deprecated positional index of this node within its parent.
runnable_base(const char *name, runner &test_runner, size_t own_index)
Constructs a runnable_base with a name, runner, and index.
const counters & totals(void) const noexcept
Returns the totals of the node.
const char * name_
The node name.
bool is_aborted(void) const noexcept
Checks whether the test execution was aborted by the owning runner.
runner & runner_
Reference to the test runner that owns this object.
bool has_running_test_case_of(const suite &target) const noexcept
Checks whether the innermost running test case belongs to a suite.
size_t child_test_cases_count_
The number of direct child test cases.
void stop(void) noexcept
Records the stop time, from the system clock.
void start(void) noexcept
Records the start time, from the system clock.
A name of a suite or of a test case, with the location where it was given.
const char * name(void) const noexcept
Returns the name.
const reflection::source_location & location(void) const noexcept
Returns the location where the name was given.
Local implementation of source location information for diagnostics.
bool help
Whether to display the usage and the list of the options, instead of running the tests.
bool list_tests
Whether the test cases are listed instead of run.
class suite * running_suite_
The suite whose body is running, if any.
void list_test_case(const class suite &suite, const class test_case &test_case)
Lists a test case, instead of running it.
bool has_option_errors(void) const noexcept
Checks whether an option error was found by initialise().
static void link_static_suite(runner &test_runner, class suite &suite) noexcept
Inserts a static suite into the list of suites, or reject it.
bool is_selected(const char *name, size_t level) const
Checks whether a suite or a test case is selected by the filter pattern of its nesting level.
void reject_call(const std::string &message, const reflection::source_location *location=nullptr)
Reports a rejected call, and records it.
void abort(const reflection::source_location &sl=reflection::source_location::current())
Aborts test execution immediately.
runner_options options_
The options of the test session.
test_case * running_test_case_
The innermost test case being run, if any.
bool aborted_
Whether the test execution was aborted.
void link_or_reject(void) noexcept
Inserts this suite into the list of suites, or reject it.
~static_suite() override
Virtual destructor.
A named, runnable test suite registered with the test runner.
void fail_unexpected_exception(const char *what)
Reports an exception that escaped the suite body as a failed check of the suite.
void unlink(void) noexcept
Removes this suite from the list of suites.
void run(void) override
Executes the suite body by invoking the stored callable.
void link(void) noexcept
Inserts this suite into the list of suites.
static suite * first_
The first suite in the list of suites.
suite * next_
The next suite in the list of suites.
friend class top_suite
The top suite, which is constructed by the runner.
detail::stopwatch stopwatch_
Stopwatch of this suite.
~suite() override
Virtual destructor.
suite(located_name &&name, runner &test_runner, Callable_T &&callable, Args_T &&... arguments)
Constructs a suite with a name, runner, and callable body.
std::function< void(suite &)> callable_
Callable storing the suite body and any bound arguments.
A named, runnable test case that lives inside a suite.
void report_rejected_test(const std::string &message, const reflection::source_location &location)
Reports a rejected call as a failed check of this test case.
void fail_unexpected_exception(const char *what)
Reports an exception that escaped the test case body as a failed check.
~test_case() override
Virtual destructor.
suite & parent_suite_
Reference to the parent suite that owns this test case.
test_case(const located_name &name, runner &test_runner, suite &parent_suite, size_t own_index, size_t nesting_depth, detail::callable_ref< test_case > body)
Constructs a test case with a name, runner, parent suite, index, nesting depth, and body.
const located_name & located_name_
The name and the location of the call to test() that created this test case.
detail::check_result && report_misdirected(detail::check_kind kind, const reflection::source_location &sl, detail::check_result &&result)
Reports a check on this test case as a failure of the running one.
void report_misdirected_test(const located_name &name)
Reports a nested test case started on this test case as a failure of the running one.
size_t nesting_depth(void) const noexcept
Returns the nesting depth of this test case.
friend class micro_test_plus::runner
The runner, which owns the top suite.
~top_suite() override
Virtual destructor.
#define MICRO_OS_PLUS_MICRO_TEST_PLUS_PRI_SIZE
Portable printf() conversion for the size_t values.
Internal implementation details for the µTest++ framework.
check_kind
The kind of a check, which determines what happens when it fails.
@ expectation
A check created by expect().
void append_control_escape(std::string &text, char c)
Appends the escape sequence of a control character.
void escape_control_characters(std::string &name)
Escapes the control characters of a name.
Primary namespace for the µTest++ testing framework.
C++ header file with declarations for the µTest++ test runner.
The details of a check, displayed when it fails.
std::string message
The message passed via operator<<(), if any.
C++ header file with declarations for the µTest++ test hierarchy.