TestCase: add isPolishScheduled() and waitForItemPolished()

These were introduced to the C++ QQuickTest namespace in 40d6072b and
7a3cad06, respectively. QML-only tests should also have access to them.

[ChangeLog][QtQuickTest][TestCase] Added isPolishScheduled()
function to allow checking if updatePolish() has been called on
an item since the last call to its polish() function.
This is useful to verify that a polish has been scheduled.

[ChangeLog][QtQuickTest][TestCase] Added waitForItemPolished()
for verifying that updatePolish() was called on an item.

Change-Id: I3e3a488197e74546358e2d5b0da7a902793c1954
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
Mitch Curtis 2018-12-06 12:15:30 +01:00
parent 50f234df50
commit 028617688b
6 changed files with 239 additions and 0 deletions

View File

@ -520,6 +520,75 @@ Item {
throw new Error("QtQuickTest::fail")
}
/*!
\since 5.13
\qmlmethod bool TestCase::isPolishScheduled(object item)
Returns \c true if \l {QQuickItem::}{updatePolish()} has not been called
on \a item since the last call to \l {QQuickItem::}{polish()},
otherwise returns \c false.
When assigning values to properties in QML, any layouting the item
must do as a result of the assignment might not take effect immediately,
but can instead be postponed until the item is polished. For these cases,
you can use this function to ensure that the item has been polished
before the execution of the test continues. For example:
\code
verify(isPolishScheduled(item))
verify(waitForItemPolished(item))
\endcode
Without the call to \c isPolishScheduled() above, the
call to \c waitForItemPolished() might see that no polish
was scheduled and therefore pass instantly, assuming that
the item had already been polished. This function
makes it obvious why an item wasn't polished and allows tests to
fail early under such circumstances.
\sa waitForItemPolished(), QQuickItem::polish(), QQuickItem::updatePolish()
*/
function isPolishScheduled(item) {
if (!item || typeof item !== "object") {
qtest_results.fail("Argument must be a valid Item; actual type is " + typeof item,
util.callerFile(), util.callerLine())
throw new Error("QtQuickTest::fail")
}
return qtest_results.isPolishScheduled(item)
}
/*!
\since 5.13
\qmlmethod bool waitForItemPolished(object item, int timeout = 5000)
Waits for \a timeout milliseconds or until
\l {QQuickItem::}{updatePolish()} has been called on \a item.
Returns \c true if \c updatePolish() was called on \a item within
\a timeout milliseconds, otherwise returns \c false.
\sa isPolishScheduled(), QQuickItem::polish(), QQuickItem::updatePolish()
*/
function waitForItemPolished(item, timeout) {
if (!item || typeof item !== "object") {
qtest_results.fail("First argument must be a valid Item; actual type is " + typeof item,
util.callerFile(), util.callerLine())
throw new Error("QtQuickTest::fail")
}
if (timeout !== undefined && typeof(timeout) != "number") {
qtest_results.fail("Second argument must be a number; actual type is " + typeof timeout,
util.callerFile(), util.callerLine())
throw new Error("QtQuickTest::fail")
}
if (!timeout)
timeout = 5000
return qtest_results.waitForItemPolished(item, timeout)
}
/*!
\since 5.9
\qmlmethod object TestCase::createTemporaryQmlObject(string qml, object parent, string filePath)

View File

@ -39,6 +39,7 @@
****************************************************************************/
#include "quicktestresult_p.h"
#include "quicktest.h"
#include <QtTest/qtestcase.h>
#include <QtTest/qtestsystem.h>
#include <QtTest/private/qtestblacklist_p.h>
@ -787,6 +788,16 @@ QObject *QuickTestResult::findChild(QObject *parent, const QString &objectName)
return parent ? parent->findChild<QObject*>(objectName) : 0;
}
bool QuickTestResult::isPolishScheduled(QQuickItem *item) const
{
return QQuickTest::qIsPolishScheduled(item);
}
bool QuickTestResult::waitForItemPolished(QQuickItem *item, int timeout)
{
return QQuickTest::qWaitForItemPolished(item, timeout);
}
namespace QTest {
void qtest_qParseArgs(int argc, char *argv[], bool qml);
};

View File

@ -160,6 +160,9 @@ public Q_SLOTS:
Q_REVISION(1) QObject *findChild(QObject *parent, const QString &objectName);
bool isPolishScheduled(QQuickItem *item) const;
bool waitForItemPolished(QQuickItem *item, int timeout);
public:
// Helper functions for the C++ main() shell.
static void parseArgs(int argc, char *argv[]);

View File

@ -0,0 +1,60 @@
/****************************************************************************
**
** Copyright (C) 2018 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:GPL-EXCEPT$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** 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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.13
import QtTest 1.13
import Test 1.0
TestCase {
id: testCase
name: "polish-qml"
when: windowShown
Component {
id: customItemComponent
CustomItem {}
}
function test_polish()
{
var item = createTemporaryObject(customItemComponent, testCase)
verify(item)
item.polishMe()
verify(isPolishScheduled(item))
verify(item.isPolishScheduled())
verify(waitForItemPolished(item))
verify(item.wasUpdatePolishCalled())
// TODO: test failure conditions when https://bugreports.qt.io/browse/QTBUG-72351 is fixed
// expectFail("", "Not a valid item")
// isPolishScheduled(null)
}
}

View File

@ -0,0 +1,12 @@
CONFIG += qmltestcase
macos:CONFIG -= app_bundle
TARGET = tst_polish-qml
QT += testlib quick quick-private
include (../../shared/util.pri)
SOURCES += tst_polish-qml.cpp
TESTDATA += \
$$PWD/data/*.qml

View File

@ -0,0 +1,84 @@
/****************************************************************************
**
** Copyright (C) 2018 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:GPL-EXCEPT$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** 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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/qtest.h>
#include <QtQml/qqmlengine.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/private/qquickitem_p.h>
#include <QtQuick/qquickview.h>
#include <QtQuickTest/quicktest.h>
#include "../../shared/util.h"
class CustomItem : public QQuickItem
{
Q_OBJECT
public:
CustomItem() {}
Q_INVOKABLE void polishMe() {
polish();
}
Q_INVOKABLE bool isPolishScheduled() const
{
return QQuickItemPrivate::get(this)->polishScheduled;
}
Q_INVOKABLE bool wasUpdatePolishCalled() const
{
return updatePolishCalled;
}
void updatePolish() override
{
updatePolishCalled = true;
}
private:
bool updatePolishCalled = false;
};
class TestSetup : public QObject
{
Q_OBJECT
public:
TestSetup() {}
public slots:
void applicationAvailable()
{
qmlRegisterType<CustomItem>("Test", 1, 0, "CustomItem");
}
};
QUICK_TEST_MAIN_WITH_SETUP(polish-qml, TestSetup)
#include "tst_polish-qml.moc"