Skip to main content

test.h File

C++ header file with declarations for the µTest++ test hierarchy. More...

Included Headers​

#include "check-result.h" #include "counters.h" #include "extension.h" #include "stopwatch.h" #include "reflection.h" #include <cstddef> #include <functional> #include <initializer_list> #include <memory> #include <string> #include <string_view> #include <tuple> #include <type_traits> #include <utility> #include "inlines/test-inlines.h"

Namespaces Index​

namespacemicro_os_plus

The primary namespace for the µOS++ framework. More...

namespacemicro_test_plus

Primary namespace for the µTest++ testing framework. More...

namespacedetail

Internal implementation details for the µTest++ framework. More...

Classes Index​

classbound_callable<Self_T, Callable_T, Args_T>

Function object that holds a callable and the additional arguments it is invoked with. More...

classcallable_ref<Self_T>

Non-owning reference to a callable invoked with a Self_T& argument. More...

classlocated_name

A name of a suite or of a test case, with the location where it was given. More...

classrunnable_base

Non-template base for all runnable objects (suites and test cases). More...

classstatic_suite

A test suite designed for static (namespace-scope) registration with a runner. More...

classsuite

A named, runnable test suite registered with the test runner. More...

classtest_case

A named, runnable test case that lives inside a suite. More...

classtop_suite

The optional top suite owned by every runner instance. More...

Concepts Index​

conceptgeneric_callable

Concept satisfied by a callable object whose call operator is not a single non-template member function. More...

conceptstatic_suite_body

The body of a static suite written for v5.0.1, whose first parameter is a static_suite& reference. More...

conceptsuite_body

Concept satisfied by a callable object that can be the body of a suite. More...

concepttest_body

Concept satisfied by a callable object that can be the body of a test case. More...

concepttest_values_range

Concept satisfied when T is a range of values for test_each(). More...

concepttest_values_tuple

Concept satisfied when T is a tuple of values for test_each(). More...

conceptunsupported_condition

Concept satisfied by a value that expect() and require() do not accept. More...

Functions Index​

template <typename Self_T, typename Callable_T, typename... Args_T>
autobind_callable (Callable_T &&callable, Args_T &&... arguments)

Creates the function object that holds the body of a test case or suite. More...

voidescape_control_characters (std::string &name)

Escapes the control characters of a name. More...

template <typename Callable_T, typename... Args_T>
constexpr voidreject_suite_body (void) noexcept

Stops the compilation with a message that tells what the body of a suite takes. More...

template <typename Callable_T, typename... Args_T>
constexpr voidreject_test_body (void) noexcept

Stops the compilation with a message that tells what the body of a test case takes. More...

template <class Self_T, class Values_T, class Callable_T>
voidtest_each_value (Self_T &self, const located_name &name, Values_T &&values, Callable_T &callable)

Adds and runs a test case for each value. More...

Variables Index​

template <typename... Ts>
constexpr booldependent_false_v = false

A value that is always false, but depends on the template arguments. More...

Description​

C++ header file with declarations for the µTest++ test hierarchy.

This header provides the declarations for the test hierarchy used within the µTest++ framework: the internal detail::runnable_base base class, and the test_case, suite, top_suite, and static_suite classes. They offer mechanisms for running test cases, managing the counters of the passed and failed checks, and registering test suites with the runner.

The test suites are non-copyable and non-movable, so that each one has a single owner. Their bodies are any callable objects, such as functions and lambdas, with optional arguments.

All definitions reside within the micro_os_plus::micro_test_plus namespace.

This file is included by micro-os-plus/micro-test-plus.h, which is the header that the applications include.

Functions​

bind_callable()​

template <typename Self_T, typename Callable_T, typename... Args_T>
auto micro_os_plus::micro_test_plus::detail::bind_callable (Callable_T && callable, Args_T &&... arguments)
nodiscard

Creates the function object that holds the body of a test case or suite.

Without additional arguments, the callable already has the signature void (Self_T&), and a copy of it is returned, without a wrapper.

Otherwise, a bound_callable stores copies of the callable and of the arguments (decayed, as by auto), since a suite may run after the caller's temporaries are gone; the callable receives the copies as non-const lvalues. A reference parameter thus refers to the copy; to refer to the caller's object, pass a pointer, or std::ref(), which converts to a T& parameter (an auto& parameter receives the std::reference_wrapper itself).

