1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
43 #include <QLibraryInfo>
47 #include <QtQuick/QQuickItem>
48 #include <QtQuick/QQuickView>
49 #include <QQmlComponent>
53 static QtMsgHandler testlibMsgHandler = 0;
54 void msgHandlerFilter(QtMsgType type, const char *msg)
56 if (type == QtCriticalMsg || type == QtFatalMsg)
57 (*testlibMsgHandler)(type, msg);
60 class tst_examples : public QObject
71 void sgexamples_data();
73 void sgsnippets_data();
76 void namingConvention();
78 QStringList excludedDirs;
79 QStringList excludedFiles;
81 void namingConvention(const QDir &);
82 QStringList findQmlFiles(const QDir &);
89 tst_examples::tst_examples() : canvas(0)
91 // Add files to exclude here
92 excludedFiles << "examples/quick/canvas/tiger/tiger.qml"; // QTBUG-26528
93 excludedFiles << "snippets/qml/listmodel/listmodel.qml"; //Just a ListModel, no root QQuickItem
95 // Add directories you want excluded here (don't add examples/, because they install to examples/qtdeclarative/)
96 excludedDirs << "shared"; //Not an example
97 excludedDirs << "qtquick/text/fonts"; // QTBUG-21415
98 excludedDirs << "snippets/qml/path"; //No root QQuickItem
99 excludedDirs << "tutorials/gettingStartedQml"; //C++ example, but no cpp files in root dir
101 // These snippets are not expected to run on their own.
102 excludedDirs << "snippets/qml/visualdatamodel_rootindex";
103 excludedDirs << "snippets/qml/qtbinding";
104 excludedDirs << "snippets/qml/imports";
107 excludedDirs << "qtquick/modelviews/webview";
108 excludedDirs << "demos/webbrowser";
109 excludedDirs << "doc/src/snippets/qml/webview";
112 #ifdef QT_NO_XMLPATTERNS
113 excludedDirs << "demos/twitter";
114 excludedDirs << "demos/flickr";
115 excludedDirs << "demos/photoviewer";
116 excludedDirs << "snippets/qml/xmlrole.qml";
119 // QTBUG-24034 - don't run customparticle examples
120 excludedDirs << "demos/flickr";
121 excludedDirs << "examples/particles/customparticle";
124 tst_examples::~tst_examples()
129 void tst_examples::init()
131 if (!qstrcmp(QTest::currentTestFunction(), "sgsnippets"))
132 testlibMsgHandler = qInstallMsgHandler(msgHandlerFilter);
135 void tst_examples::cleanup()
137 if (!qstrcmp(QTest::currentTestFunction(), "sgsnippets"))
138 qInstallMsgHandler(testlibMsgHandler);
142 This tests that the examples follow the naming convention required
143 to have them tested by the examples() test.
145 void tst_examples::namingConvention(const QDir &d)
147 for (int ii = 0; ii < excludedDirs.count(); ++ii) {
148 QString s = excludedDirs.at(ii);
149 if (d.absolutePath().endsWith(s))
153 QStringList files = d.entryList(QStringList() << QLatin1String("*.qml"),
156 bool seenQml = !files.isEmpty();
157 bool seenLowercase = false;
159 foreach (const QString &file, files) {
160 if (file.at(0).isLower())
161 seenLowercase = true;
165 QStringList dirs = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot |
167 foreach (const QString &dir, dirs) {
170 namingConvention(sub);
172 } else if(!seenLowercase) {
173 QFAIL(qPrintable(QString(
174 "Directory %1 violates naming convention; expected at least one qml file "
175 "starting with lower case, got: %2"
176 ).arg(d.absolutePath()).arg(files.join(","))));
180 void tst_examples::namingConvention()
182 QString examples = QLibraryInfo::location(QLibraryInfo::ExamplesPath);
184 namingConvention(QDir(examples));
187 QStringList tst_examples::findQmlFiles(const QDir &d)
189 for (int ii = 0; ii < excludedDirs.count(); ++ii) {
190 QString s = excludedDirs.at(ii);
191 if (d.absolutePath().endsWith(s))
192 return QStringList();
197 QStringList cppfiles = d.entryList(QStringList() << QLatin1String("*.cpp"), QDir::Files);
198 if (cppfiles.isEmpty()) {
199 QStringList files = d.entryList(QStringList() << QLatin1String("*.qml"),
201 foreach (const QString &file, files) {
202 if (file.at(0).isLower()) {
203 bool superContinue = false;
204 for (int ii = 0; ii < excludedFiles.count(); ++ii) {
205 QString e = excludedFiles.at(ii);
206 if (d.absoluteFilePath(file).endsWith(e)) {
207 superContinue = true;
213 rv << d.absoluteFilePath(file);
219 QStringList dirs = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot |
221 foreach (const QString &dir, dirs) {
224 rv << findQmlFiles(sub);
231 This test runs all the examples in the QtQml UI source tree and ensures
232 that they start and exit cleanly.
234 Examples are any .qml files under the examples/ directory that start
235 with a lower case letter.
237 void tst_examples::sgexamples_data()
239 QTest::addColumn<QString>("file");
241 QString examples = QLatin1String(SRCDIR) + "/../../../../examples/";
244 files << findQmlFiles(QDir(examples));
246 foreach (const QString &file, files)
247 QTest::newRow(qPrintable(file)) << file;
250 void tst_examples::sgexamples()
252 QFETCH(QString, file);
254 QQmlComponent component(&engine, QUrl::fromLocalFile(file));
255 if (component.status() == QQmlComponent::Error)
256 qWarning() << component.errors();
257 QCOMPARE(component.status(), QQmlComponent::Ready);
259 QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
260 QQuickItem *root = qobject_cast<QQuickItem *>(object.data());
262 component.completeCreate();
266 canvas = new QQuickCanvas();
267 canvas->resize(240, 320);
269 QTest::qWaitForWindowShown(canvas);
271 root->setParentItem(canvas->rootItem());
272 component.completeCreate();
274 qApp->processEvents();
277 void tst_examples::sgsnippets_data()
279 QTest::addColumn<QString>("file");
281 QString snippets = QLatin1String(SRCDIR) + "/../../../../src/qml/doc/snippets/qml";
283 files << findQmlFiles(QDir(snippets));
284 foreach (const QString &file, files)
285 QTest::newRow(qPrintable(file)) << file;
287 snippets = QLatin1String(SRCDIR) + "/../../../../src/quick/doc/snippets/qml";
289 files << findQmlFiles(QDir(snippets));
290 foreach (const QString &file, files)
291 QTest::newRow(qPrintable(file)) << file;
294 void tst_examples::sgsnippets()
296 QFETCH(QString, file);
298 QQmlComponent component(&engine, QUrl::fromLocalFile(file));
299 if (component.status() == QQmlComponent::Error)
300 qWarning() << component.errors();
301 QCOMPARE(component.status(), QQmlComponent::Ready);
303 QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
304 QQuickItem *root = qobject_cast<QQuickItem *>(object.data());
306 component.completeCreate();
310 canvas = new QQuickCanvas();
311 canvas->resize(240, 320);
313 QTest::qWaitForWindowShown(canvas);
315 root->setParentItem(canvas->rootItem());
316 component.completeCreate();
318 qApp->processEvents();
321 QTEST_MAIN(tst_examples)
323 #include "tst_examples.moc"