diff options
Diffstat (limited to 'src/qmltest/quicktestresult.cpp')
-rw-r--r-- | src/qmltest/quicktestresult.cpp | 181 |
1 files changed, 94 insertions, 87 deletions
diff --git a/src/qmltest/quicktestresult.cpp b/src/qmltest/quicktestresult.cpp index 3225dc95cd..c5014f66d4 100644 --- a/src/qmltest/quicktestresult.cpp +++ b/src/qmltest/quicktestresult.cpp @@ -1,44 +1,10 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Crimson AS <info@crimson.no> -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 Crimson AS <info@crimson.no> +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "quicktestresult_p.h" +#include "quicktest.h" +#include "quicktest_p.h" #include <QtTest/qtestcase.h> #include <QtTest/qtestsystem.h> #include <QtTest/private/qtestblacklist_p.h> @@ -47,11 +13,6 @@ #include <QtTest/private/qtestlog_p.h> #include "qtestoptions_p.h" #include <QtTest/qbenchmark.h> -// qbenchmark_p.h pulls windows.h via 3rd party; prevent it from defining -// the min/max macros which would clash with qnumeric_p.h's usage of min()/max(). -#if defined(Q_OS_WIN32) && !defined(NOMINMAX) -# define NOMINMAX -#endif #include <QtTest/private/qbenchmark_p.h> #include <QtCore/qset.h> #include <QtCore/qmap.h> @@ -61,7 +22,9 @@ #include <QtCore/qdebug.h> #include <QtCore/QUrl> #include <QtCore/QDir> +#if QT_CONFIG(regularexpression) #include <QtCore/qregularexpression.h> +#endif #include <QtQuick/qquickwindow.h> #include <QtGui/qvector3d.h> #include <QtGui/qimagewriter.h> @@ -78,9 +41,7 @@ static const char *globalProgramName = nullptr; static bool loggingStarted = false; static QBenchmarkGlobalData globalBenchmarkData; -extern bool qWaitForSignal(QObject *obj, const char* signal, int timeout = 5000); - -class Q_QUICK_TEST_EXPORT QuickTestImageObject : public QObject +class Q_QMLTEST_EXPORT QuickTestImageObject : public QObject { Q_OBJECT @@ -195,7 +156,7 @@ public: QTest::QBenchmarkIterationController *benchmarkIter; QBenchmarkTestMethodData *benchmarkData; int iterCount; - QList<QBenchmarkResult> results; + QList<QList<QBenchmarkResult>> resultsList; }; QByteArray QuickTestResultPrivate::intern(const QString &str) @@ -262,7 +223,8 @@ void QuickTestResult::setFunctionName(const QString &name) QString fullName = d->testCaseName + QLatin1String("::") + name; QTestResult::setCurrentTestFunction (d->intern(fullName).constData()); - QTestPrivate::checkBlackLists(fullName.toUtf8().constData(), nullptr); + if (QTestPrivate::checkBlackLists(fullName.toUtf8().constData(), nullptr)) + QTestResult::setBlacklistCurrentTest(true); } } else { QTestResult::setCurrentTestFunction(nullptr); @@ -291,7 +253,10 @@ void QuickTestResult::setDataTag(const QString &tag) if (!tag.isEmpty()) { QTestData *data = &(QTest::newRow(tag.toUtf8().constData())); QTestResult::setCurrentTestData(data); - QTestPrivate::checkBlackLists((testCaseName() + QLatin1String("::") + functionName()).toUtf8().constData(), tag.toUtf8().constData()); + if (QTestPrivate::checkBlackLists((testCaseName() + QLatin1String("::") + + functionName()).toUtf8().constData(), tag.toUtf8().constData())) { + QTestResult::setBlacklistCurrentTest(true); + } emit dataTagChanged(); } else { QTestResult::setCurrentTestData(nullptr); @@ -477,7 +442,7 @@ static QString qtestFixUrl(const QUrl &location) void QuickTestResult::fail (const QString &message, const QUrl &location, int line) { - QTestResult::addFailure(message.toLatin1().constData(), + QTestResult::addFailure(message.toUtf8().constData(), qtestFixUrl(location).toLatin1().constData(), line); } @@ -490,16 +455,18 @@ bool QuickTestResult::verify qtestFixUrl(location).toLatin1().constData(), line); } else { return QTestResult::verify - (success, message.toLatin1().constData(), "", + (success, message.toUtf8().constData(), "", qtestFixUrl(location).toLatin1().constData(), line); } } bool QuickTestResult::fuzzyCompare(const QVariant &actual, const QVariant &expected, qreal delta) { - if (actual.type() == QVariant::Color || expected.type() == QVariant::Color) { - if (!actual.canConvert(QVariant::Color) || !expected.canConvert(QVariant::Color)) + if (actual.userType() == QMetaType::QColor || expected.userType() == QMetaType::QColor) { + if (!actual.canConvert(QMetaType(QMetaType::QColor)) + || !expected.canConvert(QMetaType(QMetaType::QColor))) { return false; + } //fuzzy color comparison QColor act; @@ -511,7 +478,7 @@ bool QuickTestResult::fuzzyCompare(const QVariant &actual, const QVariant &expec return false; act = var.value<QColor>(); - QQml_colorProvider()->colorFromString(expected.toString(), &ok); + var = QQml_colorProvider()->colorFromString(expected.toString(), &ok); if (!ok) return false; exp = var.value<QColor>(); @@ -537,7 +504,7 @@ bool QuickTestResult::fuzzyCompare(const QVariant &actual, const QVariant &expec return false; } -void QuickTestResult::stringify(QQmlV4Function *args) +void QuickTestResult::stringify(QQmlV4FunctionPtr args) { if (args->length() < 1) args->setReturnValue(QV4::Encode::null()); @@ -551,22 +518,22 @@ void QuickTestResult::stringify(QQmlV4Function *args) if (value->isObject() && !value->as<QV4::FunctionObject>() && !value->as<QV4::ArrayObject>()) { - QVariant v = scope.engine->toVariant(value, QMetaType::UnknownType); + QVariant v = QV4::ExecutionEngine::toVariant(value, QMetaType {}); if (v.isValid()) { - switch (v.type()) { - case QVariant::Vector3D: + switch (v.userType()) { + case QMetaType::QVector3D: { QVector3D v3d = v.value<QVector3D>(); result = QString::fromLatin1("Qt.vector3d(%1, %2, %3)").arg(v3d.x()).arg(v3d.y()).arg(v3d.z()); break; } - case QVariant::Url: + case QMetaType::QUrl: { QUrl url = v.value<QUrl>(); result = QString::fromLatin1("Qt.url(%1)").arg(url.toString()); break; } - case QVariant::DateTime: + case QMetaType::QDateTime: { QDateTime dt = v.value<QDateTime>(); result = dt.toString(Qt::ISODateWithMs); @@ -598,7 +565,7 @@ bool QuickTestResult::compare const QUrl &location, int line) { return QTestResult::compare - (success, message.toLocal8Bit().constData(), + (success, message.toUtf8().constData(), QTest::toString(val1.toString().toLatin1().constData()), QTest::toString(val2.toString().toLatin1().constData()), "", "", @@ -608,7 +575,7 @@ bool QuickTestResult::compare void QuickTestResult::skip (const QString &message, const QUrl &location, int line) { - QTestResult::addSkip(message.toLatin1().constData(), + QTestResult::addSkip(message.toUtf8().constData(), qtestFixUrl(location).toLatin1().constData(), line); QTestResult::setSkipCurrentTest(true); } @@ -627,26 +594,34 @@ bool QuickTestResult::expectFailContinue { return QTestResult::expectFail (tag.toLatin1().constData(), - QTest::toString(comment.toLatin1().constData()), + QTest::toString(comment.toUtf8().constData()), QTest::Continue, qtestFixUrl(location).toLatin1().constData(), line); } void QuickTestResult::warn(const QString &message, const QUrl &location, int line) { - QTestLog::warn(message.toLatin1().constData(), qtestFixUrl(location).toLatin1().constData(), line); + QTestLog::warn(message.toUtf8().constData(), qtestFixUrl(location).toLatin1().constData(), line); } void QuickTestResult::ignoreWarning(const QJSValue &message) { if (message.isRegExp()) { - // ### we should probably handle QRegularExpression conversion engine-side - QRegExp re = message.toVariant().toRegExp(); - QRegularExpression::PatternOptions opts = re.caseSensitivity() == - Qt::CaseInsensitive ? QRegularExpression::CaseInsensitiveOption : QRegularExpression::NoPatternOption; - QRegularExpression re2(re.pattern(), opts); - QTestLog::ignoreMessage(QtWarningMsg, re2); +#if QT_CONFIG(regularexpression) + QTestLog::ignoreMessage(QtWarningMsg, qjsvalue_cast<QRegularExpression>(message)); +#endif } else { - QTestLog::ignoreMessage(QtWarningMsg, message.toString().toLatin1()); + QTestLog::ignoreMessage(QtWarningMsg, message.toString().toUtf8()); + } +} + +void QuickTestResult::failOnWarning(const QJSValue &message) +{ + if (message.isRegExp()) { +#if QT_CONFIG(regularexpression) + QTestLog::failOnWarning(qjsvalue_cast<QRegularExpression>(message)); +#endif + } else { + QTestLog::failOnWarning(message.toString().toUtf8()); } } @@ -674,7 +649,7 @@ void QuickTestResult::startMeasurement() d->benchmarkData = new QBenchmarkTestMethodData(); QBenchmarkTestMethodData::current = d->benchmarkData; d->iterCount = (QBenchmarkGlobalData::current->measurer->needsWarmupIteration()) ? -1 : 0; - d->results.clear(); + d->resultsList.clear(); } void QuickTestResult::beginDataRun() @@ -686,14 +661,17 @@ void QuickTestResult::endDataRun() { Q_D(QuickTestResult); QBenchmarkTestMethodData::current->endDataRun(); + const QList<QBenchmarkResult> &results = QBenchmarkTestMethodData::current->results; + if (results.isEmpty()) + return; // shouldn't happen if (d->iterCount > -1) // iteration -1 is the warmup iteration. - d->results.append(QBenchmarkTestMethodData::current->result); + d->resultsList.append(results); if (QBenchmarkGlobalData::current->verboseOutput) { if (d->iterCount == -1) { - qDebug() << "warmup stage result :" << QBenchmarkTestMethodData::current->result.value; + qDebug() << "warmup stage result :" << results.first().measurement.value; } else { - qDebug() << "accumulation stage result:" << QBenchmarkTestMethodData::current->result.value; + qDebug() << "accumulation stage result:" << results.first().measurement.value; } } } @@ -703,17 +681,20 @@ bool QuickTestResult::measurementAccepted() return QBenchmarkTestMethodData::current->resultsAccepted(); } -static QBenchmarkResult qMedian(const QList<QBenchmarkResult> &container) +static QList<QBenchmarkResult> qMedian(const QList<QList<QBenchmarkResult>> &container) { - const int count = container.count(); + const int count = container.size(); if (count == 0) - return QBenchmarkResult(); + return {}; if (count == 1) return container.at(0); - QList<QBenchmarkResult> containerCopy = container; - std::sort(containerCopy.begin(), containerCopy.end()); + QList<QList<QBenchmarkResult>> containerCopy = container; + std::sort(containerCopy.begin(), containerCopy.end(), + [](const QList<QBenchmarkResult> &a, const QList<QBenchmarkResult> &b) { + return a.first() < b.first(); + }); const int middle = count / 2; @@ -728,13 +709,13 @@ bool QuickTestResult::needsMoreMeasurements() if (d->iterCount < QBenchmarkGlobalData::current->adjustMedianIterationCount()) return true; if (QBenchmarkTestMethodData::current->resultsAccepted()) - QTestLog::addBenchmarkResult(qMedian(d->results)); + QTestLog::addBenchmarkResults(qMedian(d->resultsList)); return false; } void QuickTestResult::startBenchmark(RunMode runMode, const QString &tag) { - QBenchmarkTestMethodData::current->result = QBenchmarkResult(); + QBenchmarkTestMethodData::current->results = {}; QBenchmarkTestMethodData::current->resultAccepted = false; QBenchmarkGlobalData::current->context.tag = tag; QBenchmarkGlobalData::current->context.slotName = functionName(); @@ -773,7 +754,8 @@ QObject *QuickTestResult::grabImage(QQuickItem *item) if (item && item->window()) { QQuickWindow *window = item->window(); QImage grabbed = window->grabWindow(); - QRectF rf(item->x(), item->y(), item->width(), item->height()); + const auto dpi = grabbed.devicePixelRatio(); + QRectF rf(item->x() * dpi, item->y() * dpi, item->width() * dpi, item->height() * dpi); rf = rf.intersected(QRectF(0, 0, grabbed.width(), grabbed.height())); QObject *o = new QuickTestImageObject(grabbed.copy(rf.toAlignedRect())); QQmlEngine::setContextForObject(o, qmlContext(this)); @@ -787,6 +769,32 @@ QObject *QuickTestResult::findChild(QObject *parent, const QString &objectName) return parent ? parent->findChild<QObject*>(objectName) : 0; } +bool QuickTestResult::isPolishScheduled(QObject *itemOrWindow) const +{ + if (auto item = qobject_cast<QQuickItem*>(itemOrWindow)) + return QQuickTest::qIsPolishScheduled(item); + + if (auto window = qobject_cast<QQuickWindow*>(itemOrWindow)) + return QQuickTest::qIsPolishScheduled(window); + + qmlWarning(this) << "isPolishScheduled() expects either an Item or Window, but got" + << QDebug::toString(itemOrWindow); + return false; +} + +bool QuickTestResult::waitForPolish(QObject *itemOrWindow, int timeout) const +{ + if (auto item = qobject_cast<QQuickItem*>(itemOrWindow)) + return QQuickTest::qWaitForPolish(item, timeout); + + if (auto window = qobject_cast<QQuickWindow*>(itemOrWindow)) + return QQuickTest::qWaitForPolish(window, timeout); + + qmlWarning(this) << "waitForItemPolish() expects either an Item or Window, but got" + << QDebug::toString(itemOrWindow); + return false; +} + namespace QTest { void qtest_qParseArgs(int argc, char *argv[], bool qml); }; @@ -802,7 +810,6 @@ void QuickTestResult::setProgramName(const char *name) { if (name) { QTestPrivate::parseBlackList(); - QTestPrivate::parseGpuBlackList(); QTestResult::reset(); } else if (!name && loggingStarted) { QTestResult::setCurrentTestObject(globalProgramName); @@ -829,7 +836,7 @@ int QuickTestResult::exitCode() #endif } +QT_END_NAMESPACE + #include "quicktestresult.moc" #include "moc_quicktestresult_p.cpp" - -QT_END_NAMESPACE |