The returned object holds a copy of the callable (decayed, as by auto) when there are no additional arguments; otherwise it is a bound_callable that holds copies of the callable and of the arguments, and passes the arguments after the leading reference, which is passed when the body is invoked. No memory is allocated, other than by the copies themselves.

A suite stores the object in a std::function, since it runs later; a test case, which runs immediately, refers to it with a callable_ref.

Template Parameters
Self_T

The type referred to by the first parameter of the callable (test_case or suite).

Callable_T

The type of the callable object.

Args_T

The types of the additional callable arguments.

Parameters
callable

A generic callable object, usually a lambda.

arguments

A possibly empty list of arguments forwarded to the callable after the leading Self_T& reference.

Returns

The function object, invocable with a Self_T& argument.

Definition at line 344 of file test-inlines.h.

344 bind_callable (Callable_T&& callable, Args_T&&... arguments)
345 {
346 if constexpr (sizeof...(arguments) == 0)
347 {
348 return std::forward<Callable_T> (callable);
349 }
350 else
351 {
353 std::decay_t<Args_T>...>{
354 std::forward<Callable_T> (callable),
355 std::forward<Args_T> (arguments)...
356 };
357 }
358 }

Reference micro_os_plus::micro_test_plus::detail::bind_callable.

Referenced by micro_os_plus::micro_test_plus::detail::bind_callable and micro_os_plus::micro_test_plus::detail::runnable_base::create_test_case.

escape_control_characters()​

void micro_os_plus::micro_test_plus::detail::escape_control_characters (std::string & name)

Escapes the control characters of a name.

Replaces, in place, the control characters other than the tab, including the line feed and the NUL, with their escape sequences, so that the names reach the console and the output files as one line of visible text. Defined in src/test.cpp.

Parameters
name

The name to escape.

The text is scanned first, so that a name without control characters is not touched. The tab is kept; all the other control characters, including the line feed and the NUL, and DEL, are replaced.

Definition at line 80 of file test.cpp.

80 escape_control_characters (std::string& name)
81 {
82 const auto is_control = [] (char c)
83 {
84 const auto unit = static_cast<unsigned char> (c);
85 return (unit < 0x20 && c != '\t') || unit == 0x7F;
86 };
87
88 std::size_t first = 0;
89 while (first < name.size () && !is_control (name[first]))
90 {
91 ++first;
92 }
93 if (first == name.size ())
94 {
95 return;
96 }
97
98 std::string escaped (name, 0, first);
99 escaped.reserve (name.size () + 8);
100 for (std::size_t i = first; i < name.size (); ++i)
101 {
102 if (is_control (name[i]))
103 {
104 append_control_escape (escaped, name[i]);
105 }
106 else
107 {
108 escaped.push_back (name[i]);
109 }
110 }
111 name = std::move (escaped);
112 }

References micro_os_plus::micro_test_plus::detail::append_control_escape and micro_os_plus::micro_test_plus::detail::escape_control_characters.

Referenced by micro_os_plus::micro_test_plus::located_name::located_name, micro_os_plus::micro_test_plus::located_name::located_name, micro_os_plus::micro_test_plus::located_name::located_name, micro_os_plus::micro_test_plus::located_name::located_name and micro_os_plus::micro_test_plus::detail::escape_control_characters.

reject_suite_body()​

template <typename Callable_T, typename... Args_T>
void micro_os_plus::micro_test_plus::detail::reject_suite_body (void)
constexpr noexcept

Stops the compilation with a message that tells what the body of a suite takes.

Always fails the static assertion that applies, since it is called only when suite_body is not satisfied. A body that cannot be copied, or a body written for a test case, is recognised, to say so.

Called by the overloads of runner::add_suite() and of the static_suite constructor that are selected when the callable is not a valid body, as reject_test_body() is for the test cases.

Template Parameters
Callable_T

The type of the callable.

Args_T

The types of the additional arguments.

Parameters

None.

Returns

Nothing.

Definition at line 448 of file test-inlines.h.

