@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.
@@ -0,0 +1,134 @@
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_REFLECTION_H_
18
+ #define MICRO_TEST_PLUS_REFLECTION_H_
19
+
20
+ // ----------------------------------------------------------------------------
21
+
22
+ #ifdef __cplusplus
23
+
24
+ // ----------------------------------------------------------------------------
25
+
26
+ #include <string_view>
27
+
28
+ #if defined(__cpp_lib_source_location)
29
+ #include <source_location>
30
+ #endif
31
+
32
+ // ----------------------------------------------------------------------------
33
+
34
+ #if defined(__GNUC__)
35
+ #pragma GCC diagnostic push
36
+ #pragma GCC diagnostic ignored "-Wpadded"
37
+ #pragma GCC diagnostic ignored "-Waggregate-return"
38
+ #if defined(__clang__)
39
+ #pragma clang diagnostic ignored "-Wc++98-compat"
40
+ #endif
41
+ #endif
42
+
43
+ namespace micro_os_plus::micro_test_plus
44
+ {
45
+ // --------------------------------------------------------------------------
46
+
47
+ namespace reflection
48
+ {
49
+ #if defined(__cpp_lib_source_location)
50
+ using source_location = std::source_location;
51
+ #else
52
+ /**
53
+ * @brief Local implementation of the std::source_location.
54
+ */
55
+ class source_location
56
+ {
57
+ public:
58
+ [[nodiscard]] static constexpr auto
59
+ current (
60
+ #if (__has_builtin(__builtin_FILE) and __has_builtin(__builtin_LINE))
61
+ const char* file = __builtin_FILE(), int line = __builtin_LINE()
62
+ #else
63
+ const char* file = "unknown", int line = {}
64
+ #endif
65
+ ) noexcept
66
+ {
67
+ source_location sl{};
68
+ sl.file_ = file;
69
+ sl.line_ = line;
70
+ return sl;
71
+ }
72
+
73
+ [[nodiscard]] constexpr auto
74
+ file_name () const noexcept
75
+ {
76
+ return file_;
77
+ }
78
+
79
+ [[nodiscard]] constexpr auto
80
+ line () const noexcept
81
+ {
82
+ return line_;
83
+ }
84
+
85
+ private:
86
+ const char* file_{ "unknown" };
87
+ int line_{};
88
+ };
89
+
90
+ #endif
91
+
92
+ const char*
93
+ short_name (const char* name);
94
+
95
+ // TODO: update for the new namespaces.
96
+
97
+ /**
98
+ * @brief Parse the __PRETTY_FUNCTION__ macro to extract the type name.
99
+ */
100
+ template <class T>
101
+ [[nodiscard]] constexpr auto
102
+ type_name () -> std::string_view
103
+ {
104
+ #if defined(__clang__)
105
+ // printf("|%s|%zu|\n", __PRETTY_FUNCTION__, sizeof (__PRETTY_FUNCTION__));
106
+ // printf("|%s|\n", &__PRETTY_FUNCTION__[78]);
107
+ return { &__PRETTY_FUNCTION__[78], sizeof (__PRETTY_FUNCTION__) - 80 };
108
+ #elif defined(__GNUC__)
109
+ // printf("|%s|%zu|\n", __PRETTY_FUNCTION__, sizeof (__PRETTY_FUNCTION__));
110
+ // printf("|%s|\n", &__PRETTY_FUNCTION__[93]);
111
+ return { &__PRETTY_FUNCTION__[93], sizeof (__PRETTY_FUNCTION__) - 144 };
112
+ #else
113
+ #error "Unsupported compiler"
114
+ return "Unsupported compiler";
115
+ #endif
116
+ }
117
+ } // namespace reflection
118
+
119
+ // --------------------------------------------------------------------------
120
+ } // namespace micro_os_plus::micro_test_plus
121
+
122
+ #if defined(__GNUC__)
123
+ #pragma GCC diagnostic pop
124
+ #endif
125
+
126
+ // ----------------------------------------------------------------------------
127
+
128
+ #endif // __cplusplus
129
+
130
+ // ----------------------------------------------------------------------------
131
+
132
+ #endif // MICRO_TEST_PLUS_REFLECTION_H_
133
+
134
+ // ----------------------------------------------------------------------------
@@ -0,0 +1,231 @@
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_TEST_REPORTER_INLINES_H_
18
+ #define MICRO_TEST_PLUS_TEST_REPORTER_INLINES_H_
19
+
20
+ // ----------------------------------------------------------------------------
21
+
22
+ #ifdef __cplusplus
23
+
24
+ // ----------------------------------------------------------------------------
25
+
26
+ #include <stdio.h>
27
+ #include <cstring>
28
+
29
+ // ----------------------------------------------------------------------------
30
+
31
+ #if defined(__GNUC__)
32
+ #pragma GCC diagnostic push
33
+ #pragma GCC diagnostic ignored "-Waggregate-return"
34
+ #if defined(__clang__)
35
+ #pragma clang diagnostic ignored "-Wc++98-compat"
36
+ #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
37
+ #endif
38
+ #endif
39
+
40
+ namespace micro_os_plus::micro_test_plus
41
+ {
42
+ // --------------------------------------------------------------------------
43
+
44
+ template <typename T>
45
+ test_reporter&
46
+ test_reporter::operator<< (T* v)
47
+ {
48
+ char buff[20];
49
+ snprintf (buff, sizeof (buff), "%p", reinterpret_cast<void*> (v));
50
+ out_.append (buff);
51
+
52
+ return *this;
53
+ }
54
+
55
+ #if 0
56
+ template <class T>
57
+ test_reporter&
58
+ test_reporter::operator<< (const T& t)
59
+ {
60
+ *this << detail::get (t);
61
+ return *this;
62
+ }
63
+ #endif
64
+
65
+ template <class T>
66
+ test_reporter&
67
+ test_reporter::operator<< (const type_traits::genuine_integral_value<T>& v)
68
+ {
69
+ out_.append (std::to_string (static_cast<long long> (v.get ())));
70
+ return *this;
71
+ }
72
+
73
+ template <class T,
74
+ type_traits::requires_t<type_traits::is_container_v<
75
+ T> and not type_traits::has_npos_v<T>>>
76
+ test_reporter&
77
+ test_reporter::operator<< (T&& t)
78
+ {
79
+ *this << '{';
80
+ auto first = true;
81
+ for (const auto& arg : t)
82
+ {
83
+ *this << (first ? "" : ", ") << arg;
84
+ first = false;
85
+ }
86
+ *this << '}';
87
+ return *this;
88
+ }
89
+
90
+ template <class Lhs_T, class Rhs_T>
91
+ test_reporter&
92
+ test_reporter::operator<< (const detail::eq_<Lhs_T, Rhs_T>& op)
93
+ {
94
+ return (*this << color (op) << op.lhs () << " == " << op.rhs ()
95
+ << colors_.none);
96
+ }
97
+
98
+ template <class Lhs_T, class Rhs_T>
99
+ test_reporter&
100
+ test_reporter::operator<< (const detail::ne_<Lhs_T, Rhs_T>& op)
101
+ {
102
+ return (*this << color (op) << op.lhs () << " != " << op.rhs ()
103
+ << colors_.none);
104
+ }
105
+
106
+ template <class Lhs_T, class Rhs_T>
107
+ test_reporter&
108
+ test_reporter::operator<< (const detail::gt_<Lhs_T, Rhs_T>& op)
109
+ {
110
+ return (*this << color (op) << op.lhs () << " > " << op.rhs ()
111
+ << colors_.none);
112
+ }
113
+
114
+ template <class Lhs_T, class Rhs_T>
115
+ test_reporter&
116
+ test_reporter::operator<< (const detail::ge_<Lhs_T, Rhs_T>& op)
117
+ {
118
+ return (*this << color (op) << op.lhs () << " >= " << op.rhs ()
119
+ << colors_.none);
120
+ }
121
+
122
+ template <class Lhs_T, class Rhs_T>
123
+ test_reporter&
124
+ test_reporter::operator<< (const detail::lt_<Rhs_T, Lhs_T>& op)
125
+ {
126
+ return (*this << color (op) << op.lhs () << " < " << op.rhs ()
127
+ << colors_.none);
128
+ }
129
+
130
+ template <class Lhs_T, class Rhs_T>
131
+ test_reporter&
132
+ test_reporter::operator<< (const detail::le_<Rhs_T, Lhs_T>& op)
133
+ {
134
+ return (*this << color (op) << op.lhs () << " <= " << op.rhs ()
135
+ << colors_.none);
136
+ }
137
+
138
+ template <class Lhs_T, class Rhs_T>
139
+ test_reporter&
140
+ test_reporter::operator<< (const detail::and_<Lhs_T, Rhs_T>& op)
141
+ {
142
+ return (*this << '(' << op.lhs () << color (op) << " and " << colors_.none
143
+ << op.rhs () << ')');
144
+ }
145
+
146
+ template <class Lhs_T, class Rhs_T>
147
+ test_reporter&
148
+ test_reporter::operator<< (const detail::or_<Lhs_T, Rhs_T>& op)
149
+ {
150
+ return (*this << '(' << op.lhs () << color (op) << " or " << colors_.none
151
+ << op.rhs () << ')');
152
+ }
153
+
154
+ template <class T>
155
+ test_reporter&
156
+ test_reporter::operator<< (const detail::not_<T>& op)
157
+ {
158
+ return (*this << color (op) << "not " << op.value () << colors_.none);
159
+ }
160
+
161
+ #if defined(__cpp_exceptions)
162
+ template <class Expr_T, class Exception_T>
163
+ test_reporter&
164
+ test_reporter::operator<< (const detail::throws_<Expr_T, Exception_T>& op)
165
+ {
166
+ return (*this << color (op) << "throws<"
167
+ << reflection::type_name<Exception_T> () << ">"
168
+ << colors_.none);
169
+ }
170
+
171
+ template <class Expr_T>
172
+ test_reporter&
173
+ test_reporter::operator<< (const detail::throws_<Expr_T, void>& op)
174
+ {
175
+ return (*this << color (op) << "throws" << colors_.none);
176
+ }
177
+
178
+ template <class Expr_T>
179
+ test_reporter&
180
+ test_reporter::operator<< (const detail::nothrow_<Expr_T>& op)
181
+ {
182
+ return (*this << color (op) << "nothrow" << colors_.none);
183
+ }
184
+ #endif
185
+
186
+ template <class Expr_T>
187
+ void
188
+ test_reporter::pass (Expr_T& expr, std::string& message)
189
+ {
190
+ output_pass_prefix_ (message);
191
+
192
+ if (message.empty ())
193
+ {
194
+ // If there is no message, display the evaluated expression.
195
+ *this << expr;
196
+ }
197
+
198
+ output_pass_suffix_ ();
199
+ }
200
+
201
+ template <class Expr_T>
202
+ void
203
+ test_reporter::fail (Expr_T& expr, bool abort, std::string& message,
204
+ const reflection::source_location& location)
205
+ {
206
+ output_fail_prefix_ (message, location);
207
+
208
+ if constexpr (type_traits::is_op_v<Expr_T>)
209
+ {
210
+ *this << ", " << expr;
211
+ }
212
+
213
+ output_fail_suffix_ (abort);
214
+ }
215
+
216
+ // --------------------------------------------------------------------------
217
+ } // namespace micro_os_plus::micro_test_plus
218
+
219
+ #if defined(__GNUC__)
220
+ #pragma GCC diagnostic pop
221
+ #endif
222
+
223
+ // ----------------------------------------------------------------------------
224
+
225
+ #endif // __cplusplus
226
+
227
+ // ----------------------------------------------------------------------------
228
+
229
+ #endif // MICRO_TEST_PLUS_TEST_REPORTER_INLINES_H_
230
+
231
+ // ----------------------------------------------------------------------------
@@ -0,0 +1,347 @@
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_TEST_REPORTER_H_
18
+ #define MICRO_TEST_PLUS_TEST_REPORTER_H_
19
+
20
+ // ----------------------------------------------------------------------------
21
+
22
+ #ifdef __cplusplus
23
+
24
+ // ----------------------------------------------------------------------------
25
+
26
+ //#include <functional>
27
+ #include <string_view>
28
+ #include <string>
29
+
30
+ #include "type-traits.h"
31
+ #include "test-suite.h"
32
+ #include "detail.h"
33
+
34
+ // ----------------------------------------------------------------------------
35
+
36
+ #if defined(__GNUC__)
37
+ #pragma GCC diagnostic push
38
+ #pragma GCC diagnostic ignored "-Wpadded"
39
+ #pragma GCC diagnostic ignored "-Waggregate-return"
40
+ #if defined(__clang__)
41
+ #pragma clang diagnostic ignored "-Wc++98-compat"
42
+ #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
43
+ #endif
44
+ #endif
45
+
46
+ namespace micro_os_plus::micro_test_plus
47
+ {
48
+ // --------------------------------------------------------------------------
49
+
50
+ struct colors
51
+ {
52
+ const char* none = "\033[0m";
53
+ const char* pass = "\033[32m";
54
+ const char* fail = "\033[31m";
55
+ };
56
+
57
+ enum class verbosity
58
+ {
59
+ silent = 0, // Nothing, only return the exit code
60
+ quiet = 1, // Test suites results
61
+ normal = 2, // Test suites results and failed test cases
62
+ verbose = 3 // All, including passed checks
63
+ };
64
+
65
+ typedef verbosity verbosity_t;
66
+
67
+ class test_reporter;
68
+
69
+ test_reporter&
70
+ endl (test_reporter& stream);
71
+
72
+ // Requires events::assertion_* for and detailed operators.
73
+
74
+ /**
75
+ * @brief Reporter to display the test results. For failed
76
+ * tests it prints the actual values of the operands, with their types.
77
+ */
78
+ class test_reporter
79
+ {
80
+ public:
81
+ test_reporter () = default;
82
+
83
+ [[nodiscard]] inline auto
84
+ color (const bool cond)
85
+ {
86
+ return cond ? colors_.pass : colors_.fail;
87
+ }
88
+
89
+ test_reporter&
90
+ operator<< (std::string_view sv);
91
+
92
+ test_reporter&
93
+ operator<< (char c);
94
+
95
+ test_reporter&
96
+ operator<< (const char* s);
97
+
98
+ test_reporter&
99
+ operator<< (char* s);
100
+
101
+ test_reporter&
102
+ operator<< (bool v);
103
+
104
+ test_reporter& operator<< (std::nullptr_t);
105
+
106
+ test_reporter&
107
+ operator<< (signed char c);
108
+
109
+ test_reporter&
110
+ operator<< (unsigned char c);
111
+
112
+ test_reporter&
113
+ operator<< (signed short c);
114
+
115
+ test_reporter&
116
+ operator<< (unsigned short c);
117
+
118
+ test_reporter&
119
+ operator<< (signed int v);
120
+
121
+ test_reporter&
122
+ operator<< (unsigned int v);
123
+
124
+ test_reporter&
125
+ operator<< (signed long v);
126
+
127
+ test_reporter&
128
+ operator<< (unsigned long v);
129
+
130
+ test_reporter&
131
+ operator<< (signed long long v);
132
+
133
+ test_reporter&
134
+ operator<< (unsigned long long v);
135
+
136
+ test_reporter&
137
+ operator<< (float v);
138
+
139
+ test_reporter&
140
+ operator<< (double v);
141
+
142
+ test_reporter&
143
+ operator<< (long double v);
144
+
145
+ /**
146
+ * @brief Output operator to display any pointer.
147
+ */
148
+ template <typename T>
149
+ test_reporter&
150
+ operator<< (T* v);
151
+
152
+ /**
153
+ * @brief Output operator to display the endl.
154
+ */
155
+ test_reporter&
156
+ operator<< (test_reporter& (*func) (test_reporter&));
157
+
158
+ // ------------------------------------------------------------------------
159
+ // Specific operators.
160
+
161
+ /**
162
+ * @brief Output operator to types with a getter.
163
+ */
164
+ template <class T>
165
+ test_reporter&
166
+ operator<< (const T& t);
167
+
168
+ /**
169
+ * @brief Output operator to display genuine integers,
170
+ * without the type suffix.
171
+ */
172
+ template <class T>
173
+ test_reporter&
174
+ operator<< (const type_traits::genuine_integral_value<T>& v);
175
+
176
+ /**
177
+ * @brief Output operator to display containers. Iterate all members.
178
+ */
179
+ template <class T, type_traits::requires_t<
180
+ type_traits::is_container_v<
181
+ T> and not type_traits::has_npos_v<T>> = 0>
182
+ test_reporter&
183
+ operator<< (T&& t);
184
+
185
+ /**
186
+ * @brief Output operator to display eq() expressions.
187
+ */
188
+ template <class Lhs_T, class Rhs_T>
189
+ test_reporter&
190
+ operator<< (const detail::eq_<Lhs_T, Rhs_T>& op);
191
+
192
+ /**
193
+ * @brief Output operator to display ne() expressions.
194
+ */
195
+ template <class Lhs_T, class Rhs_T>
196
+ test_reporter&
197
+ operator<< (const detail::ne_<Lhs_T, Rhs_T>& op);
198
+
199
+ /**
200
+ * @brief Output operator to display gt() expressions.
201
+ */
202
+ template <class Lhs_T, class Rhs_T>
203
+ test_reporter&
204
+ operator<< (const detail::gt_<Lhs_T, Rhs_T>& op);
205
+
206
+ /**
207
+ * @brief Output operator to display ge() expressions.
208
+ */
209
+ template <class Lhs_T, class Rhs_T>
210
+ test_reporter&
211
+ operator<< (const detail::ge_<Lhs_T, Rhs_T>& op);
212
+
213
+ /**
214
+ * @brief Output operator to display lt() expressions.
215
+ */
216
+ template <class Lhs_T, class Rhs_T>
217
+ test_reporter&
218
+ operator<< (const detail::lt_<Rhs_T, Lhs_T>& op);
219
+
220
+ /**
221
+ * @brief Output operator to display le() expressions.
222
+ */
223
+ template <class Lhs_T, class Rhs_T>
224
+ test_reporter&
225
+ operator<< (const detail::le_<Rhs_T, Lhs_T>& op);
226
+
227
+ /**
228
+ * @brief Output operator to display and() expressions.
229
+ */
230
+ template <class Lhs_T, class Rhs_T>
231
+ test_reporter&
232
+ operator<< (const detail::and_<Lhs_T, Rhs_T>& op);
233
+
234
+ /**
235
+ * @brief Output operator to display or() expressions.
236
+ */
237
+ template <class Lhs_T, class Rhs_T>
238
+ test_reporter&
239
+ operator<< (const detail::or_<Lhs_T, Rhs_T>& op);
240
+
241
+ /**
242
+ * @brief Output operator to display not() expressions.
243
+ */
244
+ template <class T>
245
+ test_reporter&
246
+ operator<< (const detail::not_<T>& op);
247
+
248
+ #if defined(__cpp_exceptions)
249
+ template <class Expr_T, class Exception_T>
250
+ test_reporter&
251
+ operator<< (const detail::throws_<Expr_T, Exception_T>& op);
252
+
253
+ template <class Expr_T>
254
+ test_reporter&
255
+ operator<< (const detail::throws_<Expr_T, void>& op);
256
+
257
+ template <class Expr_T>
258
+ test_reporter&
259
+ operator<< (const detail::nothrow_<Expr_T>& op);
260
+ #endif
261
+
262
+ void
263
+ endline (void);
264
+
265
+ // ------------------------------------------------------------------------
266
+
267
+ /**
268
+ * @brief Report a passed condition.
269
+ */
270
+ template <class Expr_T>
271
+ void
272
+ pass (Expr_T& expr, std::string& message);
273
+
274
+ /**
275
+ * @brief Report a failed condition.
276
+ */
277
+ template <class Expr_T>
278
+ void
279
+ fail (Expr_T& expr, bool abort, std::string& message,
280
+ const reflection::source_location& location);
281
+
282
+ void
283
+ begin_test_case (const char* name);
284
+
285
+ void
286
+ end_test_case (const char* name);
287
+
288
+ void
289
+ begin_test_suite (const char* name);
290
+
291
+ void
292
+ end_test_suite (test_suite_base& suite);
293
+
294
+ /**
295
+ * @brief Flush the current buffered content.
296
+ */
297
+ void
298
+ flush (void);
299
+
300
+ void
301
+ output (void);
302
+
303
+ // Used to nicely format the output, without empty lines
304
+ // between successful test cases.
305
+ bool add_empty_line{ true };
306
+
307
+ verbosity_t verbosity{};
308
+
309
+ protected:
310
+ // The prefix/suffix methods help shorten the code
311
+ // generated by the template methods.
312
+
313
+ void
314
+ output_pass_prefix_ (std::string& message);
315
+
316
+ void
317
+ output_pass_suffix_ (void);
318
+
319
+ void
320
+ output_fail_prefix_ (std::string& message,
321
+ const reflection::source_location& location);
322
+
323
+ void
324
+ output_fail_suffix_ (bool abort);
325
+
326
+ colors colors_{};
327
+ std::string out_{};
328
+
329
+ bool is_in_test_case_ = false;
330
+ };
331
+
332
+ // --------------------------------------------------------------------------
333
+ } // namespace micro_os_plus::micro_test_plus
334
+
335
+ #if defined(__GNUC__)
336
+ #pragma GCC diagnostic pop
337
+ #endif
338
+
339
+ // ----------------------------------------------------------------------------
340
+
341
+ #endif // __cplusplus
342
+
343
+ // ----------------------------------------------------------------------------
344
+
345
+ #endif // MICRO_TEST_PLUS_TEST_REPORTER_H_
346
+
347
+ // ----------------------------------------------------------------------------