@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
@@ -54,12 +54,13 @@
54
54
 
55
55
  // ----------------------------------------------------------------------------
56
56
 
57
- // #include <functional>
57
+ #include <cstdio>
58
58
  #include <string_view>
59
59
  #include <string>
60
+ #include <memory>
61
+ #include <vector>
60
62
 
61
63
  #include "type-traits.h"
62
- #include "test-suite.h"
63
64
  #include "detail.h"
64
65
 
65
66
  // ----------------------------------------------------------------------------
@@ -74,16 +75,18 @@
74
75
  #endif
75
76
  #endif
76
77
 
78
+ // =============================================================================
79
+
77
80
  namespace micro_os_plus::micro_test_plus
78
81
  {
79
82
  // --------------------------------------------------------------------------
80
83
 
81
84
  /**
82
- * @struct colors
85
+ * @struct colours
83
86
  * @brief Colours used to highlight pass and fail results in test reports.
84
87
  *
85
88
  * @details
86
- * The `colors` structure defines ANSI escape sequences for terminal output,
89
+ * The `colours` structure defines ANSI escape sequences for terminal output,
87
90
  * enabling colour-coded highlighting of test outcomes. The `pass` member
88
91
  * specifies the colour for successful results (typically green), while the
89
92
  * `fail` member specifies the colour for failed results (typically red). The
@@ -93,27 +96,29 @@ namespace micro_os_plus::micro_test_plus
93
96
  * by making it immediately apparent which tests have passed or failed,
94
97
  * thereby improving the overall user experience when reviewing test results.
95
98
  *
96
- * @var colors::none
99
+ * @var colours::none
97
100
  * ANSI escape sequence to reset the terminal colour to default.
98
- * @var colors::pass
101
+ * @var colours::pass
99
102
  * ANSI escape sequence to set the terminal colour for passing results
100
103
  * (green).
101
- * @var colors::fail
104
+ * @var colours::fail
102
105
  * ANSI escape sequence to set the terminal colour for failing results (red).
103
106
  *
104
107
  * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
105
108
  */
106
- struct colors
109
+ struct colours
107
110
  {
108
- const char* none = ""; /**< @brief Default colour. */
109
- const char* pass = ""; /**< @brief Green colour. */
110
- const char* fail = ""; /**< @brief Red colour. */
111
+ const char* none = ""; /**< @brief Terminal colour reset sequence. */
112
+ const char* pass
113
+ = ""; /**< @brief Terminal colour sequence for passing tests. */
114
+ const char* fail
115
+ = ""; /**< @brief Terminal colour sequence for failing tests. */
111
116
  };
112
117
 
113
- const colors colors_red_green = {
114
- "\033[0m", /**< @brief Default colour. */
115
- "\033[32m", /**< @brief Green colour. */
116
- "\033[31m" /**< @brief Red colour. */
118
+ inline constexpr colours colours_red_green = {
119
+ "\033[0m", /**< @brief Terminal colour reset sequence. */
120
+ "\033[32m", /**< @brief Green colour sequence for passing tests. */
121
+ "\033[31m" /**< @brief Red colour sequence for failing tests. */
117
122
  };
118
123
 
119
124
  /**
@@ -139,43 +144,50 @@ namespace micro_os_plus::micro_test_plus
139
144
  detail. */
140
145
  };
141
146
 
142
- /**
143
- * @brief Type alias for the verbosity enumeration used in test reporting.
144
- *
145
- * @details
146
- * The `verbosity_t` type alias provides a convenient shorthand for referring
147
- * to the `verbosity` enumeration, which defines the available levels of
148
- * detail for test output within the reporting system.
149
- *
150
- * Using this alias improves code readability and consistency throughout the
151
- * framework, especially when specifying or configuring verbosity levels for
152
- * test reporters.
153
- */
154
- typedef verbosity verbosity_t;
155
-
156
- // Forward definition.
157
- class test_reporter;
147
+ // Forward definitions.
148
+ class reporter;
149
+ class runner;
158
150
 
159
151
  /**
160
152
  * @brief Output stream manipulator for ending a line in test reports.
161
153
  *
162
- * @param stream Reference to the `test_reporter` instance.
163
- * @return Reference to the same `test_reporter` instance, enabling chaining
154
+ * @param stream Reference to the `reporter` instance.
155
+ * @return Reference to the same `reporter` instance, enabling chaining
164
156
  * of output operations.
165
157
  */
166
- test_reporter&
167
- endl (test_reporter& stream);
158
+ reporter&
159
+ endl (reporter& stream);
168
160
 
169
- // Requires events::assertion_* for and detailed operators.
161
+ /**
162
+ * @brief Parameterised stream manipulator for outputting indentation.
163
+ *
164
+ * @details
165
+ * Holds the indentation level; used with `operator<<` on `reporter`
166
+ * so that `*this << indent(n) << "text"` works naturally in chains.
167
+ */
168
+ struct indent_t
169
+ {
170
+ size_t level; /**< @brief Number of four-space indentation levels. */
171
+ };
170
172
 
171
- class test_runner;
173
+ /**
174
+ * @brief Factory function that creates an `indent_t` manipulator.
175
+ *
176
+ * @param level The number of four-space indentation levels.
177
+ * @return An `indent_t` value for use with `operator<<`.
178
+ */
179
+ [[nodiscard]] inline indent_t
180
+ indent (size_t level)
181
+ {
182
+ return { level };
183
+ }
172
184
 
173
185
  /**
174
186
  * @brief Reporter to display test results, including operand values and
175
187
  * types for failures.
176
188
  *
177
189
  * @details
178
- * The `test_reporter` class is responsible for formatting and presenting
190
+ * The `reporter` class is responsible for formatting and presenting
179
191
  * test results within the µTest++ framework. It provides a comprehensive
180
192
  * suite of output operators for a wide range of data types, containers, and
181
193
  * comparator expressions, enabling detailed and informative reporting of
@@ -187,7 +199,7 @@ namespace micro_os_plus::micro_test_plus
187
199
  * output to distinguish between successful and failed tests, thereby
188
200
  * enhancing the clarity and professionalism of test reports.
189
201
  *
190
- * The `test_reporter` also offers methods for reporting the commencement and
202
+ * The `reporter` also offers methods for reporting the commencement and
191
203
  * completion of test cases and suites, as well as for handling pass and fail
192
204
  * conditions. Additional features include output stream manipulators,
193
205
  * support for exception-related expressions, and configurable formatting
@@ -199,196 +211,184 @@ namespace micro_os_plus::micro_test_plus
199
211
  *
200
212
  * @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
201
213
  */
202
- class test_reporter
214
+ class reporter
203
215
  {
204
216
  public:
205
217
  /**
206
- * @brief Default constructor for the test_reporter class.
218
+ * @brief Constructor for the reporter class.
219
+ *
220
+ * @details
221
+ * Parses the command-line arguments to determine the desired verbosity
222
+ * level and applies it to the reporter. The `--verbose`, `--quiet`, and
223
+ * `--silent` options are recognised.
224
+ *
225
+ * @param argvs Owning pointer to the command-line arguments vector;
226
+ * the reporter takes ownership via move.
207
227
  */
208
- virtual ~test_reporter ();
228
+ reporter (std::unique_ptr<std::vector<std::string_view>> argvs);
209
229
 
210
230
  /**
211
- * @brief Selects the appropriate colour code based on a condition.
212
- *
213
- * @param cond Boolean value indicating pass (true) or fail (false).
214
- * @return The corresponding ANSI colour code as a string.
215
- *
216
- * @details
217
- * Returns the ANSI colour code for pass or fail, depending on the boolean
218
- * condition provided.
231
+ * @brief Virtual destructor for the reporter class.
219
232
  */
220
- [[nodiscard]] inline auto
221
- color (const bool cond)
222
- {
223
- return cond ? colors_.pass : colors_.fail;
224
- }
233
+ virtual ~reporter ();
225
234
 
226
235
  /**
227
236
  * @brief Output operator for std::string_view.
228
237
  *
229
238
  * @param sv The string view to output.
230
- * @return Reference to the current test_reporter instance.
239
+ * @return Reference to the current reporter instance.
231
240
  */
232
- test_reporter&
241
+ reporter&
233
242
  operator<< (std::string_view sv);
234
243
 
235
244
  /**
236
245
  * @brief Output operator for a single character.
237
246
  *
238
247
  * @param c The character to output.
239
- * @return Reference to the current test_reporter instance.
248
+ * @return Reference to the current reporter instance.
240
249
  */
241
- test_reporter&
250
+ reporter&
242
251
  operator<< (char c);
243
252
 
244
253
  /**
245
254
  * @brief Output operator for a constant character string.
246
255
  *
247
256
  * @param s The string to output.
248
- * @return Reference to the current test_reporter instance.
257
+ * @return Reference to the current reporter instance.
249
258
  */
250
- test_reporter&
259
+ reporter&
251
260
  operator<< (const char* s);
252
261
 
253
- /**
254
- * @brief Output operator for a mutable character string.
255
- *
256
- * @param s The string to output.
257
- * @return Reference to the current test_reporter instance.
258
- */
259
- test_reporter&
260
- operator<< (char* s);
261
-
262
262
  /**
263
263
  * @brief Output operator for boolean values.
264
264
  *
265
265
  * @param v The boolean value to output.
266
- * @return Reference to the current test_reporter instance.
266
+ * @return Reference to the current reporter instance.
267
267
  */
268
- test_reporter&
268
+ reporter&
269
269
  operator<< (bool v);
270
270
 
271
271
  /**
272
272
  * @brief Output operator for nullptr.
273
- * @return Reference to the current test_reporter instance.
273
+ * @return Reference to the current reporter instance.
274
274
  */
275
- test_reporter& operator<< (std::nullptr_t);
275
+ reporter& operator<< (std::nullptr_t);
276
276
 
277
277
  /**
278
278
  * @brief Output operator for signed char values.
279
279
  *
280
280
  * @param c The signed char value to output.
281
- * @return Reference to the current test_reporter instance.
281
+ * @return Reference to the current reporter instance.
282
282
  */
283
- test_reporter&
283
+ reporter&
284
284
  operator<< (signed char c);
285
285
 
286
286
  /**
287
287
  * @brief Output operator for unsigned char values.
288
288
  *
289
289
  * @param c The unsigned char value to output.
290
- * @return Reference to the current test_reporter instance.
290
+ * @return Reference to the current reporter instance.
291
291
  */
292
- test_reporter&
292
+ reporter&
293
293
  operator<< (unsigned char c);
294
294
 
295
295
  /**
296
296
  * @brief Output operator for signed short values.
297
297
  *
298
298
  * @param v The signed short value to output.
299
- * @return Reference to the current test_reporter instance.
299
+ * @return Reference to the current reporter instance.
300
300
  */
301
- test_reporter&
301
+ reporter&
302
302
  operator<< (signed short v);
303
303
 
304
304
  /**
305
305
  * @brief Output operator for unsigned short values.
306
306
  *
307
307
  * @param v The unsigned short value to output.
308
- * @return Reference to the current test_reporter instance.
308
+ * @return Reference to the current reporter instance.
309
309
  */
310
- test_reporter&
310
+ reporter&
311
311
  operator<< (unsigned short v);
312
312
 
313
313
  /**
314
314
  * @brief Output operator for signed int values.
315
315
  *
316
316
  * @param v The signed int value to output.
317
- * @return Reference to the current test_reporter instance.
317
+ * @return Reference to the current reporter instance.
318
318
  */
319
- test_reporter&
319
+ reporter&
320
320
  operator<< (signed int v);
321
321
 
322
322
  /**
323
323
  * @brief Output operator for unsigned int values.
324
324
  *
325
325
  * @param v The unsigned int value to output.
326
- * @return Reference to the current test_reporter instance.
326
+ * @return Reference to the current reporter instance.
327
327
  */
328
- test_reporter&
328
+ reporter&
329
329
  operator<< (unsigned int v);
330
330
 
331
331
  /**
332
332
  * @brief Output operator for signed long values.
333
333
  *
334
334
  * @param v The signed long value to output.
335
- * @return Reference to the current test_reporter instance.
335
+ * @return Reference to the current reporter instance.
336
336
  */
337
- test_reporter&
337
+ reporter&
338
338
  operator<< (signed long v);
339
339
 
340
340
  /**
341
341
  * @brief Output operator for unsigned long values.
342
342
  *
343
343
  * @param v The unsigned long value to output.
344
- * @return Reference to the current test_reporter instance.
344
+ * @return Reference to the current reporter instance.
345
345
  */
346
- test_reporter&
346
+ reporter&
347
347
  operator<< (unsigned long v);
348
348
 
349
349
  /**
350
350
  * @brief Output operator for signed long long values.
351
351
  *
352
352
  * @param v The signed long long value to output.
353
- * @return Reference to the current test_reporter instance.
353
+ * @return Reference to the current reporter instance.
354
354
  */
355
- test_reporter&
355
+ reporter&
356
356
  operator<< (signed long long v);
357
357
 
358
358
  /**
359
359
  * @brief Output operator for unsigned long long values.
360
360
  *
361
361
  * @param v The unsigned long long value to output.
362
- * @return Reference to the current test_reporter instance.
362
+ * @return Reference to the current reporter instance.
363
363
  */
364
- test_reporter&
364
+ reporter&
365
365
  operator<< (unsigned long long v);
366
366
 
367
367
  /**
368
368
  * @brief Output operator for float values.
369
369
  *
370
370
  * @param v The float value to output.
371
- * @return Reference to the current test_reporter instance.
371
+ * @return Reference to the current reporter instance.
372
372
  */
373
- test_reporter&
373
+ reporter&
374
374
  operator<< (float v);
375
375
 
376
376
  /**
377
377
  * @brief Output operator for double values.
378
378
  *
379
379
  * @param v The double value to output.
380
- * @return Reference to the current test_reporter instance.
380
+ * @return Reference to the current reporter instance.
381
381
  */
382
- test_reporter&
382
+ reporter&
383
383
  operator<< (double v);
384
384
 
385
385
  /**
386
386
  * @brief Output operator for long double values.
387
387
  *
388
388
  * @param v The long double value to output.
389
- * @return Reference to the current test_reporter instance.
389
+ * @return Reference to the current reporter instance.
390
390
  */
391
- test_reporter&
391
+ reporter&
392
392
  operator<< (long double v);
393
393
 
394
394
  /**
@@ -397,20 +397,20 @@ namespace micro_os_plus::micro_test_plus
397
397
  * @tparam T The type of the pointer.
398
398
  *
399
399
  * @param v The pointer value to output.
400
- * @return Reference to the current test_reporter instance.
400
+ * @return Reference to the current reporter instance.
401
401
  */
402
402
  template <typename T>
403
- test_reporter&
403
+ reporter&
404
404
  operator<< (T* v);
405
405
 
406
406
  /**
407
407
  * @brief Output operator to display the endl.
408
408
  *
409
409
  * @param func Function pointer to the stream manipulator.
410
- * @return Reference to the current test_reporter instance.
410
+ * @return Reference to the current reporter instance.
411
411
  */
412
- test_reporter&
413
- operator<< (test_reporter& (*func) (test_reporter&));
412
+ reporter&
413
+ operator<< (reporter& (*func) (reporter&));
414
414
 
415
415
  // ------------------------------------------------------------------------
416
416
  // Specific operators.
@@ -421,10 +421,11 @@ namespace micro_os_plus::micro_test_plus
421
421
  * @tparam T The type with a getter method.
422
422
  *
423
423
  * @param t The object to output.
424
- * @return Reference to the current test_reporter instance.
424
+ * @return Reference to the current reporter instance.
425
425
  */
426
426
  template <class T>
427
- test_reporter&
427
+ requires type_traits::is_op<T>
428
+ reporter&
428
429
  operator<< (const T& t);
429
430
 
430
431
  /**
@@ -434,10 +435,10 @@ namespace micro_os_plus::micro_test_plus
434
435
  * @tparam T The underlying integral type.
435
436
  *
436
437
  * @param v The strongly-typed integral value to output.
437
- * @return Reference to the current test_reporter instance.
438
+ * @return Reference to the current reporter instance.
438
439
  */
439
440
  template <class T>
440
- test_reporter&
441
+ reporter&
441
442
  operator<< (const type_traits::genuine_integral_value<T>& v);
442
443
 
443
444
  /**
@@ -446,14 +447,13 @@ namespace micro_os_plus::micro_test_plus
446
447
  * @tparam T The container type.
447
448
  *
448
449
  * @param t The container to output.
449
- * @return Reference to the current test_reporter instance.
450
+ * @return Reference to the current reporter instance.
450
451
  */
451
- template <class T,
452
- type_traits::requires_t<type_traits::is_container_v<T>
453
- and not type_traits::has_npos_v<T>>
454
- = 0>
455
- test_reporter&
456
- operator<< (T&& t);
452
+ template <class T>
453
+ requires (type_traits::container_like<T>
454
+ and not type_traits::has_npos<T>)
455
+ reporter&
456
+ operator<< (const T& t);
457
457
 
458
458
  /**
459
459
  * @brief Output operator to display eq() expressions.
@@ -462,10 +462,10 @@ namespace micro_os_plus::micro_test_plus
462
462
  * @tparam Rhs_T The right-hand side type.
463
463
  *
464
464
  * @param op The equality comparator expression.
465
- * @return Reference to the current test_reporter instance.
465
+ * @return Reference to the current reporter instance.
466
466
  */
467
467
  template <class Lhs_T, class Rhs_T>
468
- test_reporter&
468
+ reporter&
469
469
  operator<< (const detail::eq_<Lhs_T, Rhs_T>& op);
470
470
 
471
471
  /**
@@ -475,10 +475,10 @@ namespace micro_os_plus::micro_test_plus
475
475
  * @tparam Rhs_T The right-hand side type.
476
476
  *
477
477
  * @param op The inequality comparator expression.
478
- * @return Reference to the current test_reporter instance.
478
+ * @return Reference to the current reporter instance.
479
479
  */
480
480
  template <class Lhs_T, class Rhs_T>
481
- test_reporter&
481
+ reporter&
482
482
  operator<< (const detail::ne_<Lhs_T, Rhs_T>& op);
483
483
 
484
484
  /**
@@ -488,10 +488,10 @@ namespace micro_os_plus::micro_test_plus
488
488
  * @tparam Rhs_T The right-hand side type.
489
489
  *
490
490
  * @param op The greater-than comparator expression.
491
- * @return Reference to the current test_reporter instance.
491
+ * @return Reference to the current reporter instance.
492
492
  */
493
493
  template <class Lhs_T, class Rhs_T>
494
- test_reporter&
494
+ reporter&
495
495
  operator<< (const detail::gt_<Lhs_T, Rhs_T>& op);
496
496
 
497
497
  /**
@@ -501,10 +501,10 @@ namespace micro_os_plus::micro_test_plus
501
501
  * @tparam Rhs_T The right-hand side type.
502
502
  *
503
503
  * @param op The greater-than-or-equal-to comparator expression.
504
- * @return Reference to the current test_reporter instance.
504
+ * @return Reference to the current reporter instance.
505
505
  */
506
506
  template <class Lhs_T, class Rhs_T>
507
- test_reporter&
507
+ reporter&
508
508
  operator<< (const detail::ge_<Lhs_T, Rhs_T>& op);
509
509
 
510
510
  /**
@@ -514,10 +514,10 @@ namespace micro_os_plus::micro_test_plus
514
514
  * @tparam Rhs_T The right-hand side type.
515
515
  *
516
516
  * @param op The less-than comparator expression.
517
- * @return Reference to the current test_reporter instance.
517
+ * @return Reference to the current reporter instance.
518
518
  */
519
519
  template <class Lhs_T, class Rhs_T>
520
- test_reporter&
520
+ reporter&
521
521
  operator<< (const detail::lt_<Rhs_T, Lhs_T>& op);
522
522
 
523
523
  /**
@@ -527,10 +527,10 @@ namespace micro_os_plus::micro_test_plus
527
527
  * @tparam Rhs_T The right-hand side type.
528
528
  *
529
529
  * @param op The less-than-or-equal-to comparator expression.
530
- * @return Reference to the current test_reporter instance.
530
+ * @return Reference to the current reporter instance.
531
531
  */
532
532
  template <class Lhs_T, class Rhs_T>
533
- test_reporter&
533
+ reporter&
534
534
  operator<< (const detail::le_<Rhs_T, Lhs_T>& op);
535
535
 
536
536
  /**
@@ -540,10 +540,10 @@ namespace micro_os_plus::micro_test_plus
540
540
  * @tparam Rhs_T The right-hand side type.
541
541
  *
542
542
  * @param op The logical conjunction (AND) expression.
543
- * @return Reference to the current test_reporter instance.
543
+ * @return Reference to the current reporter instance.
544
544
  */
545
545
  template <class Lhs_T, class Rhs_T>
546
- test_reporter&
546
+ reporter&
547
547
  operator<< (const detail::and_<Lhs_T, Rhs_T>& op);
548
548
 
549
549
  /**
@@ -553,10 +553,10 @@ namespace micro_os_plus::micro_test_plus
553
553
  * @tparam Rhs_T The right-hand side type.
554
554
  *
555
555
  * @param op The logical disjunction (OR) expression.
556
- * @return Reference to the current test_reporter instance.
556
+ * @return Reference to the current reporter instance.
557
557
  */
558
558
  template <class Lhs_T, class Rhs_T>
559
- test_reporter&
559
+ reporter&
560
560
  operator<< (const detail::or_<Lhs_T, Rhs_T>& op);
561
561
 
562
562
  /**
@@ -565,10 +565,10 @@ namespace micro_os_plus::micro_test_plus
565
565
  * @tparam T The operand type.
566
566
  *
567
567
  * @param op The logical negation expression.
568
- * @return Reference to the current test_reporter instance.
568
+ * @return Reference to the current reporter instance.
569
569
  */
570
570
  template <class T>
571
- test_reporter&
571
+ reporter&
572
572
  operator<< (const detail::not_<T>& op);
573
573
 
574
574
  #if defined(__cpp_exceptions)
@@ -580,10 +580,10 @@ namespace micro_os_plus::micro_test_plus
580
580
  * @tparam Exception_T The exception type.
581
581
  *
582
582
  * @param op The throws comparator expression.
583
- * @return Reference to the current test_reporter instance.
583
+ * @return Reference to the current reporter instance.
584
584
  */
585
585
  template <class Expr_T, class Exception_T>
586
- test_reporter&
586
+ reporter&
587
587
  operator<< (const detail::throws_<Expr_T, Exception_T>& op);
588
588
 
589
589
  /**
@@ -592,10 +592,10 @@ namespace micro_os_plus::micro_test_plus
592
592
  * @tparam Expr_T The expression type.
593
593
  *
594
594
  * @param op The throws comparator expression.
595
- * @return Reference to the current test_reporter instance.
595
+ * @return Reference to the current reporter instance.
596
596
  */
597
597
  template <class Expr_T>
598
- test_reporter&
598
+ reporter&
599
599
  operator<< (const detail::throws_<Expr_T, void>& op);
600
600
 
601
601
  /**
@@ -604,13 +604,15 @@ namespace micro_os_plus::micro_test_plus
604
604
  * @tparam Expr_T The expression type.
605
605
  *
606
606
  * @param op The nothrow comparator expression.
607
- * @return Reference to the current test_reporter instance.
607
+ * @return Reference to the current reporter instance.
608
608
  */
609
609
  template <class Expr_T>
610
- test_reporter&
610
+ reporter&
611
611
  operator<< (const detail::nothrow_<Expr_T>& op);
612
612
  #endif
613
613
 
614
+ // ------------------------------------------------------------------------
615
+
614
616
  /**
615
617
  * @brief Inserts a line ending into the output buffer.
616
618
  *
@@ -619,9 +621,35 @@ namespace micro_os_plus::micro_test_plus
619
621
  * @par Returns
620
622
  * Nothing.
621
623
  */
622
- virtual void
623
- endline (void)
624
- = 0;
624
+ void
625
+ endline (void);
626
+
627
+ /**
628
+ * @brief Output the current buffered content.
629
+ *
630
+ * @note Public because `deferred_reporter_base` calls this
631
+ * from its destructor when aborting, after the subtest
632
+ * instance is no longer accessible via the normal
633
+ * reporting path.
634
+ *
635
+ * @par Parameters
636
+ * None.
637
+ * @par Returns
638
+ * Nothing.
639
+ */
640
+ void
641
+ write_buffer_to_stdout (void);
642
+
643
+ /**
644
+ * @brief Flush the current buffered content.
645
+ *
646
+ * @par Parameters
647
+ * None.
648
+ * @par Returns
649
+ * Nothing.
650
+ */
651
+ void
652
+ flush (void);
625
653
 
626
654
  // ------------------------------------------------------------------------
627
655
 
@@ -632,12 +660,13 @@ namespace micro_os_plus::micro_test_plus
632
660
  *
633
661
  * @param expr The evaluated expression.
634
662
  * @param message The message to display.
663
+ * @param subtest The subtest that owns this check.
635
664
  * @par Returns
636
665
  * Nothing.
637
666
  */
638
667
  template <class Expr_T>
639
668
  void
640
- pass (Expr_T& expr, std::string& message);
669
+ pass (Expr_T& expr, std::string& message, subtest& subtest);
641
670
 
642
671
  /**
643
672
  * @brief Report a failed condition.
@@ -648,141 +677,157 @@ namespace micro_os_plus::micro_test_plus
648
677
  * @param abort Whether to abort execution after failure.
649
678
  * @param message The message to display.
650
679
  * @param location The source location of the failure.
680
+ * @param subtest The subtest that owns this check.
651
681
  * @par Returns
652
682
  * Nothing.
653
683
  */
654
684
  template <class Expr_T>
655
685
  void
656
686
  fail (Expr_T& expr, bool abort, std::string& message,
657
- const reflection::source_location& location);
687
+ const reflection::source_location& location, subtest& subtest);
688
+
689
+ // ------------------------------------------------------------------------
658
690
 
659
691
  /**
660
- * @brief Mark the beginning of a test case.
692
+ * @brief Mark the beginning of a test session.
661
693
  *
662
- * @param name The name of the test case.
694
+ * @param runner Reference to the test runner.
663
695
  * @par Returns
664
696
  * Nothing.
665
697
  */
666
698
  virtual void
667
- begin_test_case (const char* name)
668
- = 0;
699
+ begin_session (runner& runner) = 0;
669
700
 
670
701
  /**
671
- * @brief Mark the end of a test case.
702
+ * @brief Mark the end of a test session.
672
703
  *
673
- * @param name The name of the test case.
704
+ * @param runner Reference to the test runner.
674
705
  * @par Returns
675
706
  * Nothing.
676
707
  */
677
708
  virtual void
678
- end_test_case (const char* name)
679
- = 0;
709
+ end_session (runner& runner) = 0;
680
710
 
681
711
  /**
682
712
  * @brief Mark the beginning of a test suite.
683
713
  *
684
- * @param name The name of the test suite.
714
+ * @param suite Reference to the test suite.
685
715
  * @par Returns
686
716
  * Nothing.
687
717
  */
688
718
  virtual void
689
- begin_test_suite (const char* name)
690
- = 0;
719
+ begin_suite (suite& suite) = 0;
691
720
 
692
721
  /**
693
722
  * @brief Mark the end of a test suite.
694
723
  *
695
- * @param suite Reference to the test suite base.
724
+ * @param suite Reference to the test suite.
696
725
  * @par Returns
697
726
  * Nothing.
698
727
  */
699
728
  virtual void
700
- end_test_suite (test_suite_base& suite)
701
- = 0;
729
+ end_suite (suite& suite) = 0;
702
730
 
703
731
  /**
704
- * @brief Mark the beginning of a test.
732
+ * @brief Mark the beginning of a subtest.
705
733
  *
706
- * @param test_suites_count The number of test suites.
734
+ * @param subtest Reference to the subtest.
707
735
  * @par Returns
708
736
  * Nothing.
709
737
  */
710
738
  virtual void
711
- begin_test (size_t test_suites_count)
712
- = 0;
739
+ begin_subtest (subtest& subtest) = 0;
713
740
 
714
741
  /**
715
- * @brief Mark the end of a test.
742
+ * @brief Mark the end of a subtest.
716
743
  *
717
- * @param runner Reference to the test runner.
744
+ * @param subtest Reference to the subtest.
718
745
  * @par Returns
719
746
  * Nothing.
720
747
  */
721
748
  virtual void
722
- end_test (test_runner& runner)
723
- = 0;
749
+ end_subtest (subtest& subtest) = 0;
724
750
 
725
751
  /**
726
- * @brief Flush the current buffered content.
752
+ * @brief Returns the comment-prefix string used by this reporter format.
753
+ *
754
+ * @details
755
+ * Human reporters return an empty string; TAP reporters return `"# "`
756
+ * so that diagnostic lines conform to the TAP specification.
727
757
  *
728
758
  * @par Parameters
729
759
  * None.
730
- * @par Returns
731
- * Nothing.
760
+ * @return A null-terminated prefix string.
732
761
  */
733
- virtual void
734
- flush (void)
735
- = 0;
762
+ virtual const char*
763
+ get_comment_prefix (void) = 0;
736
764
 
737
765
  /**
738
- * @brief Output the current buffered content.
766
+ * @brief Returns the current verbosity level.
739
767
  *
740
768
  * @par Parameters
741
769
  * None.
742
- * @par Returns
743
- * Nothing.
770
+ * @return The active `verbosity` value.
744
771
  */
745
- virtual void
746
- output (void)
747
- = 0;
772
+ auto
773
+ verbosity () const -> micro_test_plus::verbosity
774
+ {
775
+ return verbosity_;
776
+ }
777
+
778
+ // ------------------------------------------------------------------------
748
779
 
780
+ protected:
749
781
  /**
750
- * @brief Controls whether to add an empty line between successful test
751
- * cases.
782
+ * @brief Selects the appropriate colour code based on a condition.
783
+ *
784
+ * @param cond Boolean value indicating pass (true) or fail (false).
785
+ * @return The corresponding ANSI colour code as a string.
752
786
  *
753
787
  * @details
754
- * Used to nicely format the output.
788
+ * Returns the ANSI colour code for pass or fail, depending on the boolean
789
+ * condition provided.
755
790
  */
756
- bool add_empty_line{ true };
791
+ [[nodiscard]] inline auto
792
+ colour_ (const bool cond) const
793
+ {
794
+ return cond ? colours_.pass : colours_.fail;
795
+ }
796
+
797
+ void
798
+ write_buffer_to_file_ (void);
757
799
 
758
800
  /**
759
- * @brief The verbosity level for test reporting.
801
+ * @brief Appends informational (non-result) text to the output buffer.
802
+ *
803
+ * @par Parameters
804
+ * None.
805
+ * @par Returns
806
+ * Nothing.
760
807
  */
761
- verbosity_t verbosity{};
808
+ void
809
+ write_info_ (void);
762
810
 
763
- protected:
764
811
  /**
765
812
  * @brief Outputs the prefix for a passing condition.
766
813
  *
767
814
  * @param message The message to display.
815
+ * @param subtest The subtest that owns this check.
768
816
  * @par Returns
769
817
  * Nothing.
770
818
  */
771
819
  virtual void
772
- output_pass_prefix_ (std::string& message)
773
- = 0;
820
+ output_pass_prefix_ (std::string& message, subtest& subtest) = 0;
774
821
 
775
822
  /**
776
823
  * @brief Outputs the suffix for a passing condition.
777
824
  *
778
- * @par Parameters
779
- * None.
825
+ * @param subtest The subtest that owns this check.
780
826
  * @par Returns
781
827
  * Nothing.
782
828
  */
783
829
  virtual void
784
- output_pass_suffix_ (void)
785
- = 0;
830
+ output_pass_suffix_ (subtest& subtest) = 0;
786
831
 
787
832
  /**
788
833
  * @brief Outputs the prefix for a failing condition.
@@ -791,41 +836,92 @@ namespace micro_os_plus::micro_test_plus
791
836
  * @param hasExpression Whether the failure is associated with an
792
837
  * expression.
793
838
  * @param location The source location of the failure.
839
+ * @param subtest The subtest that owns this check.
794
840
  * @par Returns
795
841
  * Nothing.
796
842
  */
797
843
  virtual void
798
844
  output_fail_prefix_ (std::string& message, const bool hasExpression,
799
- const reflection::source_location& location)
800
- = 0;
845
+ const reflection::source_location& location,
846
+ subtest& subtest) = 0;
801
847
 
