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

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 (51) hide show
  1. package/CHANGELOG.md +95 -0
  2. package/CMakeLists.txt +74 -24
  3. package/README.md +3 -2
  4. package/include/micro-os-plus/micro-test-plus/README.md +6 -0
  5. package/include/micro-os-plus/micro-test-plus/deferred-reporter.h +29 -54
  6. package/include/micro-os-plus/micro-test-plus/detail.h +166 -705
  7. package/include/micro-os-plus/micro-test-plus/exceptions.h +5 -6
  8. package/include/micro-os-plus/micro-test-plus/expression-formatter.h +669 -0
  9. package/include/micro-os-plus/micro-test-plus/function-comparators.h +5 -0
  10. package/include/micro-os-plus/micro-test-plus/inlines/deferred-reporter-inlines.h +25 -30
  11. package/include/micro-os-plus/micro-test-plus/inlines/detail-inlines.h +711 -0
  12. package/include/micro-os-plus/micro-test-plus/inlines/exceptions-inline.h +137 -0
  13. package/include/micro-os-plus/micro-test-plus/inlines/expression-formatter-inlines.h +510 -0
  14. package/include/micro-os-plus/micro-test-plus/inlines/function-comparators-inlines.h +17 -76
  15. package/include/micro-os-plus/micro-test-plus/inlines/literals-inlines.h +47 -25
  16. package/include/micro-os-plus/micro-test-plus/inlines/math-inlines.h +7 -7
  17. package/include/micro-os-plus/micro-test-plus/inlines/operators-inlines.h +275 -0
  18. package/include/micro-os-plus/micro-test-plus/inlines/reflection-inlines.h +4 -4
  19. package/include/micro-os-plus/micro-test-plus/inlines/reporter-inlines.h +53 -394
  20. package/include/micro-os-plus/micro-test-plus/inlines/runner-inlines.h +38 -0
  21. package/include/micro-os-plus/micro-test-plus/inlines/runner-totals-inlines.h +152 -0
  22. package/include/micro-os-plus/micro-test-plus/inlines/test-inlines.h +231 -45
  23. package/include/micro-os-plus/micro-test-plus/inlines/timings-inlines.h +120 -0
  24. package/include/micro-os-plus/micro-test-plus/inlines/type-traits-inlines.h +202 -0
  25. package/include/micro-os-plus/micro-test-plus/literals.h +8 -14
  26. package/include/micro-os-plus/micro-test-plus/math.h +5 -0
  27. package/include/micro-os-plus/micro-test-plus/operators.h +19 -169
  28. package/include/micro-os-plus/micro-test-plus/reflection.h +5 -12
  29. package/include/micro-os-plus/micro-test-plus/reporter-human.h +17 -11
  30. package/include/micro-os-plus/micro-test-plus/reporter-tap.h +14 -8
  31. package/include/micro-os-plus/micro-test-plus/reporter.h +101 -424
  32. package/include/micro-os-plus/micro-test-plus/runner-totals.h +162 -176
  33. package/include/micro-os-plus/micro-test-plus/runner.h +61 -42
  34. package/include/micro-os-plus/micro-test-plus/test.h +450 -506
  35. package/include/micro-os-plus/micro-test-plus/timings.h +259 -262
  36. package/include/micro-os-plus/micro-test-plus/type-traits.h +30 -52
  37. package/include/micro-os-plus/micro-test-plus/utility.h +5 -4
  38. package/include/micro-os-plus/micro-test-plus.h +33 -24
  39. package/meson.build +1 -0
  40. package/package.json +11 -3
  41. package/src/deferred-reporter.cpp +21 -2
  42. package/src/expression-formatter.cpp +289 -0
  43. package/src/reflection.cpp +3 -1
  44. package/src/reporter-human.cpp +31 -37
  45. package/src/reporter-tap.cpp +25 -35
  46. package/src/reporter.cpp +36 -231
  47. package/src/runner-totals.cpp +6 -3
  48. package/src/runner.cpp +131 -25
  49. package/src/test.cpp +120 -113
  50. package/src/timings.cpp +6 -5
  51. package/src/utility.cpp +1 -1
@@ -54,12 +54,14 @@
54
54
 
55
55
  // ----------------------------------------------------------------------------
56
56
 
57
- #include "runner-totals.h"
58
- #include "timings.h"
59
-
60
57
  #include <functional>
61
58
  #include <memory>
62
59
 
60
+ #include "runner-totals.h"
61
+ #include "type-traits.h"
62
+ #include "timings.h"
63
+ #include "reflection.h"
64
+
63
65
  // ----------------------------------------------------------------------------
64
66
 
65
67
  #if defined(__GNUC__)
@@ -78,431 +80,440 @@
78
80
 
79
81
  namespace micro_os_plus::micro_test_plus
