Skip to main content

test-inlines.h File

C++ header file with inline implementations for the µTest++ test suite. More...

Included Headers

#include "micro-os-plus/micro-test-plus/deferred-reporter.h" #include "micro-os-plus/micro-test-plus/reporter.h" #include <cstdio> #include <cstring>

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...

Description

C++ header file with inline implementations for the µTest++ test suite.

This header provides the inline implementations for the test suite facilities used within the µTest++ framework. It defines the logic for constructing and registering test suites, including the binding of callable objects and their arguments for flexible test suite definitions.

The implementation ensures that each test suite is automatically registered with the global test runner upon construction, enabling automated discovery and execution of test suites. The use of std::bind allows for versatile test suite initialisation with arbitrary callable types and arguments.

All definitions reside within the micro_os_plus::micro_test_plus namespace, maintaining a clear separation from user code and minimising the risk of naming conflicts.

The header files are organised within the include/micro-os-plus/micro-test-plus folder to maintain a structured and modular codebase.

This file is intended solely for internal use within the framework and should not be included directly by user code.

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 Software License,
13 * which can be obtained from https://www.boost.org/LICENSE_1_0.txt.
14 */
15
16// ----------------------------------------------------------------------------
17
45
46#ifndef MICRO_OS_PLUS_MICRO_TEST_PLUS_INLINES_TEST_INLINES_H_
47#define MICRO_OS_PLUS_MICRO_TEST_PLUS_INLINES_TEST_INLINES_H_
48
49// ----------------------------------------------------------------------------
50
51#if defined(__cplusplus)
52
53// ----------------------------------------------------------------------------
54
57
58#if __has_include("micro-os-plus/diag/trace.h")
59#include "micro-os-plus/diag/trace.h"
60#endif // __has_include("micro-os-plus/diag/trace.h")
61
62#include <cstdio>
63#include <cstring>
64
65// ----------------------------------------------------------------------------
66
67#if defined(__GNUC__)
68#pragma GCC diagnostic push
69
70#pragma GCC diagnostic ignored "-Waggregate-return"
71#if defined(__clang__)
72#pragma clang diagnostic ignored "-Wunknown-warning-option"
73#pragma clang diagnostic ignored "-Wc++98-compat"
74#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
75#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
76#else // GCC only
77#pragma GCC diagnostic ignored "-Wredundant-tags"
78#endif // defined(__clang__)
79#endif // defined(__GNUC__)
80
81// ============================================================================
82
84{
85 namespace detail
86 {
87 // ========================================================================
88
93 inline const char*
94 test_node::name (void) const noexcept
95 {
96 return name_;
97 }
98
103 inline runner_totals&
105 {
106 return totals_;
107 }
108
113 inline const runner_totals&
114 test_node::totals () const noexcept
115 {
116 return totals_;
117 }
118
119 // ========================================================================
120
125 inline size_t
126 runnable_base::own_index () const noexcept
127 {
128 return own_index_;
129 }
130
135 inline void
136 runnable_base::own_index (size_t index) noexcept
137 {
138 own_index_ = index;
139 }
140
145 inline size_t
147 {
149 }
150
157 inline size_t
159 {
161 }
162
167 inline size_t
169 {
170 return children_subtests_.size ();
171 }
172
177 inline class runner&
178 runnable_base::runner (void) const noexcept
179 {
180 return runner_;
181 }
182
183 // ========================================================================
184
192 template <typename Self_T>
193 template <typename Callable_T, typename... Args_T>
195 size_t own_index, Callable_T&& callable,
196 Args_T&&... arguments)
198 {
199 // When there are no extra arguments the callable already has the
200 // signature void(Self_T&), so store it directly. Only use std::bind when
201 // additional arguments must be pre-bound, to avoid triggering a GCC ARM
202 // bug in
203 // __is_nothrow_invocable<_Bind<...>, Self_T&> (GCC 15.2.1).
204 if constexpr (sizeof...(arguments) == 0)
205 {
206 callable_ = std::forward<Callable_T> (callable);
207 }
208 else
209 {
210 callable_ = std::bind (std::forward<Callable_T> (callable),
211 std::placeholders::_1,
212 std::forward<Args_T> (arguments)...);
213 }
215#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
216 trace::printf ("%s '%s' %zu\n", __PRETTY_FUNCTION__, name, own_index_);
217#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
218 }
219
226 template <typename Self_T>
228 {
229#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
230 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name_);
231#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
232 }
233
234 // ------------------------------------------------------------------------
235 } // namespace detail
236
237 // ==========================================================================
238
244 template <typename Callable_T, typename... Args_T>
245 subtest::subtest (const char* name, class runner& runner,
246 suite& parent_suite, size_t own_index,
247 size_t nesting_depth, Callable_T&& callable,
248 Args_T&&... arguments)
250 std::forward<Callable_T> (callable),
251 std::forward<Args_T> (arguments)... },
252 parent_suite_{ parent_suite }, nesting_depth_{ nesting_depth }
253 {
254#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
255 trace::printf ("%s '%s' %zu %zu\n", __PRETTY_FUNCTION__, name, own_index_,
256 nesting_depth_);
257#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
258 }
259
266 template <typename Callable_T, typename... Args_T>
267 void
268 subtest::test (const char* name, Callable_T&& callable,
269 Args_T&&... arguments)
270 {
271#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED)
272 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name);
273#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED
274
276 auto child_subtest = std::make_unique<subtest> (
278 std::forward<Callable_T> (callable),
279 std::forward<Args_T> (arguments)...);
280
281 after_subtest_create_ (std::move (child_subtest), parent_suite_);
282 }
283
290 template <class Expr_T>
292 auto
293 subtest::expect (const Expr_T& expr, const reflection::source_location& sl)
294 {
295 return detail::deferred_reporter{ expr, false, sl, *this,
296 reporter ().expression () };
297 }
298
305 template <class Expr_T>
307 auto
308 subtest::assume (const Expr_T& expr, const reflection::source_location& sl)
309 {
310 return detail::deferred_reporter{ expr, true, sl, *this,
311 reporter ().expression () };
312 }
313
319 inline size_t
320 subtest::nesting_depth () const noexcept
321 {
322 return nesting_depth_;
323 }
324
325 // ==========================================================================
326
333 template <typename Callable_T, typename... Args_T>
334 suite::suite (const char* name, class runner& runner, Callable_T&& callable,
335 Args_T&&... arguments)
336 : runnable<suite>{ name, runner, 0, std::forward<Callable_T> (callable),
337 std::forward<Args_T> (arguments)... }
338 {
339#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
340 trace::printf ("%s '%s' %zu\n", __PRETTY_FUNCTION__, name, own_index_);
341#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
342 }
343
344#if defined(__GNUC__)
345#pragma GCC diagnostic push
346
347#if defined(__clang__)
348#pragma clang diagnostic ignored "-Wdocumentation"
349#endif // defined(__clang__)
350#endif // defined(__GNUC__)
351
387
388 template <typename Callable_T, typename... Args_T>
389 void
390 suite::test (const char* name, Callable_T&& callable, Args_T&&... arguments)
391 {
392#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED)
393 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name);
394#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED
395
397 auto child_subtest
398 = std::make_unique<subtest> (name, runner (), *this, own_index, 1,
399 std::forward<Callable_T> (callable),
400 std::forward<Args_T> (arguments)...);
401
402 after_subtest_create_ (std::move (child_subtest), *this);
403 }
404
409 inline detail::timestamps&
410 suite::timings () noexcept
411 {
412 return timings_;
413 }
414
419 inline const detail::timestamps&
420 suite::timings () const noexcept
421 {
422 return timings_;
423 }
424
425 // ==========================================================================
426
434 inline void
435 top_suite::name (const char* new_name) noexcept
436 {
437 name_ = new_name;
438 }
439
440 // ==========================================================================
441
448 template <typename Callable_T, typename... Args_T>
450 Callable_T&& callable, Args_T&&... arguments)
451 // The nullptr passed to the base constructor is an optimisation to save
452 // some space, since this callble is not used by the static runner.
453 : suite{ name, detail::to_runner (runner), nullptr }
454 {
455 if constexpr (sizeof...(arguments) == 0)
456 {
457 static_callable_ = std::forward<Callable_T> (callable);
458 }
459 else
460 {
461 static_callable_ = std::bind (std::forward<Callable_T> (callable),
462 std::placeholders::_1,
463 std::forward<Args_T> (arguments)...);
464 }
465
466#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
467 trace::printf ("%s '%s' %zu\n", __PRETTY_FUNCTION__, name, own_index_);
468#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
471 }
472
473 // --------------------------------------------------------------------------
474} // namespace micro_os_plus::micro_test_plus
475
476// ----------------------------------------------------------------------------
477
478#if defined(__GNUC__)
479#pragma GCC diagnostic pop
480#pragma GCC diagnostic pop
481#endif // defined(__GNUC__)
482
483// ----------------------------------------------------------------------------
484
485#endif // defined(__cplusplus)
486
487// ----------------------------------------------------------------------------
488
489#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_INLINES_TEST_INLINES_H_
490
491// ----------------------------------------------------------------------------

Generated via doxygen2docusaurus 2.2.2 by Doxygen 1.17.0.