802
848
  /**
803
849
  * @brief Outputs the suffix for a failing condition.
804
850
  *
805
851
  * @param location The source location of the failure.
806
852
  * @param abort Whether to abort execution after failure.
853
+ * @param subtest The subtest that owns this check.
807
854
  * @par Returns
808
855
  * Nothing.
809
856
  */
810
857
  virtual void
811
858
  output_fail_suffix_ (const reflection::source_location& location,
812
- bool abort)
813
- = 0;
859
+ bool abort, subtest& subtest) = 0;
860
+
861
+ /**
862
+ * @brief Appends the string representation of a numeric value to a
863
+ * buffer, using `std::to_chars` for allocation-free, locale-independent
864
+ * formatting.
865
+ *
866
+ * @tparam T The numeric type to format.
867
+ *
868
+ * @param buffer The string to append to.
869
+ * @param v The value to format.
870
+ * @par Returns
871
+ * Nothing.
872
+ */
873
+ template <class T>
874
+ static void
875
+ append_number_ (std::string& buffer, T v);
876
+
877
+ protected:
878
+ /**
879
+ * @brief The verbosity level for test reporting.
880
+ */
881
+ enum verbosity verbosity_ = verbosity::normal;
814
882
 
815
883
  /**
816
884
  * @brief ANSI colour codes for output formatting.
817
885
  */
