@micro-os-plus/micro-test-plus 2.1.1 → 3.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 +42 -0
- package/CMakeLists.txt +15 -26
- package/LICENSE-Boost +23 -0
- package/README.md +1007 -255
- package/docs/NOTES.md +7 -0
- package/include/micro-os-plus/detail.h +733 -0
- package/include/micro-os-plus/inlines.h +182 -0
- package/include/micro-os-plus/literals.h +285 -0
- package/include/micro-os-plus/math.h +205 -0
- package/include/micro-os-plus/micro-test-plus.h +488 -102
- package/include/micro-os-plus/reflection.h +134 -0
- package/include/micro-os-plus/test-reporter-inlines.h +231 -0
- package/include/micro-os-plus/test-reporter.h +347 -0
- package/include/micro-os-plus/test-runner.h +132 -0
- package/include/micro-os-plus/test-suite.h +242 -0
- package/include/micro-os-plus/type-traits.h +346 -0
- package/meson.build +35 -11
- package/package.json +243 -147
- package/src/micro-test-plus.cpp +105 -188
- package/src/test-reporter.cpp +423 -0
- package/src/test-runner.cpp +183 -0
- package/src/test-suite.cpp +117 -0
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* This file is part of the µOS++ distribution.
|
|
3
|
-
* (https://github.com/micro-os-plus)
|
|
3
|
+
* (https://github.com/micro-os-plus/)
|
|
4
4
|
* Copyright (c) 2021 Liviu Ionescu.
|
|
5
5
|
*
|
|
6
6
|
* Permission to use, copy, modify, and/or distribute this software
|
|
7
7
|
* for any purpose is hereby granted, under the terms of the MIT license.
|
|
8
|
+
*
|
|
9
|
+
* If a copy of the license was not distributed with this file, it can
|
|
10
|
+
* be obtained from <https://opensource.org/licenses/MIT/>.
|
|
11
|
+
*
|
|
12
|
+
* Major parts of the code are inspired from v1.1.8 of the Boost UT project,
|
|
13
|
+
* released under the terms of the Boost Version 1.0 Software License,
|
|
14
|
+
* which can be obtained from <https://www.boost.org/LICENSE_1_0.txt>.
|
|
8
15
|
*/
|
|
9
16
|
|
|
10
17
|
#ifndef MICRO_TEST_PLUS_MICRO_TEST_PLUS_H_
|
|
@@ -16,130 +23,509 @@
|
|
|
16
23
|
|
|
17
24
|
// ----------------------------------------------------------------------------
|
|
18
25
|
|
|
26
|
+
#if defined(MICRO_OS_PLUS_INCLUDE_CONFIG_H)
|
|
27
|
+
#include <micro-os-plus/config.h>
|
|
28
|
+
#endif // MICRO_OS_PLUS_INCLUDE_CONFIG_H
|
|
29
|
+
|
|
30
|
+
#include "reflection.h"
|
|
31
|
+
#include "math.h"
|
|
32
|
+
#include "type-traits.h"
|
|
33
|
+
#include "literals.h"
|
|
34
|
+
#include "test-suite.h"
|
|
35
|
+
#include "test-runner.h"
|
|
36
|
+
#include "test-reporter.h"
|
|
37
|
+
#include "detail.h"
|
|
38
|
+
|
|
39
|
+
// ----------------------------------------------------------------------------
|
|
40
|
+
|
|
19
41
|
#if defined(__GNUC__)
|
|
20
42
|
#pragma GCC diagnostic push
|
|
43
|
+
#pragma GCC diagnostic ignored "-Wpadded"
|
|
44
|
+
#pragma GCC diagnostic ignored "-Waggregate-return"
|
|
21
45
|
#if defined(__clang__)
|
|
22
46
|
#pragma clang diagnostic ignored "-Wc++98-compat"
|
|
47
|
+
#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
|
|
48
|
+
#pragma clang diagnostic ignored "-Wctad-maybe-unsupported"
|
|
23
49
|
#endif
|
|
24
50
|
#endif
|
|
25
51
|
|
|
26
|
-
namespace micro_os_plus
|
|
52
|
+
namespace micro_os_plus::micro_test_plus
|
|
27
53
|
{
|
|
28
|
-
|
|
54
|
+
// --------------------------------------------------------------------------
|
|
55
|
+
|
|
56
|
+
extern test_runner runner;
|
|
57
|
+
extern test_reporter reporter;
|
|
58
|
+
extern test_suite_base* current_test_suite;
|
|
59
|
+
|
|
60
|
+
// --------------------------------------------------------------------------
|
|
61
|
+
// Public API.
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @brief Initialize the test framework.
|
|
65
|
+
*/
|
|
66
|
+
void
|
|
67
|
+
initialize (int argc, char* argv[], const char* name = "Main");
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @brief Define and execute a test case.
|
|
71
|
+
*/
|
|
72
|
+
template <typename Callable_T, typename... Args_T>
|
|
73
|
+
void
|
|
74
|
+
test_case (const char* name, Callable_T&& func, Args_T&&... arguments);
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @brief Trigger the execution of the globally registered test suites
|
|
78
|
+
* and return the test result.
|
|
79
|
+
*/
|
|
80
|
+
[[nodiscard]] int
|
|
81
|
+
exit_code (void);
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @brief Evaluate a generic condition. The expression must use
|
|
85
|
+
* the provided `eq(), ne(), lt(), le(), gt(), ge()` comparators,
|
|
86
|
+
* or, if the custom operators are used, to include custom type
|
|
87
|
+
* operands, otherwise support for identifying the failed check
|
|
88
|
+
* is not provided.
|
|
89
|
+
*
|
|
90
|
+
* The template is usable only for expressions that evaluate to
|
|
91
|
+
* a boolean or use custom comparators/operators derived from the
|
|
92
|
+
* local `op` type.
|
|
93
|
+
*/
|
|
94
|
+
template <
|
|
95
|
+
class Expr_T,
|
|
96
|
+
type_traits::requires_t<
|
|
97
|
+
type_traits::is_op_v<
|
|
98
|
+
Expr_T> or type_traits::is_convertible_v<Expr_T, bool>> = 0>
|
|
99
|
+
constexpr auto
|
|
100
|
+
expect (const Expr_T& expr, const reflection::source_location& sl
|
|
101
|
+
= reflection::source_location::current ())
|
|
29
102
|
{
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
103
|
+
return detail::deferred_reporter<Expr_T>{ expr, false, sl };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @brief Check a condition and, if false, abort.
|
|
108
|
+
*
|
|
109
|
+
* The template is usable only for expressions that evaluate to
|
|
110
|
+
* a boolean or use custom comparators/operators derived from the
|
|
111
|
+
* local `op` type.
|
|
112
|
+
*/
|
|
113
|
+
template <
|
|
114
|
+
class Expr_T,
|
|
115
|
+
type_traits::requires_t<
|
|
116
|
+
type_traits::is_op_v<
|
|
117
|
+
Expr_T> or type_traits::is_convertible_v<Expr_T, bool>> = 0>
|
|
118
|
+
constexpr auto
|
|
119
|
+
assume (const Expr_T& expr, const reflection::source_location& sl
|
|
120
|
+
= reflection::source_location::current ())
|
|
121
|
+
{
|
|
122
|
+
return detail::deferred_reporter<Expr_T>{ expr, true, sl };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// --------------------------------------------------------------------------
|
|
126
|
+
|
|
127
|
+
#if defined(__cpp_exceptions)
|
|
128
|
+
/**
|
|
129
|
+
* @brief Check if a callable throws a specific exception.
|
|
130
|
+
*/
|
|
131
|
+
template <class Exception_T, class Callable_T>
|
|
132
|
+
[[nodiscard]] constexpr auto
|
|
133
|
+
throws (const Callable_T& func)
|
|
134
|
+
{
|
|
135
|
+
return detail::throws_<Callable_T, Exception_T>{ func };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @brief Check if a callable throws an exception (any exception).
|
|
140
|
+
*/
|
|
141
|
+
template <class Callable_T>
|
|
142
|
+
[[nodiscard]] constexpr auto
|
|
143
|
+
throws (const Callable_T& func)
|
|
144
|
+
{
|
|
145
|
+
return detail::throws_<Callable_T>{ func };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* @brief Check if a callable doesn't throw an exception.
|
|
150
|
+
*/
|
|
151
|
+
template <class Callable_T>
|
|
152
|
+
[[nodiscard]] constexpr auto
|
|
153
|
+
nothrow (const Callable_T& func)
|
|
154
|
+
{
|
|
155
|
+
return detail::nothrow_{ func };
|
|
156
|
+
}
|
|
34
157
|
#endif
|
|
35
158
|
|
|
36
|
-
|
|
37
|
-
{
|
|
38
|
-
public:
|
|
39
|
-
session ();
|
|
40
|
-
|
|
41
|
-
session (int argc, char* argv[]);
|
|
159
|
+
// --------------------------------------------------------------------------
|
|
42
160
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
161
|
+
/**
|
|
162
|
+
* @brief Generic equality comparator. Matches any
|
|
163
|
+
* non-pointer type.
|
|
164
|
+
*/
|
|
165
|
+
template <class Lhs_T, class Rhs_T>
|
|
166
|
+
[[nodiscard]] constexpr auto
|
|
167
|
+
eq (const Lhs_T& lhs, const Rhs_T& rhs)
|
|
168
|
+
{
|
|
169
|
+
return detail::eq_{ lhs, rhs };
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* @brief Pointer equality comparator. Matches pointers
|
|
174
|
+
* to any types.
|
|
175
|
+
*/
|
|
176
|
+
template <class Lhs_T, class Rhs_T>
|
|
177
|
+
[[nodiscard]] constexpr auto
|
|
178
|
+
eq (Lhs_T* lhs, Rhs_T* rhs)
|
|
179
|
+
{
|
|
180
|
+
return detail::eq_{ lhs, rhs };
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* @brief Generic non-equality comparator.
|
|
185
|
+
*/
|
|
186
|
+
template <class Lhs_T, class Rhs_T>
|
|
187
|
+
[[nodiscard]] constexpr auto
|
|
188
|
+
ne (const Lhs_T& lhs, const Rhs_T& rhs)
|
|
189
|
+
{
|
|
190
|
+
return detail::ne_{ lhs, rhs };
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* @brief Pointer non-equality comparator.
|
|
195
|
+
*/
|
|
196
|
+
template <class Lhs_T, class Rhs_T>
|
|
197
|
+
[[nodiscard]] constexpr auto
|
|
198
|
+
ne (Lhs_T* lhs, Rhs_T* rhs)
|
|
199
|
+
{
|
|
200
|
+
return detail::ne_{ lhs, rhs };
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* @brief Generic greater than comparator.
|
|
205
|
+
*/
|
|
206
|
+
template <class Lhs_T, class Rhs_T>
|
|
207
|
+
[[nodiscard]] constexpr auto
|
|
208
|
+
gt (const Lhs_T& lhs, const Rhs_T& rhs)
|
|
209
|
+
{
|
|
210
|
+
return detail::gt_{ lhs, rhs };
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* @brief Pointer greater than comparator.
|
|
215
|
+
*/
|
|
216
|
+
template <class Lhs_T, class Rhs_T>
|
|
217
|
+
[[nodiscard]] constexpr auto
|
|
218
|
+
gt (Lhs_T* lhs, Rhs_T* rhs)
|
|
219
|
+
{
|
|
220
|
+
return detail::gt_{ lhs, rhs };
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* @brief Generic greater than or equal comparator.
|
|
225
|
+
*/
|
|
226
|
+
template <class Lhs_T, class Rhs_T>
|
|
227
|
+
[[nodiscard]] constexpr auto
|
|
228
|
+
ge (const Lhs_T& lhs, const Rhs_T& rhs)
|
|
229
|
+
{
|
|
230
|
+
return detail::ge_{ lhs, rhs };
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* @brief Pointer greater than or equal comparator.
|
|
235
|
+
*/
|
|
236
|
+
template <class Lhs_T, class Rhs_T>
|
|
237
|
+
[[nodiscard]] constexpr auto
|
|
238
|
+
ge (Lhs_T* lhs, Rhs_T* rhs)
|
|
239
|
+
{
|
|
240
|
+
return detail::ge_{ lhs, rhs };
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* @brief Generic less than comparator.
|
|
245
|
+
*/
|
|
246
|
+
template <class Lhs_T, class Rhs_T>
|
|
247
|
+
[[nodiscard]] constexpr auto
|
|
248
|
+
lt (const Lhs_T& lhs, const Rhs_T& rhs)
|
|
249
|
+
{
|
|
250
|
+
return detail::lt_{ lhs, rhs };
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* @brief Generic less than comparator.
|
|
255
|
+
*/
|
|
256
|
+
template <class Lhs_T, class Rhs_T>
|
|
257
|
+
[[nodiscard]] constexpr auto
|
|
258
|
+
lt (Lhs_T* lhs, Rhs_T* rhs)
|
|
259
|
+
{
|
|
260
|
+
return detail::lt_{ lhs, rhs };
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* @brief Generic less than or equal comparator.
|
|
265
|
+
*/
|
|
266
|
+
template <class Lhs_T, class Rhs_T>
|
|
267
|
+
[[nodiscard]] constexpr auto
|
|
268
|
+
le (const Lhs_T& lhs, const Rhs_T& rhs)
|
|
269
|
+
{
|
|
270
|
+
return detail::le_{ lhs, rhs };
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* @brief Generic less than or equal comparator.
|
|
275
|
+
*/
|
|
276
|
+
template <class Lhs_T, class Rhs_T>
|
|
277
|
+
[[nodiscard]] constexpr auto
|
|
278
|
+
le (Lhs_T* lhs, Rhs_T* rhs)
|
|
279
|
+
{
|
|
280
|
+
return detail::le_{ lhs, rhs };
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* @brief Generic logical not. The underscore is intentional,
|
|
285
|
+
* to differentiate from the standard operator.
|
|
286
|
+
*/
|
|
287
|
+
template <class Expr_T>
|
|
288
|
+
[[nodiscard]] constexpr auto
|
|
289
|
+
_not (const Expr_T& expr)
|
|
290
|
+
{
|
|
291
|
+
return detail::not_{ expr };
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* @brief Generic logical and. The underscore is intentional,
|
|
296
|
+
* to differentiate from the standard operator.
|
|
297
|
+
*/
|
|
298
|
+
template <class Lhs_T, class Rhs_T>
|
|
299
|
+
[[nodiscard]] constexpr auto
|
|
300
|
+
_and (const Lhs_T& lhs, const Rhs_T& rhs)
|
|
301
|
+
{
|
|
302
|
+
return detail::and_{ lhs, rhs };
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* @brief Generic logical or. The underscore is intentional,
|
|
307
|
+
* to differentiate from the standard operator.
|
|
308
|
+
*/
|
|
309
|
+
template <class Lhs_T, class Rhs_T>
|
|
310
|
+
[[nodiscard]] constexpr auto
|
|
311
|
+
_or (const Lhs_T& lhs, const Rhs_T& rhs)
|
|
312
|
+
{
|
|
313
|
+
return detail::or_{ lhs, rhs };
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* @brief Generic mutator, to remove const from any type.
|
|
318
|
+
*/
|
|
319
|
+
template <class T>
|
|
320
|
+
[[nodiscard]] constexpr auto
|
|
321
|
+
mut (const T& t) noexcept -> T&
|
|
322
|
+
{
|
|
323
|
+
return const_cast<T&> (t);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// --------------------------------------------------------------------------
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* @brief Separate namespace with custom operators.
|
|
330
|
+
*
|
|
331
|
+
* @warning Please note that they
|
|
332
|
+
* may interfere with other operators existing in the tested application.
|
|
333
|
+
*
|
|
334
|
+
* To minimise the interferences, these operators are recognised only
|
|
335
|
+
* for specific types, and generally require constants to be
|
|
336
|
+
* suffixed with literals (like `1_i`), and dynamic values to be
|
|
337
|
+
* casted to the custom types (like `_i(...)`).
|
|
338
|
+
*/
|
|
339
|
+
namespace operators
|
|
340
|
+
{
|
|
341
|
+
/**
|
|
342
|
+
* @brief Equality operator for string_view objects.
|
|
343
|
+
*/
|
|
344
|
+
[[nodiscard]] constexpr auto
|
|
345
|
+
operator== (std::string_view lhs, std::string_view rhs)
|
|
346
|
+
{
|
|
347
|
+
return detail::eq_{ lhs, rhs };
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* @brief Non-equality operator for string_view objects.
|
|
352
|
+
*/
|
|
353
|
+
[[nodiscard]] constexpr auto
|
|
354
|
+
operator!= (std::string_view lhs, std::string_view rhs)
|
|
355
|
+
{
|
|
356
|
+
return detail::ne_{ lhs, rhs };
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* @brief Equality operator for containers.
|
|
361
|
+
*/
|
|
362
|
+
template <class T,
|
|
363
|
+
type_traits::requires_t<type_traits::is_container_v<T>> = 0>
|
|
364
|
+
[[nodiscard]] constexpr auto
|
|
365
|
+
operator== (T&& lhs, T&& rhs)
|
|
366
|
+
{
|
|
367
|
+
return detail::eq_{ static_cast<T&&> (lhs), static_cast<T&&> (rhs) };
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* @brief Non-equality operator for containers.
|
|
372
|
+
*/
|
|
373
|
+
template <class T,
|
|
374
|
+
type_traits::requires_t<type_traits::is_container_v<T>> = 0>
|
|
375
|
+
[[nodiscard]] constexpr auto
|
|
376
|
+
operator!= (T&& lhs, T&& rhs)
|
|
377
|
+
{
|
|
378
|
+
return detail::ne_{ static_cast<T&&> (lhs), static_cast<T&&> (rhs) };
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* @brief Equality operator. It matches only if at least one
|
|
383
|
+
* operand is of local type (derived from local `op`).
|
|
384
|
+
*/
|
|
385
|
+
template <
|
|
386
|
+
class Lhs_T, class Rhs_T,
|
|
387
|
+
type_traits::requires_t<
|
|
388
|
+
type_traits::is_op_v<Lhs_T> or type_traits::is_op_v<Rhs_T>> = 0>
|
|
389
|
+
[[nodiscard]] constexpr auto
|
|
390
|
+
operator== (const Lhs_T& lhs, const Rhs_T& rhs)
|
|
391
|
+
{
|
|
392
|
+
return detail::eq_{ lhs, rhs };
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* @brief Non-equality operator. It matches only if at least one
|
|
397
|
+
* operand is of local type (derived from local `op`).
|
|
398
|
+
*/
|
|
399
|
+
template <
|
|
400
|
+
class Lhs_T, class Rhs_T,
|
|
401
|
+
type_traits::requires_t<
|
|
402
|
+
type_traits::is_op_v<Lhs_T> or type_traits::is_op_v<Rhs_T>> = 0>
|
|
403
|
+
[[nodiscard]] constexpr auto
|
|
404
|
+
operator!= (const Lhs_T& lhs, const Rhs_T& rhs)
|
|
405
|
+
{
|
|
406
|
+
return detail::ne_{ lhs, rhs };
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* @brief Greater than operator. It matches only if at least one
|
|
411
|
+
* operand is of local type (derived from local `op`).
|
|
412
|
+
*/
|
|
413
|
+
template <
|
|
414
|
+
class Lhs_T, class Rhs_T,
|
|
415
|
+
type_traits::requires_t<
|
|
416
|
+
type_traits::is_op_v<Lhs_T> or type_traits::is_op_v<Rhs_T>> = 0>
|
|
417
|
+
[[nodiscard]] constexpr auto
|
|
418
|
+
operator> (const Lhs_T& lhs, const Rhs_T& rhs)
|
|
419
|
+
{
|
|
420
|
+
return detail::gt_{ lhs, rhs };
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* @brief Greater than or equal operator. It matches only if at least one
|
|
425
|
+
* operand is of local type (derived from local `op`).
|
|
426
|
+
*/
|
|
427
|
+
template <
|
|
428
|
+
class Lhs_T, class Rhs_T,
|
|
429
|
+
type_traits::requires_t<
|
|
430
|
+
type_traits::is_op_v<Lhs_T> or type_traits::is_op_v<Rhs_T>> = 0>
|
|
431
|
+
[[nodiscard]] constexpr auto
|
|
432
|
+
operator>= (const Lhs_T& lhs, const Rhs_T& rhs)
|
|
433
|
+
{
|
|
434
|
+
return detail::ge_{ lhs, rhs };
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* @brief Less than operator. It matches only if at least one
|
|
439
|
+
* operand is of local type (derived from local `op`).
|
|
440
|
+
*/
|
|
441
|
+
template <
|
|
442
|
+
class Lhs_T, class Rhs_T,
|
|
443
|
+
type_traits::requires_t<
|
|
444
|
+
type_traits::is_op_v<Lhs_T> or type_traits::is_op_v<Rhs_T>> = 0>
|
|
445
|
+
[[nodiscard]] constexpr auto
|
|
446
|
+
operator< (const Lhs_T& lhs, const Rhs_T& rhs)
|
|
447
|
+
{
|
|
448
|
+
return detail::lt_{ lhs, rhs };
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* @brief Less than or equal operator. It matches only if at least one
|
|
453
|
+
* operand is of local type (derived from local `op`).
|
|
454
|
+
*/
|
|
455
|
+
template <
|
|
456
|
+
class Lhs_T, class Rhs_T,
|
|
457
|
+
type_traits::requires_t<
|
|
458
|
+
type_traits::is_op_v<Lhs_T> or type_traits::is_op_v<Rhs_T>> = 0>
|
|
459
|
+
[[nodiscard]] constexpr auto
|
|
460
|
+
operator<= (const Lhs_T& lhs, const Rhs_T& rhs)
|
|
461
|
+
{
|
|
462
|
+
return detail::le_{ lhs, rhs };
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* @brief Logical `and` operator. It matches only if at least one
|
|
467
|
+
* operand is of local type (derived from local `op`).
|
|
468
|
+
*/
|
|
469
|
+
template <
|
|
470
|
+
class Lhs_T, class Rhs_T,
|
|
471
|
+
type_traits::requires_t<
|
|
472
|
+
type_traits::is_op_v<Lhs_T> or type_traits::is_op_v<Rhs_T>> = 0>
|
|
473
|
+
[[nodiscard]] constexpr auto
|
|
474
|
+
operator and (const Lhs_T& lhs, const Rhs_T& rhs)
|
|
475
|
+
{
|
|
476
|
+
return detail::and_{ lhs, rhs };
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* @brief Logical `or` operator. It matches only if at least one
|
|
481
|
+
* operand is of local type (derived from local `op`).
|
|
482
|
+
*/
|
|
483
|
+
template <
|
|
484
|
+
class Lhs_T, class Rhs_T,
|
|
485
|
+
type_traits::requires_t<
|
|
486
|
+
type_traits::is_op_v<Lhs_T> or type_traits::is_op_v<Rhs_T>> = 0>
|
|
487
|
+
[[nodiscard]] constexpr auto
|
|
488
|
+
operator or (const Lhs_T& lhs, const Rhs_T& rhs)
|
|
489
|
+
{
|
|
490
|
+
return detail::or_{ lhs, rhs };
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* @brief Logical `not` operator. It matches only if the
|
|
495
|
+
* operand is of local type (derived from local `op`).
|
|
496
|
+
*/
|
|
497
|
+
template <class T, type_traits::requires_t<type_traits::is_op_v<T>> = 0>
|
|
498
|
+
[[nodiscard]] constexpr auto
|
|
499
|
+
operator not (const T& t)
|
|
500
|
+
{
|
|
501
|
+
return detail::not_{ t };
|
|
502
|
+
}
|
|
503
|
+
} // namespace operators
|
|
113
504
|
|
|
114
|
-
|
|
505
|
+
namespace utility
|
|
506
|
+
{
|
|
507
|
+
[[nodiscard]] bool
|
|
508
|
+
is_match (std::string_view input, std::string_view pattern);
|
|
115
509
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
};
|
|
510
|
+
template <class T, class Delim_T>
|
|
511
|
+
[[nodiscard]] auto
|
|
512
|
+
split (T input, Delim_T delim) -> std::vector<T>;
|
|
120
513
|
|
|
121
|
-
|
|
122
|
-
#pragma GCC diagnostic pop
|
|
123
|
-
#endif
|
|
514
|
+
} // namespace utility
|
|
124
515
|
|
|
125
|
-
|
|
126
|
-
} // namespace micro_os_plus
|
|
516
|
+
// --------------------------------------------------------------------------
|
|
517
|
+
} // namespace micro_os_plus::micro_test_plus
|
|
127
518
|
|
|
128
519
|
#if defined(__GNUC__)
|
|
129
520
|
#pragma GCC diagnostic pop
|
|
130
521
|
#endif
|
|
131
522
|
|
|
132
|
-
//
|
|
523
|
+
// ===== Inline & template implementations ====================================
|
|
133
524
|
|
|
134
|
-
|
|
135
|
-
// otherwise the direct methods can be used as well.
|
|
136
|
-
#define MTP_EXPECT_EQ(t, actual, expected, message) \
|
|
137
|
-
t.expect_eq (actual, expected, message, __FILE__, __LINE__)
|
|
138
|
-
#define MTP_EXPECT_TRUE(t, condition, message) \
|
|
139
|
-
t.expect_true (condition, message, __FILE__, __LINE__)
|
|
525
|
+
#include "test-reporter-inlines.h"
|
|
140
526
|
|
|
141
|
-
|
|
142
|
-
#
|
|
527
|
+
// All other inlines.
|
|
528
|
+
#include "inlines.h"
|
|
143
529
|
|
|
144
530
|
// ----------------------------------------------------------------------------
|
|
145
531
|
|