80
82
  {
83
+ // --------------------------------------------------------------------------
84
+
81
85
  class runner;
82
86
  class static_runner;
83
87
  class reporter;
84
88
  class runner_totals;
89
+ class subtest;
85
90
  class suite;
91
+ class static_suite;
86
92
 
87
- // --------------------------------------------------------------------------
88
-
89
- /**
90
- * @brief Base class for all test suites.
91
- *
92
- * @details
93
- * The `test_node` class provides the foundational interface for
94
- * managing test suites within the µTest++ framework. It maintains counters
95
- * for successful and failed checks, tracks test cases, and offers methods
96
- * for marking the commencement and completion of test cases and suites.
97
- *
98
- * This class ensures consistent state management and reporting for all
99
- * derived test suites. It also provides utility methods for querying the
100
- * suite's name, the number of successful and failed checks, the number of
101
- * test cases, and the overall result of the suite.
102
- *
103
- * All members and methods are defined within the
104
- * `micro_os_plus::micro_test_plus` namespace, ensuring clear separation from
105
- * user code and minimising the risk of naming conflicts.
106
- *
107
- * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
108
- */
109
- class test_node
93
+ namespace detail
110
94
  {
111
- public:
112
- /**
113
- * @brief Constructs a test suite.
114
- *
115
- * @param [in] name The test suite name.
116
- *
117
- * @details
118
- * The rule of five is enforced to prevent accidental copying or moving.
119
- */
120
- test_node (const char* name);
121
-
122
- /**
123
- * @brief Deleted copy constructor to prevent copying.
124
- */
125
- test_node (const test_node&) = delete;
126
-
127
- /**
128
- * @brief Deleted move constructor to prevent moving.
129
- */
130
- test_node (test_node&&) = delete;
131
-
132
- /**
133
- * @brief Deleted copy assignment operator to prevent copying.
134
- */
135
- test_node&
136
- operator= (const test_node&) = delete;
137
-
138
- /**
139
- * @brief Deleted move assignment operator to prevent moving.
140
- */
141
- test_node&
142
- operator= (test_node&&) = delete;
143
-
144
- /**
145
- * @brief Virtual destructor for the test_node class.
146
- */
147
- virtual ~test_node ();
148
-
149
- // ------------------------------------------------------------------------
150
-
151
- /**
152
- * @brief Gets the suite name.
153
- *
154
- * @par Parameters
155
- * None.
156
- * @return A pointer to the null-terminated test suite name.
157
- */
158
- [[nodiscard]] const char*
159
- name (void) const noexcept
160
- {
161
- return name_;
162
- }
163
-
164
- public:
165
- /**
166
- * @brief Gets the totals for the test suite.
167
- *
168
- * @par Parameters
169
- * None.
170
- * @return A reference to the runner_totals instance.
171
- */
172
- [[nodiscard]] runner_totals&
173
- totals () noexcept
174
- {
175
- return totals_;
176
- }
177
-
178
- /**
179
- * @brief Gets the totals for the test suite (const overload).
180
- *
181
- * @par Parameters
182
- * None.
183
- * @return A const reference to the runner_totals instance.
184
- */
185
- [[nodiscard]] const runner_totals&
186
- totals () const noexcept
187
- {
188
- return totals_;
189
- }
190
-
191
- protected:
192
- /**
193
- * @brief The test suite name.
194
- *
195
- * @note Derived classes may access this member directly in
196
- * addition to the public `name()` getter.
197
- */
198
- const char* name_;
95
+ // ========================================================================
199
96
 
200
97
  /**
201
- * @brief Totals for the test suite, including nested cases.
202
- */
203
- runner_totals totals_;
204
- };
205
-
206
- // ==========================================================================
207
-
208
- /**
209
- * @brief Non-template base for all runnable objects (suites and subtests).
210
- *
211
- * @details
212
- * `runnable_base` extends `test_node` with the state that is shared by
213
- * every runnable object but does not depend on the CRTP self-type:
214
- * - a reference to the owning `runner`,
215
- * - the object's own index within its parent container,
216
- * - a sequential subtest index used when creating nested subtests, and
217
- * - an owning vector of child `subtest` instances.
218
- *
219
- * Concrete runnable classes (`suite`, `subtest`) derive from
220
- * `runnable<Self_T>` which in turn derives from `runnable_base`.
221
- *
222
- * The class is non-copyable and non-movable to preserve unique ownership
223
- * and consistent state throughout the test session.
224
- *
225
- * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
226
- */
227
- class runnable_base : public test_node
228
- {
229
- public:
230
- /**
231
- * @brief Constructs a `runnable_base` with a name, runner, and index.
98
+ * @brief Converts a `static_runner` reference to a `runner` reference.
232
99
  *
233
- * @param name The name used in reports.
234
- * @param runner The test runner managing this object.
235
- * @param own_index The positional index of this object within its parent.
236
- */
237
- runnable_base (const char* name, runner& runner, size_t own_index);
238
-
239
- /**
240
- * @brief Deleted copy constructor to prevent copying.
241
- */
242
- runnable_base (const runnable_base&) = delete;
243
-
244
- /**
245
- * @brief Deleted move constructor to prevent moving.
246
- */
247
- runnable_base (runnable_base&&) = delete;
248
-
249
- /**
250
- * @brief Deleted copy assignment operator to prevent copying.
251
- */
252
- runnable_base&
253
- operator= (const runnable_base&) = delete;
254
-
255
- /**
256
- * @brief Deleted move assignment operator to prevent moving.
257
- */
258
- runnable_base&
259
- operator= (runnable_base&&) = delete;
260
-
261
- /**
262
- * @brief Virtual destructor.
263
- */
264
- virtual ~runnable_base () override;
265
-
266
- // ------------------------------------------------------------------------
267
-
268
- /**
269
- * @brief Returns the positional index of this object within its parent.
100
+ * @details
101
+ * This declaration breaks the include-order cycle between `test` and
102
+ * `runner` headers. The definition is provided in a translation unit where
103
+ * both types are complete, so the conversion remains type-safe.
270
104
  *
271
- * @par Parameters
272
- * None.
273
- * @return The one-based own index.
105
+ * @param static_runner_ref The source `static_runner` reference.
106
+ * @return The same object viewed as its `runner` base.
274
107
  */
275
- [[nodiscard]] size_t
276
- own_index () const noexcept
277
- {
278
- return own_index_;
279
- }
108
+ runner&
109
+ to_runner (static_runner& static_runner_ref) noexcept;
280
110
 
281
111
  /**
282
- * @brief Sets the positional index of this object within its parent.
112
+ * @brief Registers a static suite with a static runner.
283
113
  *
284
- * @note This overload follows the same-name getter/setter pattern
285
- * used throughout the framework: the getter is the `const` overload
286
- * and the setter is the non-`const` single-argument overload.
114
+ * @details
115
+ * This declaration allows `test-inlines.h` to request registration
116
+ * without requiring the complete `static_runner` type in that header.
287
117
  *
288
- * @param index The new index value.
289
- * @par Returns
290
- * Nothing.
118
+ * @param static_runner_ref The destination static runner.
119
+ * @param static_suite_ref The static suite to register.
291
120
  */
292
121
  void
293
- own_index (size_t index) noexcept
294
- {
295
- own_index_ = index;
296
- }
122
+ register_static_suite (static_runner& static_runner_ref,
123
+ static_suite& static_suite_ref);
297
124
 
298
125
  /**
299
- * @brief Returns the index of the most recently created child subtest.
300
- *
301
- * @par Parameters
302
- * None.
303
- * @return The current child subtest sequential index.
304
- */
305
- [[nodiscard]] size_t
306
- current_subtest_index () const noexcept
307
- {
308
- return current_subtest_index_;
309
- }
310
-
311
- /**
312
- * @brief Increments and returns the child subtest sequential index.
126
+ * @brief Base class for runners and runable tests.
313
127
  *
314
128
  * @details
315
- * Each call to `test()` invokes this method before constructing the new
316
- * `subtest`, so the index values form a strictly increasing, one-based
317
- * sequence.
318
- *
319
- * @par Parameters
320
- * None.
321
- * @return The new index value after incrementing.
322
- */
323
- size_t
324
- increment_subtest_index () noexcept
325
- {
326
- return ++current_subtest_index_;
327
- }
328
-
329
- /**
330
- * @brief Returns the number of direct child subtests owned by this node.
129
+ * The `test_node` class provides the foundational interface for
130
+ * managing test within the µTest++ framework. It maintains counters
131
+ * for successful and failed checks, tracks test cases, and offers methods
132
+ * for marking the commencement and completion of test cases and suites.
331
133
  *
332
- * @par Parameters
333
- * None.
334
- * @return The number of child subtests.
335
- */
336
- [[nodiscard]] size_t
337
- children_subtests_count (void) const noexcept
338
- {
339
- return children_subtests_.size ();
340
- }
341
-
342
- /**
343
- * @brief Gets the test reporter associated with this test suite.
344
- *
345
- * @par Parameters
346
- * None.
347
- * @return A reference to the test reporter.
348
- */
349
- [[nodiscard]] class reporter&
350
- reporter (void) const noexcept;
351
-
352
- /**
353
- * @brief Aborts test execution via the owning runner.
134
+ * This class ensures consistent state management and reporting for all
135
+ * derived classes. It also provides utility methods for querying the
136
+ * node's name, the number of successful and failed checks, the number of
137
+ * test cases, and the overall result of the node.
354
138
  *
355
- * @param sl The source location from which the abort is triggered.
356
- * @par Returns
357
- * Does not return.
358
- */
359
- [[noreturn]] void
360
- abort (const reflection::source_location& sl
361
- = reflection::source_location::current ());
362
-
363
- /**
364
- * @brief Gets the test runner associated with this test suite.
139
+ * All members and methods are defined within the
140
+ * `micro_os_plus::micro_test_plus` namespace, ensuring clear separation
141
+ * from user code and minimising the risk of naming conflicts.
365
142
  *
366
- * @par Parameters
367
- * None.
368
- * @return A reference to the test runner.
143
+ * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
369
144
  */
370
- [[nodiscard]] class runner&
371
- runner (void) const noexcept
145
+ class test_node
372
146
  {
373
- return runner_;
374
- }
375
-
376
- protected:
377
- /**
378
- * @brief Registers a newly constructed child subtest and executes it
379
- * immediately.
380
- *
381
- * @param child_test Owning pointer to the newly created `subtest`.
382
- * @param suite The parent `suite` to which execution results are reported.
383
- * @par Returns
384
- * Nothing.
385
- */
386
- void
387
- after_subtest_create_ (std::unique_ptr<class subtest> child_test,
388
- suite& suite);
389
-
390
- protected:
391
- /**
392
- * @brief Reference to the test runner that owns this object.
393
- */
394
- class runner& runner_;
395
-
396
- /**
397
- * @brief The test suite index, counting from 1.
398
- */
399
- size_t own_index_;
400
-
401
- /**
402
- * @brief The subtest index, counting from 1.
147
+ public:
148
+ /**
149
+ * @brief Constructs a test node.
150
+ *
151
+ * @param [in] name The test node name.
152
+ */
153
+ test_node (const char* name);
154
+
155
+ /**
156
+ * @brief Deleted copy constructor to prevent copying.
157
+ */
158
+ test_node (const test_node&) = delete;
159
+
160
+ /**
161
+ * @brief Deleted move constructor to prevent moving.
162
+ */
163
+ test_node (test_node&&) = delete;
164
+
165
+ /**
166
+ * @brief Deleted copy assignment operator to prevent copying.
167
+ */
168
+ test_node&
169
+ operator= (const test_node&)
170
+ = delete;
171
+
172
+ /**
173
+ * @brief Deleted move assignment operator to prevent moving.
174
+ */
175
+ test_node&
176
+ operator= (test_node&&)
177
+ = delete;
178
+
179
+ /**
180
+ * @brief Virtual destructor for the test_node class.
181
+ */
182
+ virtual ~test_node ();
183
+
184
+ // ----------------------------------------------------------------------
185
+
186
+ /**
187
+ * @brief Gets the node name.
188
+ *
189
+ * @par Parameters
190
+ * None.
191
+ * @return A pointer to the null-terminated test node name.
192
+ */
193
+ [[nodiscard]] const char*
194
+ name (void) const noexcept;
195
+
196
+ public:
197
+ /**
198
+ * @brief Gets the totals for the test.
199
+ *
200
+ * @par Parameters
201
+ * None.
202
+ * @return A reference to the runner_totals instance.
203
+ */
204
+ [[nodiscard]] runner_totals&
205
+ totals () noexcept;
206
+
207
+ /**
208
+ * @brief Gets the totals for the test (const overload).
209
+ *
210
+ * @par Parameters
211
+ * None.
212
+ * @return A const reference to the runner_totals instance.
213
+ */
214
+ [[nodiscard]] const runner_totals&
215
+ totals () const noexcept;
216
+
217
+ protected:
218
+ /**
219
+ * @brief The test node name.
220
+ *
221
+ * @note Derived classes may access this member directly in
222
+ * addition to the public `name()` getter.
223
+ */
224
+ const char* name_;
225
+
226
+ /**
227
+ * @brief Totals for the test node, including nested cases.
228
+ */
229
+ runner_totals totals_;
230
+ };
231
+
232
+ // ========================================================================
233
+
234
+ /**
235
+ * @brief Non-template base for all runnable objects (suites and subtests).
403
236
  *
404
237
  * @details
405
- * This index is used for reporting and tracking the execution order of
406
- * subtests within a suite, especially when nested subtests are
407
- * involved. It is incremented for each subtest created, allowing for
408
- * clear identification of subtests in reports and diagnostics.
409
- */
410
- size_t current_subtest_index_ = 0;
411
-
412
- /**
413
- * @brief Owning collection of direct child subtests.
414
- *
415
- * @details
416
- * Each call to `test()` appends a new `subtest` to this vector and
417
- * runs it immediately. The vector retains ownership for the lifetime of
418
- * the parent runnable.
419
- */
420
- std::vector<std::unique_ptr<subtest>> children_subtests_;
421
- };
422
-
423
- // ==========================================================================
424
-
425
- /**
426
- * @brief CRTP base class factoring out callable storage, rule-of-five, and
427
- * `run()` logic shared by `test` and `static_suite`.
428
- *
429
- * @tparam Self_T The concrete derived class type (CRTP pattern). The stored
430
- * callable receives a `Self_T&` reference when the suite is executed.
431
- *
432
- * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
433
- */
434
- template <typename Self_T>
435
- class runnable : public runnable_base
436
- {
437
- public:
438
- /**
439
- * @brief Class template constructor.
238
+ * `runnable_base` extends `test_node` with the state that is shared by
239
+ * every runnable object but does not depend on the CRTP self-type:
240
+ * - a reference to the owning `runner`,
241
+ * - the object's own index within its parent container,
242
+ * - a sequential subtest index used when creating nested subtests, and
243
+ * - an owning vector of child `subtest` instances.
440
244
  *
441
- * @tparam Callable_T The callable type.
442
- * @tparam Args_T The additional argument types.
245
+ * Concrete runnable classes (`suite`, `subtest`) derive from
246
+ * `runnable<Self_T>` which in turn derives from `runnable_base`.
443
247
  *
444
- * @param [in] name The test suite name, used in reports.
445
- * @param [in] runner The test runner managing this suite.
446
- * @param [in] own_index The suite index within the runner.
447
- * @param [in] callable The callable invoked when the suite runs.
448
- * @param [in] arguments Additional arguments forwarded to the callable
449
- * after the leading `Self_T&` reference.
248
+ * The class is non-copyable and non-movable to preserve unique ownership
249
+ * and consistent state throughout the test session.
450
250
  *
451
- * @details
452
- * The rule of five is enforced to prevent accidental copying or moving.
453
- */
454
- template <typename Callable_T, typename... Args_T>
455
- runnable (const char* name, class runner& runner, size_t own_index,
456
- Callable_T&& callable, Args_T&&... arguments);
457
-
458
- /**
459
- * @brief Deleted copy constructor to prevent copying.
460
- */
461
- runnable (const runnable&) = delete;
462
-
463
- /**
464
- * @brief Deleted move constructor to prevent moving.
251
+ * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
465
252
  */
466
- runnable (runnable&&) = delete;
467
-
468
- /**
469
- * @brief Deleted copy assignment operator to prevent copying.
470
- */
471
- runnable&
472
- operator= (const runnable&) = delete;
473
-
474
- /**
475
- * @brief Deleted move assignment operator to prevent moving.
476
- */
477
- runnable&
478
- operator= (runnable&&) = delete;
479
-
480
- /**
481
- * @brief Virtual destructor.
482
- */
483
- virtual ~runnable () override;
253
+ class runnable_base : public test_node
254
+ {
255
+ public:
256
+ /**
257
+ * @brief Constructs a `runnable_base` with a name, runner, and index.
258
+ *
259
+ * @param name The name used in reports.
260
+ * @param runner The test runner managing this object.
261
+ * @param own_index The positional index of this object within its
262
+ * parent.
263
+ */
264
+ runnable_base (const char* name, runner& runner, size_t own_index);
265
+
266
+ /**
267
+ * @brief Deleted copy constructor to prevent copying.
268
+ */
269
+ runnable_base (const runnable_base&) = delete;
270
+
271
+ /**
272
+ * @brief Deleted move constructor to prevent moving.
273
+ */
274
+ runnable_base (runnable_base&&) = delete;
275
+
276
+ /**
277
+ * @brief Deleted copy assignment operator to prevent copying.
278
+ */
279
+ runnable_base&
280
+ operator= (const runnable_base&)
281
+ = delete;
282
+
283
+ /**
284
+ * @brief Deleted move assignment operator to prevent moving.
285
+ */
286
+ runnable_base&
287
+ operator= (runnable_base&&)
288
+ = delete;
289
+
290
+ /**
291
+ * @brief Virtual destructor.
292
+ */
293
+ virtual ~runnable_base () override;
294
+
295
+ // ----------------------------------------------------------------------
296
+
297
+ /**
298
+ * @brief Returns the positional index of this object within its parent.
299
+ *
300
+ * @par Parameters
301
+ * None.
302
+ * @return The one-based own index.
303
+ */
304
+ [[nodiscard]] size_t
305
+ own_index () const noexcept;
306
+
307
+ /**
308
+ * @brief Sets the positional index of this object within its parent.
309
+ *
310
+ * @note This overload follows the same-name getter/setter pattern
311
+ * used throughout the framework: the getter is the `const` overload
312
+ * and the setter is the non-`const` single-argument overload.
313
+ *
314
+ * @param index The new index value.
315
+ * @par Returns
316
+ * Nothing.
317
+ */
318
+ void
319
+ own_index (size_t index) noexcept;
320
+
321
+ /**
322
+ * @brief Returns the index of the most recently created child subtest.
323
+ *
324
+ * @par Parameters
325
+ * None.
326
+ * @return The current child subtest sequential index.
327
+ */
328
+ [[nodiscard]] size_t
329
+ current_subtest_index () const noexcept;
330
+
331
+ /**
332
+ * @brief Increments and returns the child subtest sequential index.
333
+ *
334
+ * @par Parameters
335
+ * None.
336
+ * @return The new index value after incrementing.
337
+ */
338
+ size_t
339
+ increment_subtest_index () noexcept;
340
+
341
+ /**
342
+ * @brief Returns the number of direct child subtests owned by this node.
343
+ *
344
+ * @par Parameters
345
+ * None.
346
+ * @return The number of child subtests.
347
+ */
348
+ [[nodiscard]] size_t
349
+ children_subtests_count (void) const noexcept;
350
+
351
+ /**
352
+ * @brief Gets the test reporter associated with this test runnable.
353
+ *
354
+ * @par Parameters
355
+ * None.
356
+ * @return A reference to the test reporter.
357
+ */
358
+ [[nodiscard]] class reporter&
359
+ reporter (void) const noexcept;
360
+
361
+ /**
362
+ * @brief Aborts test execution via the owning runner.
363
+ *
364
+ * @param sl The source location from which the abort is triggered.
365
+ * @par Returns
366
+ * Does not return.
367
+ */
368
+ [[noreturn]] void
369
+ abort (const reflection::source_location& sl
370
+ = reflection::source_location::current ());
371
+
372
+ /**
373
+ * @brief Gets the test runner associated with this test runnable.
374
+ *
375
+ * @par Parameters
376
+ * None.
377
+ * @return A reference to the test runner.
378
+ */
379
+ [[nodiscard]] class runner&
380
+ runner (void) const noexcept;
381
+
382
+ protected:
383
+ /**
384
+ * @brief Registers a newly constructed child subtest and executes it
385
+ * immediately.
386
+ *
387
+ * @param child_test Owning pointer to the newly created `subtest`.
388
+ * @param suite The parent `suite` to which execution results are
389
+ * reported.
390
+ * @par Returns
391
+ * Nothing.
392
+ */
393
+ void
394
+ after_subtest_create_ (std::unique_ptr<subtest> child_test,
395
+ suite& suite);
396
+
397
+ protected:
398
+ /**
399
+ * @brief Reference to the test runner that owns this object.
400
+ */
401
+ class runner& runner_;
402
+
403
+ /**
404
+ * @brief The test index, counting from 1.
405
+ */
406
+ size_t own_index_;
407
+
408
+ /**
409
+ * @brief The subtest index, counting from 1.
410
+ *
411
+ * @details
412
+ * This index is used for reporting and tracking the execution order of
413
+ * subtests within a suite, especially when nested subtests are
414
+ * involved. It is incremented for each subtest created, allowing for
415
+ * clear identification of subtests in reports and diagnostics.
416
+ */
417
+ size_t current_subtest_index_ = 0;
418
+
419
+ /**
420
+ * @brief Owning collection of direct child subtests.
421
+ *
422
+ * @details
423
+ * Each call to `test()` appends a new `subtest` to this vector and
424
+ * runs it immediately. The vector retains ownership for the lifetime of
425
+ * the parent runnable.
426
+ */
427
+ std::vector<std::unique_ptr<subtest>> children_subtests_;
428
+ };
429
+
430
+ // ========================================================================
431
+
432
+ /**
433
+ * @brief CRTP base class factoring out callable storage, rule-of-five, and
434
+ * `run()` logic shared by `subtest` and `suite`.
435
+ *
436
+ * @tparam Self_T The concrete derived class type (CRTP pattern). The
437
+ * stored callable receives a `Self_T&` reference when the test is
438
+ * executed.
439
+ *
440
+ * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
441
+ */
442
+ template <typename Self_T>
443
+ class runnable : public detail::runnable_base
444
+ {
445
+ public:
446
+ /**
447
+ * @brief Class template constructor.
448
+ *
449
+ * @tparam Callable_T The callable type.
450
+ * @tparam Args_T The additional argument types.
451
+ *
452
+ * @param [in] name The test name, used in reports.
453
+ * @param [in] runner The test runner managing this test.
454
+ * @param [in] own_index The test index within the runner.
455
+ * @param [in] callable The callable invoked when the test runs.
456
+ * @param [in] arguments Additional arguments forwarded to the callable
457
+ * after the leading `Self_T&` reference.
458
+ */
459
+ template <typename Callable_T, typename... Args_T>
460
+ runnable (const char* name, class runner& runner, size_t own_index,
461
+ Callable_T&& callable, Args_T&&... arguments);
462
+
463
+ /**
464
+ * @brief Deleted copy constructor to prevent copying.
465
+ */
466
+ runnable (const runnable&) = delete;
467
+
468
+ /**
469
+ * @brief Deleted move constructor to prevent moving.
470
+ */
471
+ runnable (runnable&&) = delete;
472
+
473
+ /**
474
+ * @brief Deleted copy assignment operator to prevent copying.
475
+ */
476
+ runnable&
477
+ operator= (const runnable&)
478
+ = delete;
479
+
480
+ /**
481
+ * @brief Deleted move assignment operator to prevent moving.
482
+ */
483
+ runnable&
484
+ operator= (runnable&&)
485
+ = delete;
486
+
487
+ /**
488
+ * @brief Virtual destructor.
489
+ */
490
+ virtual ~runnable () override;
491
+
492
+ // ----------------------------------------------------------------------
493
+
494
+ /**
495
+ * @brief Runs the test function by invoking the stored callable with the
496
+ * derived self instance.
497
+ *
498
+ * @par Parameters
499
+ * None.
500
+ * @par Returns
501
+ * Nothing.
502
+ */
503
+ virtual void
504
+ run (void)
505
+ = 0;
506
+
507
+ protected:
508
+ /**
509
+ * @brief Callable storing the test body and any bound arguments.
510
+ * Invoked with a reference to the derived `Self_T` instance.
511
+ */
512
+ std::function<void (Self_T&)> callable_;
513
+ };
484
514
 
485
515
  // ------------------------------------------------------------------------
486
-
487
- /**
488
- * @brief Runs the test function by invoking the stored callable with the
489
- * derived self instance.
490
- *
491
- * @par Parameters
492
- * None.
493
- * @par Returns
494
- * Nothing.
495
- */
496
- virtual void
497
- run (void) = 0;
498
-
499
- protected:
500
- /**
501
- * @brief Callable storing the test suite body and any bound arguments.
502
- * Invoked with a reference to the derived `Self_T` instance.
503
- */
504
- std::function<void (Self_T&)> callable_;
505
- };
516
+ } // namespace detail
506
517
 
