@micro-os-plus/micro-test-plus 2.1.1 → 3.0.2

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,161 @@
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_INLINES_H_
18
+ #define MICRO_TEST_PLUS_INLINES_H_
19
+
20
+ // ----------------------------------------------------------------------------
21
+
22
+ #ifdef __cplusplus
23
+
24
+ // ----------------------------------------------------------------------------
25
+
26
+ #if defined(__GNUC__)
27
+ #pragma GCC diagnostic push
28
+ #pragma GCC diagnostic ignored "-Waggregate-return"
29
+ #pragma GCC diagnostic ignored "-Wpadded"
30
+ #if defined(__clang__)
31
+ #pragma clang diagnostic ignored "-Wc++98-compat"
32
+ #pragma clang diagnostic ignored "-Wc++98-c++11-c++14-c++17-compat-pedantic"
33
+ #endif
34
+ #endif
35
+
36
+ namespace micro_os_plus::micro_test_plus
37
+ {
38
+ // --------------------------------------------------------------------------
39
+
40
+ template <typename Callable_T, typename... Args_T>
41
+ test_suite::test_suite (const char* name, Callable_T&& callable,
42
+ Args_T&&... arguments)
43
+ : test_suite_base{ name }, callable_{ std::bind (callable,
44
+ arguments...) }
45
+ {
46
+ #if defined(MICRO_TEST_PLUS_TRACE)
47
+ printf ("%s\n", __PRETTY_FUNCTION__);
48
+ #endif // MICRO_TEST_PLUS_TRACE
49
+
50
+ runner.register_test_suite (this);
51
+ }
52
+
53
+ // --------------------------------------------------------------------------
54
+
55
+ template <typename Callable_T, typename... Args_T>
56
+ void
57
+ test_case (const char* name, Callable_T&& func, Args_T&&... arguments)
58
+ {
59
+ #if 0 // defined(MICRO_TEST_PLUS_TRACE)
60
+ printf ("%s\n", __PRETTY_FUNCTION__);
61
+ #endif // MICRO_TEST_PLUS_TRACE
62
+
63
+ current_test_suite->begin_test_case (name);
64
+ std::invoke (std::forward<Callable_T> (func),
65
+ std::forward<Args_T> (arguments)...);
66
+ current_test_suite->end_test_case ();
67
+ }
68
+
69
+ // --------------------------------------------------------------------------
70
+ namespace detail
71
+ {
72
+ // ------------------------------------------------------------------------
73
+
74
+ template <class T>
75
+ auto&
76
+ deferred_reporter_base::operator<< (const T& msg)
77
+ {
78
+ if constexpr (std::is_arithmetic_v<T>)
79
+ {
80
+ message_.append (std::to_string (msg));
81
+ }
82
+ else
83
+ {
84
+ message_.append (msg);
85
+ }
86
+ return *this;
87
+ }
88
+
89
+ // ------------------------------------------------------------------------
90
+
91
+ template <class Expr_T>
92
+ constexpr deferred_reporter<Expr_T>::deferred_reporter (
93
+ const Expr_T& expr, bool abort,
94
+ const reflection::source_location& location)
95
+ : deferred_reporter_base{ static_cast<bool> (expr), location }, expr_{
96
+ expr
97
+ }
98
+ {
99
+ #if 0 // defined(MICRO_TEST_PLUS_TRACE)
100
+ printf ("%s\n", __PRETTY_FUNCTION__);
101
+ #endif // MICRO_TEST_PLUS_TRACE
102
+ abort_ = abort;
103
+ }
104
+
105
+ template <class Expr_T>
106
+ deferred_reporter<Expr_T>::~deferred_reporter ()
107
+ {
108
+ if (value_)
109
+ {
110
+ reporter.pass (expr_, message_);
111
+ }
112
+ else
113
+ {
114
+ reporter.fail (expr_, abort_, message_, location_);
115
+ }
116
+ }
117
+
118
+ // ------------------------------------------------------------------------
119
+ } // namespace detail
120
+
121
+ // --------------------------------------------------------------------------
122
+ namespace utility
123
+ {
124
+ template <class T = std::string_view, class Delim_T>
125
+ [[nodiscard]] auto
126
+ split (T input, Delim_T delim) -> std::vector<T>
127
+ {
128
+ std::vector<T> output{};
129
+ std::size_t first{};
130
+ while (first < std::size (input))
131
+ {
132
+ const auto second = input.find_first_of (delim, first);
133
+ if (first != second)
134
+ {
135
+ output.emplace_back (input.substr (first, second - first));
136
+ }
137
+ if (second == T::npos)
138
+ {
139
+ break;
140
+ }
141
+ first = second + 1;
142
+ }
143
+ return output;
144
+ }
145
+ } // namespace utility
146
+
147
+ } // namespace micro_os_plus::micro_test_plus
148
+
149
+ #if defined(__GNUC__)
150
+ #pragma GCC diagnostic pop
151
+ #endif
152
+
153
+ // ----------------------------------------------------------------------------
154
+
155
+ #endif // __cplusplus
156
+
157
+ // ----------------------------------------------------------------------------
158
+
159
+ #endif // MICRO_TEST_PLUS_INLINES_H_
160
+
161
+ // ----------------------------------------------------------------------------
@@ -0,0 +1,285 @@
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_LITERALS_H_
18
+ #define MICRO_TEST_PLUS_LITERALS_H_
19
+
20
+ // ----------------------------------------------------------------------------
21
+
22
+ #ifdef __cplusplus
23
+
24
+ // ----------------------------------------------------------------------------
25
+
26
+ #include "type-traits.h"
27
+ #include "math.h"
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
+ /**
45
+ * @brief User Defined Literals (UDL). Use them to suffix
46
+ * constants and obtain specific explicit types, like `1_i`.
47
+ */
48
+ namespace literals
49
+ {
50
+ template <char... Cs>
51
+ [[nodiscard]] constexpr auto operator""_i ()
52
+ {
53
+ return type_traits::integral_constant<math::num<int, Cs...> ()>{};
54
+ }
55
+
56
+ template <char... Cs>
57
+ [[nodiscard]] constexpr auto operator""_s ()
58
+ {
59
+ return type_traits::integral_constant<math::num<short, Cs...> ()>{};
60
+ }
61
+
62
+ template <char... Cs>
63
+ [[nodiscard]] constexpr auto operator""_c ()
64
+ {
65
+ return type_traits::integral_constant<math::num<char, Cs...> ()>{};
66
+ }
67
+
68
+ template <char... Cs>
69
+ [[nodiscard]] constexpr auto operator""_sc ()
70
+ {
71
+ return type_traits::integral_constant<
72
+ math::num<signed char, Cs...> ()>{};
73
+ }
74
+
75
+ template <char... Cs>
76
+ [[nodiscard]] constexpr auto operator""_l ()
77
+ {
78
+ return type_traits::integral_constant<math::num<long, Cs...> ()>{};
79
+ }
80
+
81
+ template <char... Cs>
82
+ [[nodiscard]] constexpr auto operator""_ll ()
83
+ {
84
+ return type_traits::integral_constant<math::num<long long, Cs...> ()>{};
85
+ }
86
+
87
+ template <char... Cs>
88
+ [[nodiscard]] constexpr auto operator""_u ()
89
+ {
90
+ return type_traits::integral_constant<math::num<unsigned, Cs...> ()>{};
91
+ }
92
+
93
+ template <char... Cs>
94
+ [[nodiscard]] constexpr auto operator""_uc ()
95
+ {
96
+ return type_traits::integral_constant<
97
+ math::num<unsigned char, Cs...> ()>{};
98
+ }
99
+
100
+ template <char... Cs>
101
+ [[nodiscard]] constexpr auto operator""_us ()
102
+ {
103
+ return type_traits::integral_constant<
104
+ math::num<unsigned short, Cs...> ()>{};
105
+ }
106
+
107
+ template <char... Cs>
108
+ [[nodiscard]] constexpr auto operator""_ul ()
109
+ {
110
+ return type_traits::integral_constant<
111
+ math::num<unsigned long, Cs...> ()>{};
112
+ }
113
+
114
+ template <char... Cs>
115
+ [[nodiscard]] constexpr auto operator""_ull ()
116
+ {
117
+ return type_traits::integral_constant<
118
+ math::num<unsigned long long, Cs...> ()>{};
119
+ }
120
+
121
+ template <char... Cs>
122
+ [[nodiscard]] constexpr auto operator""_i8 ()
123
+ {
124
+ return type_traits::integral_constant<
125
+ math::num<std::int8_t, Cs...> ()>{};
126
+ }
127
+
128
+ template <char... Cs>
129
+ [[nodiscard]] constexpr auto operator""_i16 ()
130
+ {
131
+ return type_traits::integral_constant<
132
+ math::num<std::int16_t, Cs...> ()>{};
133
+ }
134
+
135
+ template <char... Cs>
136
+ [[nodiscard]] constexpr auto operator""_i32 ()
137
+ {
138
+ return type_traits::integral_constant<
139
+ math::num<std::int32_t, Cs...> ()>{};
140
+ }
141
+
142
+ template <char... Cs>
143
+ [[nodiscard]] constexpr auto operator""_i64 ()
144
+ {
145
+ return type_traits::integral_constant<
146
+ math::num<std::int64_t, Cs...> ()>{};
147
+ }
148
+
149
+ template <char... Cs>
150
+ [[nodiscard]] constexpr auto operator""_u8 ()
151
+ {
152
+ return type_traits::integral_constant<
153
+ math::num<std::uint8_t, Cs...> ()>{};
154
+ }
155
+
156
+ template <char... Cs>
157
+ [[nodiscard]] constexpr auto operator""_u16 ()
158
+ {
159
+ return type_traits::integral_constant<
160
+ math::num<std::uint16_t, Cs...> ()>{};
161
+ }
162
+
163
+ template <char... Cs>
164
+ [[nodiscard]] constexpr auto operator""_u32 ()
165
+ {
166
+ return type_traits::integral_constant<
167
+ math::num<std::uint32_t, Cs...> ()>{};
168
+ }
169
+
170
+ template <char... Cs>
171
+ [[nodiscard]] constexpr auto operator""_u64 ()
172
+ {
173
+ return type_traits::integral_constant<
174
+ math::num<std::uint64_t, Cs...> ()>{};
175
+ }
176
+
177
+ template <char... Cs>
178
+ [[nodiscard]] constexpr auto operator""_f ()
179
+ {
180
+ return type_traits::floating_point_constant<
181
+ float, math::num<unsigned long, Cs...> (),
182
+ math::den<unsigned long, Cs...> (),
183
+ math::den_size<unsigned long, Cs...> ()>{};
184
+ }
185
+
186
+ template <char... Cs>
187
+ [[nodiscard]] constexpr auto operator""_d ()
188
+ {
189
+ return type_traits::floating_point_constant<
190
+ double, math::num<unsigned long, Cs...> (),
191
+ math::den<unsigned long, Cs...> (),
192
+ math::den_size<unsigned long, Cs...> ()>{};
193
+ }
194
+
195
+ template <char... Cs>
196
+ [[nodiscard]] constexpr auto operator""_ld ()
197
+ {
198
+ return type_traits::floating_point_constant<
199
+ long double, math::num<unsigned long long, Cs...> (),
200
+ math::den<unsigned long long, Cs...> (),
201
+ math::den_size<unsigned long long, Cs...> ()>{};
202
+ }
203
+
204
+ constexpr auto operator""_b (const char* name, decltype (sizeof ("")) size)
205
+ {
206
+ struct named : std::string_view, type_traits::op
207
+ {
208
+ using value_type = bool;
209
+ [[nodiscard]] constexpr operator value_type () const
210
+ {
211
+ return true;
212
+ }
213
+
214
+ [[nodiscard]] constexpr auto
215
+ operator== (const named&) const
216
+ {
217
+ return true;
218
+ }
219
+
220
+ [[nodiscard]] constexpr auto
221
+ operator== (const bool other) const
222
+ {
223
+ return other;
224
+ }
225
+ };
226
+
227
+ return named{ { name, size }, {} };
228
+ }
229
+ } // namespace literals
230
+
231
+ // --------------------------------------------------------------------------
232
+
233
+ // Wrappers that can be used to convert dynamic values to specific types
234
+ // that are recognised by the comparators.
235
+ // The syntax is similar to function calls, like `_i(expression)`, but the
236
+ // results have custom types expected by comparators.
237
+ using _b = type_traits::value<bool>;
238
+ using _c = type_traits::value<char>;
239
+ using _sc = type_traits::value<signed char>;
240
+ using _s = type_traits::value<short>;
241
+ using _i = type_traits::value<int>;
242
+ using _l = type_traits::value<long>;
243
+ using _ll = type_traits::value<long long>;
244
+ using _u = type_traits::value<unsigned>;
245
+ using _uc = type_traits::value<unsigned char>;
246
+ using _us = type_traits::value<unsigned short>;
247
+ using _ul = type_traits::value<unsigned long>;
248
+ using _ull = type_traits::value<unsigned long long>;
249
+ using _i8 = type_traits::value<std::int8_t>;
250
+ using _i16 = type_traits::value<std::int16_t>;
251
+ using _i32 = type_traits::value<std::int32_t>;
252
+ using _i64 = type_traits::value<std::int64_t>;
253
+ using _u8 = type_traits::value<std::uint8_t>;
254
+ using _u16 = type_traits::value<std::uint16_t>;
255
+ using _u32 = type_traits::value<std::uint32_t>;
256
+ using _u64 = type_traits::value<std::uint64_t>;
257
+ using _f = type_traits::value<float>;
258
+ using _d = type_traits::value<double>;
259
+ using _ld = type_traits::value<long double>;
260
+
261
+ // Template for wrapping any other type.
262
+ template <class T>
263
+ struct _t : type_traits::value<T>
264
+ {
265
+ constexpr explicit _t (const T& t) : type_traits::value<T>{ t }
266
+ {
267
+ }
268
+ };
269
+
270
+ // --------------------------------------------------------------------------
271
+ } // namespace micro_os_plus::micro_test_plus
272
+
273
+ #if defined(__GNUC__)
274
+ #pragma GCC diagnostic pop
275
+ #endif
276
+
277
+ // ----------------------------------------------------------------------------
278
+
279
+ #endif // __cplusplus
280
+
281
+ // ----------------------------------------------------------------------------
282
+
283
+ #endif // MICRO_TEST_PLUS_LITERALS_H_
284
+
285
+ // ----------------------------------------------------------------------------
@@ -0,0 +1,205 @@
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_MATH_H_
18
+ #define MICRO_TEST_PLUS_MATH_H_
19
+
20
+ // ----------------------------------------------------------------------------
21
+
22
+ #ifdef __cplusplus
23
+
24
+ // ----------------------------------------------------------------------------
25
+
26
+ #include <array>
27
+
28
+ // ----------------------------------------------------------------------------
29
+
30
+ #if defined(__GNUC__)
31
+ #pragma GCC diagnostic push
32
+ #pragma GCC diagnostic ignored "-Wconversion"
33
+ #if defined(__clang__)
34
+ #pragma clang diagnostic ignored "-Wc++98-compat"
35
+ #endif
36
+ #endif
37
+
38
+ namespace micro_os_plus::micro_test_plus
39
+ {
40
+ // --------------------------------------------------------------------------
41
+
42
+ /**
43
+ * @brief Local mathematical functions.
44
+ *
45
+ * Some may have equivalents in the standard library, but may be
46
+ * more complicated to use, or have only floating point variants, or
47
+ * not be constexpr.
48
+ */
49
+ namespace math
50
+ {
51
+ /**
52
+ * @brief Generic absolute of any value.
53
+ */
54
+ template <class T>
55
+ [[nodiscard]] constexpr auto
56
+ abs (const T t) -> T
57
+ {
58
+ return t < T{} ? -t : t;
59
+ }
60
+
61
+ /**
62
+ * @brief Generic minimum of two values.
63
+ */
64
+ template <class T>
65
+ [[nodiscard]] constexpr auto
66
+ min_value (const T& lhs, const T& rhs) -> const T&
67
+ {
68
+ return (rhs < lhs) ? rhs : lhs;
69
+ }
70
+
71
+ /**
72
+ * @brief Generic 'power of', to raise base to exponent (base ^ exp).
73
+ */
74
+ template <class T, class Exp_T>
75
+ [[nodiscard]] constexpr auto
76
+ pow (const T base, const Exp_T exp) -> T
77
+ {
78
+ // If the exponent is 0, return 1, otherwise recurse.
79
+ return exp ? T (base * pow (base, exp - Exp_T (1))) : T (1);
80
+ }
81
+
82
+ /**
83
+ * @brief Compute the integral value of a number represented as
84
+ * an array of characters.
85
+ */
86
+ template <class T, char... Cs>
87
+ [[nodiscard]] constexpr auto
88
+ num () -> T
89
+ {
90
+ // Assume all are digits or dot or apostrophe.
91
+ static_assert (
92
+ ((Cs == '.' or Cs == '\'' or (Cs >= '0' and Cs <= '9')) and ...));
93
+ T result{};
94
+ for (const char c : { Cs... })
95
+ {
96
+ if (c == '.')
97
+ {
98
+ break;
99
+ }
100
+ if (c >= '0' and c <= '9')
101
+ {
102
+ result = result * T (10) + T (c - '0');
103
+ }
104
+ }
105
+ return result;
106
+ }
107
+
108
+ /**
109
+ * @brief Compute the decimals of a number represented as
110
+ * an array of characters.
111
+ */
112
+ template <class T, char... Cs>
113
+ [[nodiscard]] constexpr auto
114
+ den () -> T
115
+ {
116
+ constexpr const std::array cs{ Cs... };
117
+ T result{};
118
+ auto i = 0u;
119
+ while (cs[i++] != '.')
120
+ {
121
+ }
122
+
123
+ for (auto j = i; j < sizeof...(Cs); ++j)
124
+ {
125
+ result += pow (T (10), sizeof...(Cs) - j) * T (cs[j] - '0');
126
+ }
127
+ return result;
128
+ }
129
+
130
+ /**
131
+ * @brief Compute the number of decimal places of a number represented as
132
+ * an array of characters.
133
+ */
134
+ template <class T, char... Cs>
135
+ [[nodiscard]] constexpr auto
136
+ den_size () -> T
137
+ {
138
+ constexpr const std::array cs{ Cs... };
139
+ T i{};
140
+ #if defined(__GNUC__)
141
+ #pragma GCC diagnostic push
142
+ #pragma GCC diagnostic ignored "-Wconversion"
143
+ #endif
144
+ while (cs[i++] != '.')
145
+ #if defined(__GNUC__)
146
+ #pragma GCC diagnostic pop
147
+ #endif
148
+ {
149
+ }
150
+
151
+ return T (sizeof...(Cs)) - i + T (1);
152
+ }
153
+
154
+ /**
155
+ * @brief Compute the number of decimal places of a value,
156
+ * up to 7 digits.
157
+ */
158
+ template <class T, class Value_T>
159
+ [[nodiscard]] constexpr auto
160
+ den_size (Value_T value) -> T
161
+ {
162
+ constexpr auto precision = Value_T (1e-7);
163
+ T result{};
164
+ Value_T tmp{};
165
+ do
166
+ {
167
+ value *= 10;
168
+ #if defined(__GNUC__)
169
+ #pragma GCC diagnostic push
170
+ #if !defined(__clang__) // GCC only
171
+ #pragma GCC diagnostic ignored "-Warith-conversion"
172
+ #endif
173
+ #if defined(__clang__)
174
+ #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"
175
+ #endif
176
+ #endif
177
+ tmp = value - T (value);
178
+ #if defined(__GNUC__)
179
+ #pragma GCC diagnostic pop
180
+ #endif
181
+ ++result;
182
+ }
183
+ while (tmp > precision);
184
+
185
+ return result;
186
+ }
187
+
188
+ } // namespace math
189
+
190
+ // --------------------------------------------------------------------------
191
+ } // namespace micro_os_plus::micro_test_plus
192
+
193
+ #if defined(__GNUC__)
194
+ #pragma GCC diagnostic pop
195
+ #endif
196
+
197
+ // ----------------------------------------------------------------------------
198
+
199
+ #endif // __cplusplus
200
+
201
+ // ----------------------------------------------------------------------------
202
+
203
+ #endif // MICRO_TEST_PLUS_MATH_H_
204
+
205
+ // ----------------------------------------------------------------------------