[Ktutorial-commits] SF.net SVN: ktutorial:[257] trunk/ktutorial/ktutorial-library
Status: Alpha
Brought to you by:
danxuliu
|
From: <dan...@us...> - 2010-09-25 20:16:10
|
Revision: 257
http://ktutorial.svn.sourceforge.net/ktutorial/?rev=257&view=rev
Author: danxuliu
Date: 2010-09-25 20:16:03 +0000 (Sat, 25 Sep 2010)
Log Message:
-----------
Add WaitForWindow to wait for a specific window (identified by its object name) to be shown.
Modified Paths:
--------------
trunk/ktutorial/ktutorial-library/src/CMakeLists.txt
trunk/ktutorial/ktutorial-library/src/scripting/ScriptingModule.cpp
trunk/ktutorial/ktutorial-library/tests/CMakeLists.txt
trunk/ktutorial/ktutorial-library/tests/scripting/ScriptingModuleTest.cpp
Added Paths:
-----------
trunk/ktutorial/ktutorial-library/src/WaitForWindow.cpp
trunk/ktutorial/ktutorial-library/src/WaitForWindow.h
trunk/ktutorial/ktutorial-library/tests/WaitForWindowTest.cpp
Modified: trunk/ktutorial/ktutorial-library/src/CMakeLists.txt
===================================================================
--- trunk/ktutorial/ktutorial-library/src/CMakeLists.txt 2010-09-25 14:39:08 UTC (rev 256)
+++ trunk/ktutorial/ktutorial-library/src/CMakeLists.txt 2010-09-25 20:16:03 UTC (rev 257)
@@ -29,6 +29,7 @@
WaitForNot.cpp
WaitForOr.cpp
WaitForSignal.cpp
+ WaitForWindow.cpp
)
kde4_add_library(ktutorial SHARED ${ktutorial_LIB_SRCS})
@@ -58,6 +59,7 @@
WaitForNot.h
WaitForOr.h
WaitForSignal.h
+ WaitForWindow.h
)
# Hack to make headers available to other ktutorial modules (like
Added: trunk/ktutorial/ktutorial-library/src/WaitForWindow.cpp
===================================================================
--- trunk/ktutorial/ktutorial-library/src/WaitForWindow.cpp (rev 0)
+++ trunk/ktutorial/ktutorial-library/src/WaitForWindow.cpp 2010-09-25 20:16:03 UTC (rev 257)
@@ -0,0 +1,78 @@
+/***************************************************************************
+ * Copyright (C) 2010 by Daniel Calviño Sánchez *
+ * dan...@gm... *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#include "WaitForWindow.h"
+#include "KTutorial.h"
+#include "common/WindowVisibilitySpy.h"
+
+using common::WindowVisibilitySpy;
+
+//public:
+
+WaitForWindow::WaitForWindow(): WaitFor(),
+ mConditionMet(false) {
+
+ WindowVisibilitySpy* spy = new WindowVisibilitySpy(this);
+ spy->addWidgetToSpy(KTutorial::self()->parentWidget());
+ connect(spy, SIGNAL(windowShown(QWidget*)),
+ this, SLOT(checkWindowShown(QWidget*)));
+}
+
+WaitForWindow::WaitForWindow(const QString& objectName): WaitFor(),
+ mConditionMet(false) {
+
+ WindowVisibilitySpy* spy = new WindowVisibilitySpy(this);
+ spy->addWidgetToSpy(KTutorial::self()->parentWidget());
+ connect(spy, SIGNAL(windowShown(QWidget*)),
+ this, SLOT(checkWindowShown(QWidget*)));
+
+ setWindowObjectName(objectName);
+}
+
+void WaitForWindow::setWindowObjectName(const QString& objectName) {
+ mWindowObjectName = objectName;
+}
+
+bool WaitForWindow::conditionMet() const {
+ return mConditionMet;
+}
+
+void WaitForWindow::setActive(bool active) {
+ WaitFor::setActive(active);
+
+ if (active) {
+ mConditionMet = false;
+ }
+}
+
+//private slots:
+
+void WaitForWindow::checkWindowShown(QWidget* window) {
+ if (!isActive()) {
+ return;
+ }
+
+ if (window->objectName() != mWindowObjectName) {
+ return;
+ }
+
+ mConditionMet = true;
+ emit waitEnded(this);
+}
+
+#include "WaitForWindow.moc"
Property changes on: trunk/ktutorial/ktutorial-library/src/WaitForWindow.cpp
___________________________________________________________________
Added: svn:eol-style
+ native
Added: trunk/ktutorial/ktutorial-library/src/WaitForWindow.h
===================================================================
--- trunk/ktutorial/ktutorial-library/src/WaitForWindow.h (rev 0)
+++ trunk/ktutorial/ktutorial-library/src/WaitForWindow.h 2010-09-25 20:16:03 UTC (rev 257)
@@ -0,0 +1,120 @@
+/***************************************************************************
+ * Copyright (C) 2010 by Daniel Calviño Sánchez *
+ * dan...@gm... *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#ifndef WAITFORWINDOW_H
+#define WAITFORWINDOW_H
+
+#include "ktutorial_export.h"
+
+#include "WaitFor.h"
+
+/**
+ * Waits for a specific window to be shown.
+ * When the window with the expected object name is shown and the WaitForEvent
+ * is active, the wait ends.
+ *
+ * Note that if the window is shown while the WaitFor isn't active, it won't
+ * be registered and the condition won't be met. In order to met the condition,
+ * the window must be shown while the WaitForEvent is active.
+ *
+ * The term "window" is used here in a general sense: WaitForWindow can wait
+ * either for true windows or for dialogs. In fact, WaitForWindow must be used
+ * whenever there is a modal dialog; waiting for the user to click a button that
+ * causes a modal dialog to appear will not work, as the modal dialog will
+ * halt further processing of the clicked() signal until it is closed (if the
+ * modal dialog was created in a slot connected to the clicked() signal, which
+ * is very likely).
+ */
+class KTUTORIAL_EXPORT WaitForWindow: public WaitFor {
+Q_OBJECT
+public:
+
+ /**
+ * Creates a new WaitForWindow.
+ * This constructor is needed to dynamically create WaitForWindow objects in
+ * scripts using ScriptingModule::newWaitFor(const QString&). Method
+ * setWindowObjectName(const QString&) must be called to finish setting up
+ * the object. For C++ tutorials, use WaitForWindow(const QString&)
+ * constructor instead of this one.
+ */
+ Q_INVOKABLE WaitForWindow();
+
+ /**
+ * Creates a new WaitForWindow.
+ * Note that the name is the object name, not the window title.
+ *
+ * @param windowObjectName The object name of the window to wait for.
+ */
+ WaitForWindow(const QString& windowObjectName);
+
+ /**
+ * Sets the object name of the window to wait for.
+ * Note that the name is the object name, not the window title.
+ * This method can be invoked from a script.
+ *
+ * In fact, you should only invoke this method from a script, and only once,
+ * to set up the object. For C++ tutorials, use
+ * WaitForWindow(const QString&) constructor when creating this
+ * WaitForWindow.
+ *
+ * @param windowObjectName The object name of the window to wait for.
+ */
+ Q_INVOKABLE void setWindowObjectName(const QString& windowObjectName);
+
+ /**
+ * Returns true if the window was shown while active, false otherwise.
+ *
+ * @return True if the window was shown while active, false otherwise.
+ */
+ virtual bool conditionMet() const;
+
+ /**
+ * Sets this WaitForWindow active or inactive.
+ * Activating it resets its condition.
+ *
+ * @param active True to set it active, false otherwise.
+ */
+ virtual void setActive(bool active);
+
+private:
+
+ /**
+ * Whether the window with the expected object name was shown when active or
+ * not.
+ */
+ bool mConditionMet;
+
+ /**
+ * The object name of the window to wait for.
+ */
+ QString mWindowObjectName;
+
+private Q_SLOTS:
+
+ /**
+ * Checks whether the window that has been shown is the expected one.
+ * If the WaitFor is active and the object name of the window is the
+ * expected one, the condition is met and the wait ended.
+ *
+ * @param window A window that has been shown.
+ */
+ void checkWindowShown(QWidget* window);
+
+};
+
+#endif
Property changes on: trunk/ktutorial/ktutorial-library/src/WaitForWindow.h
___________________________________________________________________
Added: svn:eol-style
+ native
Modified: trunk/ktutorial/ktutorial-library/src/scripting/ScriptingModule.cpp
===================================================================
--- trunk/ktutorial/ktutorial-library/src/scripting/ScriptingModule.cpp 2010-09-25 14:39:08 UTC (rev 256)
+++ trunk/ktutorial/ktutorial-library/src/scripting/ScriptingModule.cpp 2010-09-25 20:16:03 UTC (rev 257)
@@ -28,6 +28,7 @@
#include "../WaitForNot.h"
#include "../WaitForOr.h"
#include "../WaitForSignal.h"
+#include "../WaitForWindow.h"
namespace scripting {
@@ -39,6 +40,7 @@
sSelf->registerWaitForMetaObject(WaitForNot::staticMetaObject);
sSelf->registerWaitForMetaObject(WaitForOr::staticMetaObject);
sSelf->registerWaitForMetaObject(WaitForSignal::staticMetaObject);
+ sSelf->registerWaitForMetaObject(WaitForWindow::staticMetaObject);
}
return sSelf;
Modified: trunk/ktutorial/ktutorial-library/tests/CMakeLists.txt
===================================================================
--- trunk/ktutorial/ktutorial-library/tests/CMakeLists.txt 2010-09-25 14:39:08 UTC (rev 256)
+++ trunk/ktutorial/ktutorial-library/tests/CMakeLists.txt 2010-09-25 20:16:03 UTC (rev 257)
@@ -12,6 +12,11 @@
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${ktutorial-library_SOURCE_DIR}/src ${KDE4_INCLUDES})
+# Since Qt 4.6.0, this definition is needed for GUI testing.
+# It is backwards compatible with previous Qt versions, unlike the alternative
+# which is to add #include <QTestGui> in the test files.
+add_definitions(-DQT_GUI_LIB)
+
MACRO(UNIT_TESTS)
FOREACH(_className ${ARGN})
set(_testName ${_className}Test)
@@ -33,6 +38,7 @@
WaitForNot
WaitForOr
WaitForSignal
+ WaitForWindow
)
MACRO(MEM_TESTS)
@@ -54,4 +60,5 @@
WaitForNot
WaitForOr
WaitForSignal
+ WaitForWindow
)
Added: trunk/ktutorial/ktutorial-library/tests/WaitForWindowTest.cpp
===================================================================
--- trunk/ktutorial/ktutorial-library/tests/WaitForWindowTest.cpp (rev 0)
+++ trunk/ktutorial/ktutorial-library/tests/WaitForWindowTest.cpp 2010-09-25 20:16:03 UTC (rev 257)
@@ -0,0 +1,252 @@
+/***************************************************************************
+ * Copyright (C) 2010 by Daniel Calviño Sánchez *
+ * dan...@gm... *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#include <QtTest>
+
+#include <QDialog>
+
+#include <KXmlGuiWindow>
+
+#define protected public
+#define private public
+#include "WaitForWindow.h"
+#undef private
+#undef protected
+
+#include "KTutorial.h"
+
+class WaitForWindowTest: public QObject {
+Q_OBJECT
+private slots:
+
+ void initTestCase();
+
+ void testConstructor();
+ void testConstructorDefault();
+
+ void testSetActive();
+
+ void testWaitEnded();
+ void testWaitEndedByModalDialog();
+ void testWaitEndedWithDefaultConstructor();
+ void testWaitEndedNotActive();
+
+private:
+
+ KXmlGuiWindow* mMainWindow;
+
+ void queueAssertConditionMet(WaitForWindow* waitForWindow,
+ QSignalSpy* waitEndedSpy,
+ int timeToWait);
+
+};
+
+void WaitForWindowTest::initTestCase() {
+ mMainWindow = new KXmlGuiWindow();
+ KTutorial::self()->setup(mMainWindow);
+}
+
+void WaitForWindowTest::testConstructor() {
+ WaitForWindow waitForWindow("theName");
+
+ QVERIFY(!waitForWindow.isActive());
+ QVERIFY(!waitForWindow.conditionMet());
+}
+
+void WaitForWindowTest::testConstructorDefault() {
+ WaitForWindow waitForWindow;
+ waitForWindow.setWindowObjectName("theName");
+
+ QVERIFY(!waitForWindow.isActive());
+ QVERIFY(!waitForWindow.conditionMet());
+}
+
+void WaitForWindowTest::testSetActive() {
+ WaitForWindow waitForWindow("theName");
+ waitForWindow.mConditionMet = true;
+
+ waitForWindow.setActive(true);
+
+ QVERIFY(waitForWindow.isActive());
+ QVERIFY(!waitForWindow.conditionMet());
+}
+
+//WaitFor* must be declared as a metatype to be used in qvariant_cast
+Q_DECLARE_METATYPE(WaitFor*);
+
+void WaitForWindowTest::testWaitEnded() {
+ WaitForWindow waitForWindow("theName");
+ waitForWindow.setActive(true);
+
+ //WaitFor* must be registered in order to be used with QSignalSpy
+ int waitForStarType = qRegisterMetaType<WaitFor*>("WaitFor*");
+ QSignalSpy waitEndedSpy(&waitForWindow, SIGNAL(waitEnded(WaitFor*)));
+
+ QWidget* otherWindow = new QWidget(mMainWindow);
+ otherWindow->setObjectName("otherName");
+ otherWindow->setWindowFlags(Qt::Window);
+ otherWindow->show();
+
+ otherWindow->deleteLater();
+
+ QVERIFY(!waitForWindow.conditionMet());
+ QCOMPARE(waitEndedSpy.count(), 0);
+
+ QWidget* window = new QWidget(mMainWindow);
+ window->setObjectName("theName");
+ window->setWindowFlags(Qt::Window);
+ window->show();
+
+ window->deleteLater();
+
+ QVERIFY(waitForWindow.conditionMet());
+ QCOMPARE(waitEndedSpy.count(), 1);
+ QVariant argument = waitEndedSpy.at(0).at(0);
+ QCOMPARE(argument.userType(), waitForStarType);
+ QCOMPARE(qvariant_cast<WaitFor*>(argument), &waitForWindow);
+}
+
+void WaitForWindowTest::testWaitEndedByModalDialog() {
+ WaitForWindow waitForWindow("theName");
+ waitForWindow.setActive(true);
+
+ //WaitFor* must be registered in order to be used with QSignalSpy
+ int waitForStarType = qRegisterMetaType<WaitFor*>("WaitFor*");
+ QSignalSpy waitEndedSpy(&waitForWindow, SIGNAL(waitEnded(WaitFor*)));
+
+ QDialog* modalDialog = new QDialog(mMainWindow);
+ modalDialog->setObjectName("theName");
+
+ QTimer timerAccept;
+ timerAccept.setSingleShot(true);
+ timerAccept.setInterval(1500);
+ connect(&timerAccept, SIGNAL(timeout()), modalDialog, SLOT(accept()));
+
+ //Check that the condition was met before closing the modal dialog to ensure
+ //that the processing of events or signals is not halted due to being modal.
+ queueAssertConditionMet(&waitForWindow, &waitEndedSpy, 500);
+
+ timerAccept.start();
+ modalDialog->exec();
+
+ modalDialog->deleteLater();
+
+ QVERIFY(waitForWindow.conditionMet());
+ QCOMPARE(waitEndedSpy.count(), 1);
+ QVariant argument = waitEndedSpy.at(0).at(0);
+ QCOMPARE(argument.userType(), waitForStarType);
+ QCOMPARE(qvariant_cast<WaitFor*>(argument), &waitForWindow);
+}
+
+void WaitForWindowTest::testWaitEndedWithDefaultConstructor() {
+ WaitForWindow waitForWindow;
+ waitForWindow.setWindowObjectName("theName");
+ waitForWindow.setActive(true);
+
+ //WaitFor* must be registered in order to be used with QSignalSpy
+ int waitForStarType = qRegisterMetaType<WaitFor*>("WaitFor*");
+ QSignalSpy waitEndedSpy(&waitForWindow, SIGNAL(waitEnded(WaitFor*)));
+
+ QWidget* otherWindow = new QWidget(mMainWindow);
+ otherWindow->setObjectName("otherName");
+ otherWindow->setWindowFlags(Qt::Window);
+ otherWindow->show();
+
+ otherWindow->deleteLater();
+
+ QVERIFY(!waitForWindow.conditionMet());
+ QCOMPARE(waitEndedSpy.count(), 0);
+
+ QWidget* window = new QWidget(mMainWindow);
+ window->setObjectName("theName");
+ window->setWindowFlags(Qt::Window);
+ window->show();
+
+ window->deleteLater();
+
+ QVERIFY(waitForWindow.conditionMet());
+ QCOMPARE(waitEndedSpy.count(), 1);
+ QVariant argument = waitEndedSpy.at(0).at(0);
+ QCOMPARE(argument.userType(), waitForStarType);
+ QCOMPARE(qvariant_cast<WaitFor*>(argument), &waitForWindow);
+}
+
+void WaitForWindowTest::testWaitEndedNotActive() {
+ WaitForWindow waitForWindow("theName");
+
+ qRegisterMetaType<WaitFor*>("WaitFor*");
+ QSignalSpy waitEndedSpy(&waitForWindow, SIGNAL(waitEnded(WaitFor*)));
+
+ QWidget* window = new QWidget(mMainWindow);
+ window->setObjectName("theName");
+ window->setWindowFlags(Qt::Window);
+ window->show();
+
+ window->deleteLater();
+
+ QVERIFY(!waitForWindow.conditionMet());
+ QCOMPARE(waitEndedSpy.count(), 0);
+}
+
+/////////////////////////////////// Helpers ////////////////////////////////////
+
+//Modal dialogs don't return to the test code until they are closed. Thus, the
+//actions or asserts to be performed while a modal dialog is being shown (like
+//checking if a wait for condition was met) must be "queued".
+class QueuedActionsHelper: public QObject {
+Q_OBJECT
+public:
+
+ QueuedActionsHelper(QObject* object = 0): QObject(object) {
+ }
+
+ void setWaitForWindow(WaitForWindow* waitForWindow) {
+ mWaitForWindow = waitForWindow;
+ }
+
+ void setWaitEndedSpy(QSignalSpy* waitEndedSpy) {
+ mWaitEndedSpy = waitEndedSpy;
+ }
+
+public slots:
+
+ void assertConditionMet() {
+ QVERIFY(mWaitForWindow->conditionMet());
+ QCOMPARE(mWaitEndedSpy->count(), 1);
+ }
+
+private:
+
+ WaitForWindow* mWaitForWindow;
+ QSignalSpy* mWaitEndedSpy;
+
+};
+
+void WaitForWindowTest::queueAssertConditionMet(WaitForWindow* waitForWindow,
+ QSignalSpy* waitEndedSpy,
+ int timeToWait) {
+ QueuedActionsHelper* helper = new QueuedActionsHelper();
+ helper->setWaitForWindow(waitForWindow);
+ helper->setWaitEndedSpy(waitEndedSpy);
+ QTimer::singleShot(timeToWait, helper, SLOT(assertConditionMet()));
+ QTimer::singleShot(timeToWait, helper, SLOT(deleteLater()));
+}
+
+QTEST_MAIN(WaitForWindowTest)
+
+#include "WaitForWindowTest.moc"
Property changes on: trunk/ktutorial/ktutorial-library/tests/WaitForWindowTest.cpp
___________________________________________________________________
Added: svn:eol-style
+ native
Modified: trunk/ktutorial/ktutorial-library/tests/scripting/ScriptingModuleTest.cpp
===================================================================
--- trunk/ktutorial/ktutorial-library/tests/scripting/ScriptingModuleTest.cpp 2010-09-25 14:39:08 UTC (rev 256)
+++ trunk/ktutorial/ktutorial-library/tests/scripting/ScriptingModuleTest.cpp 2010-09-25 20:16:03 UTC (rev 257)
@@ -34,6 +34,7 @@
#include "../WaitForNot.h"
#include "../WaitForOr.h"
#include "../WaitForSignal.h"
+#include "../WaitForWindow.h"
class MockWaitForDefaultNamespace: public WaitFor {
Q_OBJECT
@@ -171,6 +172,10 @@
QVERIFY(containsMetaObject(scriptingModule, "WaitForSignal"));
type = metaObject(scriptingModule, "WaitForSignal");
QCOMPARE(type.className(), WaitForSignal::staticMetaObject.className());
+
+ QVERIFY(containsMetaObject(scriptingModule, "WaitForWindow"));
+ type = metaObject(scriptingModule, "WaitForWindow");
+ QCOMPARE(type.className(), WaitForWindow::staticMetaObject.className());
}
void ScriptingModuleTest::testRegisterWaitForMetaObject() {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|