@micro-os-plus/micro-test-plus 3.3.1 → 4.0.0

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 (53) hide show
  1. package/CHANGELOG.md +330 -2
  2. package/CMakeLists.txt +79 -23
  3. package/README.md +1 -1
  4. package/config/xcdl-build.json +11 -4
  5. package/include/micro-os-plus/micro-test-plus/deferred-reporter.h +292 -0
  6. package/include/micro-os-plus/micro-test-plus/detail.h +462 -1076
  7. package/include/micro-os-plus/micro-test-plus/exceptions.h +126 -0
  8. package/include/micro-os-plus/micro-test-plus/function-comparators.h +10 -7
  9. package/include/micro-os-plus/micro-test-plus/inlines/{details-inlines.h → deferred-reporter-inlines.h} +49 -22
  10. package/include/micro-os-plus/micro-test-plus/inlines/function-comparators-inlines.h +67 -4
  11. package/include/micro-os-plus/micro-test-plus/inlines/literals-inlines.h +3 -6
  12. package/include/micro-os-plus/micro-test-plus/inlines/math-inlines.h +21 -15
  13. package/include/micro-os-plus/micro-test-plus/inlines/reflection-inlines.h +35 -17
  14. package/include/micro-os-plus/micro-test-plus/inlines/{test-reporter-inlines.h → reporter-inlines.h} +176 -106
  15. package/include/micro-os-plus/micro-test-plus/inlines/{test-suite-inlines.h → runner-inlines.h} +41 -43
  16. package/include/micro-os-plus/micro-test-plus/inlines/test-inlines.h +369 -0
  17. package/include/micro-os-plus/micro-test-plus/inlines/utility-inlines.h +126 -0
  18. package/include/micro-os-plus/micro-test-plus/literals.h +4 -3
  19. package/include/micro-os-plus/micro-test-plus/math.h +9 -6
  20. package/include/micro-os-plus/micro-test-plus/operators.h +38 -44
  21. package/include/micro-os-plus/micro-test-plus/reflection.h +15 -4
  22. package/include/micro-os-plus/micro-test-plus/{test-reporter-basic.h → reporter-human.h} +72 -72
  23. package/include/micro-os-plus/micro-test-plus/{test-reporter-tap.h → reporter-tap.h} +69 -69
  24. package/include/micro-os-plus/micro-test-plus/{test-reporter.h → reporter.h} +296 -200
  25. package/include/micro-os-plus/micro-test-plus/runner-totals.h +264 -0
  26. package/include/micro-os-plus/micro-test-plus/runner.h +453 -0
  27. package/include/micro-os-plus/micro-test-plus/test.h +1069 -0
  28. package/include/micro-os-plus/micro-test-plus/timings.h +366 -0
  29. package/include/micro-os-plus/micro-test-plus/type-traits.h +239 -545
  30. package/include/micro-os-plus/micro-test-plus/utility.h +135 -0
  31. package/include/micro-os-plus/micro-test-plus.h +25 -228
  32. package/meson.build +10 -6
  33. package/package.json +1 -1
  34. package/src/deferred-reporter.cpp +118 -0
  35. package/src/reflection.cpp +95 -0
  36. package/src/reporter-human.cpp +822 -0
  37. package/src/reporter-tap.cpp +782 -0
  38. package/src/reporter.cpp +676 -0
  39. package/src/runner-totals.cpp +95 -0
  40. package/src/runner.cpp +563 -0
  41. package/src/test.cpp +496 -0
  42. package/src/timings.cpp +209 -0
  43. package/src/utility.cpp +163 -0
  44. package/.cmake-format.yaml +0 -11
  45. package/include/micro-os-plus/micro-test-plus/inlines/micro-test-plus-inlines.h +0 -313
  46. package/include/micro-os-plus/micro-test-plus/test-runner.h +0 -281
  47. package/include/micro-os-plus/micro-test-plus/test-suite.h +0 -492
  48. package/src/micro-test-plus.cpp +0 -316
  49. package/src/test-reporter-basic.cpp +0 -466
  50. package/src/test-reporter-tap.cpp +0 -530
  51. package/src/test-reporter.cpp +0 -399
  52. package/src/test-runner.cpp +0 -311
  53. package/src/test-suite.cpp +0 -304
