Skip to main content

test-inlines.h File

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

Included Headers

#include <cstdio> #include <cstring> #include "micro-os-plus/micro-test-plus/deferred-reporter.h" #include "micro-os-plus/micro-test-plus/reporter.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...

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_TEST_PLUS_TEST_INLINES_H_
47#define MICRO_TEST_PLUS_TEST_INLINES_H_
48
49// ----------------------------------------------------------------------------
50
51#ifdef __cplusplus
52
53// ----------------------------------------------------------------------------
54
55#include <cstdio>
56#include <cstring>
57
58#if defined(MICRO_OS_PLUS_TRACE)
59#include <micro-os-plus/diag/trace.h>
60#endif // MICRO_OS_PLUS_TRACE
61
64
65// ----------------------------------------------------------------------------
66
67#if defined(__GNUC__)
68#pragma GCC diagnostic push
69#pragma GCC diagnostic ignored "-Waggregate-return"
70#if defined(__clang__)
71#pragma clang diagnostic ignored "-Wunknown-warning-option"
72#pragma clang diagnostic ignored "-Wc++98-compat"
73#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
74#else // GCC only
75#pragma GCC diagnostic ignored "-Wredundant-tags"
76#endif
77#endif
78
79// ============================================================================
80
82{
83 namespace detail
84 {
85 // ========================================================================
86
91 inline const char*
92 test_node::name (void) const noexcept
93 {
94 return name_;
95 }
96
101 inline runner_totals&
103 {
104 return totals_;
105 }
106
111 inline const runner_totals&
112 test_node::totals () const noexcept
113 {
114 return totals_;
115 }
116
117 // ========================================================================
118
123 inline size_t
124 runnable_base::own_index () const noexcept
125 {
126 return own_index_;
127 }
128
133 inline void
134 runnable_base::own_index (size_t index) noexcept
135 {
136 own_index_ = index;
137 }
138
143 inline size_t
145 {
147 }
148
155 inline size_t
157 {
159 }
160
165 inline size_t
167 {
168 return children_subtests_.size ();
169 }
170
175 inline class runner&
176 runnable_base::runner (void) const noexcept
177 {
178 return runner_;
179 }
180
181 // ========================================================================
182
190 template <typename Self_T>
191 template <typename Callable_T, typename... Args_T>
193 size_t own_index, Callable_T&& callable,
194 Args_T&&... arguments)
196 {
197 // When there are no extra arguments the callable already has the
198 // signature void(Self_T&), so store it directly. Only use std::bind when
199 // additional arguments must be pre-bound, to avoid triggering a GCC ARM
200 // bug in
201 // __is_nothrow_invocable<_Bind<...>, Self_T&> (GCC 15.2.1).
202 if constexpr (sizeof...(arguments) == 0)
203 {
204 callable_ = std::forward<Callable_T> (callable);
205 }
206 else
207 {
208 callable_ = std::bind (std::forward<Callable_T> (callable),
209 std::placeholders::_1,
210 std::forward<Args_T> (arguments)...);
211 }
212
213#if defined(MICRO_OS_PLUS_TRACE) \
214 && defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
215#if defined(__GNUC__)
216#pragma GCC diagnostic push
217#if defined(__clang__)
218#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
219#endif
220#endif
221 trace::printf ("%s '%s' %zu\n", __PRETTY_FUNCTION__, name, own_index_);
222#if defined(__GNUC__)
223#pragma GCC diagnostic pop
224#endif
225#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
226 }
227
234 template <typename Self_T>
236 {
237#if defined(MICRO_OS_PLUS_TRACE) \
238 && defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
239#if defined(__GNUC__)
240#pragma GCC diagnostic push
241#if defined(__clang__)
242#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
243#endif
244#endif
245 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name_);
246#if defined(__GNUC__)
247#pragma GCC diagnostic pop
248#endif
249#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
250 }
251
252 // ------------------------------------------------------------------------
253 } // namespace detail
254
255 // ==========================================================================
256
262 template <typename Callable_T, typename... Args_T>
263 subtest::subtest (const char* name, class runner& runner,
264 suite& parent_suite, size_t own_index,
265 size_t nesting_depth, Callable_T&& callable,
266 Args_T&&... arguments)
268 std::forward<Callable_T> (callable),
269 std::forward<Args_T> (arguments)... },
270 parent_suite_{ parent_suite }, nesting_depth_{ nesting_depth }
271 {
272#if defined(MICRO_OS_PLUS_TRACE) \
273 && defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
274#if defined(__GNUC__)
275#pragma GCC diagnostic push
276#if defined(__clang__)
277#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
278#endif
279#endif
280 trace::printf ("%s '%s' %zu %zu\n", __PRETTY_FUNCTION__, name, own_index_,
281 nesting_depth_);
282#if defined(__GNUC__)
283#pragma GCC diagnostic pop
284#endif
285#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
286 }
287
294 template <typename Callable_T, typename... Args_T>
295 void
296 subtest::test (const char* name, Callable_T&& callable,
297 Args_T&&... arguments)
298 {
299#if defined(MICRO_OS_PLUS_TRACE) \
300 && defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED)
301#if defined(__GNUC__)
302#pragma GCC diagnostic push
303#if defined(__clang__)
304#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
305#endif
306#endif
307 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name);
308#if defined(__GNUC__)
309#pragma GCC diagnostic pop
310#endif
311#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED
312
314 auto child_subtest = std::make_unique<subtest> (
316 std::forward<Callable_T> (callable),
317 std::forward<Args_T> (arguments)...);
318
319 after_subtest_create_ (std::move (child_subtest), parent_suite_);
320 }
321
328 template <class Expr_T>
330 auto
331 subtest::expect (const Expr_T& expr, const reflection::source_location& sl)
332 {
333 return detail::deferred_reporter{ expr, false, sl, *this,
334 reporter ().expression () };
335 }
336
343 template <class Expr_T>
345 auto
346 subtest::assume (const Expr_T& expr, const reflection::source_location& sl)
347 {
348 return detail::deferred_reporter{ expr, true, sl, *this,
350 }
351
357 inline size_t
358 subtest::nesting_depth () const noexcept
359 {
360 return nesting_depth_;
361 }
362
363 // ==========================================================================
364
371 template <typename Callable_T, typename... Args_T>
372 suite::suite (const char* name, class runner& runner, Callable_T&& callable,
373 Args_T&&... arguments)
374 : runnable<suite>{ name, runner, 0, std::forward<Callable_T> (callable),
375 std::forward<Args_T> (arguments)... }
376 {
377#if defined(MICRO_OS_PLUS_TRACE) \
378 && defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
379#if defined(__GNUC__)
380#pragma GCC diagnostic push
381#if defined(__clang__)
382#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
383#endif
384#endif
385 trace::printf ("%s '%s' %zu\n", __PRETTY_FUNCTION__, name, own_index_);
386#if defined(__GNUC__)
387#pragma GCC diagnostic pop
388#endif
389#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
390 }
391
392#if defined(__GNUC__)
393#pragma GCC diagnostic push
394#if defined(__clang__)
395#pragma clang diagnostic ignored "-Wdocumentation"
396#endif
397#endif
433#if defined(__GNUC__)
434#pragma GCC diagnostic pop
435#endif
436 template <typename Callable_T, typename... Args_T>
437 void
438 suite::test (const char* name, Callable_T&& callable, Args_T&&... arguments)
439 {
440#if defined(MICRO_OS_PLUS_TRACE) \
441 && defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED)
442#if defined(__GNUC__)
443#pragma GCC diagnostic push
444#if defined(__clang__)
445#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
446#endif
447#endif
448 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name);
449#if defined(__GNUC__)
450#pragma GCC diagnostic pop
451#endif
452#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED
453
455 auto child_subtest
456 = std::make_unique<subtest> (name, runner (), *this, own_index, 1,
457 std::forward<Callable_T> (callable),
458 std::forward<Args_T> (arguments)...);
459
460 after_subtest_create_ (std::move (child_subtest), *this);
461 }
462
467 inline detail::timestamps&
468 suite::timings () noexcept
469 {
470 return timings_;
471 }
472
477 inline const detail::timestamps&
478 suite::timings () const noexcept
479 {
480 return timings_;
481 }
482
483 // ==========================================================================
484
492 inline void
493 top_suite::name (const char* new_name) noexcept
494 {
495 name_ = new_name;
496 }
497
498 // ==========================================================================
499
506 template <typename Callable_T, typename... Args_T>
508 Callable_T&& callable, Args_T&&... arguments)
509 // The nullptr passed to the base constructor is an optimisation to save
510 // some space, since this callble is not used by the static runner.
511 : suite{ name, detail::to_runner (runner), nullptr }
512 {
513 if constexpr (sizeof...(arguments) == 0)
514 {
515 static_callable_ = std::forward<Callable_T> (callable);
516 }
517 else
518 {
519 static_callable_ = std::bind (std::forward<Callable_T> (callable),
520 std::placeholders::_1,
521 std::forward<Args_T> (arguments)...);
522 }
523
524#if defined(MICRO_OS_PLUS_TRACE) \
525 && defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
526#if defined(__GNUC__)
527#pragma GCC diagnostic push
528#if defined(__clang__)
529#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
530#endif
531#endif
532 trace::printf ("%s '%s' %zu\n", __PRETTY_FUNCTION__, name, own_index_);
533#if defined(__GNUC__)
534#pragma GCC diagnostic pop
535#endif
536#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
537
539 }
540
541 // --------------------------------------------------------------------------
542} // namespace micro_os_plus::micro_test_plus
543
544#if defined(__GNUC__)
545#pragma GCC diagnostic pop
546#endif
547
548// ----------------------------------------------------------------------------
549
550#endif // __cplusplus
551
552// ----------------------------------------------------------------------------
553
554#endif // MICRO_TEST_PLUS_TEST_INLINES_H_
555
556// ----------------------------------------------------------------------------

Generated via doxygen2docusaurus 2.2.0 by Doxygen 1.17.0.