@micro-os-plus/micro-test-plus 3.2.2 → 3.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/.cmake-format.yaml +11 -0
  2. package/CHANGELOG.md +352 -2
  3. package/CMakeLists.txt +32 -30
  4. package/LICENSE +1 -1
  5. package/README.md +1 -1
  6. package/{xcdl.json → config/xcdl-build.json} +6 -6
  7. package/include/micro-os-plus/micro-test-plus/detail.h +1885 -0
  8. package/include/micro-os-plus/micro-test-plus/function-comparators.h +333 -0
  9. package/include/micro-os-plus/micro-test-plus/inlines/details-inlines.h +172 -0
  10. package/include/micro-os-plus/micro-test-plus/inlines/function-comparators-inlines.h +341 -0
  11. package/include/micro-os-plus/micro-test-plus/inlines/literals-inlines.h +604 -0
  12. package/include/micro-os-plus/micro-test-plus/inlines/math-inlines.h +315 -0
  13. package/include/micro-os-plus/micro-test-plus/inlines/micro-test-plus-inlines.h +313 -0
  14. package/include/micro-os-plus/micro-test-plus/inlines/reflection-inlines.h +170 -0
  15. package/include/micro-os-plus/micro-test-plus/inlines/test-reporter-inlines.h +471 -0
  16. package/include/micro-os-plus/micro-test-plus/inlines/test-suite-inlines.h +115 -0
  17. package/include/micro-os-plus/micro-test-plus/literals.h +912 -0
  18. package/include/micro-os-plus/micro-test-plus/math.h +217 -0
  19. package/include/micro-os-plus/micro-test-plus/operators.h +514 -0
  20. package/include/micro-os-plus/micro-test-plus/reflection.h +233 -0
  21. package/include/micro-os-plus/micro-test-plus/test-reporter.h +801 -0
  22. package/include/micro-os-plus/micro-test-plus/test-runner.h +241 -0
  23. package/include/micro-os-plus/micro-test-plus/test-suite.h +456 -0
  24. package/include/micro-os-plus/micro-test-plus/type-traits.h +1148 -0
  25. package/include/micro-os-plus/micro-test-plus.h +169 -551
  26. package/meson.build +5 -5
  27. package/package.json +29 -34
  28. package/src/micro-test-plus.cpp +131 -35
  29. package/src/test-reporter.cpp +348 -6
  30. package/src/test-runner.cpp +69 -5
  31. package/src/test-suite.cpp +124 -5
  32. package/include/micro-os-plus/detail.h +0 -765
  33. package/include/micro-os-plus/inlines.h +0 -209
  34. package/include/micro-os-plus/literals.h +0 -512
  35. package/include/micro-os-plus/math.h +0 -204
  36. package/include/micro-os-plus/reflection.h +0 -139
  37. package/include/micro-os-plus/test-reporter-inlines.h +0 -230
  38. package/include/micro-os-plus/test-reporter.h +0 -356
  39. package/include/micro-os-plus/test-runner.h +0 -132
  40. package/include/micro-os-plus/test-suite.h +0 -306
  41. package/include/micro-os-plus/type-traits.h +0 -389
