diff options
author | Rhys Weatherley <rhys.weatherley@nokia.com> | 2011-02-15 09:01:22 +1000 |
---|---|---|
committer | Rhys Weatherley <rhys.weatherley@nokia.com> | 2011-02-15 11:09:16 +1000 |
commit | a8ba198b978ce8d02db106003a7784b5364930a7 (patch) | |
tree | 9e6afc1274bea630d04ea9c1cb03bb31a935a931 | |
parent | 1673a8572e0c51ab01dde65912612c3d6826b02e (diff) |
Make it possible to use QtQuickTest with QtQuick2
-rw-r--r-- | README | 9 | ||||
-rw-r--r-- | src/quicktestlib/quicktest.cpp | 193 | ||||
-rw-r--r-- | src/quicktestlib/quicktestevent.cpp | 69 | ||||
-rw-r--r-- | src/quicktestlib/quicktestevent_p.h | 16 |
4 files changed, 201 insertions, 86 deletions
@@ -19,3 +19,12 @@ shows how to integrate QML unit tests into a qmake-based build system. You can also run "make check" to verify that the example tests pass correctly, and "make docs" to generate the HTML documentation under "doc/html" using the qdoc3 tool from Qt. + +Running QtQuickTest with Qt Quick 2.0 +===================================== + +By default, test cases are run using QDeclarativeView. To switch to +QSGView instead, build against a version of Qt that has scenegraph +support and then run the unit tests as follows: + + $ QMLSCENE_IMPORT_NAME=quick1 TESTARGS=-qtquick2 make check diff --git a/src/quicktestlib/quicktest.cpp b/src/quicktestlib/quicktest.cpp index f48ade9..147f4fb 100644 --- a/src/quicktestlib/quicktest.cpp +++ b/src/quicktestlib/quicktest.cpp @@ -48,6 +48,10 @@ #include <QtDeclarative/qdeclarativeview.h> #include <QtDeclarative/qdeclarativeengine.h> #include <QtDeclarative/qdeclarativecontext.h> +#if defined(QML_VERSION) && QML_VERSION >= 0x020000 +#include <QtDeclarative/qsgview.h> +#define QUICK_TEST_SCENEGRAPH 1 +#endif #include <QtScript/qscriptvalue.h> #include <QtScript/qscriptcontext.h> #include <QtScript/qscriptengine.h> @@ -112,8 +116,10 @@ int quick_test_main(int argc, char **argv, const char *name, quick_test_viewport // Look for QML-specific command-line options. // -import dir Specify an import directory. // -input dir Specify the input directory for test cases. + // -qtquick2 Run with QtQuick 2 rather than QtQuick 1. QStringList imports; QString testPath; + bool qtQuick2 = false; int outargc = 1; int index = 1; while (index < argc) { @@ -125,6 +131,9 @@ int quick_test_main(int argc, char **argv, const char *name, quick_test_viewport index += 2; } else if (strcmp(argv[index], "-opengl") == 0) { ++index; + } else if (strcmp(argv[index], "-qtquick2") == 0) { + qtQuick2 = true; + ++index; } else if (outargc != index) { argv[outargc++] = argv[index++]; } else { @@ -165,66 +174,132 @@ int quick_test_main(int argc, char **argv, const char *name, quick_test_viewport // Scan through all of the "tst_*.qml" files and run each of them // in turn with a QDeclarativeView. - foreach (QString file, files) { - QFileInfo fi(file); - if (!fi.exists()) - continue; - QDeclarativeView view; - QTestRootObject rootobj; - QEventLoop eventLoop; - QObject::connect(view.engine(), SIGNAL(quit()), - &rootobj, SLOT(quit())); - QObject::connect(view.engine(), SIGNAL(quit()), - &eventLoop, SLOT(quit())); - if (createViewport) - view.setViewport((*createViewport)()); - view.rootContext()->setContextProperty - (QLatin1String("qtest"), &rootobj); - QScriptEngine *engine; - engine = QDeclarativeDebugHelper::getScriptEngine(view.engine()); - QScriptValue qtObject - = engine->globalObject().property(QLatin1String("Qt")); - qtObject.setProperty - (QLatin1String("qtest_wrapper"), QScriptValue(true)); - qtObject.setProperty - (QLatin1String("qtest_printAvailableFunctions"), - QScriptValue(QTest::printAvailableFunctions)); - foreach (QString path, imports) - view.engine()->addImportPath(path); - QString path = fi.absoluteFilePath(); - if (path.startsWith(QLatin1String(":/"))) - view.setSource(QUrl(QLatin1String("qrc:") + path.mid(2))); - else - view.setSource(QUrl::fromLocalFile(path)); - if (QTest::printAvailableFunctions) - continue; - if (view.status() == QDeclarativeView::Error) { - // Error compiling the test - flag failure in the log and continue. - QList<QDeclarativeError> errors = view.errors(); - QuickTestResult results; - results.setTestCaseName(fi.baseName()); - results.startLogging(); - results.setFunctionName(QLatin1String("compile")); - results.setFunctionType(QuickTestResult::Func); - results.fail(errors.at(0).description(), - errors.at(0).url().toString(), - errors.at(0).line()); - results.finishTestFunction(); - results.setFunctionName(QString()); - results.setFunctionType(QuickTestResult::NoWhere); - results.stopLogging(); - continue; +#ifdef QUICK_TEST_SCENEGRAPH + if (qtQuick2) { + foreach (QString file, files) { + QFileInfo fi(file); + if (!fi.exists()) + continue; + QSGView view; + QTestRootObject rootobj; + QEventLoop eventLoop; + QObject::connect(view.engine(), SIGNAL(quit()), + &rootobj, SLOT(quit())); + QObject::connect(view.engine(), SIGNAL(quit()), + &eventLoop, SLOT(quit())); + view.rootContext()->setContextProperty + (QLatin1String("qtest"), &rootobj); + QScriptEngine *engine; + engine = QDeclarativeDebugHelper::getScriptEngine(view.engine()); + QScriptValue qtObject + = engine->globalObject().property(QLatin1String("Qt")); + qtObject.setProperty + (QLatin1String("qtest_wrapper"), QScriptValue(true)); + qtObject.setProperty + (QLatin1String("qtest_printAvailableFunctions"), + QScriptValue(QTest::printAvailableFunctions)); + foreach (QString path, imports) + view.engine()->addImportPath(path); + QString path = fi.absoluteFilePath(); + if (path.startsWith(QLatin1String(":/"))) + view.setSource(QUrl(QLatin1String("qrc:") + path.mid(2))); + else + view.setSource(QUrl::fromLocalFile(path)); + if (QTest::printAvailableFunctions) + continue; + if (view.status() == QSGView::Error) { + // Error compiling the test - flag failure in the log and continue. + QList<QDeclarativeError> errors = view.errors(); + QuickTestResult results; + results.setTestCaseName(fi.baseName()); + results.startLogging(); + results.setFunctionName(QLatin1String("compile")); + results.setFunctionType(QuickTestResult::Func); + results.fail(errors.at(0).description(), + errors.at(0).url().toString(), + errors.at(0).line()); + results.finishTestFunction(); + results.setFunctionName(QString()); + results.setFunctionType(QuickTestResult::NoWhere); + results.stopLogging(); + continue; + } + if (!rootobj.hasQuit) { + // If the test already quit, then it was performed + // synchronously during setSource(). Otherwise it is + // an asynchronous test and we need to show the window + // and wait for the quit indication. + view.show(); + QTest::qWaitForWindowShown(&view); + rootobj.setWindowShown(true); + if (!rootobj.hasQuit) + eventLoop.exec(); + } } - if (!rootobj.hasQuit) { - // If the test already quit, then it was performed - // synchronously during setSource(). Otherwise it is - // an asynchronous test and we need to show the window - // and wait for the quit indication. - view.show(); - QTest::qWaitForWindowShown(&view); - rootobj.setWindowShown(true); - if (!rootobj.hasQuit) - eventLoop.exec(); + } else +#endif + { + foreach (QString file, files) { + QFileInfo fi(file); + if (!fi.exists()) + continue; + QDeclarativeView view; + QTestRootObject rootobj; + QEventLoop eventLoop; + QObject::connect(view.engine(), SIGNAL(quit()), + &rootobj, SLOT(quit())); + QObject::connect(view.engine(), SIGNAL(quit()), + &eventLoop, SLOT(quit())); + if (createViewport) + view.setViewport((*createViewport)()); + view.rootContext()->setContextProperty + (QLatin1String("qtest"), &rootobj); + QScriptEngine *engine; + engine = QDeclarativeDebugHelper::getScriptEngine(view.engine()); + QScriptValue qtObject + = engine->globalObject().property(QLatin1String("Qt")); + qtObject.setProperty + (QLatin1String("qtest_wrapper"), QScriptValue(true)); + qtObject.setProperty + (QLatin1String("qtest_printAvailableFunctions"), + QScriptValue(QTest::printAvailableFunctions)); + foreach (QString path, imports) + view.engine()->addImportPath(path); + QString path = fi.absoluteFilePath(); + if (path.startsWith(QLatin1String(":/"))) + view.setSource(QUrl(QLatin1String("qrc:") + path.mid(2))); + else + view.setSource(QUrl::fromLocalFile(path)); + if (QTest::printAvailableFunctions) + continue; + if (view.status() == QDeclarativeView::Error) { + // Error compiling the test - flag failure in the log and continue. + QList<QDeclarativeError> errors = view.errors(); + QuickTestResult results; + results.setTestCaseName(fi.baseName()); + results.startLogging(); + results.setFunctionName(QLatin1String("compile")); + results.setFunctionType(QuickTestResult::Func); + results.fail(errors.at(0).description(), + errors.at(0).url().toString(), + errors.at(0).line()); + results.finishTestFunction(); + results.setFunctionName(QString()); + results.setFunctionType(QuickTestResult::NoWhere); + results.stopLogging(); + continue; + } + if (!rootobj.hasQuit) { + // If the test already quit, then it was performed + // synchronously during setSource(). Otherwise it is + // an asynchronous test and we need to show the window + // and wait for the quit indication. + view.show(); + QTest::qWaitForWindowShown(&view); + rootobj.setWindowShown(true); + if (!rootobj.hasQuit) + eventLoop.exec(); + } } } diff --git a/src/quicktestlib/quicktestevent.cpp b/src/quicktestlib/quicktestevent.cpp index 07e5cd5..83aff91 100644 --- a/src/quicktestlib/quicktestevent.cpp +++ b/src/quicktestlib/quicktestevent.cpp @@ -41,15 +41,21 @@ #include "quicktestevent_p.h" #include "qtestkeyboard.h" +#include <QtDeclarative/qdeclarative.h> +#include <QtDeclarative/qdeclarativeitem.h> +#include <QtDeclarative/qdeclarativeview.h> +#if defined(QML_VERSION) && QML_VERSION >= 0x020000 +#include <QtDeclarative/qsgitem.h> +#include <QtDeclarative/qsgcanvas.h> +#define QUICK_TEST_SCENEGRAPH 1 +#endif #include <QtGui/qgraphicsscene.h> -#include <QtGui/qgraphicsview.h> QT_BEGIN_NAMESPACE -QuickTestEvent::QuickTestEvent(QDeclarativeItem *parent) - : QDeclarativeItem(parent) +QuickTestEvent::QuickTestEvent(QObject *parent) + : QObject(parent) { - setVisible(false); } QuickTestEvent::~QuickTestEvent() @@ -91,8 +97,8 @@ namespace QtQuickTest { enum MouseAction { MousePress, MouseRelease, MouseClick, MouseDoubleClick, MouseMove }; - static void mouseEvent(MouseAction action, QGraphicsView *widget, - QDeclarativeItem *item, Qt::MouseButton button, + static void mouseEvent(MouseAction action, QWidget *widget, + QObject *item, Qt::MouseButton button, Qt::KeyboardModifiers stateKey, QPointF _pos, int delay=-1) { QTEST_ASSERT(widget); @@ -109,7 +115,24 @@ namespace QtQuickTest return; } - QPoint pos = widget->mapFromScene(item->mapToScene(_pos)); + QPoint pos; + QDeclarativeView *view = qobject_cast<QDeclarativeView *>(widget); + QWidget *eventWidget = widget; +#ifdef QUICK_TEST_SCENEGRAPH + QSGItem *sgitem = qobject_cast<QSGItem *>(item); + if (sgitem) { + pos = sgitem->mapToScene(_pos).toPoint(); + } else +#endif + { + QDeclarativeItem *ditem = qobject_cast<QDeclarativeItem *>(item); + if (!ditem) { + qWarning("Mouse event target is not an Item"); + return; + } + pos = view->mapFromScene(ditem->mapToScene(_pos)); + eventWidget = view->viewport(); + } QTEST_ASSERT(button == Qt::NoButton || button & Qt::MouseButtonMask); QTEST_ASSERT(stateKey == 0 || stateKey & Qt::KeyboardModifierMask); @@ -136,7 +159,7 @@ namespace QtQuickTest QTEST_ASSERT(false); } QSpontaneKeyEvent::setSpontaneous(&me); - if (!qApp->notify(widget->viewport(), &me)) { + if (!qApp->notify(eventWidget, &me)) { static const char *mouseActionNames[] = { "MousePress", "MouseRelease", "MouseClick", "MouseDoubleClick", "MouseMove" }; QString warning = QString::fromLatin1("Mouse event \"%1\" not accepted by receiving widget"); @@ -146,10 +169,10 @@ namespace QtQuickTest }; bool QuickTestEvent::mousePress - (QDeclarativeItem *item, qreal x, qreal y, int button, + (QObject *item, qreal x, qreal y, int button, int modifiers, int delay) { - QGraphicsView *view = qobject_cast<QGraphicsView *>(eventWidget()); + QWidget *view = eventWidget(); if (!view) return false; QtQuickTest::mouseEvent(QtQuickTest::MousePress, view, item, @@ -160,10 +183,10 @@ bool QuickTestEvent::mousePress } bool QuickTestEvent::mouseRelease - (QDeclarativeItem *item, qreal x, qreal y, int button, + (QObject *item, qreal x, qreal y, int button, int modifiers, int delay) { - QGraphicsView *view = qobject_cast<QGraphicsView *>(eventWidget()); + QWidget *view = eventWidget(); if (!view) return false; QtQuickTest::mouseEvent(QtQuickTest::MouseRelease, view, item, @@ -174,10 +197,10 @@ bool QuickTestEvent::mouseRelease } bool QuickTestEvent::mouseClick - (QDeclarativeItem *item, qreal x, qreal y, int button, + (QObject *item, qreal x, qreal y, int button, int modifiers, int delay) { - QGraphicsView *view = qobject_cast<QGraphicsView *>(eventWidget()); + QWidget *view = eventWidget(); if (!view) return false; QtQuickTest::mouseEvent(QtQuickTest::MouseClick, view, item, @@ -188,10 +211,10 @@ bool QuickTestEvent::mouseClick } bool QuickTestEvent::mouseDoubleClick - (QDeclarativeItem *item, qreal x, qreal y, int button, + (QObject *item, qreal x, qreal y, int button, int modifiers, int delay) { - QGraphicsView *view = qobject_cast<QGraphicsView *>(eventWidget()); + QWidget *view = eventWidget(); if (!view) return false; QtQuickTest::mouseEvent(QtQuickTest::MouseDoubleClick, view, item, @@ -202,9 +225,9 @@ bool QuickTestEvent::mouseDoubleClick } bool QuickTestEvent::mouseMove - (QDeclarativeItem *item, qreal x, qreal y, int delay) + (QObject *item, qreal x, qreal y, int delay) { - QGraphicsView *view = qobject_cast<QGraphicsView *>(eventWidget()); + QWidget *view = eventWidget(); if (!view) return false; QtQuickTest::mouseEvent(QtQuickTest::MouseMove, view, item, @@ -215,7 +238,15 @@ bool QuickTestEvent::mouseMove QWidget *QuickTestEvent::eventWidget() { - QGraphicsScene *s = scene(); +#ifdef QUICK_TEST_SCENEGRAPH + QSGItem *sgitem = qobject_cast<QSGItem *>(parent()); + if (sgitem) + return sgitem->canvas(); +#endif + QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(parent()); + if (!item) + return 0; + QGraphicsScene *s = item->scene(); if (!s) return 0; QList<QGraphicsView *> views = s->views(); diff --git a/src/quicktestlib/quicktestevent_p.h b/src/quicktestlib/quicktestevent_p.h index 0be70e5..1f5926f 100644 --- a/src/quicktestlib/quicktestevent_p.h +++ b/src/quicktestlib/quicktestevent_p.h @@ -43,15 +43,15 @@ #define QUICKTESTEVENT_P_H #include <QtQuickTest/quicktestglobal.h> -#include <QtDeclarative/qdeclarativeitem.h> +#include <QtCore/qobject.h> QT_BEGIN_NAMESPACE -class Q_QUICK_TEST_EXPORT QuickTestEvent : public QDeclarativeItem +class Q_QUICK_TEST_EXPORT QuickTestEvent : public QObject { Q_OBJECT public: - QuickTestEvent(QDeclarativeItem *parent = 0); + QuickTestEvent(QObject *parent = 0); ~QuickTestEvent(); public Q_SLOTS: @@ -59,15 +59,15 @@ public Q_SLOTS: bool keyRelease(int key, int modifiers, int delay); bool keyClick(int key, int modifiers, int delay); - bool mousePress(QDeclarativeItem *item, qreal x, qreal y, int button, + bool mousePress(QObject *item, qreal x, qreal y, int button, int modifiers, int delay); - bool mouseRelease(QDeclarativeItem *item, qreal x, qreal y, int button, + bool mouseRelease(QObject *item, qreal x, qreal y, int button, int modifiers, int delay); - bool mouseClick(QDeclarativeItem *item, qreal x, qreal y, int button, + bool mouseClick(QObject *item, qreal x, qreal y, int button, int modifiers, int delay); - bool mouseDoubleClick(QDeclarativeItem *item, qreal x, qreal y, int button, + bool mouseDoubleClick(QObject *item, qreal x, qreal y, int button, int modifiers, int delay); - bool mouseMove(QDeclarativeItem *item, qreal x, qreal y, int delay); + bool mouseMove(QObject *item, qreal x, qreal y, int delay); private: QWidget *eventWidget(); |