Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
quicktestresult.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 Crimson AS <info@crimson.no>
2// Copyright (C) 2016 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4// Qt-Security score:significant reason:default
5
7#include "quicktest.h"
8#include "quicktest_p.h"
9#include <QtTest/qtestcase.h>
10#include <QtTest/qtestsystem.h>
11#include <QtTest/private/qtestblacklist_p.h>
12#include <QtTest/private/qtestresult_p.h>
13#include <QtTest/private/qtesttable_p.h>
14#include <QtTest/private/qtestlog_p.h>
15#include "qtestoptions_p.h"
16#include <QtTest/qbenchmark.h>
17#include <QtTest/private/qbenchmark_p.h>
18#include <QtCore/qset.h>
19#include <QtCore/qmap.h>
20#include <QtCore/qbytearray.h>
21#include <QtCore/qcoreapplication.h>
22#include <QtCore/qdatetime.h>
23#include <QtCore/qdebug.h>
24#include <QtCore/QUrl>
25#include <QtCore/QDir>
26#if QT_CONFIG(regularexpression)
27#include <QtCore/qregularexpression.h>
28#endif
29#include <QtQuick/qquickwindow.h>
30#include <QtGui/qvector3d.h>
31#include <QtGui/qimagewriter.h>
32#include <QtQml/private/qqmlglobal_p.h>
33#include <QtQml/QQmlEngine>
34#include <QtQml/QQmlContext>
35#include <private/qv4qobjectwrapper_p.h>
36
37#include <algorithm>
38
40
41static const char *globalProgramName = nullptr;
42static bool loggingStarted = false;
44
45class Q_QMLTEST_EXPORT QuickTestImageObject : public QObject
46{
47 Q_OBJECT
48
49 Q_PROPERTY(int width READ width CONSTANT)
50 Q_PROPERTY(int height READ height CONSTANT)
51 Q_PROPERTY(QSize size READ size CONSTANT)
52
53public:
54 QuickTestImageObject(const QImage& img, QObject *parent = nullptr)
55 : QObject(parent)
56 , m_image(img)
57 {
58 }
59
60 ~QuickTestImageObject() {}
61
62public Q_SLOTS:
63 int red(int x, int y) const
64 {
65 return pixel(x, y).value<QColor>().red();
66 }
67
68 int green(int x, int y) const
69 {
70 return pixel(x, y).value<QColor>().green();
71 }
72
73 int blue(int x, int y) const
74 {
75 return pixel(x, y).value<QColor>().blue();
76 }
77
78 int alpha(int x, int y) const
79 {
80 return pixel(x, y).value<QColor>().alpha();
81 }
82
83 QVariant pixel(int x, int y) const
84 {
85 if (m_image.isNull()
86 || x >= m_image.width()
87 || y >= m_image.height()
88 || x < 0
89 || y < 0
90 || x * y >= m_image.width() * m_image.height())
91 return QVariant();
92
93 return QColor::fromRgba(m_image.pixel(QPoint(x, y)));
94 }
95
96 bool equals(QuickTestImageObject *other) const
97 {
98 if (!other)
99 return m_image.isNull();
100
101 return m_image == other->m_image;
102 }
103
104 void save(const QString &filePath)
105 {
106 QImageWriter writer(filePath);
107 if (!writer.write(m_image)) {
108 QQmlEngine *engine = qmlContext(this)->engine();
109 QV4::ExecutionEngine *v4 = engine->handle();
110 v4->throwError(QStringLiteral("Can't save to %1: %2").arg(filePath, writer.errorString()));
111 }
112 }
113
114public:
115 int width() const
116 {
117 return m_image.width();
118 }
119
120 int height() const
121 {
122 return m_image.height();
123 }
124
125 QSize size() const
126 {
127 return m_image.size();
128 }
129
130private:
131 QImage m_image;
132};
133
135{
136public:
138 : table(nullptr)
139 , benchmarkIter(nullptr)
140 , benchmarkData(nullptr)
141 , iterCount(0)
142 {
143 }
145 {
146 delete table;
147 delete benchmarkIter;
148 delete benchmarkData;
149 }
150
151 QByteArray intern(const QString &str);
152
161};
162
164{
165 QByteArray bstr = str.toUtf8();
166 return *(internedStrings.insert(bstr));
167}
168
169
170/*!
171 \qmltype TestResult
172 \internal
173*/
174QuickTestResult::QuickTestResult(QObject *parent)
175 : QObject(parent), d_ptr(new QuickTestResultPrivate)
176{
177 if (!QBenchmarkGlobalData::current)
178 QBenchmarkGlobalData::current = &globalBenchmarkData;
179}
180
181QuickTestResult::~QuickTestResult()
182{
183}
184
185/*!
186 \qmlproperty string TestResult::testCaseName
187
188 This property defines the name of current TestCase element
189 that is running test cases.
190
191 \sa functionName
192*/
193QString QuickTestResult::testCaseName() const
194{
195 Q_D(const QuickTestResult);
196 return d->testCaseName;
197}
198
199void QuickTestResult::setTestCaseName(const QString &name)
200{
201 Q_D(QuickTestResult);
202 d->testCaseName = name;
203 emit testCaseNameChanged();
204}
205
206/*!
207 \qmlproperty string TestResult::functionName
208
209 This property defines the name of current test function
210 within a TestCase element that is running. If this string is
211 empty, then no function is currently running.
212
213 \sa testCaseName
214*/
215QString QuickTestResult::functionName() const
216{
217 Q_D(const QuickTestResult);
218 return d->functionName;
219}
220
221void QuickTestResult::setFunctionName(const QString &name)
222{
223 Q_D(QuickTestResult);
224 if (!name.isEmpty()) {
225 if (d->testCaseName.isEmpty()) {
226 QTestResult::setCurrentTestFunction
227 (d->intern(name).constData());
228 } else {
229 QString fullName = d->testCaseName + QLatin1String("::") + name;
230 QTestResult::setCurrentTestFunction
231 (d->intern(fullName).constData());
232 if (QTestPrivate::checkBlackLists(fullName.toUtf8().constData(), nullptr))
233 QTestResult::setBlacklistCurrentTest(true);
234 }
235 } else {
236 QTestResult::setCurrentTestFunction(nullptr);
237 }
238 d->functionName = name;
239 emit functionNameChanged();
240}
241
242/*!
243 \qmlproperty string TestResult::dataTag
244
245 This property defines the tag for the current row in a
246 data-driven test, or an empty string if not a data-driven test.
247*/
248QString QuickTestResult::dataTag() const
249{
250 const char *tag = QTestResult::currentDataTag();
251 if (tag)
252 return QString::fromUtf8(tag);
253 else
254 return QString();
255}
256
257void QuickTestResult::setDataTag(const QString &tag)
258{
259 if (!tag.isEmpty()) {
260 QTestData *data = &(QTest::newRow(tag.toUtf8().constData()));
261 QTestResult::setCurrentTestData(data);
262 if (QTestPrivate::checkBlackLists((testCaseName() + QLatin1String("::")
263 + functionName()).toUtf8().constData(), tag.toUtf8().constData())) {
264 QTestResult::setBlacklistCurrentTest(true);
265 }
266 emit dataTagChanged();
267 } else {
268 QTestResult::setCurrentTestData(nullptr);
269 }
270}
271
272/*!
273 \qmlproperty bool TestResult::failed
274
275 This property returns true if the current test function (or
276 current test data row for a data-driven test) has failed;
277 false otherwise. The fail state is reset when functionName
278 is changed or finishTestDataCleanup() is called.
279
280 \sa skipped
281*/
282bool QuickTestResult::isFailed() const
283{
284 return QTestResult::currentTestFailed();
285}
286
287/*!
288 \qmlproperty bool TestResult::skipped
289
290 This property returns true if the current test function was
291 marked as skipped; false otherwise.
292
293 \sa failed
294*/
295bool QuickTestResult::isSkipped() const
296{
297 return QTestResult::skipCurrentTest();
298}
299
300void QuickTestResult::setSkipped(bool skip)
301{
302 QTestResult::setSkipCurrentTest(skip);
303 if (!skip)
304 QTestResult::setBlacklistCurrentTest(false);
305 emit skippedChanged();
306}
307
308/*!
309 \qmlproperty int TestResult::passCount
310
311 This property returns the number of tests that have passed.
312
313 \sa failCount, skipCount
314*/
315int QuickTestResult::passCount() const
316{
317 return QTestLog::passCount();
318}
319
320/*!
321 \qmlproperty int TestResult::failCount
322
323 This property returns the number of tests that have failed.
324
325 \sa passCount, skipCount
326*/
327int QuickTestResult::failCount() const
328{
329 return QTestLog::failCount();
330}
331
332/*!
333 \qmlproperty int TestResult::skipCount
334
335 This property returns the number of tests that have been skipped.
336
337 \sa passCount, failCount
338*/
339int QuickTestResult::skipCount() const
340{
341 return QTestLog::skipCount();
342}
343
344/*!
345 \qmlproperty list<string> TestResult::functionsToRun
346
347 This property returns the list of function names to be run.
348*/
349QStringList QuickTestResult::functionsToRun() const
350{
351 return QTest::testFunctions;
352}
353
354/*!
355 \qmlproperty list<string> TestResult::tagsToRun
356
357 This property returns the list of test function's data tags to be run
358*/
359QStringList QuickTestResult::tagsToRun() const
360{
361 return QTest::testTags;
362}
363
364/*!
365 \qmlmethod TestResult::reset()
366
367 Resets all pass/fail/skip counters and prepare for testing.
368*/
369void QuickTestResult::reset()
370{
371 if (!globalProgramName) // Only if run via qmlviewer.
372 QTestResult::reset();
373}
374
375/*!
376 \qmlmethod TestResult::startLogging()
377
378 Starts logging to the test output stream and writes the
379 test header.
380
381 \sa stopLogging()
382*/
383void QuickTestResult::startLogging()
384{
385 // The program name is used for logging headers and footers if it
386 // is set. Otherwise the test case name is used.
387 if (loggingStarted)
388 return;
389 QTestLog::startLogging();
390 loggingStarted = true;
391}
392
393/*!
394 \qmlmethod TestResult::stopLogging()
395
396 Writes the test footer to the test output stream and then stops logging.
397
398 \sa startLogging()
399*/
400void QuickTestResult::stopLogging()
401{
402 Q_D(QuickTestResult);
403 if (globalProgramName)
404 return; // Logging will be stopped by setProgramName(0).
405 QTestResult::setCurrentTestObject(d->intern(d->testCaseName).constData());
406 QTestLog::stopLogging();
407}
408
409void QuickTestResult::initTestTable()
410{
411 Q_D(QuickTestResult);
412 delete d->table;
413 d->table = new QTestTable;
414 //qmltest does not really need the column for data driven test
415 //add this to avoid warnings.
416 d->table->addColumn(qMetaTypeId<QString>(), "qmltest_dummy_data_column");
417}
418
419void QuickTestResult::clearTestTable()
420{
421 Q_D(QuickTestResult);
422 delete d->table;
423 d->table = nullptr;
424}
425
426void QuickTestResult::finishTestData()
427{
428 QTestResult::finishedCurrentTestData();
429}
430
431void QuickTestResult::finishTestDataCleanup()
432{
433 QTestResult::finishedCurrentTestDataCleanup();
434}
435
436void QuickTestResult::finishTestFunction()
437{
438 QTestResult::finishedCurrentTestFunction();
439}
440
441static QString qtestFixUrl(const QUrl &location)
442{
443 if (location.isLocalFile()) // Use QUrl's logic for Windows drive letters.
444 return QDir::toNativeSeparators(location.toLocalFile());
445 return location.toString();
446}
447
448void QuickTestResult::fail
449 (const QString &message, const QUrl &location, int line)
450{
451 QTestResult::addFailure(message.toUtf8().constData(),
452 qtestFixUrl(location).toLatin1().constData(), line);
453}
454
455bool QuickTestResult::verify
456 (bool success, const QString &message, const QUrl &location, int line)
457{
458 if (!success && message.isEmpty()) {
459 return QTestResult::verify
460 (success, "verify()", "",
461 qtestFixUrl(location).toLatin1().constData(), line);
462 } else {
463 return QTestResult::verify
464 (success, message.toUtf8().constData(), "",
465 qtestFixUrl(location).toLatin1().constData(), line);
466 }
467}
468
469bool QuickTestResult::fuzzyCompare(const QVariant &actual, const QVariant &expected, qreal delta)
470{
471 if (actual.userType() == QMetaType::QColor || expected.userType() == QMetaType::QColor) {
472 if (!actual.canConvert(QMetaType(QMetaType::QColor))
473 || !expected.canConvert(QMetaType(QMetaType::QColor))) {
474 return false;
475 }
476
477 //fuzzy color comparison
478 QColor act;
479 QColor exp;
480 bool ok(false);
481
482 QVariant var = QQml_colorProvider()->colorFromString(actual.toString(), &ok);
483 if (!ok)
484 return false;
485 act = var.value<QColor>();
486
487 var = QQml_colorProvider()->colorFromString(expected.toString(), &ok);
488 if (!ok)
489 return false;
490 exp = var.value<QColor>();
491
492 return ( qAbs(act.red() - exp.red()) <= delta
493 && qAbs(act.green() - exp.green()) <= delta
494 && qAbs(act.blue() - exp.blue()) <= delta
495 && qAbs(act.alpha() - exp.alpha()) <= delta);
496 } else {
497 //number comparison
498 bool ok = true;
499 qreal act = actual.toFloat(&ok);
500 if (!ok)
501 return false;
502
503 qreal exp = expected.toFloat(&ok);
504 if (!ok)
505 return false;
506
507 return (qAbs(act - exp) <= delta);
508 }
509
510 return false;
511}
512
513void QuickTestResult::stringify(QQmlV4FunctionPtr args)
514{
515 if (args->length() < 1)
516 args->setReturnValue(QV4::Encode::null());
517
518 QV4::Scope scope(args->v4engine());
519 QV4::ScopedValue value(scope, (*args)[0]);
520
521 QString result;
522
523 //Check for Object Type
524 if (value->isObject()
525 && !value->as<QV4::FunctionObject>()
526 && !value->as<QV4::ArrayObject>()) {
527 QVariant v = QV4::ExecutionEngine::toVariant(value, QMetaType {});
528 if (v.isValid()) {
529 switch (v.userType()) {
530 case QMetaType::QVector3D:
531 {
532 QVector3D v3d = v.value<QVector3D>();
533 result = QString::fromLatin1("Qt.vector3d(%1, %2, %3)").arg(v3d.x()).arg(v3d.y()).arg(v3d.z());
534 break;
535 }
536 case QMetaType::QUrl:
537 {
538 QUrl url = v.value<QUrl>();
539 result = QString::fromLatin1("Qt.url(%1)").arg(url.toString());
540 break;
541 }
542 case QMetaType::QDateTime:
543 {
544 QDateTime dt = v.value<QDateTime>();
545 result = dt.toString(Qt::ISODateWithMs);
546 break;
547 }
548 default:
549 result = v.toString();
550 }
551
552 } else {
553 result = QLatin1String("Object");
554 }
555 }
556
557 if (result.isEmpty()) {
558 QString tmp = value->toQStringNoThrow();
559 if (value->as<QV4::ArrayObject>())
560 result += QLatin1Char('[') + tmp + QLatin1Char(']');
561 else
562 result.append(tmp);
563 }
564
565 args->setReturnValue(QV4::Encode(args->v4engine()->newString(result)));
566}
567
568bool QuickTestResult::compare
569 (bool success, const QString &message,
570 const QVariant &val1, const QVariant &val2,
571 const QUrl &location, int line)
572{
573 return QTestResult::compare
574 (success, message.toUtf8().constData(),
575 QTest::toString(val1.toString().toLatin1().constData()),
576 QTest::toString(val2.toString().toLatin1().constData()),
577 "", "",
578 qtestFixUrl(location).toLatin1().constData(), line);
579}
580
581void QuickTestResult::skip
582 (const QString &message, const QUrl &location, int line)
583{
584 QTestResult::addSkip(message.toUtf8().constData(),
585 qtestFixUrl(location).toLatin1().constData(), line);
586 QTestResult::setSkipCurrentTest(true);
587}
588
589bool QuickTestResult::expectFail
590 (const QString &tag, const QString &comment, const QUrl &location, int line)
591{
592 return QTestResult::expectFail
593 (tag.toLatin1().constData(),
594 QTest::toString(comment.toLatin1().constData()),
595 QTest::Abort, qtestFixUrl(location).toLatin1().constData(), line);
596}
597
598bool QuickTestResult::expectFailContinue
599 (const QString &tag, const QString &comment, const QUrl &location, int line)
600{
601 return QTestResult::expectFail
602 (tag.toLatin1().constData(),
603 QTest::toString(comment.toUtf8().constData()),
604 QTest::Continue, qtestFixUrl(location).toLatin1().constData(), line);
605}
606
607void QuickTestResult::warn(const QString &message, const QUrl &location, int line)
608{
609 QTestLog::warn(message.toUtf8().constData(), qtestFixUrl(location).toLatin1().constData(), line);
610}
611
612void QuickTestResult::ignoreWarning(const QJSValue &message)
613{
614 if (message.isRegExp()) {
615#if QT_CONFIG(regularexpression)
616 QTestLog::ignoreMessage(QtWarningMsg, qjsvalue_cast<QRegularExpression>(message));
617#endif
618 } else {
619 QTestLog::ignoreMessage(QtWarningMsg, message.toString().toUtf8());
620 }
621}
622
623void QuickTestResult::failOnWarning(const QJSValue &message)
624{
625 if (message.isRegExp()) {
626#if QT_CONFIG(regularexpression)
627 QTestLog::failOnWarning(qjsvalue_cast<QRegularExpression>(message));
628#endif
629 } else {
630 QTestLog::failOnWarning(message.toString().toUtf8());
631 }
632}
633
634void QuickTestResult::wait(int ms)
635{
636 QTest::qWait(ms);
637}
638
639void QuickTestResult::sleep(int ms)
640{
641 QTest::qSleep(ms);
642}
643
644bool QuickTestResult::waitForRendering(QQuickItem *item, int timeout)
645{
646 Q_ASSERT(item);
647
648 return qWaitForSignal(item->window(), SIGNAL(frameSwapped()), timeout);
649}
650
651void QuickTestResult::startMeasurement()
652{
653 Q_D(QuickTestResult);
654 delete d->benchmarkData;
655 d->benchmarkData = new QBenchmarkTestMethodData();
656 QBenchmarkTestMethodData::current = d->benchmarkData;
657 d->iterCount = (QBenchmarkGlobalData::current->measurer->needsWarmupIteration()) ? -1 : 0;
658 d->resultsList.clear();
659}
660
661void QuickTestResult::beginDataRun()
662{
663 QBenchmarkTestMethodData::current->beginDataRun();
664}
665
666void QuickTestResult::endDataRun()
667{
668 Q_D(QuickTestResult);
669 QBenchmarkTestMethodData::current->endDataRun();
670 const QList<QBenchmarkResult> &results = QBenchmarkTestMethodData::current->results;
671 if (results.isEmpty())
672 return; // shouldn't happen
673 if (d->iterCount > -1) // iteration -1 is the warmup iteration.
674 d->resultsList.append(results);
675
676 if (QBenchmarkGlobalData::current->verboseOutput) {
677 if (d->iterCount == -1) {
678 qDebug() << "warmup stage result :" << results.first().measurement.value;
679 } else {
680 qDebug() << "accumulation stage result:" << results.first().measurement.value;
681 }
682 }
683}
684
685bool QuickTestResult::measurementAccepted()
686{
687 return QBenchmarkTestMethodData::current->resultsAccepted();
688}
689
690static QList<QBenchmarkResult> qMedian(const QList<QList<QBenchmarkResult>> &container)
691{
692 const int count = container.size();
693 if (count == 0)
694 return {};
695
696 if (count == 1)
697 return container.at(0);
698
699 QList<QList<QBenchmarkResult>> containerCopy = container;
700 std::sort(containerCopy.begin(), containerCopy.end(),
701 [](const QList<QBenchmarkResult> &a, const QList<QBenchmarkResult> &b) {
702 return a.first() < b.first();
703 });
704
705 const int middle = count / 2;
706
707 // ### handle even-sized containers here by doing an aritmetic mean of the two middle items.
708 return containerCopy.at(middle);
709}
710
711bool QuickTestResult::needsMoreMeasurements()
712{
713 Q_D(QuickTestResult);
714 ++(d->iterCount);
715 if (d->iterCount < QBenchmarkGlobalData::current->adjustMedianIterationCount())
716 return true;
717 if (QBenchmarkTestMethodData::current->resultsAccepted())
718 QTestLog::addBenchmarkResults(qMedian(d->resultsList));
719 return false;
720}
721
722void QuickTestResult::startBenchmark(RunMode runMode, const QString &tag)
723{
724 QBenchmarkTestMethodData::current->results = {};
725 QBenchmarkTestMethodData::current->resultAccepted = false;
726 QBenchmarkGlobalData::current->context.tag = tag;
727 QBenchmarkGlobalData::current->context.slotName = functionName();
728
729 Q_D(QuickTestResult);
730 delete d->benchmarkIter;
731 d->benchmarkIter = new QTest::QBenchmarkIterationController
732 (QTest::QBenchmarkIterationController::RunMode(runMode));
733}
734
735bool QuickTestResult::isBenchmarkDone() const
736{
737 Q_D(const QuickTestResult);
738 if (d->benchmarkIter)
739 return d->benchmarkIter->isDone();
740 else
741 return true;
742}
743
744void QuickTestResult::nextBenchmark()
745{
746 Q_D(QuickTestResult);
747 if (d->benchmarkIter)
748 d->benchmarkIter->next();
749}
750
751void QuickTestResult::stopBenchmark()
752{
753 Q_D(QuickTestResult);
754 delete d->benchmarkIter;
755 d->benchmarkIter = nullptr;
756}
757
758QObject *QuickTestResult::grabImage(QQuickItem *item)
759{
760 if (item && item->window()) {
761 QQuickWindow *window = item->window();
762 QImage grabbed = window->grabWindow();
763 const auto dpi = grabbed.devicePixelRatio();
764 QRectF rf(item->x() * dpi, item->y() * dpi, item->width() * dpi, item->height() * dpi);
765 rf = rf.intersected(QRectF(0, 0, grabbed.width(), grabbed.height()));
766 QObject *o = new QuickTestImageObject(grabbed.copy(rf.toAlignedRect()));
767 QQmlEngine::setContextForObject(o, qmlContext(this));
768 return o;
769 }
770 return nullptr;
771}
772
773QObject *QuickTestResult::findChild(QObject *parent, const QString &objectName)
774{
775 return parent ? parent->findChild<QObject*>(objectName) : 0;
776}
777
778bool QuickTestResult::isPolishScheduled(QObject *itemOrWindow) const
779{
780 if (auto item = qobject_cast<QQuickItem*>(itemOrWindow))
781 return QQuickTest::qIsPolishScheduled(item);
782
783 if (auto window = qobject_cast<QQuickWindow*>(itemOrWindow))
784 return QQuickTest::qIsPolishScheduled(window);
785
786 qmlWarning(this) << "isPolishScheduled() expects either an Item or Window, but got"
787 << QDebug::toString(itemOrWindow);
788 return false;
789}
790
791bool QuickTestResult::waitForPolish(QObject *itemOrWindow, int timeout) const
792{
793 if (auto item = qobject_cast<QQuickItem*>(itemOrWindow))
794 return QQuickTest::qWaitForPolish(item, timeout);
795
796 if (auto window = qobject_cast<QQuickWindow*>(itemOrWindow))
797 return QQuickTest::qWaitForPolish(window, timeout);
798
799 qmlWarning(this) << "waitForItemPolish() expects either an Item or Window, but got"
800 << QDebug::toString(itemOrWindow);
801 return false;
802}
803
804namespace QTest {
805 void qtest_qParseArgs(int argc, char *argv[], bool qml);
806};
807
808void QuickTestResult::parseArgs(int argc, char *argv[])
809{
810 if (!QBenchmarkGlobalData::current)
811 QBenchmarkGlobalData::current = &globalBenchmarkData;
812 QTest::qtest_qParseArgs(argc, argv, true);
813}
814
815void QuickTestResult::setProgramName(const char *name)
816{
817 if (name) {
818 QTestPrivate::parseBlackList();
819 QTestResult::reset();
820 } else if (!name && loggingStarted) {
821 QTestResult::setCurrentTestObject(globalProgramName);
822 QTestLog::stopLogging();
823 QTestResult::setCurrentTestObject(nullptr);
824 }
825 globalProgramName = name;
826 QTestResult::setCurrentTestObject(globalProgramName);
827}
828
829void QuickTestResult::setCurrentAppname(const char *appname)
830{
831 QTestResult::setCurrentAppName(appname);
832}
833
834int QuickTestResult::exitCode()
835{
836#if defined(QTEST_NOEXITCODE)
837 return 0;
838#else
839 // make sure our exit code is never going above 127
840 // since that could wrap and indicate 0 test fails
841 return qMin(QTestLog::failCount(), 127);
842#endif
843}
844
845QT_END_NAMESPACE
846
847#include "quicktestresult.moc"
848#include "moc_quicktestresult_p.cpp"
QSet< QByteArray > internedStrings
QList< QList< QBenchmarkResult > > resultsList
QByteArray intern(const QString &str)
QBenchmarkTestMethodData * benchmarkData
QTest::QBenchmarkIterationController * benchmarkIter
Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
static bool loggingStarted
static QT_BEGIN_NAMESPACE const char * globalProgramName
static QString qtestFixUrl(const QUrl &location)
static QBenchmarkGlobalData globalBenchmarkData
static QList< QBenchmarkResult > qMedian(const QList< QList< QBenchmarkResult > > &container)