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 "-Wc++98-compat"
72#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
73#else // GCC only
74#pragma GCC diagnostic ignored "-Wredundant-tags"
75#endif
76#endif
77
78// ============================================================================
79
81{
82 namespace detail
83 {
84 // ========================================================================
85
90 inline const char*
91 test_node::name (void) const noexcept
92 {
93 return name_;
94 }
95
100 inline runner_totals&
102 {
103 return totals_;
104 }
105
110 inline const runner_totals&
111 test_node::totals () const noexcept
112 {
113 return totals_;
114 }
115
116 // ========================================================================
117
122 inline size_t
123 runnable_base::own_index () const noexcept
124 {
125 return own_index_;
126 }
127
132 inline void
133 runnable_base::own_index (size_t index) noexcept
134 {
135 own_index_ = index;
136 }
137
142 inline size_t
144 {
146 }
147
154 inline size_t
156 {
158 }
159
164 inline size_t
166 {
167 return children_subtests_.size ();
168 }
169
174 inline class runner&
175 runnable_base::runner (void) const noexcept
176 {
177 return runner_;
178 }
179
180 // ========================================================================
181
189 template <typename Self_T>
190 template <typename Callable_T, typename... Args_T>
192 size_t own_index, Callable_T&& callable,
193 Args_T&&... arguments)
195 {
196 // When there are no extra arguments the callable already has the
197 // signature void(Self_T&), so store it directly. Only use std::bind when
198 // additional arguments must be pre-bound, to avoid triggering a GCC ARM
199 // bug in
200 // __is_nothrow_invocable<_Bind<...>, Self_T&> (GCC 15.2.1).
201 if constexpr (sizeof...(arguments) == 0)
202 {
203 callable_ = std::forward<Callable_T> (callable);
204 }
205 else
206 {
207 callable_ = std::bind (std::forward<Callable_T> (callable),
208 std::placeholders::_1,
209 std::forward<Args_T> (arguments)...);
210 }
211
212#if defined(MICRO_OS_PLUS_TRACE) \
213 && defined(MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS_CONSTRUCTORS)
214#if defined(__GNUC__)
215#pragma GCC diagnostic push
216#if defined(__clang__)
217#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
218#endif
219#endif
220 trace::printf ("%s '%s' %zu\n", __PRETTY_FUNCTION__, name, own_index_);
221#if defined(__GNUC__)
222#pragma GCC diagnostic pop
223#endif
224#endif // MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS_CONSTRUCTORS
225 }
226
233 template <typename Self_T>
235 {
236#if defined(MICRO_OS_PLUS_TRACE) \
237 && defined(MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS_CONSTRUCTORS)
238#if defined(__GNUC__)
239#pragma GCC diagnostic push
240#if defined(__clang__)
241#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
242#endif
243#endif
244 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name_);
245#if defined(__GNUC__)
246#pragma GCC diagnostic pop
247#endif
248#endif // MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS_CONSTRUCTORS
249 }
250
251 // ------------------------------------------------------------------------
252 } // namespace detail
253
254 // ==========================================================================
255
261 template <typename Callable_T, typename... Args_T>
262 subtest::subtest (const char* name, class runner& runner,
263 suite& parent_suite, size_t own_index,
264 size_t nesting_depth, Callable_T&& callable,
265 Args_T&&... arguments)
267 std::forward<Callable_T> (callable),
268 std::forward<Args_T> (arguments)... },
269 parent_suite_{ parent_suite }, nesting_depth_{ nesting_depth }
270 {
271#if defined(MICRO_OS_PLUS_TRACE) \
272 && defined(MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS_CONSTRUCTORS)
273#if defined(__GNUC__)
274#pragma GCC diagnostic push
275#if defined(__clang__)
276#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
277#endif
278#endif
279 trace::printf ("%s '%s' %zu %zu\n", __PRETTY_FUNCTION__, name, own_index_,
280 nesting_depth_);
281#if defined(__GNUC__)
282#pragma GCC diagnostic pop
283#endif
284#endif // MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS_CONSTRUCTORS
285 }
286
293 template <typename Callable_T, typename... Args_T>
294 void
295 subtest::test (const char* name, Callable_T&& callable,
296 Args_T&&... arguments)
297 {
298#if defined(MICRO_OS_PLUS_TRACE) \
299 && defined(MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS)
300#if defined(__GNUC__)
301#pragma GCC diagnostic push
302#if defined(__clang__)
303#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
304#endif
305#endif
306 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name);
307#if defined(__GNUC__)
308#pragma GCC diagnostic pop
309#endif
310#endif // MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS
311
313 auto child_subtest = std::make_unique<subtest> (
315 std::forward<Callable_T> (callable),
316 std::forward<Args_T> (arguments)...);
317
318 after_subtest_create_ (std::move (child_subtest), parent_suite_);
319 }
320
327 template <class Expr_T>
329 auto
330 subtest::expect (const Expr_T& expr, const reflection::source_location& sl)
331 {
332 return detail::deferred_reporter{ expr, false, sl, *this,
333 reporter ().expression () };
334 }
335
342 template <class Expr_T>
344 auto
345 subtest::assume (const Expr_T& expr, const reflection::source_location& sl)
346 {
347 return detail::deferred_reporter{ expr, true, sl, *this,
348 reporter ().expression () };
349 }
350
356 inline size_t
357 subtest::nesting_depth () const noexcept
358 {
359 return nesting_depth_;
360 }
361
362 // ==========================================================================
363
370 template <typename Callable_T, typename... Args_T>
371 suite::suite (const char* name, class runner& runner, Callable_T&& callable,
372 Args_T&&... arguments)
373 : runnable<suite>{ name, runner, 0, std::forward<Callable_T> (callable),
374 std::forward<Args_T> (arguments)... }
375 {
376#if defined(MICRO_OS_PLUS_TRACE) \
377 && defined(MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS_CONSTRUCTORS)
378#if defined(__GNUC__)
379#pragma GCC diagnostic push
380#if defined(__clang__)
381#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
382#endif
383#endif
384 trace::printf ("%s '%s' %zu\n", __PRETTY_FUNCTION__, name, own_index_);
385#if defined(__GNUC__)
386#pragma GCC diagnostic pop
387#endif
388#endif // MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS_CONSTRUCTORS
389 }
390
391#if defined(__GNUC__)
392#pragma GCC diagnostic push
393#if defined(__clang__)
394#pragma clang diagnostic ignored "-Wdocumentation"
395#endif
396#endif
432#if defined(__GNUC__)
433#pragma GCC diagnostic pop
434#endif
435 template <typename Callable_T, typename... Args_T>
436 void
437 suite::test (const char* name, Callable_T&& callable, Args_T&&... arguments)
438 {
439#if defined(MICRO_OS_PLUS_TRACE) \
440 && defined(MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS)
441#if defined(__GNUC__)
442#pragma GCC diagnostic push
443#if defined(__clang__)
444#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
445#endif
446#endif
447 trace::printf ("%s '%s'\n", __PRETTY_FUNCTION__, name);
448#if defined(__GNUC__)
449#pragma GCC diagnostic pop
450#endif
451#endif // MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS
452
454 auto child_subtest
455 = std::make_unique<subtest> (name, runner (), *this, own_index, 1,
456 std::forward<Callable_T> (callable),
457 std::forward<Args_T> (arguments)...);
458
459 after_subtest_create_ (std::move (child_subtest), *this);
460 }
461
466 inline detail::timestamps&
467 suite::timings () noexcept
468 {
469 return timings_;
470 }
471
476 inline const detail::timestamps&
477 suite::timings () const noexcept
478 {
479 return timings_;
480 }
481
482 // ==========================================================================
483
491 inline void
492 top_suite::name (const char* new_name) noexcept
493 {
494 name_ = new_name;
495 }
496
497 // ==========================================================================
498
505 template <typename Callable_T, typename... Args_T>
507 Callable_T&& callable, Args_T&&... arguments)
508 // The nullptr passed to the base constructor is an optimisation to save
509 // some space, since this callble is not used by the static runner.
510 : suite{ name, detail::to_runner (runner), nullptr }
511 {
512 if constexpr (sizeof...(arguments) == 0)
513 {
514 static_callable_ = std::forward<Callable_T> (callable);
515 }
516 else
517 {
518 static_callable_ = std::bind (std::forward<Callable_T> (callable),
519 std::placeholders::_1,
520 std::forward<Args_T> (arguments)...);
521 }
522
523#if defined(MICRO_OS_PLUS_TRACE) \
524 && defined(MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS_CONSTRUCTORS)
525#if defined(__GNUC__)
526#pragma GCC diagnostic push
527#if defined(__clang__)
528#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
529#endif
530#endif
531 trace::printf ("%s '%s' %zu\n", __PRETTY_FUNCTION__, name, own_index_);
532#if defined(__GNUC__)
533#pragma GCC diagnostic pop
534#endif
535#endif // MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS_CONSTRUCTORS
536
538 }
539
540 // --------------------------------------------------------------------------
541} // namespace micro_os_plus::micro_test_plus
542
543#if defined(__GNUC__)
544#pragma GCC diagnostic pop
545#endif
546
547// ----------------------------------------------------------------------------
548
549#endif // __cplusplus
550
551// ----------------------------------------------------------------------------
552
553#endif // MICRO_TEST_PLUS_TEST_INLINES_H_
554
555// ----------------------------------------------------------------------------

Generated via doxygen2docusaurus 2.2.0 by Doxygen 1.17.0.