507
518
  // ==========================================================================
508
519
 
@@ -512,10 +523,10 @@ namespace micro_os_plus::micro_test_plus
512
523
  *
513
524
  * @details
514
525
  * `subtest` represents a single, named test case or a nested group of
515
- * checks within a parent `suite`. It is constructed by calling
526
+ * checks within a parent `suite` or `subtest`. It is constructed by calling
516
527
  * `suite::test()` or `subtest::test()`, both of which create the object,
517
528
  * immediately execute its callable body via `run()`, and register the
518
- * result with the parent suite.
529
+ * result with the parent node.
519
530
  *
520
531
  * The body of the subtest is supplied as a callable (typically a lambda)
521
532
  * that receives a `subtest&` reference as its first argument. Inside the
@@ -527,7 +538,7 @@ namespace micro_os_plus::micro_test_plus
527
538
  *
528
539
  * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
529
540
  */
530
- class subtest : public runnable<subtest>
541
+ class subtest : public detail::runnable<subtest>
531
542
  {
532
543
  public:
533
544
  /**
@@ -547,9 +558,6 @@ namespace micro_os_plus::micro_test_plus
547
558
  * invoked when the subtest executes.
548
559
  * @param [in] arguments A possibly empty list of arguments forwarded to
549
560
  * the callable after the leading `subtest&` reference.
550
- *
551
- * @details
552
- * The rule of five is enforced to prevent accidental copying or moving.
553
561
  */
554
562
  template <typename Callable_T, typename... Args_T>
555
563
  subtest (const char* name, class runner& runner, suite& parent_suite,
@@ -570,13 +578,15 @@ namespace micro_os_plus::micro_test_plus
570
578
  * @brief Deleted copy assignment operator to prevent copying.
571
579
  */
572
580
  subtest&
573
- operator= (const subtest&) = delete;
581
+ operator= (const subtest&)
582
+ = delete;
574
583
 
575
584
  /**
576
585
  * @brief Deleted move assignment operator to prevent moving.
577
586
  */
578
587
  subtest&
579
- operator= (subtest&&) = delete;
588
+ operator= (subtest&&)
589
+ = delete;
580
590
 
581
591
  /**
582
592
  * @brief Virtual destructor.
@@ -616,39 +626,12 @@ namespace micro_os_plus::micro_test_plus
616
626
  * @param [in] expr Logical expression to evaluate.
617
627
  * @param [in] sl Optional source location, defaulting to the current line.
618
628
  * @return An output stream to write optional messages.
619
- *
620
- * @details
621
- * The `expect` function template evaluates a logical condition or custom
622
- * expression and reports the result within the µTest++ framework. It is
623
- * designed to provide detailed diagnostics for test failures, including
624
- * the actual and expected values, when using the provided comparators
625
- * (`eq()`, `ne()`, `lt()`, `le()`, `gt()`, `ge()`) or custom operators.
626
- *
627
- * The function template can be used with any expression that evaluates to
628
- * a boolean or with custom comparators/operators derived from the local
629
- * `detail::op` type. For complex checks performed outside the `expect()`
630
- * logical expression (such as within `if` or `try`/`catch` statements),
631
- * the result can be reported by calling `expect(true)` or `expect(false)`.
632
- *
633
- * The function returns an output stream, allowing optional messages to be
634
- * appended to the test report.
635
- *
636
- * **Example**
637
- *
638
- * @code{.cpp}
639
- * namespace mt = micro_os_plus::micro_test_plus;
640
- *
641
- * t.expect(compute_answer() == 42) << "answer is 42";
642
- * @endcode
643
629
  */
644
630
  template <class Expr_T>
645
631
  requires type_traits::checkable<Expr_T>
646
632
  auto
647
633
  expect (const Expr_T& expr, const reflection::source_location& sl
648
- = reflection::source_location::current ())
649
- {
650
- return detail::deferred_reporter<Expr_T>{ expr, false, sl, *this };
651
- }
634
+ = reflection::source_location::current ());
652
635
 
653
636
  /**
654
637
  * @ingroup micro-test-plus-assumptions
@@ -663,49 +646,18 @@ namespace micro_os_plus::micro_test_plus
663
646
  * @param [in] expr Logical expression to evaluate.
664
647
  * @param [in] sl Optional source location, defaulting to the current line.
665
648
  * @return An output stream to write optional messages.
666
- *
667
- * @details
668
- * The `assume` function template evaluates a logical condition or custom
669
- * expression and reports the result within the µTest++ framework. It is
670
- * designed to provide detailed diagnostics for test failures, including
671
- * the actual and expected values, when using the provided comparators
672
- * (`eq()`, `ne()`, `lt()`, `le()`, `gt()`, `ge()`) or custom operators.
673
- *
674
- * The function template can be used with any expression that evaluates to
675
- * a boolean or with custom comparators/operators derived from the local
676
- * `detail::op` type. For complex checks performed outside the `expect()`
677
- * logical expression (such as within `if` or `try`/`catch` statements),
678
- * the result can be reported by calling `expect(true)` or `expect(false)`.
679
- *
680
- * The function returns an output stream, allowing optional messages to be
681
- * appended to the test report.
682
- *
683
- * **Example**
684
- *
685
- * @code{.cpp}
686
- * namespace mt = micro_os_plus::micro_test_plus;
687
- * mt::assume(compute_answer() == 42) << "answer is 42";
688
- * @endcode
689
649
  */
690
650
  template <class Expr_T>
691
651
  requires type_traits::checkable<Expr_T>
692
652
  auto
693
653
  assume (const Expr_T& expr, const reflection::source_location& sl
694
- = reflection::source_location::current ())
695
- {
696
- return detail::deferred_reporter<Expr_T>{ expr, true, sl, *this };
697
- }
654
+ = reflection::source_location::current ());
698
655
 