448 reject_suite_body (void) noexcept
449 {
450 if constexpr (not std::is_copy_constructible_v<std::decay_t<Callable_T>>
451 or not(std::is_copy_constructible_v<std::decay_t<Args_T>>
452 and ...))
453 {
454 static_assert (dependent_false_v<Callable_T, Args_T...>,
455 "the body of a suite and its additional arguments "
456 "must be copyable, since the suite runs later");
457 }
458 else if constexpr (std::is_invocable_v<std::decay_t<Callable_T>&,
459 test_case&,
460 std::decay_t<Args_T>&...>)
461 {
462 static_assert (dependent_false_v<Callable_T, Args_T...>,
463 "the body of a suite takes a suite& as its first "
464 "parameter, not a test_case&");
465 }
466 else
467 {
468 static_assert (dependent_false_v<Callable_T, Args_T...>,
469 "the body of a suite takes a suite& as its first "
470 "parameter, followed by the additional arguments");
471 }
472 }

References micro_os_plus::micro_test_plus::detail::dependent_false_v and micro_os_plus::micro_test_plus::detail::reject_suite_body.

Referenced by micro_os_plus::micro_test_plus::runner::add_suite and micro_os_plus::micro_test_plus::detail::reject_suite_body.

reject_test_body()​

template <typename Callable_T, typename... Args_T>
void micro_os_plus::micro_test_plus::detail::reject_test_body (void)
constexpr noexcept

Stops the compilation with a message that tells what the body of a test case takes.

Always fails the static assertion that applies, since it is called only when test_body is not satisfied. A body written for a suite is recognised, to say so.

Called by the overloads of test_case::test() and suite::test() that are selected when the callable is not a valid body, so that the diagnostic names the mistake in the terms of the application, instead of the concepts and the instantiation stack. Never called at run time.

Template Parameters
Callable_T

The type of the callable.

Args_T

The types of the additional arguments.

Parameters

None.

Returns

Nothing.

Definition at line 422 of file test-inlines.h.

422 reject_test_body (void) noexcept
423 {
424 if constexpr (std::is_invocable_v<std::decay_t<Callable_T>&, suite&,
425 std::decay_t<Args_T>&...>)
426 {
427 static_assert (dependent_false_v<Callable_T, Args_T...>,
428 "the body of a test case takes a test_case& as its "
429 "first parameter, not a suite&");
430 }
431 else
432 {
433 static_assert (dependent_false_v<Callable_T, Args_T...>,
434 "the body of a test case takes a test_case& as its "
435 "first parameter, followed by the additional "
436 "arguments passed to test ()");
437 }
438 }

References micro_os_plus::micro_test_plus::detail::dependent_false_v and micro_os_plus::micro_test_plus::detail::reject_test_body.

Referenced by micro_os_plus::micro_test_plus::detail::reject_test_body.

test_each_value()​

template <class Self_T, class Values_T, class Callable_T>
void micro_os_plus::micro_test_plus::detail::test_each_value (Self_T & self, const located_name & name, Values_T && values, Callable_T & callable)

Adds and runs a test case for each value.

For each value, the name is built in a local string, which lives while the test case runs, since a test case runs within the call to test(), and the test case is added with test(), with the location of the call to test_each(). The callable receives each value as a const lvalue, referring to the element itself; neither the values nor the callable are copied. The values of a range are iterated by a range-based for statement, and those of a tuple are expanded by std::apply(), in order.

The common implementation of test_case::test_each() and suite::test_each().

Template Parameters
Self_T

The type of the test case or suite.

Values_T

The type of the range or tuple of values.

Callable_T

The type of the callable object.

Parameters
self

The test case or suite to which the test cases are added.

name

The common name of the test cases.

values

The range or tuple of values.

callable

The callable object, invoked with the test case and each value.

Returns

Nothing.

Definition at line 1029 of file test-inlines.h.

