@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.
- package/CHANGELOG.md +330 -2
- package/CMakeLists.txt +79 -23
- package/README.md +1 -1
- package/config/xcdl-build.json +11 -4
- package/include/micro-os-plus/micro-test-plus/deferred-reporter.h +292 -0
- package/include/micro-os-plus/micro-test-plus/detail.h +462 -1076
- package/include/micro-os-plus/micro-test-plus/exceptions.h +126 -0
- package/include/micro-os-plus/micro-test-plus/function-comparators.h +10 -7
- package/include/micro-os-plus/micro-test-plus/inlines/{details-inlines.h → deferred-reporter-inlines.h} +49 -22
- package/include/micro-os-plus/micro-test-plus/inlines/function-comparators-inlines.h +67 -4
- package/include/micro-os-plus/micro-test-plus/inlines/literals-inlines.h +3 -6
- package/include/micro-os-plus/micro-test-plus/inlines/math-inlines.h +21 -15
- package/include/micro-os-plus/micro-test-plus/inlines/reflection-inlines.h +35 -17
- package/include/micro-os-plus/micro-test-plus/inlines/{test-reporter-inlines.h → reporter-inlines.h} +176 -106
- package/include/micro-os-plus/micro-test-plus/inlines/{test-suite-inlines.h → runner-inlines.h} +41 -43
- package/include/micro-os-plus/micro-test-plus/inlines/test-inlines.h +369 -0
- package/include/micro-os-plus/micro-test-plus/inlines/utility-inlines.h +126 -0
- package/include/micro-os-plus/micro-test-plus/literals.h +4 -3
- package/include/micro-os-plus/micro-test-plus/math.h +9 -6
- package/include/micro-os-plus/micro-test-plus/operators.h +38 -44
- package/include/micro-os-plus/micro-test-plus/reflection.h +15 -4
- package/include/micro-os-plus/micro-test-plus/{test-reporter-basic.h → reporter-human.h} +72 -72
- package/include/micro-os-plus/micro-test-plus/{test-reporter-tap.h → reporter-tap.h} +69 -69
- package/include/micro-os-plus/micro-test-plus/{test-reporter.h → reporter.h} +296 -200
- package/include/micro-os-plus/micro-test-plus/runner-totals.h +264 -0
- package/include/micro-os-plus/micro-test-plus/runner.h +453 -0
- package/include/micro-os-plus/micro-test-plus/test.h +1069 -0
- package/include/micro-os-plus/micro-test-plus/timings.h +366 -0
- package/include/micro-os-plus/micro-test-plus/type-traits.h +239 -545
- package/include/micro-os-plus/micro-test-plus/utility.h +135 -0
- package/include/micro-os-plus/micro-test-plus.h +25 -228
- package/meson.build +10 -6
- package/package.json +1 -1
- package/src/deferred-reporter.cpp +118 -0
- package/src/reflection.cpp +95 -0
- package/src/reporter-human.cpp +822 -0
- package/src/reporter-tap.cpp +782 -0
- package/src/reporter.cpp +676 -0
- package/src/runner-totals.cpp +95 -0
- package/src/runner.cpp +563 -0
- package/src/test.cpp +496 -0
- package/src/timings.cpp +209 -0
- package/src/utility.cpp +163 -0
- package/.cmake-format.yaml +0 -11
- package/include/micro-os-plus/micro-test-plus/inlines/micro-test-plus-inlines.h +0 -313
- package/include/micro-os-plus/micro-test-plus/test-runner.h +0 -281
- package/include/micro-os-plus/micro-test-plus/test-suite.h +0 -492
- package/src/micro-test-plus.cpp +0 -316
- package/src/test-reporter-basic.cpp +0 -466
- package/src/test-reporter-tap.cpp +0 -530
- package/src/test-reporter.cpp +0 -399
- package/src/test-runner.cpp +0 -311
- package/src/test-suite.cpp +0 -304
|
@@ -0,0 +1,1069 @@
|
|
|
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 declarations for the µTest++ test suite.
|
|
21
|
+
*
|
|
22
|
+
* @details
|
|
23
|
+
* This header provides the declarations for the test suite facilities used
|
|
24
|
+
* within the µTest++ framework. It defines the interfaces for constructing,
|
|
25
|
+
* registering, and managing test suites and their associated test cases. The
|
|
26
|
+
* core classes, `test_node` and `suite`, offer mechanisms for
|
|
27
|
+
* tracking test case execution, managing counters for successful and failed
|
|
28
|
+
* checks, and supporting automated registration and discovery of test suites.
|
|
29
|
+
*
|
|
30
|
+
* The design ensures that test suites are non-copyable and non-movable,
|
|
31
|
+
* maintaining unique ownership and consistent state. Flexible support for
|
|
32
|
+
* callable objects enables a wide range of test suite definitions,
|
|
33
|
+
* facilitating expressive and maintainable test organisation across embedded
|
|
34
|
+
* and general C++ projects.
|
|
35
|
+
*
|
|
36
|
+
* All definitions reside within the `micro_os_plus::micro_test_plus`
|
|
37
|
+
* namespace, ensuring clear separation from user code and minimising the risk
|
|
38
|
+
* of naming conflicts.
|
|
39
|
+
*
|
|
40
|
+
* The header files are organised within the
|
|
41
|
+
* `include/micro-os-plus/micro-test-plus` folder to maintain a structured and
|
|
42
|
+
* modular codebase.
|
|
43
|
+
*
|
|
44
|
+
* This file is intended solely for internal use within the framework and
|
|
45
|
+
* should not be included directly by user code.
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
#ifndef MICRO_TEST_PLUS_TEST_H_
|
|
49
|
+
#define MICRO_TEST_PLUS_TEST_H_
|
|
50
|
+
|
|
51
|
+
// ----------------------------------------------------------------------------
|
|
52
|
+
|
|
53
|
+
#ifdef __cplusplus
|
|
54
|
+
|
|
55
|
+
// ----------------------------------------------------------------------------
|
|
56
|
+
|
|
57
|
+
#include "runner-totals.h"
|
|
58
|
+
#include "timings.h"
|
|
59
|
+
|
|
60
|
+
#include <functional>
|
|
61
|
+
#include <memory>
|
|
62
|
+
|
|
63
|
+
// ----------------------------------------------------------------------------
|
|
64
|
+
|
|
65
|
+
#if defined(__GNUC__)
|
|
66
|
+
#pragma GCC diagnostic push
|
|
67
|
+
#pragma GCC diagnostic ignored "-Wpadded"
|
|
68
|
+
#if defined(__clang__)
|
|
69
|
+
#pragma clang diagnostic ignored "-Wc++98-compat"
|
|
70
|
+
#else // GCC only
|
|
71
|
+
#pragma GCC diagnostic ignored "-Wsuggest-final-types"
|
|
72
|
+
#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
|
|
73
|
+
#pragma GCC diagnostic ignored "-Wredundant-tags"
|
|
74
|
+
#endif
|
|
75
|
+
#endif
|
|
76
|
+
|
|
77
|
+
// =============================================================================
|
|
78
|
+
|
|
79
|
+
namespace micro_os_plus::micro_test_plus
|
|
80
|
+
{
|
|
81
|
+
class runner;
|
|
82
|
+
class static_runner;
|
|
83
|
+
class reporter;
|
|
84
|
+
class runner_totals;
|
|
85
|
+
class suite;
|
|
86
|
+
|
|
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
|
|
110
|
+
{
|
|
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_;
|
|
199
|
+
|
|
200
|
+
/**
|
|
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.
|
|
232
|
+
*
|
|
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.
|
|
270
|
+
*
|
|
271
|
+
* @par Parameters
|
|
272
|
+
* None.
|
|
273
|
+
* @return The one-based own index.
|
|
274
|
+
*/
|
|
275
|
+
[[nodiscard]] size_t
|
|
276
|
+
own_index () const noexcept
|
|
277
|
+
{
|
|
278
|
+
return own_index_;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* @brief Sets the positional index of this object within its parent.
|
|
283
|
+
*
|
|
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.
|
|
287
|
+
*
|
|
288
|
+
* @param index The new index value.
|
|
289
|
+
* @par Returns
|
|
290
|
+
* Nothing.
|
|
291
|
+
*/
|
|
292
|
+
void
|
|
293
|
+
own_index (size_t index) noexcept
|
|
294
|
+
{
|
|
295
|
+
own_index_ = index;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
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.
|
|
313
|
+
*
|
|
314
|
+
* @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.
|
|
331
|
+
*
|
|
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.
|
|
354
|
+
*
|
|
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.
|
|
365
|
+
*
|
|
366
|
+
* @par Parameters
|
|
367
|
+
* None.
|
|
368
|
+
* @return A reference to the test runner.
|
|
369
|
+
*/
|
|
370
|
+
[[nodiscard]] class runner&
|
|
371
|
+
runner (void) const noexcept
|
|
372
|
+
{
|
|
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.
|
|
403
|
+
*
|
|
404
|
+
* @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.
|
|
440
|
+
*
|
|
441
|
+
* @tparam Callable_T The callable type.
|
|
442
|
+
* @tparam Args_T The additional argument types.
|
|
443
|
+
*
|
|
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.
|
|
450
|
+
*
|
|
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.
|
|
465
|
+
*/
|
|
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;
|
|
484
|
+
|
|
485
|
+
// ------------------------------------------------------------------------
|
|
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
|
+
};
|
|
506
|
+
|
|
507
|
+
// ==========================================================================
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* @ingroup micro-test-plus-test-case
|
|
511
|
+
* @brief A named, runnable test case that lives inside a `suite`.
|
|
512
|
+
*
|
|
513
|
+
* @details
|
|
514
|
+
* `subtest` represents a single, named test case or a nested group of
|
|
515
|
+
* checks within a parent `suite`. It is constructed by calling
|
|
516
|
+
* `suite::test()` or `subtest::test()`, both of which create the object,
|
|
517
|
+
* immediately execute its callable body via `run()`, and register the
|
|
518
|
+
* result with the parent suite.
|
|
519
|
+
*
|
|
520
|
+
* The body of the subtest is supplied as a callable (typically a lambda)
|
|
521
|
+
* that receives a `subtest&` reference as its first argument. Inside the
|
|
522
|
+
* body, `expect()` and `assume()` are used to evaluate conditions and
|
|
523
|
+
* record the results. Subtests may be nested to an arbitrary depth.
|
|
524
|
+
*
|
|
525
|
+
* The class is non-copyable and non-movable to preserve unique ownership
|
|
526
|
+
* and consistent state throughout the test session.
|
|
527
|
+
*
|
|
528
|
+
* @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
|
|
529
|
+
*/
|
|
530
|
+
class subtest : public runnable<subtest>
|
|
531
|
+
{
|
|
532
|
+
public:
|
|
533
|
+
/**
|
|
534
|
+
* @brief Constructs a subtest with a name, runner, parent suite, index,
|
|
535
|
+
* nesting depth, and callable.
|
|
536
|
+
*
|
|
537
|
+
* @tparam Callable_T The type of a callable object.
|
|
538
|
+
* @tparam Args_T The types of the callable arguments.
|
|
539
|
+
*
|
|
540
|
+
* @param [in] name The subtest name or description, used in reports.
|
|
541
|
+
* @param [in] runner The test runner managing this subtest.
|
|
542
|
+
* @param [in] parent_suite The suite that owns this subtest.
|
|
543
|
+
* @param [in] own_index The one-based positional index within the parent.
|
|
544
|
+
* @param [in] nesting_depth The depth of nesting; 1 for top-level
|
|
545
|
+
* subtests.
|
|
546
|
+
* @param [in] callable A generic callable object, usually a lambda,
|
|
547
|
+
* invoked when the subtest executes.
|
|
548
|
+
* @param [in] arguments A possibly empty list of arguments forwarded to
|
|
549
|
+
* the callable after the leading `subtest&` reference.
|
|
550
|
+
*
|
|
551
|
+
* @details
|
|
552
|
+
* The rule of five is enforced to prevent accidental copying or moving.
|
|
553
|
+
*/
|
|
554
|
+
template <typename Callable_T, typename... Args_T>
|
|
555
|
+
subtest (const char* name, class runner& runner, suite& parent_suite,
|
|
556
|
+
size_t own_index, size_t nesting_depth, Callable_T&& callable,
|
|
557
|
+
Args_T&&... arguments);
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* @brief Deleted copy constructor to prevent copying.
|
|
561
|
+
*/
|
|
562
|
+
subtest (const subtest&) = delete;
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* @brief Deleted move constructor to prevent moving.
|
|
566
|
+
*/
|
|
567
|
+
subtest (subtest&&) = delete;
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* @brief Deleted copy assignment operator to prevent copying.
|
|
571
|
+
*/
|
|
572
|
+
subtest&
|
|
573
|
+
operator= (const subtest&) = delete;
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* @brief Deleted move assignment operator to prevent moving.
|
|
577
|
+
*/
|
|
578
|
+
subtest&
|
|
579
|
+
operator= (subtest&&) = delete;
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
* @brief Virtual destructor.
|
|
583
|
+
*/
|
|
584
|
+
virtual ~subtest () override;
|
|
585
|
+
|
|
586
|
+
// ------------------------------------------------------------------------
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
* @brief Adds a test case to the suite.
|
|
590
|
+
*
|
|
591
|
+
* @tparam Callable_T The type of a callable object.
|
|
592
|
+
* @tparam Args_T The types of the callable arguments.
|
|
593
|
+
*
|
|
594
|
+
* @param [in] name The test case name or description, used in reports.
|
|
595
|
+
* @param [in] callable A generic callable object, usually a lambda,
|
|
596
|
+
* invoked to perform the test.
|
|
597
|
+
* @param [in] arguments A possibly empty list of arguments to be passed to
|
|
598
|
+
* the callable.
|
|
599
|
+
*/
|
|
600
|
+
template <typename Callable_T, typename... Args_T>
|
|
601
|
+
void
|
|
602
|
+
test (const char* name, Callable_T&& callable, Args_T&&... arguments);
|
|
603
|
+
|
|
604
|
+
// ------------------------------------------------------------------------
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* @ingroup micro-test-plus-expectations
|
|
608
|
+
* @brief Evaluate a generic condition and report the results.
|
|
609
|
+
*
|
|
610
|
+
* @tparam Expr_T The type of the custom expression.
|
|
611
|
+
*
|
|
612
|
+
* @par Constraints
|
|
613
|
+
* Enabled only if `Expr_T` is derived from `detail::op` or
|
|
614
|
+
* is convertible to `bool` (enforced via a C++20 `requires` clause).
|
|
615
|
+
*
|
|
616
|
+
* @param [in] expr Logical expression to evaluate.
|
|
617
|
+
* @param [in] sl Optional source location, defaulting to the current line.
|
|
618
|
+
* @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
|
+
*/
|
|
644
|
+
template <class Expr_T>
|
|
645
|
+
requires type_traits::checkable<Expr_T>
|
|
646
|
+
auto
|
|
647
|
+
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
|
+
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* @ingroup micro-test-plus-assumptions
|
|
655
|
+
* @brief Check a condition and, if false, abort test execution.
|
|
656
|
+
*
|
|
657
|
+
* @tparam Expr_T The type of the custom expression.
|
|
658
|
+
*
|
|
659
|
+
* @par Constraints
|
|
660
|
+
* Enabled only if `Expr_T` is derived from `detail::op` or
|
|
661
|
+
* is convertible to `bool` (enforced via a C++20 `requires` clause).
|
|
662
|
+
*
|
|
663
|
+
* @param [in] expr Logical expression to evaluate.
|
|
664
|
+
* @param [in] sl Optional source location, defaulting to the current line.
|
|
665
|
+
* @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
|
+
*/
|
|
690
|
+
template <class Expr_T>
|
|
691
|
+
requires type_traits::checkable<Expr_T>
|
|
692
|
+
auto
|
|
693
|
+
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
|
+
}
|
|
698
|
+
|
|
699
|
+
// ------------------------------------------------------------------------
|
|
700
|
+
|
|
701
|
+
/**
|
|
702
|
+
* @brief Executes the subtest body by invoking the stored callable.
|
|
703
|
+
*
|
|
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
|
+
* @par Parameters
|
|
710
|
+
* None.
|
|
711
|
+
* @par Returns
|
|
712
|
+
* Nothing.
|
|
713
|
+
*/
|
|
714
|
+
virtual void
|
|
715
|
+
run (void) override;
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* @brief Returns the nesting depth of this subtest.
|
|
719
|
+
*
|
|
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
|
+
* @par Parameters
|
|
725
|
+
* None.
|
|
726
|
+
* @return The nesting depth (1 = top-level).
|
|
727
|
+
*/
|
|
728
|
+
[[nodiscard]] size_t
|
|
729
|
+
nesting_depth () const noexcept
|
|
730
|
+
{
|
|
731
|
+
return nesting_depth_;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
protected:
|
|
735
|
+
/**
|
|
736
|
+
* @brief Reference to the parent suite that owns this subtest.
|
|
737
|
+
*/
|
|
738
|
+
suite& parent_suite_;
|
|
739
|
+
|
|
740
|
+
/**
|
|
741
|
+
* @brief The nesting depth of this subtest within the suite.
|
|
742
|
+
*/
|
|
743
|
+
size_t nesting_depth_;
|
|
744
|
+
};
|
|
745
|
+
|
|
746
|
+
// ==========================================================================
|
|
747
|
+
|
|
748
|
+
/**
|
|
749
|
+
* @ingroup micro-test-plus-test-suites
|
|
750
|
+
* @brief A named, runnable test suite registered with the test runner.
|
|
751
|
+
*
|
|
752
|
+
* @details
|
|
753
|
+
* `suite` represents a top-level named group of related test cases within
|
|
754
|
+
* the µTest++ framework. It is created by calling `runner::suite()`, which
|
|
755
|
+
* constructs the object, stores it in the runner's collection, and runs it
|
|
756
|
+
* immediately. Each suite records its own timing information and propagates
|
|
757
|
+
* its results to the owning `runner`.
|
|
758
|
+
*
|
|
759
|
+
* The body of a suite is supplied as a callable (typically a lambda) that
|
|
760
|
+
* receives a `suite&` reference as its first argument. Inside the body,
|
|
761
|
+
* `suite::test()` is called to create and run individual subtests.
|
|
762
|
+
*
|
|
763
|
+
* The class is non-copyable and non-movable to preserve unique ownership
|
|
764
|
+
* and consistent state throughout the test session.
|
|
765
|
+
*
|
|
766
|
+
* @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
|
|
767
|
+
*/
|
|
768
|
+
class suite : public runnable<suite>
|
|
769
|
+
{
|
|
770
|
+
public:
|
|
771
|
+
/**
|
|
772
|
+
* @brief Constructs a suite with a name, runner, and callable body.
|
|
773
|
+
*
|
|
774
|
+
* @tparam Callable_T The type of the callable object.
|
|
775
|
+
* @tparam Args_T The types of any additional callable arguments.
|
|
776
|
+
*
|
|
777
|
+
* @param [in] name The suite name or description, used in reports.
|
|
778
|
+
* @param [in] runner The test runner managing this suite.
|
|
779
|
+
* @param [in] callable A generic callable object, usually a lambda,
|
|
780
|
+
* invoked when the suite executes. Its first parameter must be
|
|
781
|
+
* `suite&`.
|
|
782
|
+
* @param [in] arguments A possibly empty list of arguments forwarded to
|
|
783
|
+
* the callable after the leading `suite&` reference.
|
|
784
|
+
*
|
|
785
|
+
* @details
|
|
786
|
+
* The rule of five is enforced to prevent accidental copying or moving.
|
|
787
|
+
*/
|
|
788
|
+
template <typename Callable_T, typename... Args_T>
|
|
789
|
+
suite (const char* name, class runner& runner, Callable_T&& callable,
|
|
790
|
+
Args_T&&... arguments);
|
|
791
|
+
|
|
792
|
+
/**
|
|
793
|
+
* @brief Deleted copy constructor to prevent copying.
|
|
794
|
+
*/
|
|
795
|
+
suite (const suite&) = delete;
|
|
796
|
+
|
|
797
|
+
/**
|
|
798
|
+
* @brief Deleted move constructor to prevent moving.
|
|
799
|
+
*/
|
|
800
|
+
suite (suite&&) = delete;
|
|
801
|
+
|
|
802
|
+
/**
|
|
803
|
+
* @brief Deleted copy assignment operator to prevent copying.
|
|
804
|
+
*/
|
|
805
|
+
suite&
|
|
806
|
+
operator= (const suite&) = delete;
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* @brief Deleted move assignment operator to prevent moving.
|
|
810
|
+
*/
|
|
811
|
+
suite&
|
|
812
|
+
operator= (suite&&) = delete;
|
|
813
|
+
|
|
814
|
+
/**
|
|
815
|
+
* @brief Virtual destructor.
|
|
816
|
+
*/
|
|
817
|
+
virtual ~suite () override;
|
|
818
|
+
|
|
819
|
+
// ------------------------------------------------------------------------
|
|
820
|
+
|
|
821
|
+
/**
|
|
822
|
+
* @brief Adds a test case to the suite.
|
|
823
|
+
*
|
|
824
|
+
* @tparam Callable_T The type of a callable object.
|
|
825
|
+
* @tparam Args_T The types of the callable arguments.
|
|
826
|
+
*
|
|
827
|
+
* @param [in] name The test case name or description, used in reports.
|
|
828
|
+
* @param [in] callable A generic callable object, usually a lambda,
|
|
829
|
+
* invoked to perform the test.
|
|
830
|
+
* @param [in] arguments A possibly empty list of arguments to be passed to
|
|
831
|
+
* the callable.
|
|
832
|
+
*/
|
|
833
|
+
template <typename Callable_T, typename... Args_T>
|
|
834
|
+
void
|
|
835
|
+
test (const char* name, Callable_T&& callable, Args_T&&... arguments);
|
|
836
|
+
|
|
837
|
+
// ------------------------------------------------------------------------
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* @brief Gets the timings for this suite.
|
|
841
|
+
*
|
|
842
|
+
* @par Parameters
|
|
843
|
+
* None.
|
|
844
|
+
* @return A reference to the timestamps instance.
|
|
845
|
+
*/
|
|
846
|
+
[[nodiscard]] timestamps&
|
|
847
|
+
timings () noexcept
|
|
848
|
+
{
|
|
849
|
+
return timings_;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
/**
|
|
853
|
+
* @brief Gets the timings for this suite (const overload).
|
|
854
|
+
*
|
|
855
|
+
* @par Parameters
|
|
856
|
+
* None.
|
|
857
|
+
* @return A const reference to the timestamps instance.
|
|
858
|
+
*/
|
|
859
|
+
[[nodiscard]] const timestamps&
|
|
860
|
+
timings () const noexcept
|
|
861
|
+
{
|
|
862
|
+
return timings_;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
/**
|
|
866
|
+
* @brief Executes the suite body by invoking the stored callable.
|
|
867
|
+
*
|
|
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
|
+
* @par Parameters
|
|
874
|
+
* None.
|
|
875
|
+
* @par Returns
|
|
876
|
+
* Nothing.
|
|
877
|
+
*/
|
|
878
|
+
virtual void
|
|
879
|
+
run (void) override;
|
|
880
|
+
|
|
881
|
+
protected:
|
|
882
|
+
/**
|
|
883
|
+
* @brief Timing measurements for this suite's execution.
|
|
884
|
+
*/
|
|
885
|
+
timestamps timings_;
|
|
886
|
+
};
|
|
887
|
+
|
|
888
|
+
// ==========================================================================
|
|
889
|
+
|
|
890
|
+
/**
|
|
891
|
+
* @brief The implicit top-level suite owned by every `runner` instance.
|
|
892
|
+
*
|
|
893
|
+
* @details
|
|
894
|
+
* `top_suite` is a thin specialisation of `suite` used as the implicit
|
|
895
|
+
* root context for the `runner`. It is created by the `runner` constructor
|
|
896
|
+
* and is available to user code via `runner::initialise()`, which returns
|
|
897
|
+
* a reference to it. Unlike regular `suite` objects, `top_suite` is not
|
|
898
|
+
* stored in the runner's child-suite vector; instead it is a direct member
|
|
899
|
+
* of `runner`.
|
|
900
|
+
*
|
|
901
|
+
* Users do not normally construct `top_suite` directly.
|
|
902
|
+
*
|
|
903
|
+
* @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
|
|
904
|
+
*/
|
|
905
|
+
class top_suite : public suite
|
|
906
|
+
{
|
|
907
|
+
public:
|
|
908
|
+
/**
|
|
909
|
+
* @brief Constructs the top-level suite with a name and runner reference.
|
|
910
|
+
*
|
|
911
|
+
* @param name The suite name used in reports.
|
|
912
|
+
* @param runner The test runner that owns this suite.
|
|
913
|
+
*/
|
|
914
|
+
top_suite (const char* name, class runner& runner);
|
|
915
|
+
|
|
916
|
+
/**
|
|
917
|
+
* @brief Deleted copy constructor to prevent copying.
|
|
918
|
+
*/
|
|
919
|
+
top_suite (const top_suite&) = delete;
|
|
920
|
+
|
|
921
|
+
/**
|
|
922
|
+
* @brief Deleted move constructor to prevent moving.
|
|
923
|
+
*/
|
|
924
|
+
top_suite (top_suite&&) = delete;
|
|
925
|
+
|
|
926
|
+
/**
|
|
927
|
+
* @brief Deleted copy assignment operator to prevent copying.
|
|
928
|
+
*/
|
|
929
|
+
top_suite&
|
|
930
|
+
operator= (const top_suite&) = delete;
|
|
931
|
+
|
|
932
|
+
/**
|
|
933
|
+
* @brief Deleted move assignment operator to prevent moving.
|
|
934
|
+
*/
|
|
935
|
+
top_suite&
|
|
936
|
+
operator= (top_suite&&) = delete;
|
|
937
|
+
|
|
938
|
+
/**
|
|
939
|
+
* @brief Virtual destructor.
|
|
940
|
+
*/
|
|
941
|
+
virtual ~top_suite () override;
|
|
942
|
+
};
|
|
943
|
+
|
|
944
|
+
// ==========================================================================
|
|
945
|
+
|
|
946
|
+
/**
|
|
947
|
+
* @ingroup micro-test-plus-test-suites
|
|
948
|
+
* @brief A test suite designed for static (namespace-scope) registration
|
|
949
|
+
* with a `static_runner`.
|
|
950
|
+
*
|
|
951
|
+
* @details
|
|
952
|
+
* `static_suite` extends `suite` to support the pattern where test suites
|
|
953
|
+
* are declared as namespace-scope objects and therefore constructed before
|
|
954
|
+
* or after the `static_runner` instance, in unspecified
|
|
955
|
+
* static-initialisation order.
|
|
956
|
+
*
|
|
957
|
+
* Upon construction, the suite automatically registers itself with the
|
|
958
|
+
* supplied `static_runner` by calling
|
|
959
|
+
* `static_runner::register_suite_()`. The runner defers execution of all
|
|
960
|
+
* registered static suites until `static_runner::run_suites_()` is invoked,
|
|
961
|
+
* which typically happens inside the implicit `main()` provided by the
|
|
962
|
+
* framework.
|
|
963
|
+
*
|
|
964
|
+
* In addition to the standard callable body inherited from `suite`, a
|
|
965
|
+
* `static_suite` may carry a second, statically-registered callable stored
|
|
966
|
+
* in `static_callable_`. The overridden `run()` method invokes both bodies
|
|
967
|
+
* in sequence, allowing the suite to integrate both dynamic and static
|
|
968
|
+
* registration patterns.
|
|
969
|
+
*
|
|
970
|
+
* The class is non-copyable and non-movable to preserve unique ownership
|
|
971
|
+
* and consistent state throughout the test session.
|
|
972
|
+
*
|
|
973
|
+
* @headerfile micro-test-plus.h <micro-os-plus/micro-test-plus.h>
|
|
974
|
+
*/
|
|
975
|
+
class static_suite : public suite
|
|
976
|
+
{
|
|
977
|
+
public:
|
|
978
|
+
/**
|
|
979
|
+
* @brief Class template constructor for static_suite.
|
|
980
|
+
*
|
|
981
|
+
* @tparam Callable_T The type of a callable object.
|
|
982
|
+
* @tparam Args_T The types of the callable arguments.
|
|
983
|
+
*
|
|
984
|
+
* @param [in] name The test suite name or description, used in reports.
|
|
985
|
+
* @param [in] runner The static test runner managing this suite.
|
|
986
|
+
* @param [in] callable A generic callable object, usually a lambda or
|
|
987
|
+
* function, invoked to perform the test suite.
|
|
988
|
+
* @param [in] arguments A possibly empty list of arguments to be passed to
|
|
989
|
+
* 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
|
+
*/
|
|
996
|
+
template <typename Callable_T, typename... Args_T>
|
|
997
|
+
static_suite (const char* name, static_runner& runner,
|
|
998
|
+
Callable_T&& callable, Args_T&&... arguments);
|
|
999
|
+
|
|
1000
|
+
/**
|
|
1001
|
+
* @brief Deleted copy constructor to prevent copying.
|
|
1002
|
+
*/
|
|
1003
|
+
static_suite (const static_suite&) = delete;
|
|
1004
|
+
|
|
1005
|
+
/**
|
|
1006
|
+
* @brief Deleted move constructor to prevent moving.
|
|
1007
|
+
*/
|
|
1008
|
+
static_suite (static_suite&&) = delete;
|
|
1009
|
+
|
|
1010
|
+
/**
|
|
1011
|
+
* @brief Deleted copy assignment operator to prevent copying.
|
|
1012
|
+
*/
|
|
1013
|
+
static_suite&
|
|
1014
|
+
operator= (const static_suite&) = delete;
|
|
1015
|
+
|
|
1016
|
+
/**
|
|
1017
|
+
* @brief Deleted move assignment operator to prevent moving.
|
|
1018
|
+
*/
|
|
1019
|
+
static_suite&
|
|
1020
|
+
operator= (static_suite&&) = delete;
|
|
1021
|
+
|
|
1022
|
+
/**
|
|
1023
|
+
* @brief Virtual destructor.
|
|
1024
|
+
*/
|
|
1025
|
+
virtual ~static_suite () override;
|
|
1026
|
+
|
|
1027
|
+
// ------------------------------------------------------------------------
|
|
1028
|
+
|
|
1029
|
+
/**
|
|
1030
|
+
* @brief Executes the static suite body using the stored static callable.
|
|
1031
|
+
*
|
|
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
|
+
* @par Parameters
|
|
1039
|
+
* None.
|
|
1040
|
+
* @par Returns
|
|
1041
|
+
* Nothing.
|
|
1042
|
+
*/
|
|
1043
|
+
virtual void
|
|
1044
|
+
run (void) override;
|
|
1045
|
+
|
|
1046
|
+
protected:
|
|
1047
|
+
/**
|
|
1048
|
+
* @brief Callable storing the static suite body and any bound arguments.
|
|
1049
|
+
* Invoked with a reference to the concrete `static_suite` instance.
|
|
1050
|
+
*/
|
|
1051
|
+
std::function<void (static_suite&)> static_callable_;
|
|
1052
|
+
};
|
|
1053
|
+
|
|
1054
|
+
// --------------------------------------------------------------------------
|
|
1055
|
+
} // namespace micro_os_plus::micro_test_plus
|
|
1056
|
+
|
|
1057
|
+
#if defined(__GNUC__)
|
|
1058
|
+
#pragma GCC diagnostic pop
|
|
1059
|
+
#endif
|
|
1060
|
+
|
|
1061
|
+
// ----------------------------------------------------------------------------
|
|
1062
|
+
|
|
1063
|
+
#endif // __cplusplus
|
|
1064
|
+
|
|
1065
|
+
// ----------------------------------------------------------------------------
|
|
1066
|
+
|
|
1067
|
+
#endif // MICRO_TEST_PLUS_TEST_H_
|
|
1068
|
+
|
|
1069
|
+
// ----------------------------------------------------------------------------
|