GCC Code Coverage Report


Directory: src/gate/
File: src/gate/cxx_tests.cpp
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 73 128 57.0%
Functions: 17 22 77.3%
Branches: 26 110 23.6%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/tests.hpp"
30 #include "gate/memalloc.hpp"
31 #include "gate/tests.h"
32 #include "gate/console.hpp"
33
34 namespace gate
35 {
36 145 UnitTestBase::UnitTestBase(char const* name)
37 145 : unitName(String::createStatic(name))
38 {
39 145 }
40 290 UnitTestBase::~UnitTestBase() noexcept
41 {
42 290 }
43 145 void UnitTestBase::run()
44 {
45 try
46 {
47
1/2
✓ Branch 1 taken 145 times.
✗ Branch 2 not taken.
145 this->test();
48 }
49 catch (...)
50 {
51 }
52 145 }
53 435 char const* UnitTestBase::getUnitTestName() const
54 {
55 435 return this->unitName.c_str();
56 }
57
58
59
60
61 struct GATE_API_LOCAL UnitTestRegistry
62 {
63 public:
64 IRunnable* runnables[512];
65 char const* names[512];
66 size_t runnablesCount;
67 };
68
69 static UnitTestRegistry global_unit_test_registry = GATE_INIT_EMPTY;
70
71 8 int UnitTest::runMainHandler(char const* const* arguments, size_t argcount)
72 {
73
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
8 static StaticString const argHelp = "--help";
74
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
8 static StaticString const argList = "--list";
75
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
8 static StaticString const argTrace = "--trace";
76
77 8 bool_t showHelp = false;
78 8 bool_t listTests = false;
79 8 bool_t enableTrace = false;
80
81 char const* patterns[512];
82 8 size_t patternsCount = 0;
83 8 const size_t patternsMax = sizeof(patterns) / sizeof(patterns[0]);
84
85
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 for (size_t ndx = 0; ndx != argcount; ++ndx)
86 {
87 const StaticString arg(arguments[ndx], String::length(arguments[ndx]));
88 if (arg == argHelp)
89 {
90 showHelp = true;
91 }
92 else if (arg == argList)
93 {
94 listTests = true;
95 }
96 else if (arg == argTrace)
97 {
98 enableTrace = true;
99 }
100 else
101 {
102 if (patternsCount < patternsMax)
103 {
104 patterns[patternsCount] = arguments[ndx];
105 ++patternsCount;
106 }
107 }
108 }
109
110
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (showHelp)
111 {
112 gate::Console
113 << "Usage:" << strings::NewLine
114 << "testapp --help" << strings::NewLine
115 << "\tPrint test program usage description" << strings::NewLine
116 << "testapp --list" << strings::NewLine
117 << "\tLists all registered test cases by their anmes" << strings::NewLine
118 << "testapp" << strings::NewLine
119 << "\tExecutes all registered test cases" << strings::NewLine
120 << "testapp test_case_name1 test_case_name2" << strings::NewLine
121 << "\tExecutes only test cases named by arguments" << strings::NewLine
122 << "testapp --trace test_case_name1 test_case_name2" << strings::NewLine
123 << "\tExecutes given test cases with trace-mode enabled" << strings::NewLine
124 ;
125 return 0;
126 }
127
128
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (listTests)
129 {
130 Stream& strm = Console;
131 UnitTest::printRegisteredTests(strm);
132 return 0;
133 }
134
135
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 UnitTest::init();
136
137
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (enableTrace)
138 {
139 UnitTest::setTrace(true);
140 }
141
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 int exitCode = UnitTest::runRegisteredTests(patterns, patternsCount);
142
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 UnitTest::printTestReports();
143
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 UnitTest::uninit();
144 8 return exitCode;
145 }
146
147 8 void UnitTest::init()
148 {
149 8 gate_test_init(NULL);
150 8 }
151
152 8 void UnitTest::uninit()
153 {
154 8 gate_test_uninit();
155 8 }
156
157 145 void UnitTest::registerTest(UnitTestBase& test)
158 {
159 145 size_t const maxRunnables = sizeof(global_unit_test_registry.runnables) / sizeof(global_unit_test_registry.runnables[0]);
160
161
1/2
✓ Branch 0 taken 145 times.
✗ Branch 1 not taken.
145 if (global_unit_test_registry.runnablesCount < maxRunnables)
162 {
163
2/2
✓ Branch 0 taken 4622 times.
✓ Branch 1 taken 145 times.
4767 for (size_t ndx = 0; ndx != global_unit_test_registry.runnablesCount; ++ndx)
164 {
165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4622 times.
4622 if (global_unit_test_registry.runnables[ndx] == &test)
166 {
167 return;
168 }
169 }
170 145 global_unit_test_registry.runnables[global_unit_test_registry.runnablesCount] = &test;
171 145 global_unit_test_registry.names[global_unit_test_registry.runnablesCount] = test.getUnitTestName();
172 145 ++global_unit_test_registry.runnablesCount;
173 }
174 }
175
176 145 static bool_t isSelectedTest(char const* name, char const* const* filterPatterns, size_t filterPatternsCount)
177 {
178
1/2
✓ Branch 0 taken 145 times.
✗ Branch 1 not taken.
145 if (filterPatternsCount == 0)
179 {
180 // no filter -> all tests are selected
181 145 return true;
182 }
183
184 const StaticString tcName = name;
185
186 for (size_t ndx = 0; ndx != filterPatternsCount; ++ndx)
187 {
188 StaticString const pattern = filterPatterns[ndx];
189 if (tcName.like(pattern))
190 {
191 // matching pattern found
192 return true;
193 }
194 }
195 return false;
196 }
197
198 8 int UnitTest::runRegisteredTests(char const* const* filterPatterns, size_t filterPatternsCount)
199 {
200
2/2
✓ Branch 0 taken 145 times.
✓ Branch 1 taken 8 times.
153 for (size_t ndx = 0; ndx != global_unit_test_registry.runnablesCount; ++ndx)
201 {
202 145 char const* name = global_unit_test_registry.names[ndx];
203
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 145 times.
145 if (!isSelectedTest(name, filterPatterns, filterPatternsCount))
204 {
205 continue;
206 }
207 145 IRunnable* ptrRunnable = global_unit_test_registry.runnables[ndx];
208
1/2
✓ Branch 0 taken 145 times.
✗ Branch 1 not taken.
145 if (ptrRunnable)
209 {
210 try
211 {
212
1/2
✓ Branch 1 taken 145 times.
✗ Branch 2 not taken.
145 ptrRunnable->run();
213 }
214 catch (UnitTestException const& /*xcpt*/)
215 {
216 }
217 catch (...)
218 {
219 }
220 }
221 }
222
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if (UnitTest::haveTestsFailed())
223 {
224 return 1;
225 }
226 else
227 {
228 8 return 0;
229 }
230 }
231 void UnitTest::printRegisteredTests(Stream& strm)
232 {
233 for (size_t ndx = 0; ndx != global_unit_test_registry.runnablesCount; ++ndx)
234 {
235 char const* name = global_unit_test_registry.names[ndx];
236 strm << name << strings::NewLine;
237 }
238 }
239
240 void UnitTest::setTrace(bool_t enabled)
241 {
242 gate_test_trace_enable(enabled);
243 }
244
245 145 void UnitTest::beginTest(char const* unitname, char const* filepath, unsigned codeline)
246 {
247 145 gate_test_unit_begin(unitname, filepath, codeline);
248 145 }
249 145 void UnitTest::endTest(char const* unitname, char const* filepath, unsigned codeline)
250 {
251 145 }
252 7562 void UnitTest::countTest()
253 {
254 7562 gate_test_count_test();
255 7562 }
256 void UnitTest::countTestFailure()
257 {
258 gate_test_count_error();
259 }
260 7562 void UnitTest::printTrace(char const* message, char const* filepath, unsigned codeline)
261 {
262 7562 gate_test_trace_message(message, filepath, codeline);
263 7562 }
264 void printSuccess(char const* message, char const* filepath, unsigned codeline)
265 {
266 gate_test_success_message(message, filepath, codeline);
267 }
268 7562 void UnitTest::printSuccess(char const* message, char const* filepath, unsigned codeline)
269 {
270 7562 gate_test_success_message(message, filepath, codeline);
271 7562 }
272 void UnitTest::printError(char const* message, char const* filepath, unsigned codeline)
273 {
274 gate_test_error_message(message, filepath, codeline);
275 }
276 8 void UnitTest::printTestReports()
277 {
278 8 gate_test_print_reports();
279 8 }
280 8 bool_t UnitTest::haveTestsFailed()
281 {
282 8 return gate_test_failed();
283 }
284
285
286 } // end of namespace test
287
288
289
290