1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
43 #include <QtDeclarative/qdeclarativeengine.h>
44 #include <QtDeclarative/qdeclarativecomponent.h>
47 #include "../shared/testhttpserver.h"
48 #include "../../../shared/util.h"
50 #define SERVER_ADDR "http://127.0.0.1:14450"
51 #define SERVER_PORT 14450
54 class tst_qdeclarativemoduleplugin : public QObject
58 tst_qdeclarativemoduleplugin()
64 void importsPlugin2();
65 void importsPlugin21();
66 void importsMixedQmlCppPlugin();
67 void incorrectPluginCase();
68 void importPluginWithQmlFile();
69 void remoteImportWithQuotedUrl();
70 void remoteImportWithUnquotedUri();
71 void versionNotInstalled();
72 void versionNotInstalled_data();
76 // In Symbian OS test data is located in applications private dir
80 #define VERIFY_ERRORS(errorfile) \
82 if (qgetenv("DEBUG") != "" && !component.errors().isEmpty()) \
83 qWarning() << "Unexpected Errors:" << component.errors(); \
84 QVERIFY(!component.isError()); \
85 QVERIFY(component.errors().isEmpty()); \
87 QFile file(QLatin1String("data/") + QLatin1String(errorfile)); \
88 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); \
89 QByteArray data = file.readAll(); \
91 QList<QByteArray> expected = data.split('\n'); \
92 expected.removeAll(QByteArray("")); \
93 QList<QDeclarativeError> errors = component.errors(); \
94 QList<QByteArray> actual; \
95 for (int ii = 0; ii < errors.count(); ++ii) { \
96 const QDeclarativeError &error = errors.at(ii); \
97 QByteArray errorStr = QByteArray::number(error.line()) + ":" + \
98 QByteArray::number(error.column()) + ":" + \
99 error.description().toUtf8(); \
100 actual << errorStr; \
102 if (qgetenv("DEBUG") != "" && expected != actual) \
103 qWarning() << "Expected:" << expected << "Actual:" << actual; \
104 if (qgetenv("QDECLARATIVELANGUAGE_UPDATEERRORS") != "" && expected != actual) {\
105 QFile file(QLatin1String("data/") + QLatin1String(errorfile)); \
106 QVERIFY(file.open(QIODevice::WriteOnly)); \
107 for (int ii = 0; ii < actual.count(); ++ii) { \
108 file.write(actual.at(ii)); file.write("\n"); \
112 QCOMPARE(expected, actual); \
116 inline QUrl TEST_FILE(const QString &filename)
118 QFileInfo fileInfo(__FILE__);
119 return QUrl::fromLocalFile(fileInfo.absoluteDir().filePath(filename));
123 void tst_qdeclarativemoduleplugin::importsPlugin()
125 QDeclarativeEngine engine;
126 engine.addImportPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports"));
127 QTest::ignoreMessage(QtWarningMsg, "plugin created");
128 QTest::ignoreMessage(QtWarningMsg, "import worked");
129 QDeclarativeComponent component(&engine, TEST_FILE("data/works.qml"));
130 foreach (QDeclarativeError err, component.errors())
133 QObject *object = component.create();
134 QVERIFY(object != 0);
135 QCOMPARE(object->property("value").toInt(),123);
139 void tst_qdeclarativemoduleplugin::importsPlugin2()
141 QDeclarativeEngine engine;
142 engine.addImportPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports"));
143 QTest::ignoreMessage(QtWarningMsg, "plugin2 created");
144 QTest::ignoreMessage(QtWarningMsg, "import2 worked");
145 QDeclarativeComponent component(&engine, TEST_FILE("data/works2.qml"));
146 foreach (QDeclarativeError err, component.errors())
149 QObject *object = component.create();
150 QVERIFY(object != 0);
151 QCOMPARE(object->property("value").toInt(),123);
155 void tst_qdeclarativemoduleplugin::importsPlugin21()
157 QDeclarativeEngine engine;
158 engine.addImportPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports"));
159 QTest::ignoreMessage(QtWarningMsg, "plugin2.1 created");
160 QTest::ignoreMessage(QtWarningMsg, "import2.1 worked");
161 QDeclarativeComponent component(&engine, TEST_FILE("data/works21.qml"));
162 foreach (QDeclarativeError err, component.errors())
165 QObject *object = component.create();
166 QVERIFY(object != 0);
167 QCOMPARE(object->property("value").toInt(),123);
171 void tst_qdeclarativemoduleplugin::incorrectPluginCase()
173 QDeclarativeEngine engine;
174 engine.addImportPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports"));
176 QDeclarativeComponent component(&engine, TEST_FILE("data/incorrectCase.qml"));
178 QList<QDeclarativeError> errors = component.errors();
179 QCOMPARE(errors.count(), 1);
181 #if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
182 #if defined(Q_OS_MAC)
183 QString libname = "libPluGin.dylib";
184 #elif defined(Q_OS_WIN32)
185 QString libname = "PluGin.dll";
187 QString expectedError = QLatin1String("plugin cannot be loaded for module \"com.nokia.WrongCase\": File name case mismatch for \"") + QFileInfo(__FILE__).absoluteDir().filePath("imports/com/nokia/WrongCase/" + libname) + QLatin1String("\"");
189 QString expectedError = QLatin1String("module \"com.nokia.WrongCase\" plugin \"PluGin\" not found");
192 QCOMPARE(errors.at(0).description(), expectedError);
195 void tst_qdeclarativemoduleplugin::importPluginWithQmlFile()
197 QString path = QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports");
199 // QTBUG-16885: adding an import path with a lower-case "c:" causes assert failure
200 // (this only happens if the plugin includes pure QML files)
202 QVERIFY(path.at(0).isUpper() && path.at(1) == QLatin1Char(':'));
203 path = path.at(0).toLower() + path.mid(1);
206 QDeclarativeEngine engine;
207 engine.addImportPath(path);
209 QDeclarativeComponent component(&engine, TEST_FILE("data/pluginWithQmlFile.qml"));
210 foreach (QDeclarativeError err, component.errors())
213 QObject *object = component.create();
214 QVERIFY(object != 0);
218 void tst_qdeclarativemoduleplugin::remoteImportWithQuotedUrl()
220 TestHTTPServer server(SERVER_PORT);
221 QVERIFY(server.isValid());
222 server.serveDirectory(SRCDIR "/imports");
224 QDeclarativeEngine engine;
225 QDeclarativeComponent component(&engine);
226 component.setData("import \"http://127.0.0.1:14450/com/nokia/PureQmlModule\" \nComponentA { width: 300; ComponentB{} }", QUrl());
228 QTRY_COMPARE(component.status(), QDeclarativeComponent::Ready);
229 QObject *object = component.create();
230 QCOMPARE(object->property("width").toInt(), 300);
231 QVERIFY(object != 0);
234 foreach (QDeclarativeError err, component.errors())
239 void tst_qdeclarativemoduleplugin::remoteImportWithUnquotedUri()
241 TestHTTPServer server(SERVER_PORT);
242 QVERIFY(server.isValid());
243 server.serveDirectory(SRCDIR "/imports");
245 QDeclarativeEngine engine;
246 engine.addImportPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports"));
247 QDeclarativeComponent component(&engine);
248 component.setData("import com.nokia.PureQmlModule 1.0 \nComponentA { width: 300; ComponentB{} }", QUrl());
251 QTRY_COMPARE(component.status(), QDeclarativeComponent::Ready);
252 QObject *object = component.create();
253 QVERIFY(object != 0);
254 QCOMPARE(object->property("width").toInt(), 300);
257 foreach (QDeclarativeError err, component.errors())
263 void tst_qdeclarativemoduleplugin::importsMixedQmlCppPlugin()
265 QDeclarativeEngine engine;
266 engine.addImportPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports"));
269 QDeclarativeComponent component(&engine, TEST_FILE("data/importsMixedQmlCppPlugin.qml"));
271 QObject *o = component.create();
273 QCOMPARE(o->property("test").toBool(), true);
278 QDeclarativeComponent component(&engine, TEST_FILE("data/importsMixedQmlCppPlugin.2.qml"));
280 QObject *o = component.create();
282 QCOMPARE(o->property("test").toBool(), true);
283 QCOMPARE(o->property("test2").toBool(), true);
290 void tst_qdeclarativemoduleplugin::versionNotInstalled_data()
292 QTest::addColumn<QString>("file");
293 QTest::addColumn<QString>("errorFile");
295 QTest::newRow("versionNotInstalled") << "data/versionNotInstalled.qml" << "versionNotInstalled.errors.txt";
296 QTest::newRow("versionNotInstalled") << "data/versionNotInstalled.2.qml" << "versionNotInstalled.2.errors.txt";
299 void tst_qdeclarativemoduleplugin::versionNotInstalled()
301 QFETCH(QString, file);
302 QFETCH(QString, errorFile);
304 QDeclarativeEngine engine;
305 engine.addImportPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports"));
307 QDeclarativeComponent component(&engine, TEST_FILE(file));
308 VERIFY_ERRORS(errorFile.toLatin1().constData());
311 QTEST_MAIN(tst_qdeclarativemoduleplugin)
313 #include "tst_qdeclarativemoduleplugin.moc"