1029 test_each_value (Self_T& self, const located_name& name, Values_T&& values,
1030 Callable_T& callable)
1031 {
1032 std::size_t position = 0;
1033
1034 const auto run_one
1035 = [&self, &name, &callable, &position] (const auto& value)
1036 {
1037 ++position;
1038
1039 std::string text{ name.name () };
1040 text += " (";
1041 if constexpr (extension::printable<
1042 std::remove_cvref_t<decltype (value)>>)
1043 {
1045 }
1046 else
1047 {
1048 text += '#';
1049 plain_text::append (text, position);
1050 }
1051 text += ')';
1052
1053 // The test case runs within this call, so the value and the
1054 // callable are captured by reference, not copied.
1055 self.test (located_name{ std::move (text), name.location () },
1056 [&callable, &value] (auto& test_self)
1057 {
1058 if constexpr (std::is_member_pointer_v<
1059 std::remove_cvref_t<Callable_T>>)
1060 {
1061 std::invoke (callable, test_self, value);
1062 }
1063 else
1064 {
1065 callable (test_self, value);
1066 }
1067 });
1068 };
1069
1070 if constexpr (test_values_range<Values_T>)
1071 {
1072 for (const auto& value : values)
1073 {
1074 run_one (value);
1075 }
1076 }
1077 else
1078 {
1079 std::apply ([&run_one] (const auto&... elements)
1080 { (run_one (elements), ...); }, values);
1081 }
1082 }

References micro_os_plus::micro_test_plus::detail::plain_text::append, micro_os_plus::micro_test_plus::located_name::location, micro_os_plus::micro_test_plus::located_name::name and micro_os_plus::micro_test_plus::detail::test_each_value.

Referenced by micro_os_plus::micro_test_plus::suite::test_each, micro_os_plus::micro_test_plus::suite::test_each, micro_os_plus::micro_test_plus::test_case::test_each, micro_os_plus::micro_test_plus::test_case::test_each and micro_os_plus::micro_test_plus::detail::test_each_value.

Variables​

dependent_false_v​

template <typename... Ts>
bool micro_os_plus::micro_test_plus::detail::dependent_false_v = false
constexpr

A value that is always false, but depends on the template arguments.

Used as the condition of the static_assert of the functions that reject an argument, so that they fail only when instantiated, and their diagnostic has the message, not the concepts that were not satisfied.

Template Parameters
Ts

The template arguments to depend on.

Definition at line 1258 of file test.h.

1258 inline constexpr bool dependent_false_v = false;

Referenced by micro_os_plus::micro_test_plus::detail::reject_suite_body and micro_os_plus::micro_test_plus::detail::reject_test_body.

File Listing​

The file content with the documentation metadata removed is:

