1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). |
4 | ** Contact: http://www.qt-project.org/legal |
5 | ** |
6 | ** This file is part of the QtTest module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and Digia. For licensing terms and |
14 | ** conditions see http://qt.digia.com/licensing. For further information |
15 | ** use the contact form at http://qt.digia.com/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 2.1 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 2.1 requirements |
23 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
24 | ** |
25 | ** In addition, as a special exception, Digia gives you certain additional |
26 | ** rights. These rights are described in the Digia Qt LGPL Exception |
27 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
28 | ** |
29 | ** GNU General Public License Usage |
30 | ** Alternatively, this file may be used under the terms of the GNU |
31 | ** General Public License version 3.0 as published by the Free Software |
32 | ** Foundation and appearing in the file LICENSE.GPL included in the |
33 | ** packaging of this file. Please review the following information to |
34 | ** ensure the GNU General Public License version 3.0 requirements will be |
35 | ** met: http://www.gnu.org/copyleft/gpl.html. |
36 | ** |
37 | ** |
38 | ** $QT_END_LICENSE$ |
39 | ** |
40 | ****************************************************************************/ |
41 | |
42 | #include "QtTest/private/qtestresult_p.h" |
43 | #include <QtCore/qglobal.h> |
44 | |
45 | #include "QtTest/private/qtestlog_p.h" |
46 | #include "QtTest/qtestdata.h" |
47 | #include "QtTest/qtestassert.h" |
48 | |
49 | #include <stdio.h> |
50 | #include <string.h> |
51 | |
52 | QT_BEGIN_NAMESPACE |
53 | |
54 | namespace QTest |
55 | { |
56 | static QTestData *currentTestData = 0; |
57 | static QTestData *currentGlobalTestData = 0; |
58 | static const char *currentTestFunc = 0; |
59 | static const char *currentTestObjectName = 0; |
60 | static bool failed = false; |
61 | static bool dataFailed = false; |
62 | static bool skipCurrentTest = false; |
63 | static QTestResult::TestLocation location = QTestResult::NoWhere; |
64 | |
65 | static int fails = 0; |
66 | static int passes = 0; |
67 | static int skips = 0; |
68 | |
69 | static const char * = 0; |
70 | static int expectFailMode = 0; |
71 | |
72 | static const char *currentAppName = 0; |
73 | } |
74 | |
75 | void QTestResult::reset() |
76 | { |
77 | QTest::currentTestData = 0; |
78 | QTest::currentGlobalTestData = 0; |
79 | QTest::currentTestFunc = 0; |
80 | QTest::currentTestObjectName = 0; |
81 | QTest::failed = false; |
82 | QTest::dataFailed = false; |
83 | QTest::location = QTestResult::NoWhere; |
84 | |
85 | QTest::fails = 0; |
86 | QTest::passes = 0; |
87 | QTest::skips = 0; |
88 | |
89 | QTest::expectFailComment = 0; |
90 | QTest::expectFailMode = 0; |
91 | } |
92 | |
93 | bool QTestResult::allDataPassed() |
94 | { |
95 | return !QTest::failed; |
96 | } |
97 | |
98 | bool QTestResult::currentTestFailed() |
99 | { |
100 | return QTest::dataFailed; |
101 | } |
102 | |
103 | QTestData *QTestResult::currentGlobalTestData() |
104 | { |
105 | return QTest::currentGlobalTestData; |
106 | } |
107 | |
108 | QTestData *QTestResult::currentTestData() |
109 | { |
110 | return QTest::currentTestData; |
111 | } |
112 | |
113 | void QTestResult::setCurrentGlobalTestData(QTestData *data) |
114 | { |
115 | QTest::currentGlobalTestData = data; |
116 | } |
117 | |
118 | void QTestResult::setCurrentTestData(QTestData *data) |
119 | { |
120 | QTest::currentTestData = data; |
121 | QTest::dataFailed = false; |
122 | } |
123 | |
124 | void QTestResult::setCurrentTestFunction(const char *func) |
125 | { |
126 | QTest::currentTestFunc = func; |
127 | QTest::failed = false; |
128 | if (!func) |
129 | QTest::location = NoWhere; |
130 | if (func) |
131 | QTestLog::enterTestFunction(func); |
132 | } |
133 | |
134 | static void clearExpectFail() |
135 | { |
136 | QTest::expectFailMode = 0; |
137 | delete [] const_cast<char *>(QTest::expectFailComment); |
138 | QTest::expectFailComment = 0; |
139 | } |
140 | |
141 | void QTestResult::finishedCurrentTestFunction() |
142 | { |
143 | if (!QTest::failed && QTestLog::unhandledIgnoreMessages()) { |
144 | QTestLog::printUnhandledIgnoreMessages(); |
145 | addFailure("Not all expected messages were received" , 0, 0); |
146 | } |
147 | |
148 | if (!QTest::failed && !QTest::skipCurrentTest) { |
149 | QTestLog::addPass("" ); |
150 | ++QTest::passes; |
151 | } |
152 | QTest::currentTestFunc = 0; |
153 | QTest::failed = false; |
154 | QTest::dataFailed = false; |
155 | QTest::location = NoWhere; |
156 | |
157 | QTestLog::leaveTestFunction(); |
158 | |
159 | clearExpectFail(); |
160 | } |
161 | |
162 | const char *QTestResult::currentTestFunction() |
163 | { |
164 | return QTest::currentTestFunc; |
165 | } |
166 | |
167 | const char *QTestResult::currentDataTag() |
168 | { |
169 | return QTest::currentTestData ? QTest::currentTestData->dataTag() |
170 | : static_cast<const char *>(0); |
171 | } |
172 | |
173 | const char *QTestResult::currentGlobalDataTag() |
174 | { |
175 | return QTest::currentGlobalTestData ? QTest::currentGlobalTestData->dataTag() |
176 | : static_cast<const char *>(0); |
177 | } |
178 | |
179 | static bool isExpectFailData(const char *dataIndex) |
180 | { |
181 | if (!dataIndex || dataIndex[0] == '\0') |
182 | return true; |
183 | if (!QTest::currentTestData) |
184 | return false; |
185 | if (strcmp(dataIndex, QTest::currentTestData->dataTag()) == 0) |
186 | return true; |
187 | return false; |
188 | } |
189 | |
190 | bool QTestResult::expectFail(const char *dataIndex, const char *, |
191 | QTest::TestFailMode mode, const char *file, int line) |
192 | { |
193 | QTEST_ASSERT(comment); |
194 | QTEST_ASSERT(mode > 0); |
195 | |
196 | if (!isExpectFailData(dataIndex)) { |
197 | delete[] comment; |
198 | return true; // we don't care |
199 | } |
200 | |
201 | if (QTest::expectFailMode) { |
202 | delete[] comment; |
203 | clearExpectFail(); |
204 | addFailure("Already expecting a fail" , file, line); |
205 | return false; |
206 | } |
207 | |
208 | QTest::expectFailMode = mode; |
209 | QTest::expectFailComment = comment; |
210 | return true; |
211 | } |
212 | |
213 | static bool checkStatement(bool statement, const char *msg, const char *file, int line) |
214 | { |
215 | if (statement) { |
216 | if (QTest::expectFailMode) { |
217 | QTestLog::addXPass(msg, file, line); |
218 | bool doContinue = (QTest::expectFailMode == QTest::Continue); |
219 | clearExpectFail(); |
220 | QTest::failed = true; |
221 | ++QTest::fails; |
222 | return doContinue; |
223 | } |
224 | return true; |
225 | } |
226 | |
227 | if (QTest::expectFailMode) { |
228 | QTestLog::addXFail(QTest::expectFailComment, file, line); |
229 | bool doContinue = (QTest::expectFailMode == QTest::Continue); |
230 | clearExpectFail(); |
231 | return doContinue; |
232 | } |
233 | |
234 | QTestResult::addFailure(msg, file, line); |
235 | return false; |
236 | } |
237 | |
238 | bool QTestResult::verify(bool statement, const char *statementStr, |
239 | const char *description, const char *file, int line) |
240 | { |
241 | char msg[1024]; |
242 | |
243 | if (QTestLog::verboseLevel() >= 2) { |
244 | QTest::qt_snprintf(msg, 1024, "QVERIFY(%s)" , statementStr); |
245 | QTestLog::info(msg, file, line); |
246 | } |
247 | |
248 | QTest::qt_snprintf(msg, 1024, "'%s' returned FALSE. (%s)" , statementStr, description); |
249 | |
250 | return checkStatement(statement, msg, file, line); |
251 | } |
252 | |
253 | bool QTestResult::compare(bool success, const char *msg, const char *file, int line) |
254 | { |
255 | if (QTestLog::verboseLevel() >= 2) { |
256 | QTestLog::info(msg, file, line); |
257 | } |
258 | |
259 | return checkStatement(success, msg, file, line); |
260 | } |
261 | |
262 | bool QTestResult::compare(bool success, const char *msg, char *val1, char *val2, |
263 | const char *actual, const char *expected, const char *file, int line) |
264 | { |
265 | QTEST_ASSERT(expected); |
266 | QTEST_ASSERT(actual); |
267 | |
268 | if (!val1 && !val2) |
269 | return compare(success, msg, file, line); |
270 | |
271 | char buf[1024]; |
272 | QTest::qt_snprintf(buf, 1024, "%s\n Actual (%s): %s\n Expected (%s): %s" , msg, |
273 | actual, val1 ? val1 : "<null>" , |
274 | expected, val2 ? val2 : "<null>" ); |
275 | delete [] val1; |
276 | delete [] val2; |
277 | return compare(success, buf, file, line); |
278 | } |
279 | |
280 | void QTestResult::addFailure(const char *message, const char *file, int line) |
281 | { |
282 | clearExpectFail(); |
283 | |
284 | QTestLog::addFail(message, file, line); |
285 | QTest::failed = true; |
286 | QTest::dataFailed = true; |
287 | ++QTest::fails; |
288 | } |
289 | |
290 | void QTestResult::addSkip(const char *message, QTest::SkipMode mode, |
291 | const char *file, int line) |
292 | { |
293 | clearExpectFail(); |
294 | |
295 | QTestLog::addSkip(message, mode, file, line); |
296 | ++QTest::skips; |
297 | } |
298 | |
299 | QTestResult::TestLocation QTestResult::currentTestLocation() |
300 | { |
301 | return QTest::location; |
302 | } |
303 | |
304 | void QTestResult::setCurrentTestLocation(TestLocation loc) |
305 | { |
306 | QTest::location = loc; |
307 | } |
308 | |
309 | void QTestResult::setCurrentTestObject(const char *name) |
310 | { |
311 | QTest::currentTestObjectName = name; |
312 | } |
313 | |
314 | const char *QTestResult::currentTestObjectName() |
315 | { |
316 | return QTest::currentTestObjectName ? QTest::currentTestObjectName : "" ; |
317 | } |
318 | |
319 | int QTestResult::passCount() |
320 | { |
321 | return QTest::passes; |
322 | } |
323 | |
324 | int QTestResult::failCount() |
325 | { |
326 | return QTest::fails; |
327 | } |
328 | |
329 | int QTestResult::skipCount() |
330 | { |
331 | return QTest::skips; |
332 | } |
333 | |
334 | void QTestResult::ignoreMessage(QtMsgType type, const char *msg) |
335 | { |
336 | QTestLog::addIgnoreMessage(type, msg); |
337 | } |
338 | |
339 | bool QTestResult::testFailed() |
340 | { |
341 | return QTest::failed; |
342 | } |
343 | |
344 | void QTestResult::setSkipCurrentTest(bool value) |
345 | { |
346 | QTest::skipCurrentTest = value; |
347 | } |
348 | |
349 | bool QTestResult::skipCurrentTest() |
350 | { |
351 | return QTest::skipCurrentTest; |
352 | } |
353 | |
354 | void QTestResult::setCurrentAppName(const char *appName) |
355 | { |
356 | QTest::currentAppName = appName; |
357 | } |
358 | const char *QTestResult::currentAppName() |
359 | { |
360 | return QTest::currentAppName; |
361 | } |
362 | |
363 | QT_END_NAMESPACE |
364 | |