@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
|
@@ -0,0 +1,733 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of the µOS++ distribution.
|
|
3
|
+
* (https://github.com/micro-os-plus/)
|
|
4
|
+
* Copyright (c) 2021 Liviu Ionescu.
|
|
5
|
+
*
|
|
6
|
+
* Permission to use, copy, modify, and/or distribute this software
|
|
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>.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#ifndef MICRO_TEST_PLUS_DETAIL_H_
|
|
18
|
+
#define MICRO_TEST_PLUS_DETAIL_H_
|
|
19
|
+
|
|
20
|
+
// ----------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
#ifdef __cplusplus
|
|
23
|
+
|
|
24
|
+
// ----------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
#include <stdio.h>
|
|
27
|
+
|
|
28
|
+
// ----------------------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
#if defined(__GNUC__)
|
|
31
|
+
#pragma GCC diagnostic push
|
|
32
|
+
#pragma GCC diagnostic ignored "-Wpadded"
|
|
33
|
+
#pragma GCC diagnostic ignored "-Waggregate-return"
|
|
34
|
+
#if defined(__clang__)
|
|
35
|
+
#pragma clang diagnostic ignored "-Wc++98-compat"
|
|
36
|
+
#endif
|
|
37
|
+
#endif
|
|
38
|
+
|
|
39
|
+
namespace micro_os_plus::micro_test_plus
|
|
40
|
+
{
|
|
41
|
+
// --------------------------------------------------------------------------
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @brief Implementation details, not part of the public API.
|
|
45
|
+
*/
|
|
46
|
+
namespace detail
|
|
47
|
+
{
|
|
48
|
+
/**
|
|
49
|
+
* @brief An object used to pass assertion parameters to the evaluator.
|
|
50
|
+
*/
|
|
51
|
+
template <class Expr_T>
|
|
52
|
+
struct assertion
|
|
53
|
+
{
|
|
54
|
+
Expr_T expr{};
|
|
55
|
+
reflection::source_location location{};
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// ------------------------------------------------------------------------
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @brief Generic getter implementation. If the type has
|
|
62
|
+
* a get() method, call it. It is recommended for custom types
|
|
63
|
+
* to define a get() method.
|
|
64
|
+
*/
|
|
65
|
+
template <class T>
|
|
66
|
+
[[nodiscard]] constexpr auto
|
|
67
|
+
get_impl (const T& t, int) -> decltype (t.get ())
|
|
68
|
+
{
|
|
69
|
+
return t.get ();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @brief Variadic getter implementation that returns the
|
|
74
|
+
* first argument and discards the rest.
|
|
75
|
+
*/
|
|
76
|
+
template <class T>
|
|
77
|
+
[[nodiscard]] constexpr auto
|
|
78
|
+
get_impl (const T& t, ...) -> decltype (auto)
|
|
79
|
+
{
|
|
80
|
+
return t;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @brief Generic getter, calling the getter implementation.
|
|
85
|
+
*/
|
|
86
|
+
template <class T>
|
|
87
|
+
[[nodiscard]] constexpr auto
|
|
88
|
+
get (const T& t)
|
|
89
|
+
{
|
|
90
|
+
// Call the variadic function, besically to force it return `t`.
|
|
91
|
+
return get_impl (t, 0);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ------------------------------------------------------------------------
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @brief Equality comparator.
|
|
98
|
+
*/
|
|
99
|
+
template <class Lhs_T, class Rhs_T>
|
|
100
|
+
struct eq_ : type_traits::op
|
|
101
|
+
{
|
|
102
|
+
constexpr eq_ (const Lhs_T& lhs = {}, const Rhs_T& rhs = {})
|
|
103
|
+
: lhs_{ lhs }, rhs_{ rhs }, value_{ [&] {
|
|
104
|
+
// This lambda is called in the constructor to
|
|
105
|
+
// evaluate the comparison.
|
|
106
|
+
using std::operator==;
|
|
107
|
+
using std::operator<;
|
|
108
|
+
|
|
109
|
+
#if defined(__GNUC__)
|
|
110
|
+
#pragma GCC diagnostic push
|
|
111
|
+
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
|
112
|
+
#pragma GCC diagnostic ignored "-Wconversion"
|
|
113
|
+
#pragma GCC diagnostic ignored "-Wdouble-promotion"
|
|
114
|
+
#pragma GCC diagnostic ignored "-Wsign-compare"
|
|
115
|
+
#if defined(__clang__)
|
|
116
|
+
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"
|
|
117
|
+
#pragma clang diagnostic ignored "-Wpedantic"
|
|
118
|
+
#endif
|
|
119
|
+
#endif
|
|
120
|
+
if constexpr (type_traits::has_value_v<
|
|
121
|
+
Lhs_T> and type_traits::has_value_v<Rhs_T>)
|
|
122
|
+
{
|
|
123
|
+
// If both types have values (like numeric constants),
|
|
124
|
+
// compare them directly.
|
|
125
|
+
return Lhs_T::value == Rhs_T::value;
|
|
126
|
+
}
|
|
127
|
+
else if constexpr (
|
|
128
|
+
type_traits::has_epsilon_v<
|
|
129
|
+
Lhs_T> and type_traits::has_epsilon_v<Rhs_T>)
|
|
130
|
+
{
|
|
131
|
+
// If both values have precision, compare them using
|
|
132
|
+
// the smalles precision.
|
|
133
|
+
return math::abs (get (lhs) - get (rhs))
|
|
134
|
+
< math::min_value (Lhs_T::epsilon, Rhs_T::epsilon);
|
|
135
|
+
}
|
|
136
|
+
else if constexpr (type_traits::has_epsilon_v<Lhs_T>)
|
|
137
|
+
{
|
|
138
|
+
// If only the left operand has precision, use it.
|
|
139
|
+
return math::abs (get (lhs) - get (rhs)) < Lhs_T::epsilon;
|
|
140
|
+
}
|
|
141
|
+
else if constexpr (type_traits::has_epsilon_v<Rhs_T>)
|
|
142
|
+
{
|
|
143
|
+
// If only the right operand has precision, use it.
|
|
144
|
+
return math::abs (get (lhs) - get (rhs)) < Rhs_T::epsilon;
|
|
145
|
+
}
|
|
146
|
+
else
|
|
147
|
+
{
|
|
148
|
+
// Call the generic getters, which might
|
|
149
|
+
// either call the type get() or return the value.
|
|
150
|
+
return get (lhs) == get (rhs);
|
|
151
|
+
}
|
|
152
|
+
#if defined(__GNUC__)
|
|
153
|
+
#pragma GCC diagnostic pop
|
|
154
|
+
#endif
|
|
155
|
+
}() }
|
|
156
|
+
{
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
[[nodiscard]] constexpr operator bool () const
|
|
160
|
+
{
|
|
161
|
+
return value_;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
[[nodiscard]] constexpr auto
|
|
165
|
+
lhs () const
|
|
166
|
+
{
|
|
167
|
+
return get (lhs_);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
[[nodiscard]] constexpr auto
|
|
171
|
+
rhs () const
|
|
172
|
+
{
|
|
173
|
+
return get (rhs_);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const Lhs_T lhs_{};
|
|
177
|
+
const Rhs_T rhs_{};
|
|
178
|
+
const bool value_{};
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* @brief Non-equality comparator.
|
|
183
|
+
*/
|
|
184
|
+
template <class Lhs_T, class Rhs_T>
|
|
185
|
+
struct ne_ : type_traits::op
|
|
186
|
+
{
|
|
187
|
+
constexpr ne_ (const Lhs_T& lhs = {}, const Rhs_T& rhs = {})
|
|
188
|
+
: lhs_{ lhs }, rhs_{ rhs }, value_{ [&] {
|
|
189
|
+
using std::operator==;
|
|
190
|
+
using std::operator!=;
|
|
191
|
+
using std::operator>;
|
|
192
|
+
|
|
193
|
+
#if defined(__GNUC__)
|
|
194
|
+
#pragma GCC diagnostic push
|
|
195
|
+
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
|
196
|
+
#pragma GCC diagnostic ignored "-Wconversion"
|
|
197
|
+
#pragma GCC diagnostic ignored "-Wdouble-promotion"
|
|
198
|
+
#pragma GCC diagnostic ignored "-Wsign-compare"
|
|
199
|
+
#if defined(__clang__)
|
|
200
|
+
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"
|
|
201
|
+
#pragma clang diagnostic ignored "-Wpedantic"
|
|
202
|
+
#endif
|
|
203
|
+
#endif
|
|
204
|
+
if constexpr (type_traits::has_value_v<
|
|
205
|
+
Lhs_T> and type_traits::has_value_v<Rhs_T>)
|
|
206
|
+
{
|
|
207
|
+
return Lhs_T::value != Rhs_T::value;
|
|
208
|
+
}
|
|
209
|
+
else if constexpr (
|
|
210
|
+
type_traits::has_epsilon_v<
|
|
211
|
+
Lhs_T> and type_traits::has_epsilon_v<Rhs_T>)
|
|
212
|
+
{
|
|
213
|
+
return math::abs (get (lhs_) - get (rhs_))
|
|
214
|
+
> math::min_value (Lhs_T::epsilon, Rhs_T::epsilon);
|
|
215
|
+
}
|
|
216
|
+
else if constexpr (type_traits::has_epsilon_v<Lhs_T>)
|
|
217
|
+
{
|
|
218
|
+
return math::abs (get (lhs_) - get (rhs_)) > Lhs_T::epsilon;
|
|
219
|
+
}
|
|
220
|
+
else if constexpr (type_traits::has_epsilon_v<Rhs_T>)
|
|
221
|
+
{
|
|
222
|
+
return math::abs (get (lhs_) - get (rhs_)) > Rhs_T::epsilon;
|
|
223
|
+
}
|
|
224
|
+
else
|
|
225
|
+
{
|
|
226
|
+
return get (lhs_) != get (rhs_);
|
|
227
|
+
}
|
|
228
|
+
#if defined(__GNUC__)
|
|
229
|
+
#pragma GCC diagnostic pop
|
|
230
|
+
#endif
|
|
231
|
+
}() }
|
|
232
|
+
{
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
[[nodiscard]] constexpr operator bool () const
|
|
236
|
+
{
|
|
237
|
+
return value_;
|
|
238
|
+
}
|
|
239
|
+
[[nodiscard]] constexpr auto
|
|
240
|
+
lhs () const
|
|
241
|
+
{
|
|
242
|
+
return get (lhs_);
|
|
243
|
+
}
|
|
244
|
+
[[nodiscard]] constexpr auto
|
|
245
|
+
rhs () const
|
|
246
|
+
{
|
|
247
|
+
return get (rhs_);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const Lhs_T lhs_{};
|
|
251
|
+
const Rhs_T rhs_{};
|
|
252
|
+
const bool value_{};
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* @brief Greater than comparator.
|
|
257
|
+
*/
|
|
258
|
+
template <class Lhs_T, class Rhs_T>
|
|
259
|
+
struct gt_ : type_traits::op
|
|
260
|
+
{
|
|
261
|
+
constexpr gt_ (const Lhs_T& lhs = {}, const Rhs_T& rhs = {})
|
|
262
|
+
: lhs_{ lhs }, rhs_{ rhs }, value_{ [&] {
|
|
263
|
+
using std::operator>;
|
|
264
|
+
|
|
265
|
+
#if defined(__GNUC__)
|
|
266
|
+
#pragma GCC diagnostic push
|
|
267
|
+
#pragma GCC diagnostic ignored "-Wconversion"
|
|
268
|
+
#pragma GCC diagnostic ignored "-Wdouble-promotion"
|
|
269
|
+
#pragma GCC diagnostic ignored "-Wsign-compare"
|
|
270
|
+
#if defined(__clang__)
|
|
271
|
+
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"
|
|
272
|
+
#pragma clang diagnostic ignored "-Wpedantic"
|
|
273
|
+
#endif
|
|
274
|
+
#endif
|
|
275
|
+
if constexpr (type_traits::has_value_v<
|
|
276
|
+
Lhs_T> and type_traits::has_value_v<Rhs_T>)
|
|
277
|
+
{
|
|
278
|
+
return Lhs_T::value > Rhs_T::value;
|
|
279
|
+
}
|
|
280
|
+
else
|
|
281
|
+
{
|
|
282
|
+
return get (lhs_) > get (rhs_);
|
|
283
|
+
}
|
|
284
|
+
#if defined(__GNUC__)
|
|
285
|
+
#pragma GCC diagnostic pop
|
|
286
|
+
#endif
|
|
287
|
+
}() }
|
|
288
|
+
{
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
[[nodiscard]] constexpr operator bool () const
|
|
292
|
+
{
|
|
293
|
+
return value_;
|
|
294
|
+
}
|
|
295
|
+
[[nodiscard]] constexpr auto
|
|
296
|
+
lhs () const
|
|
297
|
+
{
|
|
298
|
+
return get (lhs_);
|
|
299
|
+
}
|
|
300
|
+
[[nodiscard]] constexpr auto
|
|
301
|
+
rhs () const
|
|
302
|
+
{
|
|
303
|
+
return get (rhs_);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const Lhs_T lhs_{};
|
|
307
|
+
const Rhs_T rhs_{};
|
|
308
|
+
const bool value_{};
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* @brief Greater than or equal comparator.
|
|
313
|
+
*/
|
|
314
|
+
template <class Lhs_T, class Rhs_T>
|
|
315
|
+
struct ge_ : type_traits::op
|
|
316
|
+
{
|
|
317
|
+
constexpr ge_ (const Lhs_T& lhs = {}, const Rhs_T& rhs = {})
|
|
318
|
+
: lhs_{ lhs }, rhs_{ rhs }, value_{ [&] {
|
|
319
|
+
using std::operator>=;
|
|
320
|
+
|
|
321
|
+
#if defined(__GNUC__)
|
|
322
|
+
#pragma GCC diagnostic push
|
|
323
|
+
#pragma GCC diagnostic ignored "-Wconversion"
|
|
324
|
+
#pragma GCC diagnostic ignored "-Wdouble-promotion"
|
|
325
|
+
#pragma GCC diagnostic ignored "-Wsign-compare"
|
|
326
|
+
#if defined(__clang__)
|
|
327
|
+
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"
|
|
328
|
+
#pragma clang diagnostic ignored "-Wpedantic"
|
|
329
|
+
#endif
|
|
330
|
+
#endif
|
|
331
|
+
if constexpr (type_traits::has_value_v<
|
|
332
|
+
Lhs_T> and type_traits::has_value_v<Rhs_T>)
|
|
333
|
+
{
|
|
334
|
+
return Lhs_T::value >= Rhs_T::value;
|
|
335
|
+
}
|
|
336
|
+
else
|
|
337
|
+
{
|
|
338
|
+
return get (lhs_) >= get (rhs_);
|
|
339
|
+
}
|
|
340
|
+
#if defined(__GNUC__)
|
|
341
|
+
#pragma GCC diagnostic pop
|
|
342
|
+
#endif
|
|
343
|
+
}() }
|
|
344
|
+
{
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
[[nodiscard]] constexpr operator bool () const
|
|
348
|
+
{
|
|
349
|
+
return value_;
|
|
350
|
+
}
|
|
351
|
+
[[nodiscard]] constexpr auto
|
|
352
|
+
lhs () const
|
|
353
|
+
{
|
|
354
|
+
return get (lhs_);
|
|
355
|
+
}
|
|
356
|
+
[[nodiscard]] constexpr auto
|
|
357
|
+
rhs () const
|
|
358
|
+
{
|
|
359
|
+
return get (rhs_);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const Lhs_T lhs_{};
|
|
363
|
+
const Rhs_T rhs_{};
|
|
364
|
+
const bool value_{};
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* @brief Less than comparator.
|
|
369
|
+
*/
|
|
370
|
+
template <class Lhs_T, class Rhs_T>
|
|
371
|
+
struct lt_ : type_traits::op
|
|
372
|
+
{
|
|
373
|
+
constexpr lt_ (const Lhs_T& lhs = {}, const Rhs_T& rhs = {})
|
|
374
|
+
: lhs_{ lhs }, rhs_{ rhs }, value_{ [&] {
|
|
375
|
+
using std::operator<;
|
|
376
|
+
|
|
377
|
+
#if defined(__GNUC__)
|
|
378
|
+
#pragma GCC diagnostic push
|
|
379
|
+
#pragma GCC diagnostic ignored "-Wconversion"
|
|
380
|
+
#pragma GCC diagnostic ignored "-Wdouble-promotion"
|
|
381
|
+
#pragma GCC diagnostic ignored "-Wsign-compare"
|
|
382
|
+
#if defined(__clang__)
|
|
383
|
+
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"
|
|
384
|
+
#pragma clang diagnostic ignored "-Wpedantic"
|
|
385
|
+
#endif
|
|
386
|
+
#endif
|
|
387
|
+
if constexpr (type_traits::has_value_v<
|
|
388
|
+
Lhs_T> and type_traits::has_value_v<Rhs_T>)
|
|
389
|
+
{
|
|
390
|
+
return Lhs_T::value < Rhs_T::value;
|
|
391
|
+
}
|
|
392
|
+
else
|
|
393
|
+
{
|
|
394
|
+
return get (lhs_) < get (rhs_);
|
|
395
|
+
}
|
|
396
|
+
#if defined(__GNUC__)
|
|
397
|
+
#pragma GCC diagnostic pop
|
|
398
|
+
#endif
|
|
399
|
+
}() }
|
|
400
|
+
{
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
[[nodiscard]] constexpr operator bool () const
|
|
404
|
+
{
|
|
405
|
+
return value_;
|
|
406
|
+
}
|
|
407
|
+
[[nodiscard]] constexpr auto
|
|
408
|
+
lhs () const
|
|
409
|
+
{
|
|
410
|
+
return get (lhs_);
|
|
411
|
+
}
|
|
412
|
+
[[nodiscard]] constexpr auto
|
|
413
|
+
rhs () const
|
|
414
|
+
{
|
|
415
|
+
return get (rhs_);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
private:
|
|
419
|
+
const Lhs_T lhs_{};
|
|
420
|
+
const Rhs_T rhs_{};
|
|
421
|
+
const bool value_{};
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* @brief Less than or equal comparator.
|
|
426
|
+
*/
|
|
427
|
+
template <class Lhs_T, class Rhs_T>
|
|
428
|
+
struct le_ : type_traits::op
|
|
429
|
+
{
|
|
430
|
+
constexpr le_ (const Lhs_T& lhs = {}, const Rhs_T& rhs = {})
|
|
431
|
+
: lhs_{ lhs }, rhs_{ rhs }, value_{ [&] {
|
|
432
|
+
using std::operator<=;
|
|
433
|
+
|
|
434
|
+
#if defined(__GNUC__)
|
|
435
|
+
#pragma GCC diagnostic push
|
|
436
|
+
#pragma GCC diagnostic ignored "-Wconversion"
|
|
437
|
+
#pragma GCC diagnostic ignored "-Wdouble-promotion"
|
|
438
|
+
#pragma GCC diagnostic ignored "-Wsign-compare"
|
|
439
|
+
#if defined(__clang__)
|
|
440
|
+
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"
|
|
441
|
+
#pragma clang diagnostic ignored "-Wpedantic"
|
|
442
|
+
#endif
|
|
443
|
+
#endif
|
|
444
|
+
if constexpr (type_traits::has_value_v<
|
|
445
|
+
Lhs_T> and type_traits::has_value_v<Rhs_T>)
|
|
446
|
+
{
|
|
447
|
+
return Lhs_T::value <= Rhs_T::value;
|
|
448
|
+
}
|
|
449
|
+
else
|
|
450
|
+
{
|
|
451
|
+
return get (lhs_) <= get (rhs_);
|
|
452
|
+
}
|
|
453
|
+
#if defined(__GNUC__)
|
|
454
|
+
#pragma GCC diagnostic pop
|
|
455
|
+
#endif
|
|
456
|
+
}() }
|
|
457
|
+
{
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
[[nodiscard]] constexpr operator bool () const
|
|
461
|
+
{
|
|
462
|
+
return value_;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
[[nodiscard]] constexpr auto
|
|
466
|
+
lhs () const
|
|
467
|
+
{
|
|
468
|
+
return get (lhs_);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
[[nodiscard]] constexpr auto
|
|
472
|
+
rhs () const
|
|
473
|
+
{
|
|
474
|
+
return get (rhs_);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
const Lhs_T lhs_{};
|
|
478
|
+
const Rhs_T rhs_{};
|
|
479
|
+
const bool value_{};
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* @brief Logical and operator.
|
|
484
|
+
*/
|
|
485
|
+
template <class Lhs_T, class Rhs_T>
|
|
486
|
+
struct and_ : type_traits::op
|
|
487
|
+
{
|
|
488
|
+
constexpr and_ (const Lhs_T& lhs = {}, const Rhs_T& rhs = {})
|
|
489
|
+
: lhs_{ lhs }, rhs_{ rhs }, value_{ static_cast<bool> (lhs)
|
|
490
|
+
and static_cast<bool> (rhs) }
|
|
491
|
+
{
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
[[nodiscard]] constexpr operator bool () const
|
|
495
|
+
{
|
|
496
|
+
return value_;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
[[nodiscard]] constexpr auto
|
|
500
|
+
lhs () const
|
|
501
|
+
{
|
|
502
|
+
return get (lhs_);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
[[nodiscard]] constexpr auto
|
|
506
|
+
rhs () const
|
|
507
|
+
{
|
|
508
|
+
return get (rhs_);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
const Lhs_T lhs_{};
|
|
512
|
+
const Rhs_T rhs_{};
|
|
513
|
+
const bool value_{};
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* @brief Logical or operator.
|
|
518
|
+
*/
|
|
519
|
+
template <class Lhs_T, class Rhs_T>
|
|
520
|
+
struct or_ : type_traits::op
|
|
521
|
+
{
|
|
522
|
+
constexpr or_ (const Lhs_T& lhs = {}, const Rhs_T& rhs = {})
|
|
523
|
+
: lhs_{ lhs }, rhs_{ rhs }, value_{ static_cast<bool> (lhs)
|
|
524
|
+
or static_cast<bool> (rhs) }
|
|
525
|
+
{
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
[[nodiscard]] constexpr operator bool () const
|
|
529
|
+
{
|
|
530
|
+
return value_;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
[[nodiscard]] constexpr auto
|
|
534
|
+
lhs () const
|
|
535
|
+
{
|
|
536
|
+
return get (lhs_);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
[[nodiscard]] constexpr auto
|
|
540
|
+
rhs () const
|
|
541
|
+
{
|
|
542
|
+
return get (rhs_);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
const Lhs_T lhs_{};
|
|
546
|
+
const Rhs_T rhs_{};
|
|
547
|
+
const bool value_{};
|
|
548
|
+
};
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* @brief Logical not operator.
|
|
552
|
+
*/
|
|
553
|
+
template <class T>
|
|
554
|
+
struct not_ : type_traits::op
|
|
555
|
+
{
|
|
556
|
+
explicit constexpr not_ (const T& t = {})
|
|
557
|
+
: t_{ t }, value_{ not static_cast<bool> (t) }
|
|
558
|
+
{
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
[[nodiscard]] constexpr operator bool () const
|
|
562
|
+
{
|
|
563
|
+
return value_;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
[[nodiscard]] constexpr auto
|
|
567
|
+
value () const
|
|
568
|
+
{
|
|
569
|
+
return get (t_);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
const T t_{};
|
|
573
|
+
const bool value_{};
|
|
574
|
+
};
|
|
575
|
+
|
|
576
|
+
#if defined(__cpp_exceptions)
|
|
577
|
+
/**
|
|
578
|
+
* @brief Operator to check if the expression throws a specific exception.
|
|
579
|
+
*/
|
|
580
|
+
template <class Callable_T, class Exception_T = void>
|
|
581
|
+
struct throws_ : type_traits::op
|
|
582
|
+
{
|
|
583
|
+
constexpr explicit throws_ (const Callable_T& func)
|
|
584
|
+
: value_{ [&func] {
|
|
585
|
+
try
|
|
586
|
+
{
|
|
587
|
+
func ();
|
|
588
|
+
}
|
|
589
|
+
catch (const Exception_T&)
|
|
590
|
+
{
|
|
591
|
+
return true;
|
|
592
|
+
}
|
|
593
|
+
catch (...)
|
|
594
|
+
{
|
|
595
|
+
return false;
|
|
596
|
+
}
|
|
597
|
+
return false;
|
|
598
|
+
}() }
|
|
599
|
+
{
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
[[nodiscard]] constexpr operator bool () const
|
|
603
|
+
{
|
|
604
|
+
return value_;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
const bool value_{};
|
|
608
|
+
};
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* @brief Operator to check if the expression throws any exception.
|
|
612
|
+
*/
|
|
613
|
+
template <class Callable_T>
|
|
614
|
+
struct throws_<Callable_T, void> : type_traits::op
|
|
615
|
+
{
|
|
616
|
+
constexpr explicit throws_ (const Callable_T& func)
|
|
617
|
+
: value_{ [&func] {
|
|
618
|
+
try
|
|
619
|
+
{
|
|
620
|
+
func ();
|
|
621
|
+
}
|
|
622
|
+
catch (...)
|
|
623
|
+
{
|
|
624
|
+
return true;
|
|
625
|
+
}
|
|
626
|
+
return false;
|
|
627
|
+
}() }
|
|
628
|
+
{
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
[[nodiscard]] constexpr operator bool () const
|
|
632
|
+
{
|
|
633
|
+
return value_;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
const bool value_{};
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* @brief Operator to check if the expression does not throw any exception.
|
|
641
|
+
*/
|
|
642
|
+
template <class Callable_T>
|
|
643
|
+
struct nothrow_ : type_traits::op
|
|
644
|
+
{
|
|
645
|
+
constexpr explicit nothrow_ (const Callable_T& func)
|
|
646
|
+
: value_{ [&func] {
|
|
647
|
+
try
|
|
648
|
+
{
|
|
649
|
+
func ();
|
|
650
|
+
}
|
|
651
|
+
catch (...)
|
|
652
|
+
{
|
|
653
|
+
return false;
|
|
654
|
+
}
|
|
655
|
+
return true;
|
|
656
|
+
}() }
|
|
657
|
+
{
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
[[nodiscard]] constexpr operator bool () const
|
|
661
|
+
{
|
|
662
|
+
return value_;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
const bool value_{};
|
|
666
|
+
};
|
|
667
|
+
#endif
|
|
668
|
+
|
|
669
|
+
// ------------------------------------------------------------------------
|
|
670
|
+
|
|
671
|
+
class deferred_reporter_base
|
|
672
|
+
{
|
|
673
|
+
public:
|
|
674
|
+
deferred_reporter_base (bool value,
|
|
675
|
+
const reflection::source_location location);
|
|
676
|
+
|
|
677
|
+
~deferred_reporter_base ();
|
|
678
|
+
|
|
679
|
+
template <class T>
|
|
680
|
+
auto&
|
|
681
|
+
operator<< (const T& msg);
|
|
682
|
+
|
|
683
|
+
[[nodiscard]] constexpr bool
|
|
684
|
+
value () const
|
|
685
|
+
{
|
|
686
|
+
return value_;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
protected:
|
|
690
|
+
bool value_{};
|
|
691
|
+
bool abort_ = false;
|
|
692
|
+
const reflection::source_location location_{};
|
|
693
|
+
|
|
694
|
+
/**
|
|
695
|
+
* @brief String to collect the expectation message passed via
|
|
696
|
+
* `operator<<()`.
|
|
697
|
+
*/
|
|
698
|
+
std::string message_{};
|
|
699
|
+
};
|
|
700
|
+
|
|
701
|
+
template <class Expr_T>
|
|
702
|
+
class deferred_reporter : public deferred_reporter_base
|
|
703
|
+
{
|
|
704
|
+
public:
|
|
705
|
+
constexpr explicit deferred_reporter (
|
|
706
|
+
const Expr_T& expr, bool abort,
|
|
707
|
+
const reflection::source_location& location);
|
|
708
|
+
|
|
709
|
+
~deferred_reporter ();
|
|
710
|
+
|
|
711
|
+
protected:
|
|
712
|
+
const Expr_T expr_{};
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
// ----------------------------------------------------------------------
|
|
716
|
+
} // namespace detail
|
|
717
|
+
|
|
718
|
+
// --------------------------------------------------------------------------
|
|
719
|
+
} // namespace micro_os_plus::micro_test_plus
|
|
720
|
+
|
|
721
|
+
#if defined(__GNUC__)
|
|
722
|
+
#pragma GCC diagnostic pop
|
|
723
|
+
#endif
|
|
724
|
+
|
|
725
|
+
// ----------------------------------------------------------------------------
|
|
726
|
+
|
|
727
|
+
#endif // __cplusplus
|
|
728
|
+
|
|
729
|
+
// ----------------------------------------------------------------------------
|
|
730
|
+
|
|
731
|
+
#endif // MICRO_TEST_PLUS_DETAIL_H_
|
|
732
|
+
|
|
733
|
+
// ----------------------------------------------------------------------------
|