diff options
author | Rhys Weatherley <rhys.weatherley@nokia.com> | 2010-12-15 14:25:15 +1000 |
---|---|---|
committer | Rhys Weatherley <rhys.weatherley@nokia.com> | 2010-12-15 15:00:28 +1000 |
commit | 81e09bb0d7bb5b8ce58773f5e9422b3c507006dd (patch) | |
tree | af445e8a92501be178b02fa0d9724ee58ee2b147 | |
parent | 6259fd7b01373fdcfb8f5e9e4a7487c0002189a3 (diff) |
Add a SignalSpy item for watching signals
-rw-r--r-- | doc/src/index.qdoc | 4 | ||||
-rw-r--r-- | src/imports/testlib/SignalSpy.qml | 109 | ||||
-rw-r--r-- | src/imports/testlib/qmldir | 1 | ||||
-rw-r--r-- | src/imports/testlib/signalspy.h | 83 | ||||
-rw-r--r-- | src/imports/testlib/signalspy.qdoc | 146 | ||||
-rw-r--r-- | src/imports/testlib/testcase.qdoc | 7 | ||||
-rw-r--r-- | src/imports/testlib/testlib.pro | 1 | ||||
-rw-r--r-- | tests/qmlauto/buttonclick/tst_buttonclick.qml | 9 |
8 files changed, 357 insertions, 3 deletions
diff --git a/doc/src/index.qdoc b/doc/src/index.qdoc index ee3b3ab..288f5ce 100644 --- a/doc/src/index.qdoc +++ b/doc/src/index.qdoc @@ -54,8 +54,8 @@ \endcode Functions whose names start with \c{test_} are treated as test cases - to be executed. See the documentation for the \l TestCase element - for more information on writing test cases. + to be executed. See the documentation for the \l TestCase and + \l SignalSpy elements for more information on writing test cases. \section1 Building QtQuickTest diff --git a/src/imports/testlib/SignalSpy.qml b/src/imports/testlib/SignalSpy.qml new file mode 100644 index 0000000..7bbad3a --- /dev/null +++ b/src/imports/testlib/SignalSpy.qml @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.0 + +Item { + id: spy + visible: false + + // Public API. + + property variant target: null + property string signalName: "" + property int count: 0 + + function clear() { + count = 0 + qtest_expectedCount = 0 + } + + function wait(timeout) { + if (timeout === undefined) + timeout = 5000 + var expected = ++qtest_expectedCount + var i = 0 + while (i < timeout && count < expected) { + qtest_results.wait(50) + i += 50 + } + var success = (count >= expected) + if (!qtest_results.verify(success, "wait for signal " + signalName, Qt.qtest_caller_file(), Qt.qtest_caller_line())) + throw new Error("QtQuickTest::fail") + } + + // Internal implementation detail follows. + + TestResult { id: qtest_results } + + onTargetChanged: { + qtest_update() + } + onSignalNameChanged: { + qtest_update() + } + + property variant qtest_prevTarget: null + property string qtest_prevSignalName: "" + property int qtest_expectedCount: 0 + + function qtest_update() { + if (qtest_prevTarget != null) { + qtest_prevTarget[qtest_prevSignalName].disconnect(spy, "qtest_activated") + qtest_prevTarget = null + qtest_prevSignalName = "" + } + if (target != null && signalName != "") { + var func = target[signalName] + if (func === undefined) { + console.log("Signal '" + signalName + "' not found") + } else { + qtest_prevTarget = target + qtest_prevSignalName = signalName + func.connect(spy.qtest_activated) + } + } + } + + function qtest_activated() { + ++count + } +} diff --git a/src/imports/testlib/qmldir b/src/imports/testlib/qmldir index 7df32c0..9e872f9 100644 --- a/src/imports/testlib/qmldir +++ b/src/imports/testlib/qmldir @@ -1,2 +1,3 @@ plugin qmltestplugin TestCase 1.0 TestCase.qml +SignalSpy 1.0 SignalSpy.qml diff --git a/src/imports/testlib/signalspy.h b/src/imports/testlib/signalspy.h new file mode 100644 index 0000000..4a97959 --- /dev/null +++ b/src/imports/testlib/signalspy.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SIGNALSPY_H +#define SIGNALSPY_H + +// This is a dummy header for defining the interface of "SignalSpy.qml" to qdoc. + +#include <QtDeclarative/qdeclarativeitem.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class SignalSpy : public QDeclarativeItem +{ + Q_OBJECT + Q_PROPERTY(QObject *target READ target WRITE setTarget NOTIFY targetChanged) + Q_PROPERTY(QString signalName READ signalName WRITE signalName NOTIFY signalNameChanged) + Q_PROPERTY(int count READ count countChanged) +public: + SignalSpy(QDeclarativeItem *parent) : QDeclarativeItem(parent) {} + ~SignalSpy() + + QObject *target() const; + void setTarget(QObject *target); + + QString signalName() const; + void setSignalName(const QString &signalName); + + int count() const; + +Q_SIGNALS: + void targetChanged(); + void signalNameChanged(); + void countChanged(); +}; + +QML_DECLARE_TYPE(SignalSpy) + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/imports/testlib/signalspy.qdoc b/src/imports/testlib/signalspy.qdoc new file mode 100644 index 0000000..3ed39c4 --- /dev/null +++ b/src/imports/testlib/signalspy.qdoc @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \qmlclass SignalSpy SignalSpy + \brief The SignalSpy item enables introspection of signal emission. + \since 4.8 + \ingroup qtest::qml + + In the following example, a SignalSpy is installed to watch the + "clicked" signal on a user-defined Button element. When the signal + is emitted, the \l count property on the spy will be increased. + + \code + Button { + id: button + SignalSpy { + id: spy + target: button + signalName: "clicked" + } + TestCase { + name: "ButtonClick" + function test_click() { + compare(spy.count, 0) + button.clicked(); + compare(spy.count, 1) + } + } + } + \endcode + + The above style of test is suitable for signals that are emitted + synchronously. For asynchronous signals, the wait() method can be + used to block the test until the signal occurs (or a timeout expires). + + \sa TestCase +*/ + +/*! + \qmlproperty object SignalSpy::target + + This property defines the target object that will be used to + listen for emissions of the \l signalName signal. + + \sa signalName, count +*/ + +/*! + \qmlproperty string SignalSpy::signalName + + This property defines the name of the signal on \l target to + listen for. + + \sa target, count +*/ + +/*! + \qmlproperty int SignalSpy::count + + This property defines the number of times that \l signalName has + been emitted from \l target since the last call to clear(). + + \sa target, signalName, clear() +*/ + +/*! + \qmlmethod SignalSpy::clear() + + Clears \l count to 0. + + \sa count, wait() +*/ + +/*! + \qmlmethod SignalSpy::wait(timeout = 5000) + + Waits for the signal \l signalName on \l target to be emitted, + for up to \a timeout milliseconds. The test case will fail if + the signal is not emitted. + + \code + SignalSpy { + id: spy + target: button + signalName: "clicked" + } + + function test_async_click() { + ... + // do something that will cause clicked() to be emitted + ... + spy.wait() + compare(spy.count, 1) + } + \endcode + + There are two possible scenarios: the signal has already been + emitted when wait() is called, or the signal has not yet been + emitted. The wait() function handles the first scenario by immediately + returning if the signal has already occurred. + + The clear() method can be used to discard information about signals + that have already occurred to synchronize wait() with future signal + emissions. + + \sa clear(), TestCase::tryCompare() +*/ diff --git a/src/imports/testlib/testcase.qdoc b/src/imports/testlib/testcase.qdoc index ddd2b79..4e95c5e 100644 --- a/src/imports/testlib/testcase.qdoc +++ b/src/imports/testlib/testcase.qdoc @@ -184,6 +184,8 @@ main window has been shown. Attempts to deliver events before then will fail. Use the \l when and windowShown properties to track when the main window has been shown. + + \sa SignalSpy */ /*! @@ -349,7 +351,10 @@ compare(img.verticalTileMode, BorderImage.Stretch) \endcode - \sa compare() + SignalSpy::wait() provides an alternative method to wait for a + signal to be emitted. + + \sa compare(), SignalSpy::wait() */ /*! diff --git a/src/imports/testlib/testlib.pro b/src/imports/testlib/testlib.pro index 3605ebf..13721db 100644 --- a/src/imports/testlib/testlib.pro +++ b/src/imports/testlib/testlib.pro @@ -19,6 +19,7 @@ HEADERS += qdeclarativesources.files += \ qmldir \ TestCase.qml \ + SignalSpy.qml \ testlogger.js qdeclarativesources.path += $$[QT_INSTALL_IMPORTS]/QtQuickTest diff --git a/tests/qmlauto/buttonclick/tst_buttonclick.qml b/tests/qmlauto/buttonclick/tst_buttonclick.qml index 2fb13f7..907b442 100644 --- a/tests/qmlauto/buttonclick/tst_buttonclick.qml +++ b/tests/qmlauto/buttonclick/tst_buttonclick.qml @@ -45,13 +45,22 @@ import QtQuickTest 1.0 Button { id: button onClicked: text = "Clicked" + + SignalSpy { + id: spy + target: button + signalName: "clicked" + } + TestCase { name: "ButtonClick" when: windowShown function test_click() { + compare(spy.count, 0) button.clicked(); compare(button.text, "Clicked"); + compare(spy.count, 1) } } } |