@@ -0,0 +1,163 @@
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++ source file with implementations for the µTest++ methods.
21
+ *
22
+ * @details
23
+ * This source file contains the implementations of the utility functions
24
+ * for the µTest++ framework. It provides `extract_file_name()`, which
25
+ * strips the folder path from a file path returning only the base name,
26
+ * and `is_match()`, which performs wildcard pattern matching with `*`
27
+ * (any sequence of characters) and `?` (any single character) support.
28
+ *
29
+ * All definitions reside within the
30
+ * `micro_os_plus::micro_test_plus::utility` namespace.
31
+ *
32
+ * This file must be included when building the µTest++ library.
33
+ */
34
+
35
+ // ----------------------------------------------------------------------------
36
+
37
+ #if defined(MICRO_OS_PLUS_INCLUDE_CONFIG_H)
38
+ #include <micro-os-plus/config.h>
39
+ #endif // MICRO_OS_PLUS_INCLUDE_CONFIG_H
40
+
41
+ #include <micro-os-plus/micro-test-plus.h>
42
+
43
+ // ----------------------------------------------------------------------------
44
+
45
+ #if defined(__GNUC__)
46
+ #pragma GCC diagnostic ignored "-Waggregate-return"
47
+ #if defined(__clang__)
48
+ #pragma clang diagnostic ignored "-Wc++98-compat"
49
+ #endif
50
+ #endif
51
+
52
+ // ============================================================================
53
+
54
+ namespace micro_os_plus::micro_test_plus
55
+ {
56
+ // --------------------------------------------------------------------------
57
+
58
+ namespace utility
59
+ {
60
+ #if defined(__GNUC__)
61
+ #pragma GCC diagnostic push
62
+ #if defined(__clang__)
63
+ #pragma clang diagnostic ignored "-Wdocumentation"
64
+ #endif
65
+ #endif
66
+ /**
67
+ * @details
68
+ * The `extract_file_name` function extracts the file name from a given
69
+ * file path, handling both Unix-style (`/`) and Windows-style (`\`) path
70
+ * separators. It returns a pointer to the start of the file name within
71
+ * the input string, or the original string if no separators are found.
72
+ *
73
+ * This utility is particularly useful for test reporting, allowing for
74
+ * concise display of file names without full paths.
75
+ *
76
+ * @par Example
77
+ *
78
+ * @code{.cpp}
79
+ * const char* path = "/home/user/project/test.cpp";
80
+ * const char* filename = utility::extract_file_name (path);
81
+ * // filename now points to "test.cpp"
82
+ * @endcode
83
+ */
84
+ [[nodiscard]] const char*
85
+ extract_file_name (const char* path) noexcept
86
+ {
87
+ const std::string_view sv{ path };
88
+ const auto pos = sv.find_last_of ("/\\");
89
+ if (pos == std::string_view::npos)
90
+ {
91
+ return path; // No separators found, return original string.
92
+ }
93
+ return sv.substr (pos + 1).data ();
94
+ }
95
+
96
+ /**
97
+ * @details
98
+ * This function enables pattern-based string comparison for tests, supporting
99
+ * both exact matches and wildcard patterns. The pattern may include `*` to
100
+ * match any sequence of characters and `?` to match any single character. This
101
+ * allows for flexible validation of string content in test assertions,
102
+ * accommodating variable or partially known values.
103
+ *
104
+ * @warning The `*` wildcard is handled via recursion with a linear loop,
105
+ * giving $O(2^n)$ worst-case complexity in the number of `*` wildcards
106
+ * (e.g. a pattern such as `"a*a*a*b"` against a long string of `'a'`
107
+ * characters). For the typical short suite-name patterns used in a test
108
+ * framework this is not a concern, but callers should avoid patterns with
109
+ * many consecutive wildcards against long input strings.
110
+ *
111
+ * @par Examples
112
+ *
113
+ * @code{.cpp}
114
+ * namespace mt = micro_os_plus::micro_test_plus;
115
+ *
116
+ * t.expect (mt::utility::is_match ("abc", "a?c")) << "abc matches a?c";
117
+ * t.expect (mt::utility::is_match ("abc", "a*c")) << "abc matches a*c";
118
+ * @endcode
119
+ */
120
+ #if defined(__GNUC__)
121
+ #pragma GCC diagnostic pop
122
+ #endif
123
+ [[nodiscard]] bool
124
+ is_match (std::string_view input, std::string_view pattern)
125
+ {
126
+ if (std::empty (pattern))
127
+ {
128
+ return std::empty (input);
129
+ }
130
+
131
+ if (std::empty (input))
132
+ {
133
+ return pattern[0] == '*' ? is_match (input, pattern.substr (1))
134
+ : false;
135
+ }
136
+
137
+ if (pattern[0] != '?' and pattern[0] != '*' and pattern[0] != input[0])
138
+ {
139
+ return false;
140
+ }
141
+
142
+ if (pattern[0] == '*')
143
+ {
144
+ for (decltype (std::size (input)) i = 0u; i <= std::size (input);
145
+ ++i)
146
+ {
147
+ if (is_match (input.substr (i), pattern.substr (1)))
148
+ {
149
+ return true;
150
+ }
151
+ }
152
+ return false;
153
+ }
154
+
155
+ return is_match (input.substr (1), pattern.substr (1));
156
+ }
157
+
158
+ } // namespace utility
159
+
160
+ // ==========================================================================
161
+ } // namespace micro_os_plus::micro_test_plus
162
+
163
+ // ----------------------------------------------------------------------------
@@ -1,11 +0,0 @@
1
- # .cmake-format.yaml
2
- # https://cmake-format.readthedocs.io/en/latest/configuration.html
3
-
4
- tab_size: 2
5
- use_tabchars: false
6
- line_width: 80
7
-
8
- # Put closing parens on a dedicated line for multi-line calls.
9
- dangle_parens: true
10
-
11
- enable_markup: true
@@ -1,313 +0,0 @@
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
- // ----------------------------------------------------------------------------