summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRhys Weatherley <rhys.weatherley@nokia.com>2010-12-03 10:37:36 +1000
committerRhys Weatherley <rhys.weatherley@nokia.com>2010-12-03 10:56:07 +1000
commit706b4f1aa415a51d2696ce918aa7cc42ac2bc60e (patch)
tree9acc49a42c1bc0c9a2c9519e2fa8f3efa0f7d9d9 /src
parenta1f706e45bce11fba38d5f557660617654899ef9 (diff)
Add a test harness for launching QML tests
Diffstat (limited to 'src')
-rw-r--r--src/imports/testlib/testlib.pro9
-rw-r--r--src/quicktestlib/qdeclarativetest.cpp188
-rw-r--r--src/quicktestlib/qdeclarativetest.h97
-rw-r--r--src/quicktestlib/qdeclarativetestreport.cpp84
-rw-r--r--src/quicktestlib/qdeclarativetestreport.h2
-rw-r--r--src/quicktestlib/quicktestlib.pro2
-rw-r--r--src/quicktestlib/quicktestlib_dep.pri22
7 files changed, 354 insertions, 50 deletions
diff --git a/src/imports/testlib/testlib.pro b/src/imports/testlib/testlib.pro
index 341d576..b3b91c9 100644
--- a/src/imports/testlib/testlib.pro
+++ b/src/imports/testlib/testlib.pro
@@ -13,8 +13,6 @@ symbian {
QT += declarative
-INCLUDEPATH += $$PWD/../../quicktestlib
-
SOURCES += main.cpp
HEADERS +=
@@ -27,9 +25,4 @@ qdeclarativesources.path += $$[QT_INSTALL_IMPORTS]/QtTest
target.path += $$[QT_INSTALL_IMPORTS]/QtTest
INSTALLS += qdeclarativesources target
-LIBS += -L../../../lib -L../../../bin
-win32:CONFIG(debug, debug|release) {
- LIBS += -lQtTestQuick$${QT_LIBINFIX}d
-} else {
- LIBS += -lQtTestQuick$${QT_LIBINFIX}
-}
+include(../../quicktestlib/quicktestlib_dep.pri)
diff --git a/src/quicktestlib/qdeclarativetest.cpp b/src/quicktestlib/qdeclarativetest.cpp
new file mode 100644
index 0000000..7e56608
--- /dev/null
+++ b/src/quicktestlib/qdeclarativetest.cpp
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qdeclarativetest.h"
+#include "qdeclarativetestreport.h"
+#include <QApplication>
+#include <QtDeclarative/qdeclarative.h>
+#include <QtDeclarative/qdeclarativeview.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtOpenGL/qgl.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qeventloop.h>
+#include <QtGui/qtextdocument.h>
+#include <stdio.h>
+
+QT_BEGIN_NAMESPACE
+
+// Defined in qdeclarativetestreport.cpp.
+extern bool qtest_quick_xmlOutput;
+extern int qtest_quick_passed;
+extern int qtest_quick_failed;
+extern int qtest_quick_skipped;
+extern FILE *qtest_quick_stream;
+
+class QTestQuitObject : public QObject
+{
+ Q_OBJECT
+public:
+ QTestQuitObject(QObject *parent = 0) : QObject(parent), hasQuit(false) {}
+
+ bool hasQuit;
+
+private Q_SLOTS:
+ void quit() { hasQuit = true; }
+};
+
+int qtest_quick_main(int argc, char **argv, const char *name, const char *sourceDir, qtest_create_viewport createViewport)
+{
+ QApplication app(argc, argv);
+
+ // Parse the command-line arguments.
+ const char *filename = 0;
+ for (int index = 1; index < argc; ++index) {
+ QString arg = QString::fromLocal8Bit(argv[index]);
+ if (arg == QLatin1String("-xml"))
+ qtest_quick_xmlOutput = true;
+ else if (arg == QLatin1String("-o") && (index + 1) < argc)
+ filename = argv[++index];
+ }
+
+ // Determine where to look for the test data. On a device it will
+ // typically be necessary to set QTEST_QUICK_SOURCE_DIR.
+ QString testPath = QString::fromLocal8Bit(qgetenv("QTEST_QUICK_SOURCE_DIR"));
+ if (testPath.isEmpty() && sourceDir)
+ testPath = QString::fromLocal8Bit(sourceDir);
+ if (!testPath.isEmpty() && !QFile::exists(testPath))
+ testPath = QString();
+ if (testPath.isEmpty())
+ testPath = QLatin1String(".");
+
+ // Find the subdirectories that look like they may contain test cases.
+ // We also include "." in this list.
+ QDir dir(testPath);
+ QStringList entries = dir.entryList(QDir::Dirs);
+ entries.removeAll(QLatin1String(".."));
+ if (!entries.contains(QLatin1String(".")))
+ entries.append(QLatin1String("."));
+
+ if (filename) {
+ qtest_quick_stream = fopen(filename, "w");
+ if (!qtest_quick_stream) {
+ perror(filename);
+ return 1;
+ }
+ } else {
+ qtest_quick_stream = stdout;
+ }
+
+ if (qtest_quick_xmlOutput) {
+ fprintf(qtest_quick_stream, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
+ "<TestCase name=\"%s\">\n", name);
+ fprintf(qtest_quick_stream, "<Environment>\n"
+ " <QtVersion>%s</QtVersion>\n"
+ " <QTestVersion>%s</QTestVersion>\n"
+ "</Environment>\n", qVersion(), qVersion());
+ } else {
+ fprintf(qtest_quick_stream, "********* Start testing of %s *********\n", name);
+ }
+
+ // Scan through all of the "tst_*.qml" files in the subdirectories
+ // and run each of them in turn with a QDeclarativeView.
+ QStringList filters;
+ filters += QLatin1String("tst_*.qml");
+ foreach (QString name, entries) {
+ QDir subdir(testPath + QDir::separator() + name);
+ QStringList files = subdir.entryList(filters, QDir::Files);
+ foreach (QString file, files) {
+ QString source = subdir.path() + QDir::separator() + file;
+ QFileInfo fi(source);
+ if (fi.exists()) {
+ QDeclarativeView view;
+ QTestQuitObject quitobj;
+ QEventLoop eventLoop;
+ QObject::connect(view.engine(), SIGNAL(quit()),
+ &quitobj, SLOT(quit()));
+ QObject::connect(view.engine(), SIGNAL(quit()),
+ &eventLoop, SLOT(quit()));
+ if (createViewport)
+ view.setViewport((*createViewport)());
+ view.engine()->addImportPath(testPath);
+ view.setSource(QUrl::fromLocalFile(fi.absoluteFilePath()));
+ if (view.status() == QDeclarativeView::Error) {
+ // Error compiling the test - flag failure and continue.
+ ++qtest_quick_failed;
+ continue;
+ }
+ if (!quitobj.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();
+ eventLoop.exec();
+ }
+ }
+ }
+ }
+
+ if (qtest_quick_xmlOutput) {
+ fprintf(qtest_quick_stream, "</TestCase>\n");
+ } else {
+ fprintf(qtest_quick_stream, "Totals: %d passed, %d failed, %d skipped\n",
+ qtest_quick_passed, qtest_quick_failed, qtest_quick_skipped);
+ fprintf(qtest_quick_stream, "********* Finished testing of %s *********\n", name);
+ }
+
+ if (filename)
+ fclose(qtest_quick_stream);
+
+ return qtest_quick_failed != 0;
+}
+
+QT_END_NAMESPACE
+
+#include "qdeclarativetest.moc"
diff --git a/src/quicktestlib/qdeclarativetest.h b/src/quicktestlib/qdeclarativetest.h
new file mode 100644
index 0000000..643653f
--- /dev/null
+++ b/src/quicktestlib/qdeclarativetest.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** 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 QDECLARATIVETEST_H
+#define QDECLARATIVETEST_H
+
+#include "quicktestglobal.h"
+#include <QtGui/qwidget.h>
+#ifdef QT_OPENGL_LIB
+#include <QtOpenGL/qgl.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+typedef QWidget *(*qtest_create_viewport)();
+
+Q_TEST_QUICK_EXPORT int qtest_quick_main(int argc, char **argv, const char *name, const char *sourceDir, qtest_create_viewport createViewport);
+
+#ifndef QTEST_QUICK_SOURCE_DIR
+
+#define QTEST_QUICK_MAIN(name) \
+ int main(int argc, char **argv) \
+ { \
+ return qtest_quick_main(argc, argv, #name, 0, 0); \
+ }
+
+#define QTEST_QUICK_OPENGL_MAIN(name) \
+ static QWidget *name##_create_viewport() \
+ { \
+ return new QGLWidget(); \
+ } \
+ int main(int argc, char **argv) \
+ { \
+ return qtest_quick_main(argc, argv, #name, 0, name##_create_viewport); \
+ }
+
+#else
+
+#define QTEST_QUICK_MAIN(name) \
+ int main(int argc, char **argv) \
+ { \
+ return qtest_quick_main(argc, argv, #name, QTEST_QUICK_SOURCE_DIR, 0); \
+ }
+
+#define QTEST_QUICK_OPENGL_MAIN(name) \
+ static QWidget *name##_create_viewport() \
+ { \
+ return new QGLWidget(); \
+ } \
+ int main(int argc, char **argv) \
+ { \
+ return qtest_quick_main(argc, argv, #name, QTEST_QUICK_SOURCE_DIR, name##_create_viewport); \
+ }
+
+#endif
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/quicktestlib/qdeclarativetestreport.cpp b/src/quicktestlib/qdeclarativetestreport.cpp
index 7930405..719240f 100644
--- a/src/quicktestlib/qdeclarativetestreport.cpp
+++ b/src/quicktestlib/qdeclarativetestreport.cpp
@@ -45,91 +45,91 @@
QT_BEGIN_NAMESPACE
-static bool xmlOutput = false;
-static int passed = 0;
-static int failed = 0;
-static int skipped = 0;
-static FILE *stream = 0;
+bool qtest_quick_xmlOutput = false;
+int qtest_quick_passed = 0;
+int qtest_quick_failed = 0;
+int qtest_quick_skipped = 0;
+FILE *qtest_quick_stream = 0;
void QDeclarativeTestReport::report(int pass, int fail, int skip)
{
- passed += pass;
- failed += fail;
- skipped += skip;
+ qtest_quick_passed += pass;
+ qtest_quick_failed += fail;
+ qtest_quick_skipped += skip;
}
void QDeclarativeTestReport::log_fail(const QString &testCase, const QString &message)
{
- if (!stream)
- stream = stdout;
- if (xmlOutput) {
+ if (!qtest_quick_stream)
+ qtest_quick_stream = stdout;
+ if (qtest_quick_xmlOutput) {
log_incident("fail", testCase, message);
} else if (!message.isEmpty()) {
- fprintf(stream, "FAIL! : %s %s\n",
+ fprintf(qtest_quick_stream, "FAIL! : %s %s\n",
testCase.toLatin1().constData(),
message.toLatin1().constData());
} else {
- fprintf(stream, "FAIL! : %s\n", testCase.toLatin1().constData());
+ fprintf(qtest_quick_stream, "FAIL! : %s\n", testCase.toLatin1().constData());
}
}
void QDeclarativeTestReport::log_expect_fail
(const QString &testCase, const QString &message)
{
- if (!stream)
- stream = stdout;
- if (xmlOutput) {
+ if (!qtest_quick_stream)
+ qtest_quick_stream = stdout;
+ if (qtest_quick_xmlOutput) {
log_incident("xfail", testCase, message);
} else if (!message.isEmpty()) {
- fprintf(stream, "XFAIL : %s %s\n",
+ fprintf(qtest_quick_stream, "XFAIL : %s %s\n",
testCase.toLatin1().constData(),
message.toLatin1().constData());
} else {
- fprintf(stream, "XFAIL : %s\n", testCase.toLatin1().constData());
+ fprintf(qtest_quick_stream, "XFAIL : %s\n", testCase.toLatin1().constData());
}
}
void QDeclarativeTestReport::log_expect_fail_pass(const QString &testCase)
{
- if (!stream)
- stream = stdout;
- if (xmlOutput)
+ if (!qtest_quick_stream)
+ qtest_quick_stream = stdout;
+ if (qtest_quick_xmlOutput)
log_incident("xpass", testCase, QString());
else
- fprintf(stream, "XPASS : %s\n", testCase.toLatin1().constData());
+ fprintf(qtest_quick_stream, "XPASS : %s\n", testCase.toLatin1().constData());
}
void QDeclarativeTestReport::log_skip(const QString &testCase, const QString &message)
{
- if (!stream)
- stream = stdout;
- if (xmlOutput) {
+ if (!qtest_quick_stream)
+ qtest_quick_stream = stdout;
+ if (qtest_quick_xmlOutput) {
log_incident("skip", testCase, message);
} else if (!message.isEmpty()) {
- fprintf(stream, "SKIP : %s %s\n",
+ fprintf(qtest_quick_stream, "SKIP : %s %s\n",
testCase.toLatin1().constData(),
message.toLatin1().constData());
} else {
- fprintf(stream, "SKIP : %s\n", testCase.toLatin1().constData());
+ fprintf(qtest_quick_stream, "SKIP : %s\n", testCase.toLatin1().constData());
}
}
void QDeclarativeTestReport::log_pass(const QString &testCase)
{
- if (!stream)
- stream = stdout;
- if (xmlOutput)
+ if (!qtest_quick_stream)
+ qtest_quick_stream = stdout;
+ if (qtest_quick_xmlOutput)
log_incident("pass", testCase, QString());
else
- fprintf(stream, "PASS : %s\n", testCase.toLatin1().constData());
+ fprintf(qtest_quick_stream, "PASS : %s\n", testCase.toLatin1().constData());
}
void QDeclarativeTestReport::log_message(const QString &message)
{
- if (!stream)
- stream = stdout;
- if (!xmlOutput)
- fprintf(stream, "%s\n", message.toLatin1().constData());
+ if (!qtest_quick_stream)
+ qtest_quick_stream = stdout;
+ if (!qtest_quick_xmlOutput)
+ fprintf(qtest_quick_stream, "%s\n", message.toLatin1().constData());
}
void QDeclarativeTestReport::log_incident
@@ -146,23 +146,23 @@ void QDeclarativeTestReport::log_incident
tag = tag.left(tag.length() - 1);
name = name.left(tagIndex);
}
- fprintf(stream, "<TestFunction name=\"%s\">\n",
+ fprintf(qtest_quick_stream, "<TestFunction name=\"%s\">\n",
Qt::escape(name).toLatin1().constData());
if (message.isEmpty() && tag.isEmpty()) {
- fprintf(stream, "<Incident type=\"%s\" file=\"\" line=\"0\" />\n", type);
+ fprintf(qtest_quick_stream, "<Incident type=\"%s\" file=\"\" line=\"0\" />\n", type);
} else {
- fprintf(stream, "<Incident type=\"%s\" file=\"\" line=\"0\">\n", type);
+ fprintf(qtest_quick_stream, "<Incident type=\"%s\" file=\"\" line=\"0\">\n", type);
if (!tag.isEmpty()) {
- fprintf(stream, " <DataTag>%s</DataTag>\n",
+ fprintf(qtest_quick_stream, " <DataTag>%s</DataTag>\n",
Qt::escape(tag).toLatin1().constData());
}
if (!message.isEmpty()) {
- fprintf(stream, " <Description>%s</Description>\n",
+ fprintf(qtest_quick_stream, " <Description>%s</Description>\n",
Qt::escape(message).toLatin1().constData());
}
- fprintf(stream, "</Incident>\n");
+ fprintf(qtest_quick_stream, "</Incident>\n");
}
- fprintf(stream, "</TestFunction>\n");
+ fprintf(qtest_quick_stream, "</TestFunction>\n");
}
QT_END_NAMESPACE
diff --git a/src/quicktestlib/qdeclarativetestreport.h b/src/quicktestlib/qdeclarativetestreport.h
index a505de4..7f40788 100644
--- a/src/quicktestlib/qdeclarativetestreport.h
+++ b/src/quicktestlib/qdeclarativetestreport.h
@@ -72,4 +72,6 @@ private:
QML_DECLARE_TYPE(QDeclarativeTestReport)
+QT_END_NAMESPACE
+
#endif
diff --git a/src/quicktestlib/quicktestlib.pro b/src/quicktestlib/quicktestlib.pro
index e35913f..9351b55 100644
--- a/src/quicktestlib/quicktestlib.pro
+++ b/src/quicktestlib/quicktestlib.pro
@@ -25,9 +25,11 @@ symbian {
}
SOURCES += \
+ qdeclarativetest.cpp \
qdeclarativetestreport.cpp
HEADERS += \
quicktestglobal.h \
+ qdeclarativetest.h \
qdeclarativetestreport.h
PUBLIC_HEADERS += $$HEADERS
diff --git a/src/quicktestlib/quicktestlib_dep.pri b/src/quicktestlib/quicktestlib_dep.pri
new file mode 100644
index 0000000..a615cd3
--- /dev/null
+++ b/src/quicktestlib/quicktestlib_dep.pri
@@ -0,0 +1,22 @@
+
+QT += declarative
+
+INCLUDEPATH += $$PWD
+LIBS += -L../../lib -L../../bin
+
+win32:CONFIG(debug, debug|release) {
+ LIBS += -lQtTestQuick$${QT_LIBINFIX}d
+} else {
+ LIBS += -lQtTestQuick$${QT_LIBINFIX}
+}
+
+# Locate the "lib" directory in the build tree and put it before
+# the Qt "lib" directory in the library path so that we link
+# against the libQtTestQuick.so in our build tree, not the Qt one.
+FIND_TOP=..
+for(i,forever) {
+ exists($$_PRO_FILE_PWD_/$$FIND_TOP/qtest-qml.pro):break()
+ FIND_TOP=../$$FIND_TOP
+}
+load(qt)
+QMAKE_LIBDIR=$$OUT_PWD/$$FIND_TOP/lib $$QMAKE_LIBDIR