@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.
- package/CHANGELOG.md +349 -72
- package/CMakeLists.txt +15 -26
- package/LICENSE-Boost +23 -0
- package/README.md +1036 -256
- package/include/micro-os-plus/detail.h +733 -0
- package/include/micro-os-plus/inlines.h +161 -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 +490 -103
- 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 +241 -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 +186 -0
- package/src/test-suite.cpp +133 -0
package/src/micro-test-plus.cpp
CHANGED
|
@@ -1,252 +1,169 @@
|
|
|
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
|
|
|
17
|
+
// ----------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
#if defined(MICRO_OS_PLUS_INCLUDE_CONFIG_H)
|
|
20
|
+
#include <micro-os-plus/config.h>
|
|
21
|
+
#endif // MICRO_OS_PLUS_INCLUDE_CONFIG_H
|
|
22
|
+
|
|
10
23
|
#include <micro-os-plus/micro-test-plus.h>
|
|
11
|
-
#include <stdio.h>
|
|
12
24
|
#include <cstring>
|
|
25
|
+
// <iostream> is too heavy for embedded, use printf().
|
|
26
|
+
#include <stdio.h>
|
|
27
|
+
#include <unistd.h>
|
|
13
28
|
|
|
14
29
|
// ----------------------------------------------------------------------------
|
|
15
30
|
|
|
16
|
-
#
|
|
17
|
-
#pragma GCC diagnostic push
|
|
31
|
+
#pragma GCC diagnostic ignored "-Waggregate-return"
|
|
18
32
|
#if defined(__clang__)
|
|
19
33
|
#pragma clang diagnostic ignored "-Wc++98-compat"
|
|
20
|
-
#
|
|
34
|
+
#pragma clang diagnostic ignored "-Wexit-time-destructors"
|
|
35
|
+
#pragma clang diagnostic ignored "-Wglobal-constructors"
|
|
21
36
|
#endif
|
|
22
37
|
|
|
23
|
-
namespace micro_os_plus
|
|
38
|
+
namespace micro_os_plus::micro_test_plus
|
|
24
39
|
{
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
// ------------------------------------------------------------------------
|
|
29
|
-
|
|
30
|
-
session::session ()
|
|
31
|
-
{
|
|
32
|
-
this->argc_ = 0;
|
|
33
|
-
this->argv_ = nullptr;
|
|
34
|
-
|
|
35
|
-
passed_ = 0;
|
|
36
|
-
failed_ = 0;
|
|
37
|
-
test_cases_ = 0;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
session::session (int argc, char* argv[])
|
|
41
|
-
{
|
|
42
|
-
init (argc, argv);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
void
|
|
46
|
-
session::init (int argc, char* argv[])
|
|
47
|
-
{
|
|
48
|
-
this->argc_ = argc;
|
|
49
|
-
this->argv_ = argv;
|
|
40
|
+
// --------------------------------------------------------------------------
|
|
41
|
+
// Public API.
|
|
50
42
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
printf ("Built with clang " __VERSION__);
|
|
57
|
-
#elif defined(__GNUC__)
|
|
58
|
-
printf ("Built with GCC " __VERSION__);
|
|
59
|
-
#elif defined(_MSC_VER)
|
|
60
|
-
// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-170
|
|
61
|
-
printf ("Built with MSVC %d", _MSC_VER);
|
|
62
|
-
#else
|
|
63
|
-
printf ("Built with an unknown compiler");
|
|
64
|
-
#endif
|
|
65
|
-
#if defined(__ARM_PCS_VFP)
|
|
66
|
-
printf (", with FP");
|
|
67
|
-
#else
|
|
68
|
-
printf (", no FP");
|
|
69
|
-
#endif
|
|
70
|
-
#if defined(__EXCEPTIONS)
|
|
71
|
-
printf (", with exceptions");
|
|
72
|
-
#else
|
|
73
|
-
printf (", no exceptions");
|
|
74
|
-
#endif
|
|
75
|
-
#if defined(DEBUG)
|
|
76
|
-
printf (", with DEBUG");
|
|
77
|
-
#endif
|
|
78
|
-
puts (".");
|
|
79
|
-
|
|
80
|
-
#if defined(DEBUG)
|
|
81
|
-
printf ("argv[] = ");
|
|
82
|
-
for (int i = 0; i < argc; ++i)
|
|
83
|
-
{
|
|
84
|
-
printf ("'%s' ", argv[i]);
|
|
85
|
-
}
|
|
86
|
-
puts ("");
|
|
43
|
+
void
|
|
44
|
+
initialize (int argc, char* argv[], const char* name)
|
|
45
|
+
{
|
|
46
|
+
#if defined(MICRO_TEST_PLUS_TRACE)
|
|
47
|
+
printf ("%s\n", __PRETTY_FUNCTION__);
|
|
87
48
|
#endif
|
|
88
|
-
|
|
49
|
+
runner.initialize (argc, argv, name);
|
|
50
|
+
}
|
|
89
51
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
void
|
|
98
|
-
session::run_test_case (void (*function) (session&), const char* name)
|
|
99
|
-
{
|
|
100
|
-
printf ("\n %s\n", name);
|
|
52
|
+
int
|
|
53
|
+
exit_code (void)
|
|
54
|
+
{
|
|
55
|
+
return runner.exit_code ();
|
|
56
|
+
}
|
|
101
57
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
58
|
+
// --------------------------------------------------------------------------
|
|
59
|
+
// Too small to deserve a separate source file.
|
|
60
|
+
namespace reflection
|
|
61
|
+
{
|
|
105
62
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
|
109
|
-
#endif
|
|
110
|
-
void
|
|
111
|
-
session::pass (const char* message, const char* file, int line)
|
|
63
|
+
const char*
|
|
64
|
+
short_name (const char* name)
|
|
112
65
|
{
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
66
|
+
const char* p = strrchr (name, '/');
|
|
67
|
+
if (p != nullptr)
|
|
68
|
+
return p + 1;
|
|
69
|
+
else
|
|
70
|
+
return name;
|
|
118
71
|
}
|
|
119
|
-
#if defined(__GNUC__)
|
|
120
|
-
#pragma GCC diagnostic pop
|
|
121
|
-
#endif
|
|
122
72
|
|
|
123
|
-
|
|
124
|
-
session::fail (const char* message, const char* file, int line)
|
|
125
|
-
{
|
|
126
|
-
printf (" ✗ %s", message);
|
|
127
|
-
print_where_ (" (in '%s:%d')", file, line);
|
|
128
|
-
printf ("\n");
|
|
73
|
+
} // namespace reflection
|
|
129
74
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
session::expect_true (bool condition, const char* message,
|
|
135
|
-
const char* file, int line)
|
|
75
|
+
namespace utility
|
|
76
|
+
{
|
|
77
|
+
[[nodiscard]] bool
|
|
78
|
+
is_match (std::string_view input, std::string_view pattern)
|
|
136
79
|
{
|
|
137
|
-
if (
|
|
80
|
+
if (std::empty (pattern))
|
|
138
81
|
{
|
|
139
|
-
|
|
140
|
-
passed_++;
|
|
82
|
+
return std::empty (input);
|
|
141
83
|
}
|
|
142
|
-
|
|
84
|
+
|
|
85
|
+
if (std::empty (input))
|
|
143
86
|
{
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
printf ("\n");
|
|
147
|
-
failed_++;
|
|
87
|
+
return pattern[0] == '*' ? is_match (input, pattern.substr (1))
|
|
88
|
+
: false;
|
|
148
89
|
}
|
|
149
|
-
}
|
|
150
90
|
|
|
151
|
-
|
|
152
|
-
session::expect_eq (int actual, int expected, const char* message,
|
|
153
|
-
const char* file, int line)
|
|
154
|
-
{
|
|
155
|
-
if (actual == expected)
|
|
91
|
+
if (pattern[0] != '?' and pattern[0] != '*' and pattern[0] != input[0])
|
|
156
92
|
{
|
|
157
|
-
|
|
158
|
-
passed_++;
|
|
93
|
+
return false;
|
|
159
94
|
}
|
|
160
|
-
|
|
95
|
+
|
|
96
|
+
if (pattern[0] == '*')
|
|
161
97
|
{
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
98
|
+
for (decltype (std::size (input)) i = 0u; i <= std::size (input);
|
|
99
|
+
++i)
|
|
100
|
+
{
|
|
101
|
+
if (is_match (input.substr (i), pattern.substr (1)))
|
|
102
|
+
{
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return false;
|
|
166
107
|
}
|
|
108
|
+
|
|
109
|
+
return is_match (input.substr (1), pattern.substr (1));
|
|
167
110
|
}
|
|
168
111
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
112
|
+
} // namespace utility
|
|
113
|
+
|
|
114
|
+
namespace detail
|
|
115
|
+
{
|
|
116
|
+
deferred_reporter_base::deferred_reporter_base (
|
|
117
|
+
bool value, const reflection::source_location location)
|
|
118
|
+
: value_{ value }, location_{ location }
|
|
172
119
|
{
|
|
173
|
-
if (
|
|
120
|
+
if (value_)
|
|
174
121
|
{
|
|
175
|
-
|
|
176
|
-
passed_++;
|
|
122
|
+
current_test_suite->increment_successful ();
|
|
177
123
|
}
|
|
178
124
|
else
|
|
179
125
|
{
|
|
180
|
-
|
|
181
|
-
actual);
|
|
182
|
-
print_where_ (", in '%s:%d'", file, line);
|
|
183
|
-
printf (")\n");
|
|
184
|
-
failed_++;
|
|
126
|
+
current_test_suite->increment_failed ();
|
|
185
127
|
}
|
|
186
128
|
}
|
|
187
129
|
|
|
188
|
-
|
|
189
|
-
session::expect_eq (const char* actual, const char* expected,
|
|
190
|
-
const char* message, const char* file, int line)
|
|
130
|
+
deferred_reporter_base::~deferred_reporter_base ()
|
|
191
131
|
{
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
else
|
|
132
|
+
#if 0 // defined(MICRO_TEST_PLUS_TRACE)
|
|
133
|
+
printf ("%s\n", __PRETTY_FUNCTION__);
|
|
134
|
+
#endif // MICRO_TEST_PLUS_TRACE
|
|
135
|
+
|
|
136
|
+
if (abort_ && !value_)
|
|
198
137
|
{
|
|
199
|
-
printf ("
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
printf (")\n");
|
|
203
|
-
failed_++;
|
|
138
|
+
printf ("\n");
|
|
139
|
+
reporter.output ();
|
|
140
|
+
abort ();
|
|
204
141
|
}
|
|
205
142
|
}
|
|
206
143
|
|
|
207
|
-
|
|
208
|
-
#pragma GCC diagnostic push
|
|
209
|
-
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
|
210
|
-
#endif
|
|
144
|
+
} // namespace detail
|
|
211
145
|
|
|
212
|
-
|
|
213
|
-
session::print_where_ (const char* format, const char* file, int line)
|
|
214
|
-
{
|
|
215
|
-
if (file != nullptr)
|
|
216
|
-
{
|
|
217
|
-
printf (format, file, line);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
146
|
+
// ==========================================================================
|
|
220
147
|
|
|
221
148
|
#if defined(__GNUC__)
|
|
222
|
-
#pragma GCC diagnostic
|
|
149
|
+
#pragma GCC diagnostic push
|
|
150
|
+
#if defined(__clang__)
|
|
151
|
+
#pragma clang diagnostic ignored "-Wexit-time-destructors"
|
|
152
|
+
#pragma clang diagnostic ignored "-Wglobal-constructors"
|
|
153
|
+
#endif
|
|
223
154
|
#endif
|
|
224
155
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
// Also fail if none passed.
|
|
229
|
-
if (failed_ == 0 && passed_ != 0)
|
|
230
|
-
{
|
|
231
|
-
printf ("\n%s passed (%d tests in %d test cases)\n", name_, passed_,
|
|
232
|
-
test_cases_);
|
|
233
|
-
return 0;
|
|
234
|
-
}
|
|
235
|
-
else
|
|
236
|
-
{
|
|
237
|
-
printf (
|
|
238
|
-
"\n%s failed (%d tests passed, %d failed, in %d test cases)\n",
|
|
239
|
-
name_, passed_, failed_, test_cases_);
|
|
240
|
-
return 1;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
156
|
+
// Static instances;
|
|
157
|
+
test_runner runner;
|
|
158
|
+
test_reporter reporter;
|
|
243
159
|
|
|
244
|
-
|
|
245
|
-
} // namespace micro_test_plus
|
|
246
|
-
} // namespace micro_os_plus
|
|
160
|
+
test_suite_base* current_test_suite;
|
|
247
161
|
|
|
248
162
|
#if defined(__GNUC__)
|
|
249
163
|
#pragma GCC diagnostic pop
|
|
250
164
|
#endif
|
|
251
165
|
|
|
166
|
+
// --------------------------------------------------------------------------
|
|
167
|
+
} // namespace micro_os_plus::micro_test_plus
|
|
168
|
+
|
|
252
169
|
// ----------------------------------------------------------------------------
|