699
656
  // ------------------------------------------------------------------------
700
657
 
701
658
  /**
702
659
  * @brief Executes the subtest body by invoking the stored callable.
703
660
  *
704
- * @details
705
- * Calls `begin_subtest()` on the reporter, invokes `callable_(*this)`,
706
- * then calls `end_subtest()`. The results are propagated to the parent
707
- * suite's totals.
708
- *
709
661
  * @par Parameters
710
662
  * None.
711
663
  * @par Returns
@@ -717,19 +669,12 @@ namespace micro_os_plus::micro_test_plus
717
669
  /**
718
670
  * @brief Returns the nesting depth of this subtest.
719
671
  *
720
- * @details
721
- * Top-level subtests (direct children of a `suite`) have depth 1.
722
- * Each additional level of nesting increments the depth by 1.
723
- *
724
672
  * @par Parameters
725
673
  * None.
726
674
  * @return The nesting depth (1 = top-level).
727
675
  */
728
676
  [[nodiscard]] size_t
729
- nesting_depth () const noexcept
730
- {
731
- return nesting_depth_;
732
- }
677
+ nesting_depth () const noexcept;
733
678
 
734
679
  protected:
735
680
  /**
@@ -765,7 +710,7 @@ namespace micro_os_plus::micro_test_plus
765
710
  *
766
711
  * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
767
712
  */