@@ -0,0 +1,315 @@
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
+
18
+ /**
19
+ * @file
20
+ * @brief C++ header file with inline implementations for the µTest++
21
+ * mathematical utilities.
22
+ *
23
+ * @details
24
+ * This header provides the inline implementations for the mathematical utility
25
+ * templates used within the µTest++ framework. It defines constexpr logic for
26
+ * common mathematical operations, including absolute value, minimum value
27
+ * selection, exponentiation, and compile-time parsing of numeric values from
28
+ * character sequences.
29
+ *
30
+ * These utilities are designed to be lightweight and suitable for embedded
31
+ * environments, supporting both integral and floating-point types, and
32
+ * enabling expressive, type-safe, and efficient compile-time computations.
33
+ * Special attention is given to constexpr compatibility and minimal reliance
34
+ * on the standard library, ensuring portability and performance.
35
+ *
36
+ * All definitions reside within the `micro_os_plus::micro_test_plus::math`
37
+ * namespace, ensuring clear separation from user code and minimising the risk
38
+ * of naming conflicts.
39
+ *
40
+ * The header files are organised within the
41
+ * `include/micro-os-plus/micro-test-plus` folder to maintain a structured and
42
+ * modular codebase.
43
+ *
44
+ * This file is intended solely for internal use within the framework and
45
+ * should not be included directly by user code.
46
+ */
47
+
48
+ #ifndef MICRO_TEST_PLUS_MATH_INLINES_H_
49
+ #define MICRO_TEST_PLUS_MATH_INLINES_H_
50
+
51
+ // ----------------------------------------------------------------------------
52
+
53
+ #ifdef __cplusplus
54
+
55
+ // ----------------------------------------------------------------------------
56
+
57
+ #include <cstdint>
58
+
59
+ // #include "type-traits.h"
60
+
61
+ // ----------------------------------------------------------------------------
62
+
63
+ #if defined(__GNUC__)
64
+ #pragma GCC diagnostic push
65
+ #pragma GCC diagnostic ignored "-Waggregate-return"
66
+ #if defined(__clang__)
67
+ #pragma clang diagnostic ignored "-Wc++98-compat"
68
+ #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
69
+ #endif
70
+ #endif
71
+
72
+ namespace micro_os_plus::micro_test_plus
73
+ {
74
+ // --------------------------------------------------------------------------
75
+
76
+ namespace math
77
+ {
78
+
79
+ /**
80
+ * @details
81
+ * This function template provides a generic, constexpr implementation for
82
+ * obtaining the absolute value of any type that supports comparison and
83
+ * unary negation.
84
+ *
85
+ * The function returns the non-negative value of the input. If the input
86
+ * is less than the default-constructed value of its type (typically zero),
87
+ * the negated value is returned; otherwise, the original value is
88
+ * returned.
89
+ *
90
+ * This utility is designed to be lightweight and suitable for embedded
91
+ * environments, where standard library alternatives may be unavailable,
92
+ * less efficient, or not constexpr.
93
+ */
94
+ template <class T>
95
+ [[nodiscard]] constexpr auto
96
+ abs (const T t) -> T
97
+ {
98
+ return t < T{} ? -t : t;
99
+ }
100
+
101
+ /**
102
+ * @details
103
+ * This function template provides a generic, constexpr implementation for
104
+ * determining the minimum of two values of any type that supports
105
+ * comparison.
106
+ *
107
+ * The function returns a reference to the lesser of the two input values,
108
+ * as determined by the `<` operator. If the second argument is less than
109
+ * the first, it is returned; otherwise, the first argument is returned.
110
+ *
111
+ * This utility is designed to be lightweight and suitable for embedded
112
+ * environments, where standard library alternatives may be unavailable,
113
+ * less efficient, or not constexpr.
114
+ */
115
+ template <class T>
116
+ [[nodiscard]] constexpr auto
117
+ min_value (const T& lhs, const T& rhs) -> const T&
118
+ {
119
+ return (rhs < lhs) ? rhs : lhs;
120
+ }
121
+
122
+ /**
123
+ * @details
124
+ * This function template provides a constexpr implementation for raising a
125
+ * base value to a given exponent, supporting any types that allow
126
+ * multiplication and subtraction.
127
+ *
128
+ * The function recursively multiplies the base by itself exponent times.
129
+ * If the exponent is zero, the function returns one (the multiplicative
130
+ * identity for the type).
131
+ *
132
+ * This utility is designed to be lightweight and suitable for embedded
133
+ * environments, where standard library alternatives may be unavailable,
134
+ * less efficient, or not constexpr.
135
+ */
136
+ template <class T, class Exp_T>
137
+ [[nodiscard]] constexpr auto
138
+ pow (const T base, const Exp_T exp) -> T
139
+ {
140
+ // If the exponent is 0, return 1, otherwise recurse.
141
+ return exp ? T (base * pow (base, exp - Exp_T (1))) : T (1);
142
+ }
143
+
144
+ /**
145
+ * @details
146
+ * This function template performs compile-time parsing of a numeric value
147
+ * from a sequence of characters, typically provided as a template
148
+ * parameter pack.
149
+ *
150
+ * The function assumes that all characters are either digits, a dot (`.`),
151
+ * or an apostrophe (`'`). Parsing stops at the first dot, allowing the
152
+ * function to extract only the integral part of the number.
153
+ *
154
+ * This utility is particularly useful for user-defined literals and other
155
+ * compile-time constant expressions, enabling efficient and type-safe
156
+ * conversion from character sequences to integral values.
157
+ */
158
+ template <class T, char... Cs>
159
+ [[nodiscard]] constexpr auto
160
+ num (void) -> T
161
+ {
162
+ // Assume all are digits or dot or apostrophe.
163
+ static_assert (
164
+ ((Cs == '.' or Cs == '\'' or (Cs >= '0' and Cs <= '9')) and ...));
165
+ T result{};
166
+ for (const char c : { Cs... })
167
+ {
168
+ if (c == '.')
169
+ {
170
+ break;
171
+ }
172
+ if (c >= '0' and c <= '9')
173
+ {
174
+ result = static_cast<T> (result * static_cast<T> (10)
175
+ + static_cast<T> (c - '0'));
176
+ }
177
+ }
178
+ return result;
179
+ }
180
+
181
+ /**
182
+ * @details
183
+ * This function template performs compile-time extraction of the decimal
184
+ * (fractional) part from a sequence of characters, typically provided as a
185
+ * template parameter pack.
186
+ *
187
+ * The function expects the character sequence to represent a numeric
188
+ * value, where all characters are either digits, a dot (`.`), or an
189
+ * apostrophe (`'`). Parsing begins after the first dot, accumulating the
190
+ * decimal digits as an integer value, each weighted by its decimal
191
+ * position.
192
+ *
193
+ * This utility is particularly useful for user-defined literals and other
194
+ * compile-time constant expressions, enabling efficient and type-safe
195
+ * conversion from character sequences to the decimal part of numeric
196
+ * values.
197
+ */
198
+ template <class T, char... Cs>
199
+ [[nodiscard]] constexpr auto
200
+ den (void) -> T
201
+ {
202
+ constexpr const std::array cs{ Cs... };
203
+ T result{};
204
+ auto i = 0u;
205
+ while (cs[i++] != '.')
206
+ {
207
+ }
208
+
209
+ for (auto j = i; j < sizeof...(Cs); ++j)
210
+ {
211
+ result += pow (T (10), sizeof...(Cs) - j) * T (cs[j] - '0');
212
+ }
213
+ return result;
214
+ }
215
+
216
+ /**
217
+ * @details
218
+ * This function template determines, at compile time, the number of
219
+ * decimal (fractional) digits present in a numeric value represented by a
220
+ * character sequence, typically provided as a template parameter pack.
221
+ *
222
+ * The function expects the character sequence to represent a numeric
223
+ * value, where all characters are either digits, a dot (`.`), or an
224
+ * apostrophe (`'`). It locates the first dot and counts the number of
225
+ * digits that follow, returning the count as the number of decimal places.
226
+ *
227
+ * This utility is particularly useful for user-defined literals and other
228
+ * compile-time constant expressions, enabling efficient and type-safe
229
+ * determination of decimal precision from character sequences.
230
+ */
231
+ template <class T, char... Cs>
232
+ [[nodiscard]] constexpr auto
233
+ den_size (void) -> T
234
+ {
235
+ constexpr const std::array cs{ Cs... };
236
+ T i{};
237
+ #if defined(__GNUC__)
238
+ #pragma GCC diagnostic push
239
+ #pragma GCC diagnostic ignored "-Wconversion"
240
+ #endif
241
+ while (cs[i++] != '.')
242
+ #if defined(__GNUC__)
243
+ #pragma GCC diagnostic pop
244
+ #endif
245
+ {
246
+ }
247
+
248
+ return T (sizeof...(Cs)) - i + T (1);
249
+ }
250
+
251
+ /**
252
+ * @details
253
+ * This function template determines, at compile time, the number of
254
+ * decimal (fractional) digits present in a floating-point value, up to a
255
+ * maximum of seven digits of precision.
256
+ *
257
+ * The function repeatedly multiplies the input value by ten, incrementing
258
+ * a counter until the fractional part is less than a defined precision
259
+ * threshold (1e-7). This approach provides a robust means of estimating
260
+ * decimal precision for values where exact representation is not possible
261
+ * due to floating-point limitations.
262
+ *
263
+ * This utility is particularly useful for user-defined literals and
264
+ * compile-time constant expressions, enabling efficient and type-safe
265
+ * determination of decimal precision from floating-point values.
266
+ */
267
+ template <class T, class Value_T>
268
+ [[nodiscard]] constexpr auto
269
+ den_size (Value_T value) -> T
270
+ {
271
+ constexpr auto precision = Value_T (1e-7);
272
+ T result{};
273
+ Value_T tmp{};
274
+ do
275
+ {
276
+ value *= 10;
277
+ #if defined(__GNUC__)
278
+ #pragma GCC diagnostic push
279
+ #if !defined(__clang__) // GCC only
280
+ #pragma GCC diagnostic ignored "-Warith-conversion"
281
+ #endif
282
+ #if defined(__clang__)
283
+ #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"
284
+ #endif
285
+ #endif
286
+ tmp = value - T (value);
287
+ #if defined(__GNUC__)
288
+ #pragma GCC diagnostic pop
289
+ #endif
290
+ ++result;
291
+ }
292
+ while (tmp > precision);
293
+
294
+ return result;
295
+ }
296
+
297
+ // ------------------------------------------------------------------------
298
+ } // namespace math
299
+
300
+ // --------------------------------------------------------------------------
301
+ } // namespace micro_os_plus::micro_test_plus
302
+
303
+ #if defined(__GNUC__)
304
+ #pragma GCC diagnostic pop
305
+ #endif
306
+
307
+ // ----------------------------------------------------------------------------
308
+
309
+ #endif // __cplusplus
310
+
311
+ // ----------------------------------------------------------------------------
312
+
313
+ #endif // MICRO_TEST_PLUS_MATH_INLINES_H_
314
+
315
+ // ----------------------------------------------------------------------------
@@ -0,0 +1,313 @@
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
+
18
+ /**
19
+ * @file
20
+ * @brief C++ header file with inline implementations for the µTest++ Testing
21
+ * Framework.
22
+ *
23
+ * @details
24
+ * This header provides the inline implementations for the principal public API
25
+ * functions and utilities of the µTest++ framework, including test case
26
+ * registration, expectation and assumption evaluation, exception verification,
27
+ * and utility helpers for string processing in tests.
28
+ *
29
+ * It defines the logic for registering and executing test cases, evaluating
30
+ * logical conditions and custom comparators, and reporting test results with
31
+ * detailed diagnostics. The exception verification functions enable robust
32
+ * testing of error handling and exception safety, while utility functions such
33
+ * as string splitting support flexible validation of string processing logic.
34
+ *
35
+ * All definitions reside within the `micro_os_plus::micro_test_plus`
36
+ * namespace, ensuring clear separation from user code and minimising the risk
37
+ * of naming conflicts.
38
+ *
39
+ * The header files are organised within the
40
+ * `include/micro-os-plus/micro-test-plus` folder to maintain a structured and
41
+ * modular codebase.
42
+ *
43
+ * This file is intended solely for internal use within the framework and
44
+ * should not be included directly by user code.
45
+ */
46
+
47
+ #ifndef MICRO_TEST_PLUS_INLINES_H_
48
+ #define MICRO_TEST_PLUS_INLINES_H_
49
+
50
+ // ----------------------------------------------------------------------------
51
+
52
+ #ifdef __cplusplus
53
+
54
+ // ----------------------------------------------------------------------------
55
+
56
+ #if defined(__GNUC__)
57
+ #pragma GCC diagnostic push
58
+ #pragma GCC diagnostic ignored "-Waggregate-return"
59
+ #pragma GCC diagnostic ignored "-Wpadded"
60
+ #if defined(__clang__)
61
+ #pragma clang diagnostic ignored "-Wc++98-compat"
62
+ #pragma clang diagnostic ignored "-Wc++98-c++11-c++14-c++17-compat-pedantic"
63
+ #endif
64
+ #endif
65
+
66
+ namespace micro_os_plus::micro_test_plus
67
+ {
68
+ // --------------------------------------------------------------------------
69
+
70
+ #if defined(__clang__)
71
+ #pragma clang diagnostic push
72
+ #pragma clang diagnostic ignored "-Wdocumentation"
73
+ #endif
74
+ /**
75
+ * @details
76
+ * The `test_case` function template registers and executes a test case
77
+ * within the µTest++ framework. It accepts a descriptive name, a callable
78
+ * object (such as a lambda or function pointer), and an optional list of
79
+ * arguments to be passed to the callable. The test case is reported using
80
+ * the provided name, and its execution is managed by the framework's test
81
+ * runner.
82
+ *
83
+ * Each test case typically involves evaluating a logical expression, such as
84
+ * comparing a computed result to an expected value. For C++ projects, it is
85
+ * also possible to verify whether evaluating an expression throws
86
+ * exceptions. Each test either succeeds or fails, and for expectations, the
87
+ * test runner maintains counts of successful and failed checks.
88
+ *
89
+ * This function template enables flexible and expressive test case
90
+ * definitions, supporting both parameterised and non-parameterised tests. It
91
+ * is typically invoked at global scope or within test suite definitions to
92
+ * ensure automatic registration and execution.
93
+ *
94
+ * A test case is characterised by a name, a function that performs the
95
+ * checks, and optionally, arguments to be passed to that function. The
96
+ * implementation of `test_case` invokes the provided function with the given
97
+ * arguments and reports the results to the test runner.
98
+ *
99
+ * @par Example
100
+ *
101
+ * @code{.cpp}
102
+ * namespace mt = micro_os_plus::micro_test_plus;
103
+ *
104
+ * mt::test_case ("Check answer with comparator", [] {
105
+ * mt::expect (mt::eq (compute_answer (), 42)) << "answer is 42";
106
+ * });
107
+ * @endcode
108
+ */
109
+ #if defined(__clang__)
110
+ #pragma clang diagnostic pop
111
+ #endif
112
+ template <typename Callable_T, typename... Args_T>
113
+ void
114
+ test_case (const char* name, Callable_T&& callable, Args_T&&... arguments)
115
+ {
116
+ #if 0 // defined(MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS)
117
+ printf ("%s\n", __PRETTY_FUNCTION__);
118
+ #endif // MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS
119
+
120
+ current_test_suite->begin_test_case (name);
121
+ std::invoke (std::forward<Callable_T> (callable),
122
+ std::forward<Args_T> (arguments)...);
123
+ current_test_suite->end_test_case ();
124
+ }
125
+
126
+ /**
127
+ * @details
128
+ * The `expect` function template evaluates a logical condition or custom
129
+ * expression and reports the result within the µTest++ framework. It is
130
+ * designed to provide detailed diagnostics for test failures, including the
131
+ * actual and expected values, when using the provided comparators (`eq()`,
132
+ * `ne()`, `lt()`, `le()`, `gt()`, `ge()`) or custom operators.
133
+ *
134
+ * The function template can be used with any expression that evaluates to a
135
+ * boolean or with custom comparators/operators derived from the local
136
+ * `detail::op` type. For complex checks performed outside the `expect()`
137
+ * logical expression (such as within `if` or `try`/`catch` statements), the
138
+ * result can be reported by calling `expect(true)` or `expect(false)`.
139
+ *
140
+ * The function returns an output stream, allowing optional messages to be
141
+ * appended to the test report.
142
+ *
143
+ * **Example**
144
+ *
145
+ * @code{.cpp}
146
+ * namespace mt = micro_os_plus::micro_test_plus;
147
+ * mt::expect(compute_answer() == 42) << "answer is 42";
148
+ * @endcode
149
+ */
150
+
151
+ template <class Expr_T, type_traits::requires_t<
152
+ type_traits::is_op_v<Expr_T>
153
+ or type_traits::is_convertible_v<Expr_T, bool>>>
154
+ constexpr auto
155
+ expect (const Expr_T& expr, const reflection::source_location& sl)
156
+ {
157
+ return detail::deferred_reporter<Expr_T>{ expr, false, sl };
158
+ }
159
+
160
+ /**
161
+ * @details
162
+ * The `assume` function template evaluates a logical condition or custom
163
+ * expression and reports the result within the µTest++ framework. It is
164
+ * designed to provide detailed diagnostics for test failures, including the
165
+ * actual and expected values, when using the provided comparators (`eq()`,
166
+ * `ne()`, `lt()`, `le()`, `gt()`, `ge()`) or custom operators.
167
+ *
168
+ * The function template can be used with any expression that evaluates to a
169
+ * boolean or with custom comparators/operators derived from the local
170
+ * `detail::op` type. For complex checks performed outside the `expect()`
171
+ * logical expression (such as within `if` or `try`/`catch` statements), the
172
+ * result can be reported by calling `expect(true)` or `expect(false)`.
173
+ *
174
+ * The function returns an output stream, allowing optional messages to be
175
+ * appended to the test report.
176
+ *
177
+ * **Example**
178
+ *
179
+ * @code{.cpp}
180
+ * namespace mt = micro_os_plus::micro_test_plus;
181
+ * mt::assume(compute_answer() == 42) << "answer is 42";
182
+ * @endcode
183
+ */
184
+ template <class Expr_T, type_traits::requires_t<
185
+ type_traits::is_op_v<Expr_T>
186
+ or type_traits::is_convertible_v<Expr_T, bool>>>
187
+ constexpr auto
188
+ assume (const Expr_T& expr, const reflection::source_location& sl)
189
+ {
190
+ return detail::deferred_reporter<Expr_T>{ expr, true, sl };
191
+ }
192
+
193
+ #if defined(__cpp_exceptions)
194
+
195
+ /**
196
+ * @details
197
+ * The `throws` function template verifies whether invoking the provided
198
+ * callable object results in the throwing of a specific exception type
199
+ * within the µTest++ framework. This is useful for testing error handling
200
+ * and exception safety in code under test.
201
+ *
202
+ * The function returns an output stream, allowing optional messages to be
203
+ * appended to the test report for diagnostic purposes.
204
+ */
205
+ template <class Exception_T, class Callable_T>
206
+ [[nodiscard]] constexpr auto
207
+ throws (const Callable_T& func)
208
+ {
209
+ return detail::throws_<Callable_T, Exception_T>{ func };
210
+ }
211
+
212
+ /**
213
+ * @details
214
+ * The `throws` function template verifies whether invoking the provided
215
+ * callable object results in the throwing of any exception within the
216
+ * µTest++ framework. This is useful for testing general exception safety and
217
+ * ensuring that code under test properly signals error conditions.
218
+ *
219
+ * The function returns an output stream, allowing optional messages to be
220
+ * appended to the test report for diagnostic purposes.
221
+ */
222
+ template <class Callable_T>
223
+ [[nodiscard]] constexpr auto
224
+ throws (const Callable_T& func)
225
+ {
226
+ return detail::throws_<Callable_T>{ func };
227
+ }
228
+
229
+ /**
230
+ * @details
231
+ * The `nothrow` function template verifies whether invoking the provided
232
+ * callable object does not result in the throwing of any exception within
233
+ * the µTest++ framework. This is useful for testing exception safety and
234
+ * ensuring that code under test does not unexpectedly signal error
235
+ * conditions.
236
+ *
237
+ * The function returns an output stream, allowing optional messages to be
238
+ * appended to the test report for diagnostic purposes.
239
+ */
240
+ template <class Callable_T>
241
+ [[nodiscard]] constexpr auto
242
+ nothrow (const Callable_T& func)
243
+ {
244
+ return detail::nothrow_<Callable_T>{ func };
245
+ }
246
+
247
+ #endif // defined(__cpp_exceptions)
248
+
249
+ // --------------------------------------------------------------------------
250
+ namespace utility
251
+ {
252
+ /**
253
+ * @details
254
+ * This function template facilitates string handling in tests by splitting
255
+ * a string into a vector of substrings, using the specified delimiter.
256
+ *
257
+ * The function iterates through the input string, identifying delimiter
258
+ * positions and extracting substrings between them. Each resulting
259
+ * substring is added to the output vector. This approach supports flexible
260
+ * parsing of delimited data, which is particularly useful for validating
261
+ * string processing logic in test cases.
262
+ *
263
+ * **Example**
264
+ *
265
+ * @code{.cpp}
266
+ * namespace mt = micro_os_plus::micro_test_plus;
267
+ *
268
+ * mt::expect (std::vector<std::string_view>{ "a", "b" }
269
+ * == mt::utility::split<std::string_view> ("a.b", "."))
270
+ * << "a.b splits into [a,b]";
271
+ * @endcode
272
+ */
273
+ template <class T = std::string_view, class Delim_T>
274
+ [[nodiscard]] auto
275
+ split (T input, Delim_T delim) -> std::vector<T>
276
+ {
277
+ std::vector<T> output{};
278
+ std::size_t first{};
279
+ while (first < std::size (input))
280
+ {
281
+ const auto second = input.find_first_of (delim, first);
282
+ if (first != second)
283
+ {
284
+ output.emplace_back (input.substr (first, second - first));
285
+ }
286
+ if (second == T::npos)
287
+ {
288
+ break;
289
+ }
290
+ first = second + 1;
291
+ }
292
+ return output;
293
+ }
294
+
295
+ // ------------------------------------------------------------------------
296
+ } // namespace utility
297
+
298
+ // --------------------------------------------------------------------------
299
+ } // namespace micro_os_plus::micro_test_plus
300
+
301
+ #if defined(__GNUC__)
302
+ #pragma GCC diagnostic pop
303
+ #endif
304
+
305
+ // ----------------------------------------------------------------------------
306
+
307
+ #endif // __cplusplus
308
+
309
+ // ----------------------------------------------------------------------------
310
+
311
+ #endif // MICRO_TEST_PLUS_INLINES_H_
312
+
313
+ // ----------------------------------------------------------------------------