Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/qmltest/quicktest.cpp |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /**************************************************************************** | - | ||||||||||||||||||
2 | ** | - | ||||||||||||||||||
3 | ** Copyright (C) 2016 The Qt Company Ltd. | - | ||||||||||||||||||
4 | ** Contact: https://www.qt.io/licensing/ | - | ||||||||||||||||||
5 | ** | - | ||||||||||||||||||
6 | ** This file is part of the test suite 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 The Qt Company. For licensing terms | - | ||||||||||||||||||
14 | ** and conditions see https://www.qt.io/terms-conditions. For further | - | ||||||||||||||||||
15 | ** information use the contact form at https://www.qt.io/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 3 as published by the Free Software | - | ||||||||||||||||||
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the | - | ||||||||||||||||||
21 | ** packaging of this file. Please review the following information to | - | ||||||||||||||||||
22 | ** ensure the GNU Lesser General Public License version 3 requirements | - | ||||||||||||||||||
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. | - | ||||||||||||||||||
24 | ** | - | ||||||||||||||||||
25 | ** GNU General Public License Usage | - | ||||||||||||||||||
26 | ** Alternatively, this file may be used under the terms of the GNU | - | ||||||||||||||||||
27 | ** General Public License version 2.0 or (at your option) the GNU General | - | ||||||||||||||||||
28 | ** Public license version 3 or any later version approved by the KDE Free | - | ||||||||||||||||||
29 | ** Qt Foundation. The licenses are as published by the Free Software | - | ||||||||||||||||||
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 | - | ||||||||||||||||||
31 | ** included in the packaging of this file. Please review the following | - | ||||||||||||||||||
32 | ** information to ensure the GNU General Public License requirements will | - | ||||||||||||||||||
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and | - | ||||||||||||||||||
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. | - | ||||||||||||||||||
35 | ** | - | ||||||||||||||||||
36 | ** $QT_END_LICENSE$ | - | ||||||||||||||||||
37 | ** | - | ||||||||||||||||||
38 | ****************************************************************************/ | - | ||||||||||||||||||
39 | - | |||||||||||||||||||
40 | #include "quicktest.h" | - | ||||||||||||||||||
41 | #include "quicktestresult_p.h" | - | ||||||||||||||||||
42 | #include <QtTest/qtestsystem.h> | - | ||||||||||||||||||
43 | #include "qtestoptions_p.h" | - | ||||||||||||||||||
44 | #include <QtQml/qqml.h> | - | ||||||||||||||||||
45 | #include <QtQml/qqmlengine.h> | - | ||||||||||||||||||
46 | #include <QtQml/qqmlcontext.h> | - | ||||||||||||||||||
47 | #include <QtQuick/qquickview.h> | - | ||||||||||||||||||
48 | #include <QtQml/qjsvalue.h> | - | ||||||||||||||||||
49 | #include <QtQml/qjsengine.h> | - | ||||||||||||||||||
50 | #include <QtQml/qqmlpropertymap.h> | - | ||||||||||||||||||
51 | #include <QtGui/qopengl.h> | - | ||||||||||||||||||
52 | #include <QtCore/qurl.h> | - | ||||||||||||||||||
53 | #include <QtCore/qfileinfo.h> | - | ||||||||||||||||||
54 | #include <QtCore/qdir.h> | - | ||||||||||||||||||
55 | #include <QtCore/qdiriterator.h> | - | ||||||||||||||||||
56 | #include <QtCore/qfile.h> | - | ||||||||||||||||||
57 | #include <QtCore/qdebug.h> | - | ||||||||||||||||||
58 | #include <QtCore/qeventloop.h> | - | ||||||||||||||||||
59 | #include <QtCore/qtextstream.h> | - | ||||||||||||||||||
60 | #include <QtGui/qtextdocument.h> | - | ||||||||||||||||||
61 | #include <stdio.h> | - | ||||||||||||||||||
62 | #include <QtGui/QGuiApplication> | - | ||||||||||||||||||
63 | #include <QtCore/QTranslator> | - | ||||||||||||||||||
64 | #include <QtTest/QSignalSpy> | - | ||||||||||||||||||
65 | #include <QtQml/QQmlFileSelector> | - | ||||||||||||||||||
66 | - | |||||||||||||||||||
67 | #include <private/qqmlcomponent_p.h> | - | ||||||||||||||||||
68 | - | |||||||||||||||||||
69 | #ifdef QT_QMLTEST_WITH_WIDGETS | - | ||||||||||||||||||
70 | #include <QtWidgets/QApplication> | - | ||||||||||||||||||
71 | #endif | - | ||||||||||||||||||
72 | - | |||||||||||||||||||
73 | QT_BEGIN_NAMESPACE | - | ||||||||||||||||||
74 | - | |||||||||||||||||||
75 | class QTestRootObject : public QObject | - | ||||||||||||||||||
76 | { | - | ||||||||||||||||||
77 | Q_OBJECT | - | ||||||||||||||||||
78 | Q_PROPERTY(bool windowShown READ windowShown NOTIFY windowShownChanged) | - | ||||||||||||||||||
79 | Q_PROPERTY(bool hasTestCase READ hasTestCase WRITE setHasTestCase NOTIFY hasTestCaseChanged) | - | ||||||||||||||||||
80 | Q_PROPERTY(QObject *defined READ defined) | - | ||||||||||||||||||
81 | public: | - | ||||||||||||||||||
82 | QTestRootObject(QObject *parent = nullptr) | - | ||||||||||||||||||
83 | : QObject(parent), hasQuit(false), m_windowShown(false), m_hasTestCase(false) { | - | ||||||||||||||||||
84 | m_defined = new QQmlPropertyMap(this); | - | ||||||||||||||||||
85 | #if defined(QT_OPENGL_ES_2_ANGLE) | - | ||||||||||||||||||
86 | m_defined->insert(QLatin1String("QT_OPENGL_ES_2_ANGLE"), QVariant(true)); | - | ||||||||||||||||||
87 | #endif | - | ||||||||||||||||||
88 | } executed 32 times by 4 tests: end of block Executed by:
| 32 | ||||||||||||||||||
89 | - | |||||||||||||||||||
90 | static QTestRootObject *instance() { | - | ||||||||||||||||||
91 | static QPointer<QTestRootObject> object = new QTestRootObject; | - | ||||||||||||||||||
92 | if (!object) {
| 16-176 | ||||||||||||||||||
93 | // QTestRootObject was deleted when previous test ended, create a new one | - | ||||||||||||||||||
94 | object = new QTestRootObject; | - | ||||||||||||||||||
95 | } executed 16 times by 3 tests: end of block Executed by:
| 16 | ||||||||||||||||||
96 | return object; executed 192 times by 4 tests: return object; Executed by:
| 192 | ||||||||||||||||||
97 | } | - | ||||||||||||||||||
98 | - | |||||||||||||||||||
99 | bool hasQuit:1; | - | ||||||||||||||||||
100 | bool hasTestCase() const { return m_hasTestCase; } never executed: return m_hasTestCase; | 0 | ||||||||||||||||||
101 | void setHasTestCase(bool value) { m_hasTestCase = value; emit hasTestCaseChanged(); } executed 64 times by 4 tests: end of block Executed by:
| 64 | ||||||||||||||||||
102 | - | |||||||||||||||||||
103 | bool windowShown() const { return m_windowShown; } executed 48 times by 4 tests: return m_windowShown; Executed by:
| 48 | ||||||||||||||||||
104 | void setWindowShown(bool value) { m_windowShown = value; emit windowShownChanged(); } executed 48 times by 4 tests: end of block Executed by:
| 48 | ||||||||||||||||||
105 | QQmlPropertyMap *defined() const { return m_defined; } never executed: return m_defined; | 0 | ||||||||||||||||||
106 | - | |||||||||||||||||||
107 | void init() { setWindowShown(false); setHasTestCase(false); hasQuit = false; } executed 32 times by 4 tests: end of block Executed by:
| 32 | ||||||||||||||||||
108 | - | |||||||||||||||||||
109 | Q_SIGNALS: | - | ||||||||||||||||||
110 | void windowShownChanged(); | - | ||||||||||||||||||
111 | void hasTestCaseChanged(); | - | ||||||||||||||||||
112 | - | |||||||||||||||||||
113 | private Q_SLOTS: | - | ||||||||||||||||||
114 | void quit() { hasQuit = true; } executed 32 times by 4 tests: end of block Executed by:
| 32 | ||||||||||||||||||
115 | - | |||||||||||||||||||
116 | private: | - | ||||||||||||||||||
117 | bool m_windowShown : 1; | - | ||||||||||||||||||
118 | bool m_hasTestCase :1; | - | ||||||||||||||||||
119 | QQmlPropertyMap *m_defined; | - | ||||||||||||||||||
120 | }; | - | ||||||||||||||||||
121 | - | |||||||||||||||||||
122 | static QObject *testRootObject(QQmlEngine *engine, QJSEngine *jsEngine) | - | ||||||||||||||||||
123 | { | - | ||||||||||||||||||
124 | Q_UNUSED(engine); | - | ||||||||||||||||||
125 | Q_UNUSED(jsEngine); | - | ||||||||||||||||||
126 | return QTestRootObject::instance(); executed 32 times by 4 tests: return QTestRootObject::instance(); Executed by:
| 32 | ||||||||||||||||||
127 | } | - | ||||||||||||||||||
128 | - | |||||||||||||||||||
129 | static inline QString stripQuotes(const QString &s) | - | ||||||||||||||||||
130 | { | - | ||||||||||||||||||
131 | if (s.length() >= 2 && s.startsWith(QLatin1Char('"')) && s.endsWith(QLatin1Char('"')))
| 0 | ||||||||||||||||||
132 | return s.mid(1, s.length() - 2); never executed: return s.mid(1, s.length() - 2); | 0 | ||||||||||||||||||
133 | else | - | ||||||||||||||||||
134 | return s; never executed: return s; | 0 | ||||||||||||||||||
135 | } | - | ||||||||||||||||||
136 | - | |||||||||||||||||||
137 | void handleCompileErrors(const QFileInfo &fi, QQuickView *view) | - | ||||||||||||||||||
138 | { | - | ||||||||||||||||||
139 | // Error compiling the test - flag failure in the log and continue. | - | ||||||||||||||||||
140 | const QList<QQmlError> errors = view->errors(); | - | ||||||||||||||||||
141 | QuickTestResult results; | - | ||||||||||||||||||
142 | results.setTestCaseName(fi.baseName()); | - | ||||||||||||||||||
143 | results.startLogging(); | - | ||||||||||||||||||
144 | results.setFunctionName(QLatin1String("compile")); | - | ||||||||||||||||||
145 | // Verbose warning output of all messages and relevant parameters | - | ||||||||||||||||||
146 | QString message; | - | ||||||||||||||||||
147 | QTextStream str(&message); | - | ||||||||||||||||||
148 | str << "\n " << QDir::toNativeSeparators(fi.absoluteFilePath()) << " produced " | - | ||||||||||||||||||
149 | << errors.size() << " error(s):\n"; | - | ||||||||||||||||||
150 | for (const QQmlError &e : errors) { | - | ||||||||||||||||||
151 | str << " "; | - | ||||||||||||||||||
152 | if (e.url().isLocalFile()) {
| 0 | ||||||||||||||||||
153 | str << QDir::toNativeSeparators(e.url().toLocalFile()); | - | ||||||||||||||||||
154 | } else { never executed: end of block | 0 | ||||||||||||||||||
155 | str << e.url().toString(); | - | ||||||||||||||||||
156 | } never executed: end of block | 0 | ||||||||||||||||||
157 | if (e.line() > 0)
| 0 | ||||||||||||||||||
158 | str << ':' << e.line() << ',' << e.column(); never executed: str << ':' << e.line() << ',' << e.column(); | 0 | ||||||||||||||||||
159 | str << ": " << e.description() << '\n'; | - | ||||||||||||||||||
160 | } never executed: end of block | 0 | ||||||||||||||||||
161 | str << " Working directory: " << QDir::toNativeSeparators(QDir::current().absolutePath()) << '\n'; | - | ||||||||||||||||||
162 | if (QQmlEngine *engine = view->engine()) {
| 0 | ||||||||||||||||||
163 | str << " View: " << view->metaObject()->className() << ", import paths:\n"; | - | ||||||||||||||||||
164 | const auto importPaths = engine->importPathList(); | - | ||||||||||||||||||
165 | for (const QString &i : importPaths) | - | ||||||||||||||||||
166 | str << " '" << QDir::toNativeSeparators(i) << "'\n"; never executed: str << " '" << QDir::toNativeSeparators(i) << "'\n"; | 0 | ||||||||||||||||||
167 | const QStringList pluginPaths = engine->pluginPathList(); | - | ||||||||||||||||||
168 | str << " Plugin paths:\n"; | - | ||||||||||||||||||
169 | for (const QString &p : pluginPaths) | - | ||||||||||||||||||
170 | str << " '" << QDir::toNativeSeparators(p) << "'\n"; never executed: str << " '" << QDir::toNativeSeparators(p) << "'\n"; | 0 | ||||||||||||||||||
171 | } never executed: end of block | 0 | ||||||||||||||||||
172 | qWarning("%s", qPrintable(message)); | - | ||||||||||||||||||
173 | // Fail with error 0. | - | ||||||||||||||||||
174 | results.fail(errors.at(0).description(), | - | ||||||||||||||||||
175 | errors.at(0).url(), errors.at(0).line()); | - | ||||||||||||||||||
176 | results.finishTestData(); | - | ||||||||||||||||||
177 | results.finishTestDataCleanup(); | - | ||||||||||||||||||
178 | results.finishTestFunction(); | - | ||||||||||||||||||
179 | results.setFunctionName(QString()); | - | ||||||||||||||||||
180 | results.stopLogging(); | - | ||||||||||||||||||
181 | } never executed: end of block | 0 | ||||||||||||||||||
182 | - | |||||||||||||||||||
183 | bool qWaitForSignal(QObject *obj, const char* signal, int timeout = 5000) | - | ||||||||||||||||||
184 | { | - | ||||||||||||||||||
185 | QSignalSpy spy(obj, signal); | - | ||||||||||||||||||
186 | QElapsedTimer timer; | - | ||||||||||||||||||
187 | timer.start(); | - | ||||||||||||||||||
188 | - | |||||||||||||||||||
189 | while (!spy.size()) {
| 56-109 | ||||||||||||||||||
190 | int remaining = timeout - int(timer.elapsed()); | - | ||||||||||||||||||
191 | if (remaining <= 0)
| 0-109 | ||||||||||||||||||
192 | break; never executed: break; | 0 | ||||||||||||||||||
193 | QCoreApplication::processEvents(QEventLoop::AllEvents, remaining); | - | ||||||||||||||||||
194 | QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); | - | ||||||||||||||||||
195 | QTest::qSleep(10); | - | ||||||||||||||||||
196 | } executed 109 times by 1 test: end of block Executed by:
| 109 | ||||||||||||||||||
197 | - | |||||||||||||||||||
198 | return spy.size(); executed 56 times by 1 test: return spy.size(); Executed by:
| 56 | ||||||||||||||||||
199 | } | - | ||||||||||||||||||
200 | - | |||||||||||||||||||
201 | using namespace QV4::CompiledData; | - | ||||||||||||||||||
202 | - | |||||||||||||||||||
203 | class TestCaseCollector | - | ||||||||||||||||||
204 | { | - | ||||||||||||||||||
205 | public: | - | ||||||||||||||||||
206 | typedef QList<QString> TestCaseList; | - | ||||||||||||||||||
207 | - | |||||||||||||||||||
208 | TestCaseCollector(const QFileInfo &fileInfo, QQmlEngine *engine) | - | ||||||||||||||||||
209 | { | - | ||||||||||||||||||
210 | QString path = fileInfo.absoluteFilePath(); | - | ||||||||||||||||||
211 | if (path.startsWith(QLatin1String(":/")))
| 0-42 | ||||||||||||||||||
212 | path.prepend(QLatin1String("qrc")); never executed: path.prepend(QLatin1String("qrc")); | 0 | ||||||||||||||||||
213 | - | |||||||||||||||||||
214 | QQmlComponent component(engine, path); | - | ||||||||||||||||||
215 | m_errors += component.errors(); | - | ||||||||||||||||||
216 | - | |||||||||||||||||||
217 | if (component.isReady()) {
| 0-42 | ||||||||||||||||||
218 | QQmlRefPointer<CompilationUnit> rootCompilationUnit = QQmlComponentPrivate::get(&component)->compilationUnit; | - | ||||||||||||||||||
219 | TestCaseEnumerationResult result = enumerateTestCases(rootCompilationUnit.data()); | - | ||||||||||||||||||
220 | m_testCases = result.testCases + result.finalizedPartialTestCases(); | - | ||||||||||||||||||
221 | m_errors += result.errors; | - | ||||||||||||||||||
222 | } executed 42 times by 4 tests: end of block Executed by:
| 42 | ||||||||||||||||||
223 | } executed 42 times by 4 tests: end of block Executed by:
| 42 | ||||||||||||||||||
224 | - | |||||||||||||||||||
225 | TestCaseList testCases() const { return m_testCases; } executed 42 times by 4 tests: return m_testCases; Executed by:
| 42 | ||||||||||||||||||
226 | QList<QQmlError> errors() const { return m_errors; } executed 42 times by 4 tests: return m_errors; Executed by:
| 42 | ||||||||||||||||||
227 | - | |||||||||||||||||||
228 | private: | - | ||||||||||||||||||
229 | TestCaseList m_testCases; | - | ||||||||||||||||||
230 | QList<QQmlError> m_errors; | - | ||||||||||||||||||
231 | - | |||||||||||||||||||
232 | struct TestCaseEnumerationResult | - | ||||||||||||||||||
233 | { | - | ||||||||||||||||||
234 | TestCaseList testCases; | - | ||||||||||||||||||
235 | QList<QQmlError> errors; | - | ||||||||||||||||||
236 | - | |||||||||||||||||||
237 | // Partially constructed test cases | - | ||||||||||||||||||
238 | bool isTestCase = false; | - | ||||||||||||||||||
239 | TestCaseList testFunctions; | - | ||||||||||||||||||
240 | QString testCaseName; | - | ||||||||||||||||||
241 | - | |||||||||||||||||||
242 | TestCaseList finalizedPartialTestCases() const | - | ||||||||||||||||||
243 | { | - | ||||||||||||||||||
244 | TestCaseList result; | - | ||||||||||||||||||
245 | for (const QString &function : testFunctions) | - | ||||||||||||||||||
246 | result << QString(QStringLiteral("%1::%2")).arg(testCaseName).arg(function); executed 168 times by 3 tests: result << QString(([]() noexcept -> QString { enum { Size = sizeof(u"" "%1::%2")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "%1::%2" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }())).arg(testCaseName).arg(function); Executed by:
executed 168 times by 3 tests: return qstring_literal_temp; Executed by:
| 168 | ||||||||||||||||||
247 | return result; executed 430 times by 4 tests: return result; Executed by:
| 430 | ||||||||||||||||||
248 | } | - | ||||||||||||||||||
249 | - | |||||||||||||||||||
250 | TestCaseEnumerationResult &operator<<(const TestCaseEnumerationResult &other) | - | ||||||||||||||||||
251 | { | - | ||||||||||||||||||
252 | testCases += other.testCases + other.finalizedPartialTestCases(); | - | ||||||||||||||||||
253 | errors += other.errors; | - | ||||||||||||||||||
254 | return *this; executed 388 times by 2 tests: return *this; Executed by:
| 388 | ||||||||||||||||||
255 | } | - | ||||||||||||||||||
256 | }; | - | ||||||||||||||||||
257 | - | |||||||||||||||||||
258 | TestCaseEnumerationResult enumerateTestCases(CompilationUnit *compilationUnit, const Object *object = nullptr) | - | ||||||||||||||||||
259 | { | - | ||||||||||||||||||
260 | QQmlType testCaseType; | - | ||||||||||||||||||
261 | for (quint32 i = 0; i < compilationUnit->data->nImports; ++i) {
| 0-860 | ||||||||||||||||||
262 | const Import *import = compilationUnit->data->importAt(i); | - | ||||||||||||||||||
263 | if (compilationUnit->stringAt(import->uriIndex) != QLatin1Literal("QtTest"))
| 430 | ||||||||||||||||||
264 | continue; executed 430 times by 4 tests: continue; Executed by:
| 430 | ||||||||||||||||||
265 | - | |||||||||||||||||||
266 | QString testCaseTypeName(QStringLiteral("TestCase")); executed 430 times by 4 tests: return qstring_literal_temp; Executed by:
| 430 | ||||||||||||||||||
267 | QString typeQualifier = compilationUnit->stringAt(import->qualifierIndex); | - | ||||||||||||||||||
268 | if (!typeQualifier.isEmpty())
| 0-430 | ||||||||||||||||||
269 | testCaseTypeName = typeQualifier % QLatin1Char('.') % testCaseTypeName; never executed: testCaseTypeName = typeQualifier % QLatin1Char('.') % testCaseTypeName; | 0 | ||||||||||||||||||
270 | - | |||||||||||||||||||
271 | testCaseType = compilationUnit->typeNameCache->query(testCaseTypeName).type; | - | ||||||||||||||||||
272 | if (testCaseType.isValid())
| 0-430 | ||||||||||||||||||
273 | break; executed 430 times by 4 tests: break; Executed by:
| 430 | ||||||||||||||||||
274 | } never executed: end of block | 0 | ||||||||||||||||||
275 | - | |||||||||||||||||||
276 | TestCaseEnumerationResult result; | - | ||||||||||||||||||
277 | - | |||||||||||||||||||
278 | if (!object) // Start at root of compilation unit if not enumerating a specific child
| 42-388 | ||||||||||||||||||
279 | object = compilationUnit->objectAt(0); executed 42 times by 4 tests: object = compilationUnit->objectAt(0); Executed by:
| 42 | ||||||||||||||||||
280 | - | |||||||||||||||||||
281 | if (CompilationUnit *superTypeUnit = compilationUnit->resolvedTypes.value(object->inheritedTypeNameIndex)->compilationUnit.data()) {
| 42-388 | ||||||||||||||||||
282 | // We have a non-C++ super type, which could indicate we're a subtype of a TestCase | - | ||||||||||||||||||
283 | if (testCaseType.isValid() && superTypeUnit->url() == testCaseType.sourceUrl())
| 0-42 | ||||||||||||||||||
284 | result.isTestCase = true; executed 42 times by 4 tests: result.isTestCase = true; Executed by:
| 42 | ||||||||||||||||||
285 | else | - | ||||||||||||||||||
286 | result = enumerateTestCases(superTypeUnit); never executed: result = enumerateTestCases(superTypeUnit); | 0 | ||||||||||||||||||
287 | - | |||||||||||||||||||
288 | if (result.isTestCase) {
| 0-42 | ||||||||||||||||||
289 | // Look for override of name in this type | - | ||||||||||||||||||
290 | for (auto binding = object->bindingsBegin(); binding != object->bindingsEnd(); ++binding) {
| 0-70 | ||||||||||||||||||
291 | if (compilationUnit->stringAt(binding->propertyNameIndex) == QLatin1Literal("name")) {
| 28-42 | ||||||||||||||||||
292 | if (binding->type == QV4::CompiledData::Binding::Type_String) {
| 0-42 | ||||||||||||||||||
293 | result.testCaseName = compilationUnit->stringAt(binding->stringIndex); | - | ||||||||||||||||||
294 | } else { executed 42 times by 4 tests: end of block Executed by:
| 42 | ||||||||||||||||||
295 | QQmlError error; | - | ||||||||||||||||||
296 | error.setUrl(compilationUnit->url()); | - | ||||||||||||||||||
297 | error.setLine(binding->location.line); | - | ||||||||||||||||||
298 | error.setColumn(binding->location.column); | - | ||||||||||||||||||
299 | error.setDescription(QStringLiteral("the 'name' property of a TestCase must be a literal string")); never executed: return qstring_literal_temp; | 0 | ||||||||||||||||||
300 | result.errors << error; | - | ||||||||||||||||||
301 | } never executed: end of block | 0 | ||||||||||||||||||
302 | break; executed 42 times by 4 tests: break; Executed by:
| 42 | ||||||||||||||||||
303 | } | - | ||||||||||||||||||
304 | } executed 28 times by 2 tests: end of block Executed by:
| 28 | ||||||||||||||||||
305 | - | |||||||||||||||||||
306 | // Look for additional functions in this type | - | ||||||||||||||||||
307 | auto functionsEnd = compilationUnit->objectFunctionsEnd(object); | - | ||||||||||||||||||
308 | for (auto function = compilationUnit->objectFunctionsBegin(object); function != functionsEnd; ++function) {
| 42-190 | ||||||||||||||||||
309 | QString functionName = compilationUnit->stringAt(function->nameIndex); | - | ||||||||||||||||||
310 | if (!(functionName.startsWith(QLatin1Literal("test_")) || functionName.startsWith(QLatin1Literal("benchmark_"))))
| 0-180 | ||||||||||||||||||
311 | continue; executed 10 times by 2 tests: continue; Executed by:
| 10 | ||||||||||||||||||
312 | - | |||||||||||||||||||
313 | if (functionName.endsWith(QLatin1Literal("_data")))
| 12-168 | ||||||||||||||||||
314 | continue; executed 12 times by 2 tests: continue; Executed by:
| 12 | ||||||||||||||||||
315 | - | |||||||||||||||||||
316 | result.testFunctions << functionName; | - | ||||||||||||||||||
317 | } executed 168 times by 3 tests: end of block Executed by:
| 168 | ||||||||||||||||||
318 | } executed 42 times by 4 tests: end of block Executed by:
| 42 | ||||||||||||||||||
319 | } executed 42 times by 4 tests: end of block Executed by:
| 42 | ||||||||||||||||||
320 | - | |||||||||||||||||||
321 | for (auto binding = object->bindingsBegin(); binding != object->bindingsEnd(); ++binding) {
| 430-1254 | ||||||||||||||||||
322 | if (binding->type == QV4::CompiledData::Binding::Type_Object) {
| 388-866 | ||||||||||||||||||
323 | const Object *child = compilationUnit->objectAt(binding->value.objectIndex); | - | ||||||||||||||||||
324 | result << enumerateTestCases(compilationUnit, child); | - | ||||||||||||||||||
325 | } executed 388 times by 2 tests: end of block Executed by:
| 388 | ||||||||||||||||||
326 | } executed 1254 times by 4 tests: end of block Executed by:
| 1254 | ||||||||||||||||||
327 | - | |||||||||||||||||||
328 | return result; executed 430 times by 4 tests: return result; Executed by:
| 430 | ||||||||||||||||||
329 | } | - | ||||||||||||||||||
330 | }; | - | ||||||||||||||||||
331 | - | |||||||||||||||||||
332 | int quick_test_main(int argc, char **argv, const char *name, const char *sourceDir) | - | ||||||||||||||||||
333 | { | - | ||||||||||||||||||
334 | return quick_test_main_with_setup(argc, argv, name, sourceDir, nullptr); executed 16 times by 3 tests: return quick_test_main_with_setup(argc, argv, name, sourceDir, nullptr); Executed by:
| 16 | ||||||||||||||||||
335 | } | - | ||||||||||||||||||
336 | - | |||||||||||||||||||
337 | int quick_test_main_with_setup(int argc, char **argv, const char *name, const char *sourceDir, QObject *setup) | - | ||||||||||||||||||
338 | { | - | ||||||||||||||||||
339 | // Peek at arguments to check for '-widgets' argument | - | ||||||||||||||||||
340 | #ifdef QT_QMLTEST_WITH_WIDGETS | - | ||||||||||||||||||
341 | bool withWidgets = false; | - | ||||||||||||||||||
342 | for (int index = 1; index < argc; ++index) {
| 18-20 | ||||||||||||||||||
343 | if (strcmp(argv[index], "-widgets") == 0) {
| 0-20 | ||||||||||||||||||
344 | withWidgets = true; | - | ||||||||||||||||||
345 | break; never executed: break; | 0 | ||||||||||||||||||
346 | } | - | ||||||||||||||||||
347 | } executed 20 times by 1 test: end of block Executed by:
| 20 | ||||||||||||||||||
348 | #endif | - | ||||||||||||||||||
349 | - | |||||||||||||||||||
350 | QCoreApplication *app = nullptr; | - | ||||||||||||||||||
351 | if (!QCoreApplication::instance()) {
| 0-18 | ||||||||||||||||||
352 | #ifdef QT_QMLTEST_WITH_WIDGETS | - | ||||||||||||||||||
353 | if (withWidgets)
| 0-18 | ||||||||||||||||||
354 | app = new QApplication(argc, argv); never executed: app = new QApplication(argc, argv); | 0 | ||||||||||||||||||
355 | else | - | ||||||||||||||||||
356 | #endif | - | ||||||||||||||||||
357 | { | - | ||||||||||||||||||
358 | app = new QGuiApplication(argc, argv); | - | ||||||||||||||||||
359 | } executed 18 times by 4 tests: end of block Executed by:
| 18 | ||||||||||||||||||
360 | } | - | ||||||||||||||||||
361 | - | |||||||||||||||||||
362 | if (setup) {
| 2-16 | ||||||||||||||||||
363 | // Don't check the return value; it's OK if it doesn't exist. | - | ||||||||||||||||||
364 | QMetaObject::invokeMethod(setup, "applicationAvailable"); | - | ||||||||||||||||||
365 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||||||||
366 | - | |||||||||||||||||||
367 | // Look for QML-specific command-line options. | - | ||||||||||||||||||
368 | // -import dir Specify an import directory. | - | ||||||||||||||||||
369 | // -plugins dir Specify a directory where to search for plugins. | - | ||||||||||||||||||
370 | // -input dir Specify the input directory for test cases. | - | ||||||||||||||||||
371 | // -translation file Specify the translation file. | - | ||||||||||||||||||
372 | // -file-selector Specify a file selector | - | ||||||||||||||||||
373 | QStringList imports; | - | ||||||||||||||||||
374 | QStringList pluginPaths; | - | ||||||||||||||||||
375 | QString testPath; | - | ||||||||||||||||||
376 | QString translationFile; | - | ||||||||||||||||||
377 | QStringList fileSelectors; | - | ||||||||||||||||||
378 | int index = 1; | - | ||||||||||||||||||
379 | QScopedArrayPointer<char *> testArgV(new char *[argc + 1]); | - | ||||||||||||||||||
380 | testArgV[0] = argv[0]; | - | ||||||||||||||||||
381 | int testArgC = 1; | - | ||||||||||||||||||
382 | while (index < argc) {
| 18-20 | ||||||||||||||||||
383 | if (strcmp(argv[index], "-import") == 0 && (index + 1) < argc) {
| 0-20 | ||||||||||||||||||
384 | imports += stripQuotes(QString::fromLocal8Bit(argv[index + 1])); | - | ||||||||||||||||||
385 | index += 2; | - | ||||||||||||||||||
386 | } else if (strcmp(argv[index], "-plugins") == 0 && (index + 1) < argc) { never executed: end of block
| 0-20 | ||||||||||||||||||
387 | pluginPaths += stripQuotes(QString::fromLocal8Bit(argv[index + 1])); | - | ||||||||||||||||||
388 | index += 2; | - | ||||||||||||||||||
389 | } else if (strcmp(argv[index], "-input") == 0 && (index + 1) < argc) { never executed: end of block
| 0-20 | ||||||||||||||||||
390 | testPath = stripQuotes(QString::fromLocal8Bit(argv[index + 1])); | - | ||||||||||||||||||
391 | index += 2; | - | ||||||||||||||||||
392 | } else if (strcmp(argv[index], "-opengl") == 0) { never executed: end of block
| 0-20 | ||||||||||||||||||
393 | ++index; | - | ||||||||||||||||||
394 | #ifdef QT_QMLTEST_WITH_WIDGETS | - | ||||||||||||||||||
395 | } else if (strcmp(argv[index], "-widgets") == 0) { never executed: end of block
| 0-20 | ||||||||||||||||||
396 | withWidgets = true; | - | ||||||||||||||||||
397 | ++index; | - | ||||||||||||||||||
398 | #endif | - | ||||||||||||||||||
399 | } else if (strcmp(argv[index], "-translation") == 0 && (index + 1) < argc) { never executed: end of block
| 0-20 | ||||||||||||||||||
400 | translationFile = stripQuotes(QString::fromLocal8Bit(argv[index + 1])); | - | ||||||||||||||||||
401 | index += 2; | - | ||||||||||||||||||
402 | } else if (strcmp(argv[index], "-file-selector") == 0 && (index + 1) < argc) { never executed: end of block
| 0-20 | ||||||||||||||||||
403 | fileSelectors += stripQuotes(QString::fromLocal8Bit(argv[index + 1])); | - | ||||||||||||||||||
404 | index += 2; | - | ||||||||||||||||||
405 | } else { never executed: end of block | 0 | ||||||||||||||||||
406 | testArgV[testArgC++] = argv[index++]; | - | ||||||||||||||||||
407 | } executed 20 times by 1 test: end of block Executed by:
| 20 | ||||||||||||||||||
408 | } | - | ||||||||||||||||||
409 | testArgV[testArgC] = 0; | - | ||||||||||||||||||
410 | - | |||||||||||||||||||
411 | // Setting currentAppname and currentTestObjectName (via setProgramName) are needed | - | ||||||||||||||||||
412 | // for the code coverage analysis. Must be done before parseArgs is called. | - | ||||||||||||||||||
413 | QuickTestResult::setCurrentAppname(argv[0]); | - | ||||||||||||||||||
414 | QuickTestResult::setProgramName(name); | - | ||||||||||||||||||
415 | - | |||||||||||||||||||
416 | QuickTestResult::parseArgs(testArgC, testArgV.data()); | - | ||||||||||||||||||
417 | - | |||||||||||||||||||
418 | #if QT_CONFIG(translation) | - | ||||||||||||||||||
419 | QTranslator translator; | - | ||||||||||||||||||
420 | if (!translationFile.isEmpty()) {
| 0-18 | ||||||||||||||||||
421 | if (translator.load(translationFile)) {
| 0 | ||||||||||||||||||
422 | app->installTranslator(&translator); | - | ||||||||||||||||||
423 | } else { never executed: end of block | 0 | ||||||||||||||||||
424 | qWarning("Could not load the translation file '%s'.", qPrintable(translationFile)); | - | ||||||||||||||||||
425 | } never executed: end of block | 0 | ||||||||||||||||||
426 | } | - | ||||||||||||||||||
427 | #endif | - | ||||||||||||||||||
428 | - | |||||||||||||||||||
429 | #ifdef Q_OS_ANDROID | - | ||||||||||||||||||
430 | if (testPath.isEmpty()) | - | ||||||||||||||||||
431 | testPath = QLatin1String(":/"); | - | ||||||||||||||||||
432 | #endif | - | ||||||||||||||||||
433 | - | |||||||||||||||||||
434 | // Determine where to look for the test data. | - | ||||||||||||||||||
435 | if (testPath.isEmpty() && sourceDir) {
| 0-18 | ||||||||||||||||||
436 | const QString s = QString::fromLocal8Bit(sourceDir); | - | ||||||||||||||||||
437 | if (QFile::exists(s))
| 0-18 | ||||||||||||||||||
438 | testPath = s; executed 18 times by 4 tests: testPath = s; Executed by:
| 18 | ||||||||||||||||||
439 | } executed 18 times by 4 tests: end of block Executed by:
| 18 | ||||||||||||||||||
440 | if (testPath.isEmpty()) {
| 0-18 | ||||||||||||||||||
441 | QDir current = QDir::current(); | - | ||||||||||||||||||
442 | #ifdef Q_OS_WIN | - | ||||||||||||||||||
443 | // Skip release/debug subfolders | - | ||||||||||||||||||
444 | if (!current.dirName().compare(QLatin1String("Release"), Qt::CaseInsensitive) | - | ||||||||||||||||||
445 | || !current.dirName().compare(QLatin1String("Debug"), Qt::CaseInsensitive)) | - | ||||||||||||||||||
446 | current.cdUp(); | - | ||||||||||||||||||
447 | #endif // Q_OS_WIN | - | ||||||||||||||||||
448 | testPath = current.absolutePath(); | - | ||||||||||||||||||
449 | } never executed: end of block | 0 | ||||||||||||||||||
450 | QStringList files; | - | ||||||||||||||||||
451 | - | |||||||||||||||||||
452 | const QFileInfo testPathInfo(testPath); | - | ||||||||||||||||||
453 | if (testPathInfo.isFile()) {
| 0-18 | ||||||||||||||||||
454 | if (!testPath.endsWith(QLatin1String(".qml"))) {
| 0 | ||||||||||||||||||
455 | qWarning("'%s' does not have the suffix '.qml'.", qPrintable(testPath)); | - | ||||||||||||||||||
456 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
457 | } | - | ||||||||||||||||||
458 | files << testPath; | - | ||||||||||||||||||
459 | } else if (testPathInfo.isDir()) { never executed: end of block
| 0-18 | ||||||||||||||||||
460 | // Scan the test data directory recursively, looking for "tst_*.qml" files. | - | ||||||||||||||||||
461 | const QStringList filters(QStringLiteral("tst_*.qml")); executed 18 times by 4 tests: return qstring_literal_temp; Executed by:
| 18 | ||||||||||||||||||
462 | QDirIterator iter(testPathInfo.absoluteFilePath(), filters, QDir::Files, | - | ||||||||||||||||||
463 | QDirIterator::Subdirectories | | - | ||||||||||||||||||
464 | QDirIterator::FollowSymlinks); | - | ||||||||||||||||||
465 | while (iter.hasNext())
| 18-42 | ||||||||||||||||||
466 | files += iter.next(); executed 42 times by 4 tests: files += iter.next(); Executed by:
| 42 | ||||||||||||||||||
467 | files.sort(); | - | ||||||||||||||||||
468 | if (files.isEmpty()) {
| 0-18 | ||||||||||||||||||
469 | qWarning("The directory '%s' does not contain any test files matching '%s'", | - | ||||||||||||||||||
470 | qPrintable(testPath), qPrintable(filters.front())); | - | ||||||||||||||||||
471 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
472 | } | - | ||||||||||||||||||
473 | } else { executed 18 times by 4 tests: end of block Executed by:
| 18 | ||||||||||||||||||
474 | qWarning("'%s' does not exist under '%s'.", | - | ||||||||||||||||||
475 | qPrintable(testPath), qPrintable(QDir::currentPath())); | - | ||||||||||||||||||
476 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
477 | } | - | ||||||||||||||||||
478 | - | |||||||||||||||||||
479 | qputenv("QT_QTESTLIB_RUNNING", "1"); | - | ||||||||||||||||||
480 | - | |||||||||||||||||||
481 | // Register the test object | - | ||||||||||||||||||
482 | qmlRegisterSingletonType<QTestRootObject>("Qt.test.qtestroot", 1, 0, "QTestRootObject", testRootObject); | - | ||||||||||||||||||
483 | - | |||||||||||||||||||
484 | QSet<QString> commandLineTestFunctions = QTest::testFunctions.toSet(); | - | ||||||||||||||||||
485 | const bool filteringTestFunctions = !commandLineTestFunctions.isEmpty(); | - | ||||||||||||||||||
486 | - | |||||||||||||||||||
487 | // Scan through all of the "tst_*.qml" files and run each of them | - | ||||||||||||||||||
488 | // in turn with a separate QQuickView (for test isolation). | - | ||||||||||||||||||
489 | for (const QString &file : qAsConst(files)) { | - | ||||||||||||||||||
490 | const QFileInfo fi(file); | - | ||||||||||||||||||
491 | if (!fi.exists())
| 0-42 | ||||||||||||||||||
492 | continue; never executed: continue; | 0 | ||||||||||||||||||
493 | - | |||||||||||||||||||
494 | QQmlEngine engine; | - | ||||||||||||||||||
495 | for (const QString &path : qAsConst(imports)) | - | ||||||||||||||||||
496 | engine.addImportPath(path); never executed: engine.addImportPath(path); | 0 | ||||||||||||||||||
497 | for (const QString &path : qAsConst(pluginPaths)) | - | ||||||||||||||||||
498 | engine.addPluginPath(path); never executed: engine.addPluginPath(path); | 0 | ||||||||||||||||||
499 | - | |||||||||||||||||||
500 | if (!fileSelectors.isEmpty()) {
| 0-42 | ||||||||||||||||||
501 | QQmlFileSelector* const qmlFileSelector = new QQmlFileSelector(&engine, &engine); | - | ||||||||||||||||||
502 | qmlFileSelector->setExtraSelectors(fileSelectors); | - | ||||||||||||||||||
503 | } never executed: end of block | 0 | ||||||||||||||||||
504 | - | |||||||||||||||||||
505 | TestCaseCollector testCaseCollector(fi, &engine); | - | ||||||||||||||||||
506 | if (!testCaseCollector.errors().isEmpty()) {
| 0-42 | ||||||||||||||||||
507 | for (const QQmlError &error : testCaseCollector.errors()) | - | ||||||||||||||||||
508 | qWarning() << error; never executed: QMessageLogger(__FILE__, 508, __PRETTY_FUNCTION__).warning() << error; | 0 | ||||||||||||||||||
509 | exit(1); never executed: exit(1); | 0 | ||||||||||||||||||
510 | } | - | ||||||||||||||||||
511 | - | |||||||||||||||||||
512 | TestCaseCollector::TestCaseList availableTestFunctions = testCaseCollector.testCases(); | - | ||||||||||||||||||
513 | if (QTest::printAvailableFunctions) {
| 0-42 | ||||||||||||||||||
514 | for (const QString &function : availableTestFunctions) | - | ||||||||||||||||||
515 | qDebug("%s()", qPrintable(function)); never executed: QMessageLogger(__FILE__, 515, __PRETTY_FUNCTION__).debug("%s()", QtPrivate::asString(function).toLocal8Bit().constData()); | 0 | ||||||||||||||||||
516 | continue; never executed: continue; | 0 | ||||||||||||||||||
517 | } | - | ||||||||||||||||||
518 | - | |||||||||||||||||||
519 | const QSet<QString> availableTestSet = availableTestFunctions.toSet(); | - | ||||||||||||||||||
520 | if (filteringTestFunctions && !availableTestSet.intersects(commandLineTestFunctions))
| 10-22 | ||||||||||||||||||
521 | continue; executed 10 times by 1 test: continue; Executed by:
| 10 | ||||||||||||||||||
522 | commandLineTestFunctions.subtract(availableTestSet); | - | ||||||||||||||||||
523 | - | |||||||||||||||||||
524 | QQuickView view(&engine, nullptr); | - | ||||||||||||||||||
525 | view.setFlags(Qt::Window | Qt::WindowSystemMenuHint | - | ||||||||||||||||||
526 | | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | - | ||||||||||||||||||
527 | | Qt::WindowCloseButtonHint); | - | ||||||||||||||||||
528 | QEventLoop eventLoop; | - | ||||||||||||||||||
529 | QObject::connect(view.engine(), SIGNAL(quit()), | - | ||||||||||||||||||
530 | QTestRootObject::instance(), SLOT(quit())); | - | ||||||||||||||||||
531 | QObject::connect(view.engine(), SIGNAL(quit()), | - | ||||||||||||||||||
532 | &eventLoop, SLOT(quit())); | - | ||||||||||||||||||
533 | view.rootContext()->setContextProperty | - | ||||||||||||||||||
534 | (QLatin1String("qtest"), QTestRootObject::instance()); // Deprecated. Use QTestRootObject from Qt.test.qtestroot instead | - | ||||||||||||||||||
535 | - | |||||||||||||||||||
536 | // Do this down here so that import paths, plugin paths, | - | ||||||||||||||||||
537 | // file selectors, etc. are available in case the user needs access to them. | - | ||||||||||||||||||
538 | if (setup) {
| 2-30 | ||||||||||||||||||
539 | // Don't check the return value; it's OK if it doesn't exist. | - | ||||||||||||||||||
540 | // If we add more callbacks in the future, it makes sense if the user only implements one of them. | - | ||||||||||||||||||
541 | QMetaObject::invokeMethod(setup, "qmlEngineAvailable", Q_ARG(QQmlEngine*, view.engine())); | - | ||||||||||||||||||
542 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||||||||
543 | - | |||||||||||||||||||
544 | view.setObjectName(fi.baseName()); | - | ||||||||||||||||||
545 | view.setTitle(view.objectName()); | - | ||||||||||||||||||
546 | QTestRootObject::instance()->init(); | - | ||||||||||||||||||
547 | QString path = fi.absoluteFilePath(); | - | ||||||||||||||||||
548 | if (path.startsWith(QLatin1String(":/")))
| 0-32 | ||||||||||||||||||
549 | view.setSource(QUrl(QLatin1String("qrc:") + path.midRef(1))); never executed: view.setSource(QUrl(QLatin1String("qrc:") + path.midRef(1))); | 0 | ||||||||||||||||||
550 | else | - | ||||||||||||||||||
551 | view.setSource(QUrl::fromLocalFile(path)); executed 32 times by 4 tests: view.setSource(QUrl::fromLocalFile(path)); Executed by:
| 32 | ||||||||||||||||||
552 | - | |||||||||||||||||||
553 | while (view.status() == QQuickView::Loading)
| 0-32 | ||||||||||||||||||
554 | QTest::qWait(10); never executed: QTest::qWait(10); | 0 | ||||||||||||||||||
555 | if (view.status() == QQuickView::Error) {
| 0-32 | ||||||||||||||||||
556 | handleCompileErrors(fi, &view); | - | ||||||||||||||||||
557 | continue; never executed: continue; | 0 | ||||||||||||||||||
558 | } | - | ||||||||||||||||||
559 | if (!QTestRootObject::instance()->hasQuit) {
| 16 | ||||||||||||||||||
560 | // If the test already quit, then it was performed | - | ||||||||||||||||||
561 | // synchronously during setSource(). Otherwise it is | - | ||||||||||||||||||
562 | // an asynchronous test and we need to show the window | - | ||||||||||||||||||
563 | // and wait for the first frame to be rendered | - | ||||||||||||||||||
564 | // and then wait for quit indication. | - | ||||||||||||||||||
565 | view.setFramePosition(QPoint(50, 50)); | - | ||||||||||||||||||
566 | if (view.size().isEmpty()) { // Avoid hangs with empty windows.
| 0-16 | ||||||||||||||||||
567 | view.resize(200, 200); | - | ||||||||||||||||||
568 | } never executed: end of block | 0 | ||||||||||||||||||
569 | view.show(); | - | ||||||||||||||||||
570 | if (!QTest::qWaitForWindowExposed(&view)) {
| 0-16 | ||||||||||||||||||
571 | qWarning().nospace() | - | ||||||||||||||||||
572 | << "Test '" << QDir::toNativeSeparators(path) << "' window not exposed after show()."; | - | ||||||||||||||||||
573 | } never executed: end of block | 0 | ||||||||||||||||||
574 | view.requestActivate(); | - | ||||||||||||||||||
575 | if (!QTest::qWaitForWindowActive(&view)) {
| 0-16 | ||||||||||||||||||
576 | qWarning().nospace() | - | ||||||||||||||||||
577 | << "Test '" << QDir::toNativeSeparators(path) << "' window not active after requestActivate()."; | - | ||||||||||||||||||
578 | } never executed: end of block | 0 | ||||||||||||||||||
579 | if (view.isExposed()) {
| 0-16 | ||||||||||||||||||
580 | QTestRootObject::instance()->setWindowShown(true); | - | ||||||||||||||||||
581 | } else { executed 16 times by 2 tests: end of block Executed by:
| 16 | ||||||||||||||||||
582 | qWarning().nospace() | - | ||||||||||||||||||
583 | << "Test '" << QDir::toNativeSeparators(path) << "' window was never exposed! " | - | ||||||||||||||||||
584 | << "If the test case was expecting windowShown, it will hang."; | - | ||||||||||||||||||
585 | } never executed: end of block | 0 | ||||||||||||||||||
586 | if (!QTestRootObject::instance()->hasQuit && QTestRootObject::instance()->hasTestCase())
| 0-16 | ||||||||||||||||||
587 | eventLoop.exec(); never executed: eventLoop.exec(); | 0 | ||||||||||||||||||
588 | } executed 16 times by 2 tests: end of block Executed by:
| 16 | ||||||||||||||||||
589 | } executed 32 times by 4 tests: end of block Executed by:
| 32 | ||||||||||||||||||
590 | - | |||||||||||||||||||
591 | // Flush the current logging stream. | - | ||||||||||||||||||
592 | QuickTestResult::setProgramName(nullptr); | - | ||||||||||||||||||
593 | delete app; | - | ||||||||||||||||||
594 | - | |||||||||||||||||||
595 | // Check that all test functions passed on the command line were found | - | ||||||||||||||||||
596 | if (!commandLineTestFunctions.isEmpty()) {
| 4-14 | ||||||||||||||||||
597 | qWarning() << "Could not find the following test functions:"; | - | ||||||||||||||||||
598 | for (const QString &functionName : qAsConst(commandLineTestFunctions)) | - | ||||||||||||||||||
599 | qWarning(" %s()", qUtf8Printable(functionName)); executed 4 times by 1 test: QMessageLogger(__FILE__, 599, __PRETTY_FUNCTION__).warning(" %s()", QtPrivate::asString(functionName).toUtf8().constData()); Executed by:
| 4 | ||||||||||||||||||
600 | return commandLineTestFunctions.count(); executed 4 times by 1 test: return commandLineTestFunctions.count(); Executed by:
| 4 | ||||||||||||||||||
601 | } | - | ||||||||||||||||||
602 | - | |||||||||||||||||||
603 | // Return the number of failures as the exit code. | - | ||||||||||||||||||
604 | return QuickTestResult::exitCode(); executed 14 times by 4 tests: return QuickTestResult::exitCode(); Executed by:
| 14 | ||||||||||||||||||
605 | } | - | ||||||||||||||||||
606 | - | |||||||||||||||||||
607 | QT_END_NAMESPACE | - | ||||||||||||||||||
608 | - | |||||||||||||||||||
609 | #include "quicktest.moc" | - | ||||||||||||||||||
Source code | Switch to Preprocessed file |