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 <QDeclarativeComponent>
50 #include <QDeclarativeEngine>
51 #include <QDeclarativeError>
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
70 void sgexamples_data();
72 void sgsnippets_data();
75 void namingConvention();
77 QStringList excludedDirs;
78 QStringList excludedFiles;
80 void namingConvention(const QDir &);
81 QStringList findQmlFiles(const QDir &);
83 QDeclarativeEngine engine;
86 tst_examples::tst_examples()
88 // Add files to exclude here
89 excludedFiles << "doc/src/snippets/declarative/listmodel.qml"; //Just a ListModel, no root QQuickItem
91 // Add directories you want excluded here
92 excludedDirs << "examples/declarative/text/fonts"; // QTBUG-21415
93 excludedDirs << "doc/src/snippets/declarative/path"; //No root QQuickItem
95 // Not run in QQuickView
96 excludedDirs << "examples/declarative/qtquick1";
98 // These snippets are not expected to run on their own.
99 excludedDirs << "doc/src/snippets/declarative/visualdatamodel_rootindex";
100 excludedDirs << "doc/src/snippets/declarative/qtbinding";
101 excludedDirs << "doc/src/snippets/declarative/imports";
102 excludedDirs << "doc/src/snippets/qtquick1/visualdatamodel_rootindex";
103 excludedDirs << "doc/src/snippets/qtquick1/qtbinding";
104 excludedDirs << "doc/src/snippets/qtquick1/imports";
107 excludedDirs << "examples/declarative/modelviews/webview";
108 excludedDirs << "examples/declarative/webbrowser";
109 excludedDirs << "doc/src/snippets/declarative/webview";
110 excludedDirs << "doc/src/snippets/qtquick1/webview";
113 #ifdef QT_NO_XMLPATTERNS
114 excludedDirs << "examples/declarative/xml/xmldata";
115 excludedDirs << "examples/declarative/twitter";
116 excludedDirs << "examples/declarative/flickr";
117 excludedDirs << "examples/declarative/photoviewer";
121 void tst_examples::init()
123 if (!qstrcmp(QTest::currentTestFunction(), "sgsnippets"))
124 testlibMsgHandler = qInstallMsgHandler(msgHandlerFilter);
127 void tst_examples::cleanup()
129 if (!qstrcmp(QTest::currentTestFunction(), "sgsnippets"))
130 qInstallMsgHandler(testlibMsgHandler);
134 This tests that the examples follow the naming convention required
135 to have them tested by the examples() test.
137 void tst_examples::namingConvention(const QDir &d)
139 for (int ii = 0; ii < excludedDirs.count(); ++ii) {
140 QString s = excludedDirs.at(ii);
141 if (d.absolutePath().endsWith(s))
145 QStringList files = d.entryList(QStringList() << QLatin1String("*.qml"),
148 bool seenQml = !files.isEmpty();
149 bool seenLowercase = false;
151 foreach (const QString &file, files) {
152 if (file.at(0).isLower())
153 seenLowercase = true;
157 QStringList dirs = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot |
159 foreach (const QString &dir, dirs) {
162 namingConvention(sub);
164 } else if(!seenLowercase) {
165 QFAIL(qPrintable(QString(
166 "Directory %1 violates naming convention; expected at least one qml file "
167 "starting with lower case, got: %2"
168 ).arg(d.absolutePath()).arg(files.join(","))));
172 void tst_examples::namingConvention()
174 QString examples = QLibraryInfo::location(QLibraryInfo::ExamplesPath);
176 namingConvention(QDir(examples));
179 QStringList tst_examples::findQmlFiles(const QDir &d)
181 for (int ii = 0; ii < excludedDirs.count(); ++ii) {
182 QString s = excludedDirs.at(ii);
183 if (d.absolutePath().endsWith(s))
184 return QStringList();
189 QStringList cppfiles = d.entryList(QStringList() << QLatin1String("*.cpp"), QDir::Files);
190 if (cppfiles.isEmpty()) {
191 QStringList files = d.entryList(QStringList() << QLatin1String("*.qml"),
193 foreach (const QString &file, files) {
194 if (file.at(0).isLower()) {
195 bool superContinue = false;
196 for (int ii = 0; ii < excludedFiles.count(); ++ii) {
197 QString e = excludedFiles.at(ii);
198 if (d.absoluteFilePath(file).endsWith(e)) {
199 superContinue = true;
205 rv << d.absoluteFilePath(file);
211 QStringList dirs = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot |
213 foreach (const QString &dir, dirs) {
216 rv << findQmlFiles(sub);
223 This test runs all the examples in the declarative UI source tree and ensures
224 that they start and exit cleanly.
226 Examples are any .qml files under the examples/ directory that start
227 with a lower case letter.
229 void tst_examples::sgexamples_data()
231 QTest::addColumn<QString>("file");
233 QString examples = QLatin1String(SRCDIR) + "/../../../../examples/declarative/";
234 QString tutorials = QLatin1String(SRCDIR) + "/../../../../examples/tutorials/"; //Only declarative tutorials since modularization
237 files << findQmlFiles(QDir(examples));
238 files << findQmlFiles(QDir(tutorials));
240 foreach (const QString &file, files)
241 QTest::newRow(qPrintable(file)) << file;
244 void tst_examples::sgexamples()
246 QFETCH(QString, file);
248 QDeclarativeComponent component(&engine, QUrl::fromLocalFile(file));
249 if (component.status() == QDeclarativeComponent::Error)
250 qWarning() << component.errors();
251 QCOMPARE(component.status(), QDeclarativeComponent::Ready);
253 QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
254 QQuickItem *root = qobject_cast<QQuickItem *>(object.data());
256 component.completeCreate();
260 root->setParentItem(canvas.rootItem());
261 component.completeCreate();
264 QTest::qWaitForWindowShown(&canvas);
268 void tst_examples::sgsnippets_data()
270 QTest::addColumn<QString>("file");
272 QString snippets = QLatin1String(SRCDIR) + "/../../../../doc/src/snippets/declarative";
275 files << findQmlFiles(QDir(snippets));
277 foreach (const QString &file, files)
278 QTest::newRow(qPrintable(file)) << file;
281 void tst_examples::sgsnippets()
283 QFETCH(QString, file);
285 QDeclarativeComponent component(&engine, QUrl::fromLocalFile(file));
286 if (component.status() == QDeclarativeComponent::Error)
287 qWarning() << component.errors();
288 QCOMPARE(component.status(), QDeclarativeComponent::Ready);
290 QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
291 QQuickItem *root = qobject_cast<QQuickItem *>(object.data());
293 component.completeCreate();
297 root->setParentItem(canvas.rootItem());
298 component.completeCreate();
301 QTest::qWaitForWindowShown(&canvas);
305 QTEST_MAIN(tst_examples)
307 #include "tst_examples.moc"