1/*
2 * This file is part of the µOS++ project (https://micro-os-plus.github.io/).
3 * Copyright (c) 2021-2026 Liviu Ionescu. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose is hereby granted, under the terms of the MIT license.
7 *
8 * If a copy of the license was not distributed with this file, it can be
9 * obtained from https://opensource.org/licenses/mit.
10 *
11 * Major parts of the code are inspired from v1.1.8 of the Boost UT project,
12 * released under the terms of the Boost Version 1.0 Software License,
13 * which can be obtained from https://www.boost.org/LICENSE_1_0.txt.
14 */
15
16// ----------------------------------------------------------------------------
17
39
40#ifndef MICRO_OS_PLUS_MICRO_TEST_PLUS_TEST_H_
41#define MICRO_OS_PLUS_MICRO_TEST_PLUS_TEST_H_
42
43// ----------------------------------------------------------------------------
44
45#if defined(__cplusplus)
46
47// ----------------------------------------------------------------------------
48
49#if __has_include("micro-os-plus/project-config.h")
50#include "micro-os-plus/project-config.h"
51#endif // __has_include("micro-os-plus/project-config.h")
52
53#if __has_include("micro-os-plus/micro-test-plus-defines.h")
54#include "micro-os-plus/micro-test-plus-defines.h"
55#endif // __has_include("micro-os-plus/micro-test-plus-defines.h")
56
57#include "check-result.h"
58#include "counters.h"
59#include "extension.h"
60#include "stopwatch.h"
61#include "reflection.h"
62
63#include <cstddef>
64#include <functional>
65#include <initializer_list>
66#include <memory>
67#include <string>
68#include <string_view>
69#include <tuple>
70#include <type_traits>
71#include <utility>
72
73// ----------------------------------------------------------------------------
74
75#if defined(__GNUC__)
76#pragma GCC diagnostic push
77
78#pragma GCC diagnostic ignored "-Waggregate-return"
79#pragma GCC diagnostic ignored "-Wpadded"
80#if defined(__clang__)
81#pragma clang diagnostic ignored "-Wc++98-compat"
82#pragma clang diagnostic ignored "-Wc++98-compat-bind-to-temporary-copy"
83#pragma clang diagnostic ignored "-Wdocumentation"
84#else // GCC only
85#pragma GCC diagnostic ignored "-Wsuggest-final-types"
86#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
87#pragma GCC diagnostic ignored "-Wredundant-tags"
88#endif // defined(__clang__)
89#endif // defined(__GNUC__)
90
91// ============================================================================
92
94{
95 // --------------------------------------------------------------------------
96
97 class counters;
98 class runner;
99 class test_case;
100
101 namespace detail
102 {
114 void
115 escape_control_characters (std::string& name);
116 } // namespace detail
117 class suite;
118 class top_suite;
119 class static_suite;
120
121 // --------------------------------------------------------------------------
122
177 {
178 public:
195 template <typename Pointer_T>
196 requires (std::is_same_v<Pointer_T, const char*>
197 or std::is_same_v<Pointer_T, char*>
198 or std::is_null_pointer_v<Pointer_T>)
201
218 template <std::size_t N>
219 located_name (const char (&name)[N],
222
231 located_name (const std::string& name,
234
243 located_name (std::string&& name,
246
256 located_name (std::string_view name,
259
268 [[nodiscard]] const char*
269 name (void) const noexcept;
270
278 [[nodiscard]] const reflection::source_location&
279 location (void) const noexcept;
280
281 private:
289 std::string name_;
290
299 };
300
301 // --------------------------------------------------------------------------
302
303 namespace detail
304 {
305 class check_result;
306 class reporter;
307 class reporter_human;
308 class reporter_tap;
309
310 // ========================================================================
311
349 {
358
366 friend class check_result;
367
375 friend class reporter_human;
376
385 friend class reporter_tap;
386
387 public:
396 runnable_base (const char* name, runner& test_runner, size_t own_index);
397
404 runnable_base (const runnable_base&) = delete;
405
414
423 = delete;
424
434 = delete;
435
442 virtual ~runnable_base ();
443
444 // ----------------------------------------------------------------------
445
453 [[nodiscard]] const char*
454 name (void) const noexcept;
455
470 [[nodiscard]] const counters&
471 totals (void) const noexcept;
472
473#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
478
492 [[deprecated ("internal to the framework (since 6.0.0)"),
493 nodiscard]] size_t
494 own_index (void) const noexcept;
495
508 [[deprecated ("internal to the framework (since 6.0.0)"),
509 nodiscard]] size_t
510 current_subtest_index (void) const noexcept;
511
523 [[deprecated ("internal to the framework (since 6.0.0)"),
524 nodiscard]] size_t
525 children_subtests_count (void) const noexcept;
526
530#endif // defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
531
532 private:
550 virtual void
551 run (void)
552 = 0;
553
567 [[noreturn]] void
570
571 protected:
588 [[nodiscard]] runner&
589 test_runner (void) const noexcept;
590
606 [[nodiscard]] class reporter&
607 test_reporter (void) const noexcept;
608
623 [[nodiscard]] class test_case*
624 running_test_case (void) const noexcept;
625
642 [[nodiscard]] bool
643 has_running_test_case_of (const suite& target) const noexcept;
644
658 [[nodiscard]] bool
659 is_aborted (void) const noexcept;
660
674 [[nodiscard]] bool
675 is_listing (void) const noexcept;
676
691 suite*
692 exchange_running_suite (suite* running) noexcept;
693
720 [[nodiscard]] bool
721 accepts_test_case (const suite& target, const located_name& name);
722
738 void
740
753 size_t
754 next_test_point_number (void) noexcept;
755
770 void
772
808 template <typename Callable_T, typename... Args_T>
809 [[gnu::always_inline]] void
810 create_test_case (const located_name& name, suite& parent_suite,
811 size_t nesting_depth, Callable_T&& callable,
812 Args_T&&... arguments);
813
814 protected:
823 const char* name_;
824
839
849
859 size_t own_index_;
860
872
884 };
885
886 // ========================================================================
887
914 template <typename Self_T, typename Callable_T, typename... Args_T>
915 [[nodiscard]] auto
916 bind_callable (Callable_T&& callable, Args_T&&... arguments);
917
918 // ========================================================================
919
942 template <typename Self_T, typename Callable_T, typename... Args_T>
944 {
945 public:
968 template <typename C, typename... A>
969 requires (sizeof...(A) > 0)
970 constexpr explicit bound_callable (C&& callable, A&&... arguments);
971
983 [[gnu::always_inline]] void
984 operator()(Self_T& self);
985
986 private:
1000 template <std::size_t... Is>
1001 [[gnu::always_inline]] void
1002 invoke (Self_T& self, std::index_sequence<Is...>);
1003
1011 Callable_T callable_;
1012
1020 std::tuple<Args_T...> arguments_;
1021 };
1022
1023 // ========================================================================
1024
1045 template <typename Self_T>
1047 {
1048 public:
1065 template <typename Callable_T>
1066 requires (!std::is_same_v<std::remove_cv_t<Callable_T>,
1068 explicit callable_ref (Callable_T& callable) noexcept;
1069
1084 [[gnu::always_inline]] void
1085 operator()(Self_T& self) const;
1086
1087 private:
1102 template <typename Callable_T>
1103 static void
1104 invoke_callable (void* callable, Self_T& self);
1105
1113
1121 void (*invoke_) (void* callable, Self_T& self);
1122 };
1123
1124 // ------------------------------------------------------------------------
1125
1138 template <class T>
1139 concept test_values_range = std::is_array_v<std::remove_cvref_t<T>>
1142
1154 template <class T>
1155 concept test_values_tuple = (not test_values_range<T>) and requires {
1156 std::tuple_size<std::remove_cvref_t<T>>::value;
1157 };
1158
1175 template <typename Callable_T>
1177 = std::is_class_v<std::decay_t<Callable_T>>
1178 && (!requires { &std::decay_t<Callable_T>::operator(); });
1179
1196 template <typename Callable_T, typename... Args_T>
1197 concept test_body
1199 || std::is_invocable_v<std::decay_t<Callable_T>&, test_case&,
1200 std::decay_t<Args_T>&...>;
1201
1215 template <typename Callable_T, typename... Args_T>
1218 || std::is_invocable_v<std::decay_t<Callable_T>&, suite&,
1219 std::decay_t<Args_T>&...>)
1220 && std::is_copy_constructible_v<std::decay_t<Callable_T>>
1221 && (std::is_copy_constructible_v<std::decay_t<Args_T>> && ...);
1222
1237 template <class T>
1241#else
1243#endif // defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
1244
1257 template <typename... Ts>
1258 inline constexpr bool dependent_false_v = false;
1259
1278 template <typename Callable_T, typename... Args_T>
1279 constexpr void
1280 reject_test_body (void) noexcept;
1281
1298 template <typename Callable_T, typename... Args_T>
1299 constexpr void
1300 reject_suite_body (void) noexcept;
1301
1322 template <class Self_T, class Values_T, class Callable_T>
1323 void
1324 test_each_value (Self_T& self, const located_name& name, Values_T&& values,
1325 Callable_T& callable);
1326
1327 // ------------------------------------------------------------------------
1328 } // namespace detail
1329
1330 // ==========================================================================
1331
1361 class test_case final : public detail::runnable_base
1362 {
1374
1383
1384 private:
1406 suite& parent_suite, size_t own_index, size_t nesting_depth,
1408
1409 public:
1416 test_case (const test_case&) = delete;
1417
1425 test_case (test_case&&) = delete;
1426
1433 test_case&
1435 = delete;
1436
1444 test_case&
1446 = delete;
1447
1455 ~test_case () override;
1456
1457 // ------------------------------------------------------------------------
1458
1486 template <typename Callable_T, typename... Args_T>
1487 requires detail::test_body<Callable_T, Args_T...>
1488 void
1489 test (const located_name& name, Callable_T&& callable,
1490 Args_T&&... arguments);
1491
1492#if !defined(__DOXYGEN__)
1511 template <typename Callable_T, typename... Args_T>
1512 requires (!detail::test_body<Callable_T, Args_T...>)
1513 void
1514 test (const located_name& name, Callable_T&& callable,
1515 Args_T&&... arguments);
1516#endif // !defined(__DOXYGEN__)
1517
1561 template <typename Values_T, typename Callable_T>
1564 void
1565 test_each (const located_name& name, Values_T&& values,
1566 Callable_T&& callable);
1567
1589 template <typename T, typename Callable_T>
1590 void
1591 test_each (const located_name& name, std::initializer_list<T> values,
1592 Callable_T&& callable);
1593
1594 // ------------------------------------------------------------------------
1595
1625 template <class Expr_T>
1628 expect (const Expr_T& expr,
1632
1633#if !defined(__DOXYGEN__)
1653 template <class Expr_T>
1656 expect (const Expr_T& expr,
1660#endif // !defined(__DOXYGEN__)
1661
1704 template <class Expr_T>
1705 requires extension::checkable<Expr_T>
1706 detail::check_result&&
1707 require (const Expr_T& expr,
1708 const reflection::source_location& sl
1710 detail::check_result&& result = detail::check_result{});
1711
1712#if !defined(__DOXYGEN__)
1732 template <class Expr_T>
1733 requires detail::unsupported_condition<Expr_T>
1734 detail::check_result&&
1735 require (const Expr_T& expr,
1736 const reflection::source_location& sl
1738 detail::check_result&& result = detail::check_result{});
1739#endif // !defined(__DOXYGEN__)
1740
1741#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
1746
1768 template <class Expr_T>
1769 requires detail::legacy_checkable<Expr_T>
1770 [[deprecated ("the argument is always true; write the condition "
1771 "(since 6.0.0)")]] detail::check_result&&
1772 expect (const Expr_T& expr,
1776
1795 template <class Expr_T>
1797 [[deprecated ("the argument is always true; write the condition "
1798 "(since 6.0.0)")]] detail::check_result&&
1799 require (const Expr_T& expr,
1803
1831 template <class Expr_T>
1833 [[deprecated ("use require() (since 6.0.0)")]] detail::check_result&&
1834 assume (const Expr_T& expr,
1838
1842#endif // defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
1843
1844 // ------------------------------------------------------------------------
1845
1853 [[nodiscard]] size_t
1854 nesting_depth (void) const noexcept;
1855
1856 private:
1871 [[nodiscard]] bool
1872 is_misdirected (void) const noexcept;
1873
1890 detail::check_result&&
1892 const reflection::source_location& sl,
1893 detail::check_result&& result);
1894
1910 void
1911 report_misdirected_test (const located_name& name);
1912
1931 void
1932 report_rejected_test (const std::string& message,
1933 const reflection::source_location& location);
1934
1953 [[gnu::always_inline]] void
1954 run (void) override;
1955
1956 private:
1957#if defined(__cpp_exceptions)
1972 void
1973 fail_unexpected_exception (const char* what);
1974#endif // defined(__cpp_exceptions)
1975
1976 private:
1986
1999
2008
2016 };
2017
2018 // ==========================================================================
2019
2059 {
2068
2076
2084
2091 friend class top_suite;
2092
2099 friend class static_suite;
2100
2101 private:
2122 template <typename Callable_T, typename... Args_T>
2123 suite (located_name&& name, runner& test_runner, Callable_T&& callable,
2124 Args_T&&... arguments);
2125
2126 public:
2133 suite (const suite&) = delete;
2134
2142 suite (suite&&) = delete;
2143
2150 suite&
2152 = delete;
2153
2161 suite&
2163 = delete;
2164
2173 ~suite () override;
2174
2175 // ------------------------------------------------------------------------
2176
2194 template <typename Callable_T, typename... Args_T>
2195 requires detail::test_body<Callable_T, Args_T...>
2196 void
2197 test (const located_name& name, Callable_T&& callable,
2198 Args_T&&... arguments);
2199
2200#if !defined(__DOXYGEN__)
2219 template <typename Callable_T, typename... Args_T>
2220 requires (!detail::test_body<Callable_T, Args_T...>)
2221 void
2222 test (const located_name& name, Callable_T&& callable,
2223 Args_T&&... arguments);
2224#endif // !defined(__DOXYGEN__)
2225
2269 template <typename Values_T, typename Callable_T>
2272 void
2273 test_each (const located_name& name, Values_T&& values,
2274 Callable_T&& callable);
2275
2297 template <typename T, typename Callable_T>
2298 void
2299 test_each (const located_name& name, std::initializer_list<T> values,
2300 Callable_T&& callable);
2301
2302#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
2307
2323 [[deprecated ("the timings are internal (since 6.0.0)"),
2324 nodiscard]] const detail::stopwatch&
2325 timings (void) const noexcept;
2326
2341 [[deprecated ("the timings are internal (since 6.0.0)"),
2342 nodiscard]] detail::stopwatch&
2343 timings (void) noexcept;
2344
2348#endif // defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
2349
2350 private:
2363 void
2364 run (void) override;
2365
2366 private:
2367#if defined(__cpp_exceptions)
2383 void
2384 fail_unexpected_exception (const char* what);
2385#endif // defined(__cpp_exceptions)
2386
2403 void
2404 link (void) noexcept;
2405
2419 void
2420 unlink (void) noexcept;
2421
2422 private:
2431 std::function<void (suite&)> callable_;
2432
2442
2454
2463 suite* next_ = nullptr;
2464
2475 static suite* first_;
2476 };
2477
2478 // ==========================================================================
2479
2497 class top_suite final : public suite
2498 {
2507
2508 private:
2519 top_suite (const char* name, runner& test_runner);
2520
2521 public:
2528 top_suite (const top_suite&) = delete;
2529
2537 top_suite (top_suite&&) = delete;
2538
2545 top_suite&
2547 = delete;
2548
2556 top_suite&
2558 = delete;
2559
2568 ~top_suite () override;
2569 };
2570
2571 // ==========================================================================
2572
2573 class static_suite;
2574
2575 namespace detail
2576 {
2592 template <typename Callable_T, typename... Args_T>
2594 = (!std::is_invocable_v<std::decay_t<Callable_T>&, suite&,
2595 std::decay_t<Args_T>&...>)
2596 && std::is_invocable_v<std::decay_t<Callable_T>&, static_suite&,
2597 std::decay_t<Args_T>&...>;
2598 } // namespace detail
2599
2600 // ==========================================================================
2601
2644 class static_suite final : public suite
2645 {
2646 public:
2675 template <typename Callable_T, typename... Args_T>
2676 requires (!detail::static_suite_body<Callable_T, Args_T...>
2677 && detail::suite_body<Callable_T, Args_T...>)
2679 Callable_T&& callable, Args_T&&... arguments);
2680
2681#if !defined(__DOXYGEN__)
2698 template <typename Callable_T, typename... Args_T>
2699 requires (!detail::static_suite_body<Callable_T, Args_T...>
2700 && !detail::suite_body<Callable_T, Args_T...>)
2702 Callable_T&& callable, Args_T&&... arguments);
2703#endif // !defined(__DOXYGEN__)
2704
2705#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
2710
2745 template <typename Callable_T, typename... Args_T>
2746 requires (detail::static_suite_body<Callable_T, Args_T...>)
2747 [[deprecated ("use a suite& first parameter (since 6.0.0)")]]
2749 Callable_T&& callable, Args_T&&... arguments);
2750
2754#endif // defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_DEPRECATED_ENABLED)
2755
2762 static_suite (const static_suite&) = delete;
2763
2772
2781 = delete;
2782
2792 = delete;
2793
2802 ~static_suite () override;
2803
2804 private:
2819 void
2820 link_or_reject (void) noexcept;
2821 };
2822
2823 // --------------------------------------------------------------------------
2824} // namespace micro_os_plus::micro_test_plus
2825
2826#if defined(__GNUC__)
2827#pragma GCC diagnostic pop
2828#endif // defined(__GNUC__)
2829
2830// ----------------------------------------------------------------------------
2831
2832#endif // defined(__cplusplus)
2833
2834// ============================================================================
2835// Templates, inlines & constexpr implementations.
2836
2837#include "inlines/test-inlines.h"
2838
2839// ----------------------------------------------------------------------------
2840
2841#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TEST_H_
2842
2843// ----------------------------------------------------------------------------

Generated via doxygen2docusaurus 2.2.8 by Doxygen 1.18.0.