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/diag/trace.h> #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#include <micro-os-plus/diag/trace.h>
59
62
63// ----------------------------------------------------------------------------
64
65#if defined(__GNUC__)
66#pragma GCC diagnostic push
67#pragma GCC diagnostic ignored "-Waggregate-return"
68#if defined(__clang__)
69#pragma clang diagnostic ignored "-Wunknown-warning-option"
70#pragma clang diagnostic ignored "-Wc++98-compat"
71#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
72#else // GCC only
73#pragma GCC diagnostic ignored "-Wredundant-tags"
74#endif
75#endif
76
77// ============================================================================
78
80{
81 namespace detail
82 {
83 // ========================================================================
84
89 inline const char*
90 test_node::name (void) const noexcept
91 {
92 return name_;
93 }
94
99 inline runner_totals&
101 {
102 return totals_;
103 }
104
109 inline const runner_totals&
110 test_node::totals () const noexcept
111 {
112 return totals_;
113 }
114
115 // ========================================================================
116
121 inline size_t
122 runnable_base::own_index () const noexcept
123 {
124 return own_index_;
125 }
126
131 inline void
132 runnable_base::own_index (size_t index) noexcept
133 {
134 own_index_ = index;
135 }
136
141 inline size_t
143 {
145 }
146
153 inline size_t
155 {
157 }
158
163 inline size_t
165 {
166 return children_subtests_.size ();
167 }
168
173 inline class runner&
174 runnable_base::runner (void) const noexcept
175 {
176 return runner_;
177 }
178
179 // ========================================================================
180
188 template <typename Self_T>
189 template <typename Callable_T, typename... Args_T>
191 size_t own_index, Callable_T&& callable,
192 Args_T&&... arguments)
194 {
195 // When there are no extra arguments the callable already has the
196 // signature void(Self_T&), so store it directly. Only use std::bind when
197 // additional arguments must be pre-bound, to avoid triggering a GCC ARM
198 // bug in
199 // __is_nothrow_invocable<_Bind<...>, Self_T&> (GCC 15.2.1).
200 if constexpr (sizeof...(arguments) == 0)
201 {
202 callable_ = std::forward<Callable_T> (callable);
203 }
204 else
205 {
206 callable_ = std::bind (std::forward<Callable_T> (callable),
207 std::placeholders::_1,
208 std::forward<Args_T> (arguments)...);
209 }
210
211#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
212#if defined(__GNUC__)
213#pragma GCC diagnostic push
214#if defined(__clang__)
215#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
216#endif
217#endif
218 trace::printf ("%s '%s' %zu\n", __PRETTY_FUNCTION__, name, own_index_);
219#if defined(__GNUC__)
220#pragma GCC diagnostic pop
221#endif
222#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
223 }
224
231 template <typename Self_T>
233 {
234#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
235#if defined(__GNUC__)
236#pragma GCC diagnostic push
237#if defined(__clang__)
238#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
239#endif
240#endif
241 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name_);
242#if defined(__GNUC__)
243#pragma GCC diagnostic pop
244#endif
245#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
246 }
247
248 // ------------------------------------------------------------------------
249 } // namespace detail
250
251 // ==========================================================================
252
258 template <typename Callable_T, typename... Args_T>
259 subtest::subtest (const char* name, class runner& runner,
260 suite& parent_suite, size_t own_index,
261 size_t nesting_depth, Callable_T&& callable,
262 Args_T&&... arguments)
264 std::forward<Callable_T> (callable),
265 std::forward<Args_T> (arguments)... },
266 parent_suite_{ parent_suite }, nesting_depth_{ nesting_depth }
267 {
268#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
269#if defined(__GNUC__)
270#pragma GCC diagnostic push
271#if defined(__clang__)
272#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
273#endif
274#endif
275 trace::printf ("%s '%s' %zu %zu\n", __PRETTY_FUNCTION__, name, own_index_,
276 nesting_depth_);
277#if defined(__GNUC__)
278#pragma GCC diagnostic pop
279#endif
280#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
281 }
282
289 template <typename Callable_T, typename... Args_T>
290 void
291 subtest::test (const char* name, Callable_T&& callable,
292 Args_T&&... arguments)
293 {
294#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED)
295#if defined(__GNUC__)
296#pragma GCC diagnostic push
297#if defined(__clang__)
298#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
299#endif
300#endif
301 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name);
302#if defined(__GNUC__)
303#pragma GCC diagnostic pop
304#endif
305#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED
306
308 auto child_subtest = std::make_unique<subtest> (
310 std::forward<Callable_T> (callable),
311 std::forward<Args_T> (arguments)...);
312
313 after_subtest_create_ (std::move (child_subtest), parent_suite_);
314 }
315
322 template <class Expr_T>
324 auto
325 subtest::expect (const Expr_T& expr, const reflection::source_location& sl)
326 {
327 return detail::deferred_reporter{ expr, false, sl, *this,
328 reporter ().expression () };
329 }
330
337 template <class Expr_T>
339 auto
340 subtest::assume (const Expr_T& expr, const reflection::source_location& sl)
341 {
342 return detail::deferred_reporter{ expr, true, sl, *this,
343 reporter ().expression () };
344 }
345
351 inline size_t
352 subtest::nesting_depth () const noexcept
353 {
354 return nesting_depth_;
355 }
356
357 // ==========================================================================
358
365 template <typename Callable_T, typename... Args_T>
366 suite::suite (const char* name, class runner& runner, Callable_T&& callable,
367 Args_T&&... arguments)
368 : runnable<suite>{ name, runner, 0, std::forward<Callable_T> (callable),
369 std::forward<Args_T> (arguments)... }
370 {
371#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
372#if defined(__GNUC__)
373#pragma GCC diagnostic push
374#if defined(__clang__)
375#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
376#endif
377#endif
378 trace::printf ("%s '%s' %zu\n", __PRETTY_FUNCTION__, name, own_index_);
379#if defined(__GNUC__)
380#pragma GCC diagnostic pop
381#endif
382#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
383 }
384
385#if defined(__GNUC__)
386#pragma GCC diagnostic push
387#if defined(__clang__)
388#pragma clang diagnostic ignored "-Wdocumentation"
389#endif
390#endif
426#if defined(__GNUC__)
427#pragma GCC diagnostic pop
428#endif
429 template <typename Callable_T, typename... Args_T>
430 void
431 suite::test (const char* name, Callable_T&& callable, Args_T&&... arguments)
432 {
433#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED)
434#if defined(__GNUC__)
435#pragma GCC diagnostic push
436#if defined(__clang__)
437#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
438#endif
439#endif
440 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name);
441#if defined(__GNUC__)
442#pragma GCC diagnostic pop
443#endif
444#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_ENABLED
445
447 auto child_subtest
448 = std::make_unique<subtest> (name, runner (), *this, own_index, 1,
449 std::forward<Callable_T> (callable),
450 std::forward<Args_T> (arguments)...);
451
452 after_subtest_create_ (std::move (child_subtest), *this);
453 }
454
459 inline detail::timestamps&
460 suite::timings () noexcept
461 {
462 return timings_;
463 }
464
469 inline const detail::timestamps&
470 suite::timings () const noexcept
471 {
472 return timings_;
473 }
474
475 // ==========================================================================
476
484 inline void
485 top_suite::name (const char* new_name) noexcept
486 {
487 name_ = new_name;
488 }
489
490 // ==========================================================================
491
498 template <typename Callable_T, typename... Args_T>
500 Callable_T&& callable, Args_T&&... arguments)
501 // The nullptr passed to the base constructor is an optimisation to save
502 // some space, since this callble is not used by the static runner.
503 : suite{ name, detail::to_runner (runner), nullptr }
504 {
505 if constexpr (sizeof...(arguments) == 0)
506 {
507 static_callable_ = std::forward<Callable_T> (callable);
508 }
509 else
510 {
511 static_callable_ = std::bind (std::forward<Callable_T> (callable),
512 std::placeholders::_1,
513 std::forward<Args_T> (arguments)...);
514 }
515
516#if defined(MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED)
517#if defined(__GNUC__)
518#pragma GCC diagnostic push
519#if defined(__clang__)
520#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
521#endif
522#endif
523 trace::printf ("%s '%s' %zu\n", __PRETTY_FUNCTION__, name, own_index_);
524#if defined(__GNUC__)
525#pragma GCC diagnostic pop
526#endif
527#endif // MICRO_OS_PLUS_MICRO_TEST_PLUS_TRACE_CONSTRUCTORS_ENABLED
528
530 }
531
532 // --------------------------------------------------------------------------
533} // namespace micro_os_plus::micro_test_plus
534
535#if defined(__GNUC__)
536#pragma GCC diagnostic pop
537#endif
538
539// ----------------------------------------------------------------------------
540
541#endif // __cplusplus
542
543// ----------------------------------------------------------------------------
544
545#endif // MICRO_TEST_PLUS_TEST_INLINES_H_
546
547// ----------------------------------------------------------------------------

Generated via doxygen2docusaurus 2.2.1 by Doxygen 1.17.0.