1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
43 #include <QDeclarativeEngine>
44 #include <QDeclarativeContext>
45 #include <QNetworkAccessManager>
48 #include <QStandardPaths>
50 #include <QDeclarativeComponent>
51 #include <QDeclarativeNetworkAccessManagerFactory>
52 #include <QDeclarativeExpression>
54 class tst_qdeclarativeengine : public QObject
58 tst_qdeclarativeengine() {}
62 void networkAccessManager();
64 void contextForObject();
65 void offlineStoragePath();
66 void clearComponentCache();
67 void outputWarningsToStandardError();
68 void objectOwnership();
69 void multipleEngines();
72 void tst_qdeclarativeengine::rootContext()
74 QDeclarativeEngine engine;
76 QVERIFY(engine.rootContext());
78 QCOMPARE(engine.rootContext()->engine(), &engine);
79 QVERIFY(engine.rootContext()->parentContext() == 0);
82 class NetworkAccessManagerFactory : public QDeclarativeNetworkAccessManagerFactory
85 NetworkAccessManagerFactory() : manager(0) {}
87 QNetworkAccessManager *create(QObject *parent) {
88 manager = new QNetworkAccessManager(parent);
92 QNetworkAccessManager *manager;
95 void tst_qdeclarativeengine::networkAccessManager()
97 QDeclarativeEngine *engine = new QDeclarativeEngine;
99 // Test QDeclarativeEngine created manager
100 QPointer<QNetworkAccessManager> manager = engine->networkAccessManager();
101 QVERIFY(manager != 0);
104 // Test factory created manager
105 engine = new QDeclarativeEngine;
106 NetworkAccessManagerFactory factory;
107 engine->setNetworkAccessManagerFactory(&factory);
108 QVERIFY(engine->networkAccessManagerFactory() == &factory);
109 QVERIFY(engine->networkAccessManager() == factory.manager);
113 void tst_qdeclarativeengine::baseUrl()
115 QDeclarativeEngine engine;
117 QUrl cwd = QUrl::fromLocalFile(QDir::currentPath() + QDir::separator());
119 QCOMPARE(engine.baseUrl(), cwd);
120 QCOMPARE(engine.rootContext()->resolvedUrl(QUrl("main.qml")), cwd.resolved(QUrl("main.qml")));
122 QDir dir = QDir::current();
124 QVERIFY(dir != QDir::current());
125 QDir::setCurrent(dir.path());
126 QVERIFY(QDir::current() == dir);
128 QUrl cwd2 = QUrl::fromLocalFile(QDir::currentPath() + QDir::separator());
129 QCOMPARE(engine.baseUrl(), cwd2);
130 QCOMPARE(engine.rootContext()->resolvedUrl(QUrl("main.qml")), cwd2.resolved(QUrl("main.qml")));
132 engine.setBaseUrl(cwd);
133 QCOMPARE(engine.baseUrl(), cwd);
134 QCOMPARE(engine.rootContext()->resolvedUrl(QUrl("main.qml")), cwd.resolved(QUrl("main.qml")));
137 void tst_qdeclarativeengine::contextForObject()
139 QDeclarativeEngine *engine = new QDeclarativeEngine;
142 QVERIFY(QDeclarativeEngine::contextForObject(0) == 0);
144 // Test an object with no context
146 QVERIFY(QDeclarativeEngine::contextForObject(&object) == 0);
148 // Test setting null-object
149 QDeclarativeEngine::setContextForObject(0, engine->rootContext());
151 // Test setting null-context
152 QDeclarativeEngine::setContextForObject(&object, 0);
154 // Test setting context
155 QDeclarativeEngine::setContextForObject(&object, engine->rootContext());
156 QVERIFY(QDeclarativeEngine::contextForObject(&object) == engine->rootContext());
158 QDeclarativeContext context(engine->rootContext());
160 // Try changing context
161 QTest::ignoreMessage(QtWarningMsg, "QDeclarativeEngine::setContextForObject(): Object already has a QDeclarativeContext");
162 QDeclarativeEngine::setContextForObject(&object, &context);
163 QVERIFY(QDeclarativeEngine::contextForObject(&object) == engine->rootContext());
166 delete engine; engine = 0;
167 QVERIFY(QDeclarativeEngine::contextForObject(&object) == 0);
170 void tst_qdeclarativeengine::offlineStoragePath()
172 // Without these set, QDesktopServices::storageLocation returns
173 // strings with extra "//" at the end. We set them to ignore this problem.
174 qApp->setApplicationName("tst_qdeclarativeengine");
175 qApp->setOrganizationName("Nokia");
176 qApp->setOrganizationDomain("nokia.com");
178 QDeclarativeEngine engine;
180 QDir dir(QStandardPaths::writableLocation(QStandardPaths::DataLocation));
183 dir.mkpath("OfflineStorage");
184 dir.cd("OfflineStorage");
186 QCOMPARE(QDir::fromNativeSeparators(engine.offlineStoragePath()), dir.path());
188 engine.setOfflineStoragePath(QDir::homePath());
189 QCOMPARE(engine.offlineStoragePath(), QDir::homePath());
192 void tst_qdeclarativeengine::clearComponentCache()
194 QDeclarativeEngine engine;
196 // Create original qml file
198 QFile file("temp.qml");
199 QVERIFY(file.open(QIODevice::WriteOnly));
200 file.write("import QtQuick 1.0\nQtObject {\nproperty int test: 10\n}\n");
204 // Test "test" property
206 QDeclarativeComponent component(&engine, "temp.qml");
207 QObject *obj = component.create();
209 QCOMPARE(obj->property("test").toInt(), 10);
215 QFile file("temp.qml");
216 QVERIFY(file.open(QIODevice::WriteOnly));
217 file.write("import QtQuick 1.0\nQtObject {\nproperty int test: 11\n}\n");
223 QDeclarativeComponent component(&engine, "temp.qml");
224 QObject *obj = component.create();
226 QCOMPARE(obj->property("test").toInt(), 10);
231 engine.clearComponentCache();
233 // Test cache refresh
235 QDeclarativeComponent component(&engine, "temp.qml");
236 QObject *obj = component.create();
238 QCOMPARE(obj->property("test").toInt(), 11);
243 static QStringList warnings;
244 static void msgHandler(QtMsgType, const char *warning)
246 warnings << QString::fromUtf8(warning);
249 void tst_qdeclarativeengine::outputWarningsToStandardError()
251 QDeclarativeEngine engine;
253 QCOMPARE(engine.outputWarningsToStandardError(), true);
255 QDeclarativeComponent c(&engine);
256 c.setData("import QtQuick 1.0; QtObject { property int a: undefined }", QUrl());
258 QVERIFY(c.isReady() == true);
261 QtMsgHandler old = qInstallMsgHandler(msgHandler);
263 QObject *o = c.create();
265 qInstallMsgHandler(old);
270 QCOMPARE(warnings.count(), 1);
271 QCOMPARE(warnings.at(0), QLatin1String("<Unknown File>:1: Unable to assign [undefined] to int"));
275 engine.setOutputWarningsToStandardError(false);
276 QCOMPARE(engine.outputWarningsToStandardError(), false);
279 old = qInstallMsgHandler(msgHandler);
283 qInstallMsgHandler(old);
288 QCOMPARE(warnings.count(), 0);
291 void tst_qdeclarativeengine::objectOwnership()
294 QCOMPARE(QDeclarativeEngine::objectOwnership(0), QDeclarativeEngine::CppOwnership);
295 QDeclarativeEngine::setObjectOwnership(0, QDeclarativeEngine::JavaScriptOwnership);
296 QCOMPARE(QDeclarativeEngine::objectOwnership(0), QDeclarativeEngine::CppOwnership);
301 QCOMPARE(QDeclarativeEngine::objectOwnership(&o), QDeclarativeEngine::CppOwnership);
302 QDeclarativeEngine::setObjectOwnership(&o, QDeclarativeEngine::CppOwnership);
303 QCOMPARE(QDeclarativeEngine::objectOwnership(&o), QDeclarativeEngine::CppOwnership);
304 QDeclarativeEngine::setObjectOwnership(&o, QDeclarativeEngine::JavaScriptOwnership);
305 QCOMPARE(QDeclarativeEngine::objectOwnership(&o), QDeclarativeEngine::JavaScriptOwnership);
306 QDeclarativeEngine::setObjectOwnership(&o, QDeclarativeEngine::CppOwnership);
307 QCOMPARE(QDeclarativeEngine::objectOwnership(&o), QDeclarativeEngine::CppOwnership);
311 QDeclarativeEngine engine;
312 QDeclarativeComponent c(&engine);
313 c.setData("import QtQuick 1.0; QtObject { property QtObject object: QtObject {} }", QUrl());
315 QObject *o = c.create();
318 QCOMPARE(QDeclarativeEngine::objectOwnership(o), QDeclarativeEngine::CppOwnership);
320 QObject *o2 = qvariant_cast<QObject *>(o->property("object"));
321 QCOMPARE(QDeclarativeEngine::objectOwnership(o2), QDeclarativeEngine::JavaScriptOwnership);
328 // Test an object can be accessed by multiple engines
329 void tst_qdeclarativeengine::multipleEngines()
332 o.setObjectName("TestName");
334 // Simultaneous engines
336 QDeclarativeEngine engine1;
337 QDeclarativeEngine engine2;
338 engine1.rootContext()->setContextProperty("object", &o);
339 engine2.rootContext()->setContextProperty("object", &o);
341 QDeclarativeExpression expr1(engine1.rootContext(), 0, QString("object.objectName"));
342 QDeclarativeExpression expr2(engine2.rootContext(), 0, QString("object.objectName"));
344 QCOMPARE(expr1.evaluate().toString(), QString("TestName"));
345 QCOMPARE(expr2.evaluate().toString(), QString("TestName"));
350 QDeclarativeEngine engine1;
351 engine1.rootContext()->setContextProperty("object", &o);
352 QDeclarativeExpression expr1(engine1.rootContext(), 0, QString("object.objectName"));
353 QCOMPARE(expr1.evaluate().toString(), QString("TestName"));
356 QDeclarativeEngine engine1;
357 engine1.rootContext()->setContextProperty("object", &o);
358 QDeclarativeExpression expr1(engine1.rootContext(), 0, QString("object.objectName"));
359 QCOMPARE(expr1.evaluate().toString(), QString("TestName"));
363 QTEST_MAIN(tst_qdeclarativeengine)
365 #include "tst_qdeclarativeengine.moc"