Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / tests / auto / declarative / qdeclarativeconnection / tst_qdeclarativeconnection.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
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.
16 **
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.
20 **
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.
28 **
29 ** Other Usage
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.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #include <qtest.h>
42 #include <QtDeclarative/qdeclarativeengine.h>
43 #include <QtDeclarative/qdeclarativecomponent.h>
44 #include <private/qdeclarativeconnections_p.h>
45 #include <private/qquickitem_p.h>
46 #include "../../shared/util.h"
47 #include <QtDeclarative/qdeclarativescriptstring.h>
48
49 class tst_qdeclarativeconnection : public QDeclarativeDataTest
50 {
51     Q_OBJECT
52 public:
53     tst_qdeclarativeconnection();
54
55 private slots:
56     void defaultValues();
57     void properties();
58     void connection();
59     void trimming();
60     void targetChanged();
61     void unknownSignals_data();
62     void unknownSignals();
63     void errors_data();
64     void errors();
65     void moduleApiTarget();
66
67 private:
68     QDeclarativeEngine engine;
69 };
70
71 tst_qdeclarativeconnection::tst_qdeclarativeconnection()
72 {
73 }
74
75 void tst_qdeclarativeconnection::defaultValues()
76 {
77     QDeclarativeEngine engine;
78     QDeclarativeComponent c(&engine, testFileUrl("test-connection3.qml"));
79     QDeclarativeConnections *item = qobject_cast<QDeclarativeConnections*>(c.create());
80
81     QVERIFY(item != 0);
82     QVERIFY(item->target() == 0);
83
84     delete item;
85 }
86
87 void tst_qdeclarativeconnection::properties()
88 {
89     QDeclarativeEngine engine;
90     QDeclarativeComponent c(&engine, testFileUrl("test-connection2.qml"));
91     QDeclarativeConnections *item = qobject_cast<QDeclarativeConnections*>(c.create());
92
93     QVERIFY(item != 0);
94
95     QVERIFY(item != 0);
96     QVERIFY(item->target() == item);
97
98     delete item;
99 }
100
101 void tst_qdeclarativeconnection::connection()
102 {
103     QDeclarativeEngine engine;
104     QDeclarativeComponent c(&engine, testFileUrl("test-connection.qml"));
105     QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
106
107     QVERIFY(item != 0);
108
109     QCOMPARE(item->property("tested").toBool(), false);
110     QCOMPARE(item->width(), 50.);
111     emit item->setWidth(100.);
112     QCOMPARE(item->width(), 100.);
113     QCOMPARE(item->property("tested").toBool(), true);
114
115     delete item;
116 }
117
118 void tst_qdeclarativeconnection::trimming()
119 {
120     QDeclarativeEngine engine;
121     QDeclarativeComponent c(&engine, testFileUrl("trimming.qml"));
122     QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
123
124     QVERIFY(item != 0);
125
126     QCOMPARE(item->property("tested").toString(), QString(""));
127     int index = item->metaObject()->indexOfSignal("testMe(int,QString)");
128     QMetaMethod method = item->metaObject()->method(index);
129     method.invoke(item,
130                   Qt::DirectConnection,
131                   Q_ARG(int, 5),
132                   Q_ARG(QString, "worked"));
133     QCOMPARE(item->property("tested").toString(), QString("worked5"));
134
135     delete item;
136 }
137
138 // Confirm that target can be changed by one of our signal handlers
139 void tst_qdeclarativeconnection::targetChanged()
140 {
141     QDeclarativeEngine engine;
142     QDeclarativeComponent c(&engine, testFileUrl("connection-targetchange.qml"));
143     QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
144     QVERIFY(item != 0);
145
146     QDeclarativeConnections *connections = item->findChild<QDeclarativeConnections*>("connections");
147     QVERIFY(connections);
148
149     QQuickItem *item1 = item->findChild<QQuickItem*>("item1");
150     QVERIFY(item1);
151
152     item1->setWidth(200);
153
154     QQuickItem *item2 = item->findChild<QQuickItem*>("item2");
155     QVERIFY(item2);
156     QVERIFY(connections->target() == item2);
157
158     // If we don't crash then we're OK
159
160     delete item;
161 }
162
163 void tst_qdeclarativeconnection::unknownSignals_data()
164 {
165     QTest::addColumn<QString>("file");
166     QTest::addColumn<QString>("error");
167
168     QTest::newRow("basic") << "connection-unknownsignals.qml" << ":6:5: QML Connections: Cannot assign to non-existent property \"onFooBar\"";
169     QTest::newRow("parent") << "connection-unknownsignals-parent.qml" << ":6:5: QML Connections: Cannot assign to non-existent property \"onFooBar\"";
170     QTest::newRow("ignored") << "connection-unknownsignals-ignored.qml" << ""; // should be NO error
171     QTest::newRow("notarget") << "connection-unknownsignals-notarget.qml" << ""; // should be NO error
172 }
173
174 void tst_qdeclarativeconnection::unknownSignals()
175 {
176     QFETCH(QString, file);
177     QFETCH(QString, error);
178
179     QUrl url = testFileUrl(file);
180     if (!error.isEmpty()) {
181         QTest::ignoreMessage(QtWarningMsg, (url.toString() + error).toLatin1());
182     } else {
183         // QTest has no way to insist no message (i.e. fail)
184     }
185
186     QDeclarativeEngine engine;
187     QDeclarativeComponent c(&engine, url);
188     QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
189     QVERIFY(item != 0);
190
191     // check that connection is created (they are all runtime errors)
192     QDeclarativeConnections *connections = item->findChild<QDeclarativeConnections*>("connections");
193     QVERIFY(connections);
194
195     if (file == "connection-unknownsignals-ignored.qml")
196         QVERIFY(connections->ignoreUnknownSignals());
197
198     delete item;
199 }
200
201 void tst_qdeclarativeconnection::errors_data()
202 {
203     QTest::addColumn<QString>("file");
204     QTest::addColumn<QString>("error");
205
206     QTest::newRow("no \"on\"") << "error-property.qml" << "Cannot assign to non-existent property \"fakeProperty\"";
207     QTest::newRow("3rd letter lowercase") << "error-property2.qml" << "Cannot assign to non-existent property \"onfakeProperty\"";
208     QTest::newRow("child object") << "error-object.qml" << "Connections: nested objects not allowed";
209     QTest::newRow("grouped object") << "error-syntax.qml" << "Connections: syntax error";
210 }
211
212 void tst_qdeclarativeconnection::errors()
213 {
214     QFETCH(QString, file);
215     QFETCH(QString, error);
216
217     QUrl url = testFileUrl(file);
218
219     QDeclarativeEngine engine;
220     QDeclarativeComponent c(&engine, url);
221     QVERIFY(c.isError() == true);
222     QList<QDeclarativeError> errors = c.errors();
223     QVERIFY(errors.count() == 1);
224     QCOMPARE(errors.at(0).description(), error);
225 }
226
227
228 class MyTestModuleApi : public QObject
229 {
230 Q_OBJECT
231 Q_PROPERTY(int intProp READ intProp WRITE setIntProp NOTIFY intPropChanged)
232
233 public:
234     MyTestModuleApi(QObject *parent = 0) : QObject(parent), m_intProp(0), m_changeCount(0) {}
235     ~MyTestModuleApi() {}
236
237     Q_INVOKABLE int otherMethod(int val) { return val + 4; }
238
239     int intProp() const { return m_intProp; }
240     void setIntProp(int val)
241     {
242         if (++m_changeCount % 3 == 0) emit otherSignal();
243         m_intProp = val; emit intPropChanged();
244     }
245
246 signals:
247     void intPropChanged();
248     void otherSignal();
249
250 private:
251     int m_intProp;
252     int m_changeCount;
253 };
254
255 static QObject *module_api_factory(QDeclarativeEngine *engine, QJSEngine *scriptEngine)
256 {
257    Q_UNUSED(engine)
258    Q_UNUSED(scriptEngine)
259    MyTestModuleApi *api = new MyTestModuleApi();
260    return api;
261 }
262
263 // QTBUG-20937
264 void tst_qdeclarativeconnection::moduleApiTarget()
265 {
266     qmlRegisterModuleApi("MyTestModuleApi", 1, 0, module_api_factory);
267     QDeclarativeComponent component(&engine, testFileUrl("moduleapi-target.qml"));
268     QObject *object = component.create();
269     QVERIFY(object != 0);
270
271     QCOMPARE(object->property("moduleIntPropChangedCount").toInt(), 0);
272     QCOMPARE(object->property("moduleOtherSignalCount").toInt(), 0);
273
274     QMetaObject::invokeMethod(object, "setModuleIntProp");
275     QCOMPARE(object->property("moduleIntPropChangedCount").toInt(), 1);
276     QCOMPARE(object->property("moduleOtherSignalCount").toInt(), 0);
277
278     QMetaObject::invokeMethod(object, "setModuleIntProp");
279     QCOMPARE(object->property("moduleIntPropChangedCount").toInt(), 2);
280     QCOMPARE(object->property("moduleOtherSignalCount").toInt(), 0);
281
282     // the module API emits otherSignal every 3 times the int property changes.
283     QMetaObject::invokeMethod(object, "setModuleIntProp");
284     QCOMPARE(object->property("moduleIntPropChangedCount").toInt(), 3);
285     QCOMPARE(object->property("moduleOtherSignalCount").toInt(), 1);
286
287     delete object;
288 }
289
290 QTEST_MAIN(tst_qdeclarativeconnection)
291
292 #include "tst_qdeclarativeconnection.moc"