@micro-os-plus/micro-test-plus 3.2.3 → 3.3.1
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 +76 -2
- package/CMakeLists.txt +2 -1
- package/README.md +1 -1
- package/include/micro-os-plus/micro-test-plus/detail.h +173 -150
- package/include/micro-os-plus/micro-test-plus/inlines/details-inlines.h +2 -2
- package/include/micro-os-plus/micro-test-plus/inlines/test-reporter-inlines.h +8 -3
- package/include/micro-os-plus/micro-test-plus/test-reporter-basic.h +289 -0
- package/include/micro-os-plus/micro-test-plus/test-reporter-tap.h +281 -0
- package/include/micro-os-plus/micro-test-plus/test-reporter.h +72 -27
- package/include/micro-os-plus/micro-test-plus/test-runner.h +55 -15
- package/include/micro-os-plus/micro-test-plus/test-suite.h +47 -11
- package/include/micro-os-plus/micro-test-plus.h +4 -2
- package/meson.build +2 -0
- package/package.json +1 -1
- package/src/micro-test-plus.cpp +6 -5
- package/src/test-reporter-basic.cpp +466 -0
- package/src/test-reporter-tap.cpp +530 -0
- package/src/test-reporter.cpp +5 -380
- package/src/test-runner.cpp +66 -18
- package/src/test-suite.cpp +58 -5
package/src/test-reporter.cpp
CHANGED
|
@@ -62,6 +62,10 @@ namespace micro_os_plus::micro_test_plus
|
|
|
62
62
|
{
|
|
63
63
|
// --------------------------------------------------------------------------
|
|
64
64
|
|
|
65
|
+
test_reporter::~test_reporter () = default;
|
|
66
|
+
|
|
67
|
+
// --------------------------------------------------------------------------
|
|
68
|
+
|
|
65
69
|
/**
|
|
66
70
|
* @details
|
|
67
71
|
* The `endl` function inserts a newline character into the specified
|
|
@@ -73,127 +77,10 @@ namespace micro_os_plus::micro_test_plus
|
|
|
73
77
|
test_reporter&
|
|
74
78
|
endl (test_reporter& stream)
|
|
75
79
|
{
|
|
76
|
-
reporter
|
|
80
|
+
reporter->endline ();
|
|
77
81
|
return stream;
|
|
78
82
|
}
|
|
79
83
|
|
|
80
|
-
// --------------------------------------------------------------------------
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* @details
|
|
84
|
-
* This method outputs the prefix for a passing test result, applying the
|
|
85
|
-
* appropriate colour formatting and symbols to clearly indicate success. If
|
|
86
|
-
* the output occurs within a test case, additional indentation is applied
|
|
87
|
-
* for readability. The prefix includes a tick symbol (`✓`) and, if provided,
|
|
88
|
-
* an associated message. Colour formatting is reset after the prefix to
|
|
89
|
-
* maintain consistent output style across all test cases and folders.
|
|
90
|
-
*
|
|
91
|
-
* The prefix/suffix methods help shorten the code
|
|
92
|
-
* generated by the template methods.
|
|
93
|
-
*/
|
|
94
|
-
void
|
|
95
|
-
test_reporter::output_pass_prefix_ (std::string& message)
|
|
96
|
-
{
|
|
97
|
-
*this << colors_.pass;
|
|
98
|
-
if (is_in_test_case_)
|
|
99
|
-
{
|
|
100
|
-
*this << " ";
|
|
101
|
-
}
|
|
102
|
-
*this << " ✓ ";
|
|
103
|
-
*this << colors_.none;
|
|
104
|
-
if (!message.empty ())
|
|
105
|
-
{
|
|
106
|
-
*this << message.c_str ();
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* @details
|
|
112
|
-
* The `endl` function acts as a stream manipulator for the `test_reporter`,
|
|
113
|
-
* inserting a line ending into the output buffer and flushing the current
|
|
114
|
-
* content if necessary. This ensures that test report output is clearly
|
|
115
|
-
* separated and formatted, improving readability and professionalism in the
|
|
116
|
-
* presentation of test results.
|
|
117
|
-
*
|
|
118
|
-
* Using `endl` in conjunction with the `test_reporter` output operators
|
|
119
|
-
* provides a familiar and convenient mechanism for managing line breaks,
|
|
120
|
-
* similar to standard C++ stream manipulators.
|
|
121
|
-
*
|
|
122
|
-
* The prefix/suffix methods help shorten the code
|
|
123
|
-
* generated by the template methods.
|
|
124
|
-
*/
|
|
125
|
-
void
|
|
126
|
-
test_reporter::output_pass_suffix_ (void)
|
|
127
|
-
{
|
|
128
|
-
*this << endl;
|
|
129
|
-
|
|
130
|
-
flush ();
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* @details
|
|
135
|
-
* This method outputs the prefix for a failing test result, applying the
|
|
136
|
-
* appropriate colour formatting and symbols to clearly indicate failure. If
|
|
137
|
-
* the output occurs within a test case, additional indentation is applied
|
|
138
|
-
* for readability. The prefix includes a cross symbol (`✗`), an optional
|
|
139
|
-
* message, and the label "FAILED". The source location is appended in
|
|
140
|
-
* parentheses, showing the file or folder name and line number where the
|
|
141
|
-
* failure occurred. Colour formatting is reset after the prefix to maintain
|
|
142
|
-
* consistent output style across all test cases and folders.
|
|
143
|
-
*/
|
|
144
|
-
void
|
|
145
|
-
test_reporter::output_fail_prefix_ (
|
|
146
|
-
std::string& message, const reflection::source_location& location)
|
|
147
|
-
{
|
|
148
|
-
*this << colors_.fail;
|
|
149
|
-
if (is_in_test_case_)
|
|
150
|
-
{
|
|
151
|
-
*this << " ";
|
|
152
|
-
}
|
|
153
|
-
*this << " ✗ ";
|
|
154
|
-
*this << colors_.none;
|
|
155
|
-
if (!message.empty ())
|
|
156
|
-
{
|
|
157
|
-
*this << message.c_str ();
|
|
158
|
-
*this << " ";
|
|
159
|
-
}
|
|
160
|
-
*this << colors_.fail << "FAILED" << colors_.none;
|
|
161
|
-
#pragma GCC diagnostic push
|
|
162
|
-
#if defined(__clang__)
|
|
163
|
-
#pragma clang diagnostic ignored "-Wsign-conversion"
|
|
164
|
-
#elif defined(__GNUC__)
|
|
165
|
-
#pragma GCC diagnostic ignored "-Wnarrowing"
|
|
166
|
-
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
|
167
|
-
#endif
|
|
168
|
-
*this << " (" << reflection::short_name (location.file_name ()) << ":"
|
|
169
|
-
<< type_traits::genuine_integral_value<unsigned int>{
|
|
170
|
-
location.line ()
|
|
171
|
-
};
|
|
172
|
-
#pragma GCC diagnostic pop
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* @details
|
|
177
|
-
* This method outputs the suffix for a failing test result by closing the
|
|
178
|
-
* location information, appending an "aborted..." message if the test was
|
|
179
|
-
* aborted, and then adding a newline to the test output. The output stream
|
|
180
|
-
* is flushed to ensure immediate visibility. This approach guarantees that
|
|
181
|
-
* failure results are clearly separated, promptly reported, and easily
|
|
182
|
-
* distinguishable across all test cases and folders.
|
|
183
|
-
*/
|
|
184
|
-
void
|
|
185
|
-
test_reporter::output_fail_suffix_ (bool abort)
|
|
186
|
-
{
|
|
187
|
-
*this << ")";
|
|
188
|
-
if (abort)
|
|
189
|
-
{
|
|
190
|
-
*this << " aborted...";
|
|
191
|
-
}
|
|
192
|
-
*this << endl;
|
|
193
|
-
|
|
194
|
-
flush ();
|
|
195
|
-
}
|
|
196
|
-
|
|
197
84
|
/**
|
|
198
85
|
* @details
|
|
199
86
|
* This operator overload enables manipulators, such as `endl`, to be used
|
|
@@ -211,34 +98,6 @@ namespace micro_os_plus::micro_test_plus
|
|
|
211
98
|
return *this;
|
|
212
99
|
}
|
|
213
100
|
|
|
214
|
-
/**
|
|
215
|
-
* @details
|
|
216
|
-
* This method appends a newline character to the internal output buffer of
|
|
217
|
-
* the `test_reporter` and immediately flushes the stream. This ensures that
|
|
218
|
-
* each line of test output is clearly separated and promptly displayed,
|
|
219
|
-
* enhancing the readability and organisation of test results across all test
|
|
220
|
-
* cases and folders.
|
|
221
|
-
*/
|
|
222
|
-
void
|
|
223
|
-
test_reporter::endline (void)
|
|
224
|
-
{
|
|
225
|
-
out_.append ("\n");
|
|
226
|
-
flush ();
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* @details
|
|
231
|
-
* This method flushes the output buffer of the `test_reporter` by
|
|
232
|
-
* synchronising it with the standard output stream. This guarantees that all
|
|
233
|
-
* pending test output is immediately written and visible, ensuring prompt
|
|
234
|
-
* and reliable reporting of test results across all test cases and folders.
|
|
235
|
-
*/
|
|
236
|
-
void
|
|
237
|
-
test_reporter::flush (void)
|
|
238
|
-
{
|
|
239
|
-
fflush (stdout); // Sync STDOUT.
|
|
240
|
-
}
|
|
241
|
-
|
|
242
101
|
/**
|
|
243
102
|
* @details
|
|
244
103
|
* This operator overload appends the contents of the provided
|
|
@@ -534,240 +393,6 @@ namespace micro_os_plus::micro_test_plus
|
|
|
534
393
|
return *this;
|
|
535
394
|
}
|
|
536
395
|
|
|
537
|
-
/**
|
|
538
|
-
* @details
|
|
539
|
-
* This method marks the beginning of a test case, setting the internal state
|
|
540
|
-
* to indicate that test output is now within a test case context. If there
|
|
541
|
-
* is pending output and the verbosity level is set to verbose, it ensures
|
|
542
|
-
* that output is properly separated and displayed, adding an empty line if
|
|
543
|
-
* necessary. The output buffer is cleared and the stream is flushed to
|
|
544
|
-
* guarantee that all previous output is visible before the new test case
|
|
545
|
-
* begins. This approach enhances the clarity and organisation of test
|
|
546
|
-
* results across all test cases and folders.
|
|
547
|
-
*/
|
|
548
|
-
void
|
|
549
|
-
test_reporter::begin_test_case ([[maybe_unused]] const char* name)
|
|
550
|
-
{
|
|
551
|
-
is_in_test_case_ = true;
|
|
552
|
-
|
|
553
|
-
if (!out_.empty () && (verbosity == verbosity::verbose))
|
|
554
|
-
{
|
|
555
|
-
if (add_empty_line)
|
|
556
|
-
{
|
|
557
|
-
printf ("\n");
|
|
558
|
-
}
|
|
559
|
-
output ();
|
|
560
|
-
add_empty_line = true;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
out_.clear ();
|
|
564
|
-
|
|
565
|
-
flush ();
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
/**
|
|
569
|
-
* @details
|
|
570
|
-
* This method marks the end of a test case, summarising its outcome and
|
|
571
|
-
* outputting the results with appropriate formatting and colour coding. If
|
|
572
|
-
* any checks have failed, a failure message is displayed, including the
|
|
573
|
-
* number of successful and failed checks. For passing test cases, a success
|
|
574
|
-
* message is shown with the total number of checks. The output is adjusted
|
|
575
|
-
* according to the verbosity level, and additional spacing is managed for
|
|
576
|
-
* clarity. The output buffer is cleared and the stream is flushed to ensure
|
|
577
|
-
* all results are immediately visible, supporting clear and organised
|
|
578
|
-
* reporting across all test cases and folders.
|
|
579
|
-
*/
|
|
580
|
-
void
|
|
581
|
-
test_reporter::end_test_case ([[maybe_unused]] const char* name)
|
|
582
|
-
{
|
|
583
|
-
if (verbosity == verbosity::normal || verbosity == verbosity::verbose)
|
|
584
|
-
{
|
|
585
|
-
if (current_test_suite->current_test_case.failed_checks > 0)
|
|
586
|
-
{
|
|
587
|
-
if (true /* add_empty_line */)
|
|
588
|
-
{
|
|
589
|
-
printf ("\n");
|
|
590
|
-
}
|
|
591
|
-
#pragma GCC diagnostic push
|
|
592
|
-
#if defined(__clang__)
|
|
593
|
-
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
|
|
594
|
-
#endif
|
|
595
|
-
printf (" • %s - test case started\n", name);
|
|
596
|
-
output ();
|
|
597
|
-
printf (
|
|
598
|
-
" %s✗%s %s - test case %sFAILED%s (%d %s passed, %d "
|
|
599
|
-
"failed)\n",
|
|
600
|
-
colors_.fail, colors_.none, name, colors_.fail, colors_.none,
|
|
601
|
-
current_test_suite->current_test_case.successful_checks,
|
|
602
|
-
current_test_suite->current_test_case.successful_checks == 1
|
|
603
|
-
? "check"
|
|
604
|
-
: "checks",
|
|
605
|
-
current_test_suite->current_test_case.failed_checks);
|
|
606
|
-
#pragma GCC diagnostic pop
|
|
607
|
-
add_empty_line = true;
|
|
608
|
-
}
|
|
609
|
-
else
|
|
610
|
-
{
|
|
611
|
-
if (add_empty_line)
|
|
612
|
-
{
|
|
613
|
-
printf ("\n");
|
|
614
|
-
}
|
|
615
|
-
if (verbosity == verbosity::verbose)
|
|
616
|
-
{
|
|
617
|
-
#pragma GCC diagnostic push
|
|
618
|
-
#if defined(__clang__)
|
|
619
|
-
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
|
|
620
|
-
#endif
|
|
621
|
-
printf (" • %s - test case started\n", name);
|
|
622
|
-
output ();
|
|
623
|
-
printf (
|
|
624
|
-
" %s✓%s %s - test case passed (%d %s)\n", colors_.pass,
|
|
625
|
-
colors_.none, name,
|
|
626
|
-
current_test_suite->current_test_case.successful_checks,
|
|
627
|
-
current_test_suite->current_test_case.successful_checks
|
|
628
|
-
== 1
|
|
629
|
-
? "check"
|
|
630
|
-
: "checks");
|
|
631
|
-
#pragma GCC diagnostic pop
|
|
632
|
-
add_empty_line = true;
|
|
633
|
-
}
|
|
634
|
-
else
|
|
635
|
-
{
|
|
636
|
-
#pragma GCC diagnostic push
|
|
637
|
-
#if defined(__clang__)
|
|
638
|
-
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
|
|
639
|
-
#endif
|
|
640
|
-
printf (
|
|
641
|
-
" %s✓%s %s - test case passed (%d %s)\n", colors_.pass,
|
|
642
|
-
colors_.none, name,
|
|
643
|
-
current_test_suite->current_test_case.successful_checks,
|
|
644
|
-
current_test_suite->current_test_case.successful_checks
|
|
645
|
-
== 1
|
|
646
|
-
? "check"
|
|
647
|
-
: "checks");
|
|
648
|
-
#pragma GCC diagnostic pop
|
|
649
|
-
|
|
650
|
-
add_empty_line = false;
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
out_.clear ();
|
|
656
|
-
flush ();
|
|
657
|
-
|
|
658
|
-
is_in_test_case_ = false;
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
/**
|
|
662
|
-
* @details
|
|
663
|
-
* This method marks the beginning of a test suite, ensuring that output is
|
|
664
|
-
* properly separated and clearly presented. If there is pending output, the
|
|
665
|
-
* stream is flushed and an empty line is added for clarity. For silent or
|
|
666
|
-
* quiet verbosity levels, output is suppressed. Otherwise, a message
|
|
667
|
-
* indicating the start of the test suite is displayed. This approach
|
|
668
|
-
* enhances the organisation and readability of test results across all test
|
|
669
|
-
* cases and folders.
|
|
670
|
-
*/
|
|
671
|
-
void
|
|
672
|
-
test_reporter::begin_test_suite (const char* name)
|
|
673
|
-
{
|
|
674
|
-
if (add_empty_line)
|
|
675
|
-
{
|
|
676
|
-
flush ();
|
|
677
|
-
printf ("\n");
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
if (verbosity == verbosity::silent || verbosity == verbosity::quiet)
|
|
681
|
-
{
|
|
682
|
-
add_empty_line = false;
|
|
683
|
-
return;
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
#pragma GCC diagnostic push
|
|
687
|
-
#if defined(__clang__)
|
|
688
|
-
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
|
|
689
|
-
#endif
|
|
690
|
-
printf ("• %s - test suite started\n", name);
|
|
691
|
-
#pragma GCC diagnostic pop
|
|
692
|
-
|
|
693
|
-
add_empty_line = true;
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
/**
|
|
697
|
-
* @details
|
|
698
|
-
* This method marks the end of a test suite, summarising the overall results
|
|
699
|
-
* and presenting them with appropriate formatting and colour coding. If the
|
|
700
|
-
* suite contains test cases and the verbosity is not set to quiet, an empty
|
|
701
|
-
* line is added for clarity. For suites with no failed checks and at least
|
|
702
|
-
* one successful check, a success message is displayed, including the number
|
|
703
|
-
* of checks and test cases. Otherwise, a failure message is shown, detailing
|
|
704
|
-
* the number of successful and failed checks, as well as the total number of
|
|
705
|
-
* test cases. The output is immediately flushed to ensure prompt and
|
|
706
|
-
* organised reporting across all test cases and folders.
|
|
707
|
-
*/
|
|
708
|
-
void
|
|
709
|
-
test_reporter::end_test_suite (test_suite_base& suite)
|
|
710
|
-
{
|
|
711
|
-
if (verbosity == verbosity::silent)
|
|
712
|
-
{
|
|
713
|
-
return;
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
if (suite.test_cases () > 0 && verbosity != verbosity::quiet)
|
|
717
|
-
{
|
|
718
|
-
printf ("\n");
|
|
719
|
-
add_empty_line = true;
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
// Also fail if none passed.
|
|
723
|
-
if (suite.failed_checks () == 0 && suite.successful_checks () != 0)
|
|
724
|
-
{
|
|
725
|
-
#pragma GCC diagnostic push
|
|
726
|
-
#if defined(__clang__)
|
|
727
|
-
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
|
|
728
|
-
#endif
|
|
729
|
-
printf ("%s✓%s %s - test suite passed (%d %s in %d test %s)\n",
|
|
730
|
-
colors_.pass, colors_.none, suite.name (),
|
|
731
|
-
suite.successful_checks (),
|
|
732
|
-
suite.successful_checks () == 1 ? "check" : "checks",
|
|
733
|
-
suite.test_cases (),
|
|
734
|
-
suite.test_cases () == 1 ? "case" : "cases");
|
|
735
|
-
#pragma GCC diagnostic pop
|
|
736
|
-
}
|
|
737
|
-
else
|
|
738
|
-
{
|
|
739
|
-
#pragma GCC diagnostic push
|
|
740
|
-
#if defined(__clang__)
|
|
741
|
-
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
|
|
742
|
-
#endif
|
|
743
|
-
printf ("%s✗%s %s - test suite %sFAILED%s (%d %s passed, %d failed, "
|
|
744
|
-
"in %d test %s)\n",
|
|
745
|
-
colors_.fail, colors_.none, suite.name (), colors_.fail,
|
|
746
|
-
colors_.none, suite.successful_checks (),
|
|
747
|
-
suite.successful_checks () == 1 ? "check" : "checks",
|
|
748
|
-
suite.failed_checks (), suite.test_cases (),
|
|
749
|
-
suite.test_cases () == 1 ? "case" : "cases");
|
|
750
|
-
#pragma GCC diagnostic pop
|
|
751
|
-
}
|
|
752
|
-
flush ();
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
/**
|
|
756
|
-
* @details
|
|
757
|
-
* This method writes the contents of the internal output buffer to the
|
|
758
|
-
* standard output stream without appending a newline character. After
|
|
759
|
-
* outputting the buffer, it is cleared to prepare for subsequent output.
|
|
760
|
-
* This approach ensures that test results are presented promptly and
|
|
761
|
-
* efficiently, supporting clear and organised reporting across all test
|
|
762
|
-
* cases and folders.
|
|
763
|
-
*/
|
|
764
|
-
void
|
|
765
|
-
test_reporter::output (void)
|
|
766
|
-
{
|
|
767
|
-
printf ("%s", out_.c_str ()); // No `\n` here.
|
|
768
|
-
out_.clear ();
|
|
769
|
-
}
|
|
770
|
-
|
|
771
396
|
// --------------------------------------------------------------------------
|
|
772
397
|
} // namespace micro_os_plus::micro_test_plus
|
|
773
398
|
|
package/src/test-runner.cpp
CHANGED
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
#include <micro-os-plus/micro-test-plus.h>
|
|
46
46
|
|
|
47
47
|
#include <stdio.h>
|
|
48
|
+
#include <stdlib.h>
|
|
48
49
|
#include <vector>
|
|
49
50
|
|
|
50
51
|
// ----------------------------------------------------------------------------
|
|
@@ -99,6 +100,14 @@ namespace micro_os_plus::micro_test_plus
|
|
|
99
100
|
printf ("%s\n", __PRETTY_FUNCTION__);
|
|
100
101
|
#endif // MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS
|
|
101
102
|
|
|
103
|
+
#if defined(_WIN32) || defined(CLOCK_MONOTONIC)
|
|
104
|
+
#if defined(_WIN32)
|
|
105
|
+
timespec_get (&begin_time, TIME_UTC);
|
|
106
|
+
#else
|
|
107
|
+
clock_gettime (CLOCK_MONOTONIC, &begin_time);
|
|
108
|
+
#endif
|
|
109
|
+
#endif
|
|
110
|
+
|
|
102
111
|
argc_ = argc;
|
|
103
112
|
argv_ = argv;
|
|
104
113
|
|
|
@@ -120,6 +129,7 @@ namespace micro_os_plus::micro_test_plus
|
|
|
120
129
|
#endif // !defined(MICRO_OS_PLUS_INCLUDE_STARTUP)
|
|
121
130
|
|
|
122
131
|
verbosity_t verbosity = verbosity::normal;
|
|
132
|
+
const char* reporter_name = "tap";
|
|
123
133
|
for (int i = 0; i < argc; ++i)
|
|
124
134
|
{
|
|
125
135
|
if (strcmp (argv[i], "--verbose") == 0)
|
|
@@ -134,10 +144,27 @@ namespace micro_os_plus::micro_test_plus
|
|
|
134
144
|
{
|
|
135
145
|
verbosity = verbosity::silent;
|
|
136
146
|
}
|
|
147
|
+
else if (strncmp (argv[i], "--reporter=", 11) == 0)
|
|
148
|
+
{
|
|
149
|
+
reporter_name = argv[i] + 11;
|
|
150
|
+
}
|
|
137
151
|
}
|
|
138
152
|
|
|
139
|
-
//
|
|
140
|
-
|
|
153
|
+
// Initialize and configure the reporter.
|
|
154
|
+
if (strcmp (reporter_name, "basic") == 0)
|
|
155
|
+
{
|
|
156
|
+
reporter = new test_reporter_basic ();
|
|
157
|
+
}
|
|
158
|
+
else if (strcmp (reporter_name, "tap") == 0)
|
|
159
|
+
{
|
|
160
|
+
reporter = new test_reporter_tap ();
|
|
161
|
+
}
|
|
162
|
+
else
|
|
163
|
+
{
|
|
164
|
+
fprintf (stderr, "error: unknown reporter '%s'\n", reporter_name);
|
|
165
|
+
exit (1);
|
|
166
|
+
}
|
|
167
|
+
reporter->verbosity = verbosity;
|
|
141
168
|
|
|
142
169
|
// ------------------------------------------------------------------------
|
|
143
170
|
|
|
@@ -177,11 +204,12 @@ namespace micro_os_plus::micro_test_plus
|
|
|
177
204
|
|
|
178
205
|
// ------------------------------------------------------------------------
|
|
179
206
|
|
|
180
|
-
|
|
181
|
-
current_test_suite =
|
|
207
|
+
default_test_suite = new test_suite_base (default_suite_name_);
|
|
208
|
+
current_test_suite = default_test_suite;
|
|
182
209
|
|
|
183
210
|
// Deferred to first test case or test suite end, to allow various
|
|
184
211
|
// initialisations to display their messages.
|
|
212
|
+
// reporter->begin_test (test_suites_count ());
|
|
185
213
|
// default_test_suite_->begin_test_suite ();
|
|
186
214
|
}
|
|
187
215
|
#pragma GCC diagnostic pop
|
|
@@ -191,29 +219,48 @@ namespace micro_os_plus::micro_test_plus
|
|
|
191
219
|
{
|
|
192
220
|
bool was_successful = true;
|
|
193
221
|
|
|
194
|
-
if (!
|
|
222
|
+
if (!default_test_suite->unused ())
|
|
195
223
|
{
|
|
196
|
-
|
|
197
|
-
was_successful =
|
|
224
|
+
default_test_suite->end_test_suite ();
|
|
225
|
+
was_successful = default_test_suite->was_successful ();
|
|
226
|
+
|
|
227
|
+
totals.successful_checks += default_test_suite->successful_checks ();
|
|
228
|
+
totals.failed_checks += default_test_suite->failed_checks ();
|
|
229
|
+
totals.test_cases_count += default_test_suite->test_cases_count ();
|
|
198
230
|
}
|
|
199
231
|
|
|
200
|
-
if (
|
|
232
|
+
if (test_suites != nullptr)
|
|
201
233
|
{
|
|
202
|
-
for (auto
|
|
234
|
+
for (auto test_suite : *test_suites)
|
|
203
235
|
{
|
|
204
|
-
current_test_suite =
|
|
236
|
+
current_test_suite = test_suite;
|
|
205
237
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
238
|
+
test_suite->begin_test_suite ();
|
|
239
|
+
test_suite->run ();
|
|
240
|
+
test_suite->end_test_suite ();
|
|
209
241
|
|
|
210
|
-
was_successful &=
|
|
242
|
+
was_successful &= test_suite->was_successful ();
|
|
243
|
+
|
|
244
|
+
totals.successful_checks += test_suite->successful_checks ();
|
|
245
|
+
totals.failed_checks += test_suite->failed_checks ();
|
|
246
|
+
totals.test_cases_count += test_suite->test_cases_count ();
|
|
211
247
|
}
|
|
212
|
-
if (reporter
|
|
248
|
+
if (reporter->verbosity != verbosity::silent)
|
|
213
249
|
{
|
|
214
250
|
// printf ("\n");
|
|
215
251
|
}
|
|
216
252
|
}
|
|
253
|
+
|
|
254
|
+
#if defined(_WIN32) || defined(CLOCK_MONOTONIC)
|
|
255
|
+
#if defined(_WIN32)
|
|
256
|
+
timespec_get (&end_time, TIME_UTC);
|
|
257
|
+
#else
|
|
258
|
+
clock_gettime (CLOCK_MONOTONIC, &end_time);
|
|
259
|
+
#endif
|
|
260
|
+
#endif
|
|
261
|
+
|
|
262
|
+
reporter->end_test (*this);
|
|
263
|
+
|
|
217
264
|
return was_successful ? 0 : 1;
|
|
218
265
|
}
|
|
219
266
|
|
|
@@ -235,11 +282,12 @@ namespace micro_os_plus::micro_test_plus
|
|
|
235
282
|
printf ("%s\n", __PRETTY_FUNCTION__);
|
|
236
283
|
#endif // MICRO_OS_PLUS_TRACE_MICRO_TEST_PLUS
|
|
237
284
|
|
|
238
|
-
if (
|
|
285
|
+
if (test_suites == nullptr)
|
|
239
286
|
{
|
|
240
|
-
|
|
287
|
+
test_suites = new std::vector<test_suite_base*> ();
|
|
241
288
|
}
|
|
242
|
-
|
|
289
|
+
test_suites->push_back (suite);
|
|
290
|
+
suite->index = test_suites->size () + 1;
|
|
243
291
|
}
|
|
244
292
|
|
|
245
293
|
/**
|
package/src/test-suite.cpp
CHANGED
|
@@ -121,9 +121,17 @@ namespace micro_os_plus::micro_test_plus
|
|
|
121
121
|
void
|
|
122
122
|
test_suite_base::begin_test_suite (void)
|
|
123
123
|
{
|
|
124
|
+
#if defined(_WIN32) || defined(CLOCK_MONOTONIC)
|
|
125
|
+
#if defined(_WIN32)
|
|
126
|
+
timespec_get (&begin_time, TIME_UTC);
|
|
127
|
+
#else
|
|
128
|
+
clock_gettime (CLOCK_MONOTONIC, &begin_time);
|
|
129
|
+
#endif
|
|
130
|
+
#endif
|
|
131
|
+
|
|
124
132
|
process_deferred_begin = false;
|
|
125
133
|
|
|
126
|
-
reporter
|
|
134
|
+
reporter->begin_test_suite (name_);
|
|
127
135
|
}
|
|
128
136
|
|
|
129
137
|
/**
|
|
@@ -140,9 +148,19 @@ namespace micro_os_plus::micro_test_plus
|
|
|
140
148
|
{
|
|
141
149
|
if (process_deferred_begin)
|
|
142
150
|
{
|
|
151
|
+
reporter->begin_test (runner.test_suites_count ());
|
|
152
|
+
|
|
143
153
|
begin_test_suite ();
|
|
144
154
|
}
|
|
145
|
-
|
|
155
|
+
|
|
156
|
+
#if defined(_WIN32) || defined(CLOCK_MONOTONIC)
|
|
157
|
+
#if defined(_WIN32)
|
|
158
|
+
timespec_get (&end_time, TIME_UTC);
|
|
159
|
+
#else
|
|
160
|
+
clock_gettime (CLOCK_MONOTONIC, &end_time);
|
|
161
|
+
#endif
|
|
162
|
+
#endif
|
|
163
|
+
reporter->end_test_suite (*this);
|
|
146
164
|
}
|
|
147
165
|
|
|
148
166
|
/**
|
|
@@ -160,15 +178,17 @@ namespace micro_os_plus::micro_test_plus
|
|
|
160
178
|
{
|
|
161
179
|
if (process_deferred_begin)
|
|
162
180
|
{
|
|
181
|
+
reporter->begin_test (runner.test_suites_count ());
|
|
182
|
+
|
|
163
183
|
begin_test_suite ();
|
|
164
184
|
}
|
|
165
185
|
|
|
166
186
|
test_case_name_ = name;
|
|
167
|
-
++
|
|
187
|
+
++test_cases_count_;
|
|
168
188
|
|
|
169
189
|
current_test_case = {};
|
|
170
190
|
|
|
171
|
-
reporter
|
|
191
|
+
reporter->begin_test_case (test_case_name_);
|
|
172
192
|
}
|
|
173
193
|
|
|
174
194
|
/**
|
|
@@ -182,7 +202,7 @@ namespace micro_os_plus::micro_test_plus
|
|
|
182
202
|
void
|
|
183
203
|
test_suite_base::end_test_case (void)
|
|
184
204
|
{
|
|
185
|
-
reporter
|
|
205
|
+
reporter->end_test_case (test_case_name_);
|
|
186
206
|
}
|
|
187
207
|
|
|
188
208
|
/**
|
|
@@ -213,6 +233,39 @@ namespace micro_os_plus::micro_test_plus
|
|
|
213
233
|
++current_test_case.failed_checks;
|
|
214
234
|
}
|
|
215
235
|
|
|
236
|
+
#if defined(_WIN32) || defined(CLOCK_MONOTONIC)
|
|
237
|
+
/**
|
|
238
|
+
* @details
|
|
239
|
+
* Subtracts `begin_time` from `end_time` using monotonic clock arithmetic,
|
|
240
|
+
* handling the nanosecond borrow correctly, then splits the result into
|
|
241
|
+
* whole milliseconds and the sub-millisecond remainder expressed in
|
|
242
|
+
* microseconds (0–999).
|
|
243
|
+
*/
|
|
244
|
+
#pragma GCC diagnostic push
|
|
245
|
+
#pragma GCC diagnostic ignored "-Wshadow"
|
|
246
|
+
void
|
|
247
|
+
test_suite_base::compute_elapsed_time (timespec& begin_time,
|
|
248
|
+
timespec& end_time,
|
|
249
|
+
long& milliseconds,
|
|
250
|
+
long& microseconds)
|
|
251
|
+
{
|
|
252
|
+
long long delta_ns = end_time.tv_nsec - begin_time.tv_nsec;
|
|
253
|
+
long long delta_s = end_time.tv_sec - begin_time.tv_sec;
|
|
254
|
+
if (delta_ns < 0)
|
|
255
|
+
{
|
|
256
|
+
delta_ns += 1000000000LL;
|
|
257
|
+
--delta_s;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Split into milliseconds and microseconds.
|
|
261
|
+
const long long total_us = delta_s * 1000000LL + delta_ns / 1000LL;
|
|
262
|
+
milliseconds = static_cast<long> (total_us / 1000LL);
|
|
263
|
+
microseconds = static_cast<long> (total_us % 1000LL);
|
|
264
|
+
}
|
|
265
|
+
#pragma GCC diagnostic pop
|
|
266
|
+
|
|
267
|
+
#endif
|
|
268
|
+
|
|
216
269
|
// ==========================================================================
|
|
217
270
|
|
|
218
271
|
/**
|