768
- class suite : public runnable<suite>
713
+ class suite : public detail::runnable<suite>
769
714
  {
770
715
  public:
771
716
  /**
@@ -781,9 +726,6 @@ namespace micro_os_plus::micro_test_plus
781
726
  * `suite&`.
782
727
  * @param [in] arguments A possibly empty list of arguments forwarded to
783
728
  * the callable after the leading `suite&` reference.
784
- *
785
- * @details
786
- * The rule of five is enforced to prevent accidental copying or moving.
787
729
  */
788
730
  template <typename Callable_T, typename... Args_T>
789
731
  suite (const char* name, class runner& runner, Callable_T&& callable,
@@ -803,13 +745,15 @@ namespace micro_os_plus::micro_test_plus
803
745
  * @brief Deleted copy assignment operator to prevent copying.
804
746
  */
805
747
  suite&
806
- operator= (const suite&) = delete;
748
+ operator= (const suite&)
749
+ = delete;
807
750
 
808
751
  /**
809
752
  * @brief Deleted move assignment operator to prevent moving.
810
753
  */
811
754
  suite&
812
- operator= (suite&&) = delete;
755
+ operator= (suite&&)
756
+ = delete;
813
757
 
814
758
  /**
815
759
  * @brief Virtual destructor.
@@ -843,11 +787,8 @@ namespace micro_os_plus::micro_test_plus
843
787
  * None.
844
788
  * @return A reference to the timestamps instance.
845
789
  */
846
- [[nodiscard]] timestamps&
847
- timings () noexcept
848
- {
849
- return timings_;
850
- }
790
+ [[nodiscard]] detail::timestamps&
791
+ timings () noexcept;
851
792
 
852
793
  /**
853
794
  * @brief Gets the timings for this suite (const overload).
@@ -856,20 +797,12 @@ namespace micro_os_plus::micro_test_plus
856
797
  * None.
857
798
  * @return A const reference to the timestamps instance.
858
799
  */
859
- [[nodiscard]] const timestamps&
860
- timings () const noexcept
861
- {
862
- return timings_;
863
- }
800
+ [[nodiscard]] const detail::timestamps&
801
+ timings () const noexcept;
864
802
 
865
803
  /**
866
804
  * @brief Executes the suite body by invoking the stored callable.
867
805
  *
868
- * @details
869
- * Calls `begin_suite()` on the reporter, records timing, invokes
870
- * `callable_(*this)`, records end timing, and calls `end_suite()`. The
871
- * results are propagated to the owning `runner`'s totals.
872
- *
873
806
  * @par Parameters
874
807
  * None.
875
808
  * @par Returns
@@ -882,7 +815,7 @@ namespace micro_os_plus::micro_test_plus
882
815
  /**
883
816
  * @brief Timing measurements for this suite's execution.
884
817
  */
885
- timestamps timings_;
818
+ detail::timestamps timings_;
886
819
  };
887
820
 
888
821
  // ==========================================================================
@@ -905,6 +838,11 @@ namespace micro_os_plus::micro_test_plus
905
838
  class top_suite : public suite
906
839
  {
907
840
  public:
841
+ // Expose the accessor for the suite name from the base test_node class,
842
+ // since the top_suite may need to change its name after construction, and
843
+ // the base class provides the necessary interface for that purpose.
844
+ using detail::test_node::name;
845
+
908
846
  /**
909
847
  * @brief Constructs the top-level suite with a name and runner reference.
910
848
  *
@@ -927,18 +865,28 @@ namespace micro_os_plus::micro_test_plus
927
865
  * @brief Deleted copy assignment operator to prevent copying.
928
866
  */
929
867
  top_suite&
930
- operator= (const top_suite&) = delete;
868
+ operator= (const top_suite&)
869
+ = delete;
931
870
 
932
871
  /**
933
872
  * @brief Deleted move assignment operator to prevent moving.
934
873
  */
935
874
  top_suite&
936
- operator= (top_suite&&) = delete;
875
+ operator= (top_suite&&)
876
+ = delete;
937
877
 
938
878
  /**
939
879
  * @brief Virtual destructor.
940
880
  */
941
881
  virtual ~top_suite () override;
882
+
883
+ /**
884
+ * @brief Sets the name of the top-level suite.
885
+ *
886
+ * @param [in] new_name The new name for the top-level suite.
887
+ */
888
+ void
889
+ name (const char* new_name) noexcept;
942
890
  };
943
891
 
944
892
  // ==========================================================================
@@ -987,11 +935,6 @@ namespace micro_os_plus::micro_test_plus
987
935
  * function, invoked to perform the test suite.
988
936
  * @param [in] arguments A possibly empty list of arguments to be passed to
989
937
  * the callable.
990
- *
991
- * @details
992
- * The rule of five is enforced to prevent accidental copying or moving.
993
- * Upon construction, the suite is automatically registered with the
994
- * runner.
995
938
  */
996
939
  template <typename Callable_T, typename... Args_T>
997
940
  static_suite (const char* name, static_runner& runner,
@@ -1011,13 +954,15 @@ namespace micro_os_plus::micro_test_plus
1011
954
  * @brief Deleted copy assignment operator to prevent copying.
1012
955
  */
1013
956
  static_suite&
1014
- operator= (const static_suite&) = delete;
957
+ operator= (const static_suite&)
958
+ = delete;
1015
959
 
1016
960
  /**
1017
961
  * @brief Deleted move assignment operator to prevent moving.
1018
962
  */
1019
963
  static_suite&
1020
- operator= (static_suite&&) = delete;
964
+ operator= (static_suite&&)
965
+ = delete;
1021
966
 
1022
967
  /**
1023
968
  * @brief Virtual destructor.
@@ -1029,12 +974,6 @@ namespace micro_os_plus::micro_test_plus
1029
974
  /**
1030
975
  * @brief Executes the static suite body using the stored static callable.
1031
976
  *
1032
- * @details
1033
- * Calls the base `suite::run()` implementation for the dynamically
1034
- * registered callable, then additionally invokes `static_callable_(*this)`
1035
- * if it is set. This allows `static_suite` objects to carry two separate
1036
- * bodies: a standard one and a statically-registered one.
1037
- *
1038
977
  * @par Parameters
1039
978
  * None.
1040
979
  * @par Returns
@@ -1062,6 +1001,11 @@ namespace micro_os_plus::micro_test_plus
1062
1001
 
1063
1002
  #endif // __cplusplus
1064
1003
 
1004
+ // ============================================================================
1005
+ // Templates & constexpr implementations.
1006
+
1007
+ #include "inlines/test-inlines.h"
1008
+
1065
1009
  // ----------------------------------------------------------------------------
1066
1010
 
1067
1011
  #endif // MICRO_TEST_PLUS_TEST_H_