818
- colors colors_{};
886
+ colours colours_{};
819
887
 
820
888
  /**
821
889
  * @brief Internal output buffer for accumulating report content.
822
890
  */
823
- std::string out_{};
891
+ std::string buffer_{};
892
+
893
+ /**
894
+ * @brief Controls whether to add an empty line between successful test
895
+ * cases.
896
+ *
897
+ * @details
898
+ * Used to nicely format the output.
899
+ */
900
+ bool add_empty_line_{ true };
901
+
902
+ /**
903
+ * @brief Optional file path for redirecting test report output.
904
+ *
905
+ * @details
906
+ * When non-null, `write_buffer_to_file_()` writes accumulated output
907
+ * to this path in addition to (or instead of) standard output.
908
+ */
909
+ const char* output_file_path_{ nullptr };
910
+
911
+ /**
912
+ * @brief Optional output file for redirecting test report output.
913
+ *
914
+ * @details
915
+ * When non-null, all output is written to this file instead of
916
+ * standard output. The reporter does not own the file; the caller
917
+ * is responsible for its lifetime.
918
+ */
919
+ FILE* output_file_{ nullptr };
824
920
 
825
921
  /**
826
- * @brief Indicates whether the reporter is currently within a test case.
922
+ * @brief Owns the command-line arguments passed to the test runner.
827
923
  */
828
- bool is_in_test_case_ = false;
924
+ std::unique_ptr<std::vector<std::string_view>> argvs_{};
829
925
  };
830
926
 
831
927
  // --------------------------------------------------------------------------