Allow QML URLs to contain pre-encoded octets
[profile/ivi/qtdeclarative.git] / tests / auto / declarative / qdeclarativeproperty / tst_qdeclarativeproperty.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the test suite of the Qt Toolkit.
8 **
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.
17 **
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.
21 **
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.
29 **
30 ** Other Usage
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.
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 <QtDeclarative/qdeclarativeproperty.h>
45 #include <QtDeclarative/private/qdeclarativeproperty_p.h>
46 #include <private/qdeclarativebinding_p.h>
47 #include <QtWidgets/QLineEdit>
48 #include <QtCore/qfileinfo.h>
49 #include <QtCore/qdir.h>
50 #include "../../shared/util.h"
51
52 #include <QDebug>
53 class MyQmlObject : public QObject
54 {
55     Q_OBJECT
56 public:
57     MyQmlObject() {}
58 };
59
60 QML_DECLARE_TYPE(MyQmlObject);
61
62 class MyAttached : public QObject
63 {
64     Q_OBJECT
65     Q_PROPERTY(int foo READ foo WRITE setFoo)
66 public:
67     MyAttached(QObject *parent) : QObject(parent), m_foo(13) {}
68
69     int foo() const { return m_foo; }
70     void setFoo(int f) { m_foo = f; }
71
72 private:
73     int m_foo;
74 };
75
76 class MyContainer : public QObject
77 {
78     Q_OBJECT
79     Q_PROPERTY(QDeclarativeListProperty<MyQmlObject> children READ children)
80 public:
81     MyContainer() {}
82
83     QDeclarativeListProperty<MyQmlObject> children() { return QDeclarativeListProperty<MyQmlObject>(this, m_children); }
84
85     static MyAttached *qmlAttachedProperties(QObject *o) {
86         return new MyAttached(o);
87     }
88
89 private:
90     QList<MyQmlObject*> m_children;
91 };
92
93 QML_DECLARE_TYPE(MyContainer);
94 QML_DECLARE_TYPEINFO(MyContainer, QML_HAS_ATTACHED_PROPERTIES)
95
96 class tst_qdeclarativeproperty : public QDeclarativeDataTest
97 {
98     Q_OBJECT
99 public:
100     tst_qdeclarativeproperty() {}
101
102 private slots:
103     void initTestCase();
104
105     // Constructors
106     void qmlmetaproperty();
107     void qmlmetaproperty_object();
108     void qmlmetaproperty_object_string();
109     void qmlmetaproperty_object_context();
110     void qmlmetaproperty_object_string_context();
111
112     // Methods
113     void name();
114     void read();
115     void write();
116     void reset();
117
118     // Functionality
119     void writeObjectToList();
120     void writeListToList();
121
122     //writeToReadOnly();
123
124     void urlHandling_data();
125     void urlHandling();
126
127     // Bugs
128     void crashOnValueProperty();
129     void aliasPropertyBindings();
130     void noContext();
131
132     void copy();
133 private:
134     QDeclarativeEngine engine;
135 };
136
137 void tst_qdeclarativeproperty::qmlmetaproperty()
138 {
139     QDeclarativeProperty prop;
140
141     QWeakPointer<QDeclarativeBinding> binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext()));
142     QVERIFY(binding != 0);
143     QWeakPointer<QDeclarativeExpression> expression(new QDeclarativeExpression());
144     QVERIFY(expression != 0);
145
146     QObject *obj = new QObject;
147
148     QCOMPARE(prop.name(), QString());
149     QCOMPARE(prop.read(), QVariant());
150     QCOMPARE(prop.write(QVariant()), false);
151     QCOMPARE(prop.hasNotifySignal(), false);
152     QCOMPARE(prop.needsNotifySignal(), false);
153     QCOMPARE(prop.connectNotifySignal(0, SLOT(deleteLater())), false);
154     QCOMPARE(prop.connectNotifySignal(obj, SLOT(deleteLater())), false);
155     QCOMPARE(prop.connectNotifySignal(obj, 0), false);
156     QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
157     QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
158     QCOMPARE(prop.connectNotifySignal(obj, -1), false);
159     QVERIFY(prop.method().signature() == 0);
160     QCOMPARE(prop.type(), QDeclarativeProperty::Invalid);
161     QCOMPARE(prop.isProperty(), false);
162     QCOMPARE(prop.isWritable(), false);
163     QCOMPARE(prop.isDesignable(), false);
164     QCOMPARE(prop.isResettable(), false);
165     QCOMPARE(prop.isSignalProperty(), false);
166     QCOMPARE(prop.isValid(), false);
167     QCOMPARE(prop.object(), (QObject *)0);
168     QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory);
169     QCOMPARE(prop.propertyType(), 0);
170     QCOMPARE(prop.propertyTypeName(), (const char *)0);
171     QVERIFY(prop.property().name() == 0);
172     QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0);
173     QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0);
174     QVERIFY(binding == 0);
175     QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0);
176     QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
177     QVERIFY(expression == 0);
178     QCOMPARE(prop.index(), -1);
179     QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1);
180
181     delete obj;
182 }
183
184 class PropertyObject : public QObject
185 {
186     Q_OBJECT
187     Q_PROPERTY(int defaultProperty READ defaultProperty)
188     Q_PROPERTY(QRect rectProperty READ rectProperty)
189     Q_PROPERTY(QRect wrectProperty READ wrectProperty WRITE setWRectProperty)
190     Q_PROPERTY(QUrl url READ url WRITE setUrl)
191     Q_PROPERTY(int resettableProperty READ resettableProperty WRITE setResettableProperty RESET resetProperty)
192     Q_PROPERTY(int propertyWithNotify READ propertyWithNotify WRITE setPropertyWithNotify NOTIFY oddlyNamedNotifySignal)
193     Q_PROPERTY(MyQmlObject *qmlObject READ qmlObject)
194
195     Q_CLASSINFO("DefaultProperty", "defaultProperty")
196 public:
197     PropertyObject() : m_resetProperty(9) {}
198
199     int defaultProperty() { return 10; }
200     QRect rectProperty() { return QRect(10, 10, 1, 209); }
201
202     QRect wrectProperty() { return m_rect; }
203     void setWRectProperty(const QRect &r) { m_rect = r; }
204
205     QUrl url() { return m_url; }
206     void setUrl(const QUrl &u) { m_url = u; }
207
208     int resettableProperty() const { return m_resetProperty; }
209     void setResettableProperty(int r) { m_resetProperty = r; }
210     void resetProperty() { m_resetProperty = 9; }
211
212     int propertyWithNotify() const { return m_propertyWithNotify; }
213     void setPropertyWithNotify(int i) { m_propertyWithNotify = i; emit oddlyNamedNotifySignal(); }
214
215     MyQmlObject *qmlObject() { return &m_qmlObject; }
216 signals:
217     void clicked();
218     void oddlyNamedNotifySignal();
219
220 private:
221     int m_resetProperty;
222     QRect m_rect;
223     QUrl m_url;
224     int m_propertyWithNotify;
225     MyQmlObject m_qmlObject;
226 };
227
228 QML_DECLARE_TYPE(PropertyObject);
229
230 void tst_qdeclarativeproperty::qmlmetaproperty_object()
231 {
232     QObject object; // Has no default property
233     PropertyObject dobject; // Has default property
234
235     {
236         QDeclarativeProperty prop(&object);
237
238         QWeakPointer<QDeclarativeBinding> binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext()));
239         QVERIFY(binding != 0);
240         QWeakPointer<QDeclarativeExpression> expression(new QDeclarativeExpression());
241         QVERIFY(expression != 0);
242
243         QObject *obj = new QObject;
244
245         QCOMPARE(prop.name(), QString());
246         QCOMPARE(prop.read(), QVariant());
247         QCOMPARE(prop.write(QVariant()), false);
248         QCOMPARE(prop.hasNotifySignal(), false);
249         QCOMPARE(prop.needsNotifySignal(), false);
250         QCOMPARE(prop.connectNotifySignal(0, SLOT(deleteLater())), false);
251         QCOMPARE(prop.connectNotifySignal(obj, SLOT(deleteLater())), false);
252         QCOMPARE(prop.connectNotifySignal(obj, 0), false);
253         QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
254         QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
255         QCOMPARE(prop.connectNotifySignal(obj, -1), false);
256         QVERIFY(prop.method().signature() == 0);
257         QCOMPARE(prop.type(), QDeclarativeProperty::Invalid);
258         QCOMPARE(prop.isProperty(), false);
259         QCOMPARE(prop.isWritable(), false);
260         QCOMPARE(prop.isDesignable(), false);
261         QCOMPARE(prop.isResettable(), false);
262         QCOMPARE(prop.isSignalProperty(), false);
263         QCOMPARE(prop.isValid(), false);
264         QCOMPARE(prop.object(), (QObject *)0);
265         QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory);
266         QCOMPARE(prop.propertyType(), 0);
267         QCOMPARE(prop.propertyTypeName(), (const char *)0);
268         QVERIFY(prop.property().name() == 0);
269         QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0);
270         QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0);
271         QVERIFY(binding == 0);
272         QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0);
273         QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
274         QVERIFY(expression == 0);
275         QCOMPARE(prop.index(), -1);
276         QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1);
277
278         delete obj;
279     }
280
281     {
282         QDeclarativeProperty prop(&dobject);
283
284         QWeakPointer<QDeclarativeBinding> binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext()));
285         binding.data()->setTarget(prop);
286         QVERIFY(binding != 0);
287         QWeakPointer<QDeclarativeExpression> expression(new QDeclarativeExpression());
288         QVERIFY(expression != 0);
289
290         QObject *obj = new QObject;
291
292         QCOMPARE(prop.name(), QString("defaultProperty"));
293         QCOMPARE(prop.read(), QVariant(10));
294         QCOMPARE(prop.write(QVariant()), false);
295         QCOMPARE(prop.hasNotifySignal(), false);
296         QCOMPARE(prop.needsNotifySignal(), true);
297         QCOMPARE(prop.connectNotifySignal(0, SLOT(deleteLater())), false);
298         QCOMPARE(prop.connectNotifySignal(obj, SLOT(deleteLater())), false);
299         QCOMPARE(prop.connectNotifySignal(obj, 0), false);
300         QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
301         QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
302         QCOMPARE(prop.connectNotifySignal(obj, -1), false);
303         QVERIFY(prop.method().signature() == 0);
304         QCOMPARE(prop.type(), QDeclarativeProperty::Property);
305         QCOMPARE(prop.isProperty(), true);
306         QCOMPARE(prop.isWritable(), false);
307         QCOMPARE(prop.isDesignable(), true);
308         QCOMPARE(prop.isResettable(), false);
309         QCOMPARE(prop.isSignalProperty(), false);
310         QCOMPARE(prop.isValid(), true);
311         QCOMPARE(prop.object(), qobject_cast<QObject*>(&dobject));
312         QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::Normal);
313         QCOMPARE(prop.propertyType(), (int)QVariant::Int);
314         QCOMPARE(prop.propertyTypeName(), "int");
315         QCOMPARE(QString(prop.property().name()), QString("defaultProperty"));
316         QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0);
317         QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: Unable to assign null to int");
318         QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0);
319         QVERIFY(binding != 0);
320         QVERIFY(QDeclarativePropertyPrivate::binding(prop) == binding.data());
321         QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0);
322         QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
323         QVERIFY(expression == 0);
324         QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty"));
325         QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1);
326
327         delete obj;
328     }
329 }
330
331 void tst_qdeclarativeproperty::qmlmetaproperty_object_string()
332 {
333     QObject object; 
334     PropertyObject dobject; 
335
336     {
337         QDeclarativeProperty prop(&object, QString("defaultProperty"));
338
339         QWeakPointer<QDeclarativeBinding> binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext()));
340         QVERIFY(binding != 0);
341         QWeakPointer<QDeclarativeExpression> expression(new QDeclarativeExpression());
342         QVERIFY(expression != 0);
343
344         QObject *obj = new QObject;
345
346         QCOMPARE(prop.name(), QString());
347         QCOMPARE(prop.read(), QVariant());
348         QCOMPARE(prop.write(QVariant()), false);
349         QCOMPARE(prop.hasNotifySignal(), false);
350         QCOMPARE(prop.needsNotifySignal(), false);
351         QCOMPARE(prop.connectNotifySignal(0, SLOT(deleteLater())), false);
352         QCOMPARE(prop.connectNotifySignal(obj, SLOT(deleteLater())), false);
353         QCOMPARE(prop.connectNotifySignal(obj, 0), false);
354         QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
355         QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
356         QCOMPARE(prop.connectNotifySignal(obj, -1), false);
357         QVERIFY(prop.method().signature() == 0);
358         QCOMPARE(prop.type(), QDeclarativeProperty::Invalid);
359         QCOMPARE(prop.isProperty(), false);
360         QCOMPARE(prop.isWritable(), false);
361         QCOMPARE(prop.isDesignable(), false);
362         QCOMPARE(prop.isResettable(), false);
363         QCOMPARE(prop.isSignalProperty(), false);
364         QCOMPARE(prop.isValid(), false);
365         QCOMPARE(prop.object(), (QObject *)0);
366         QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory);
367         QCOMPARE(prop.propertyType(), 0);
368         QCOMPARE(prop.propertyTypeName(), (const char *)0);
369         QVERIFY(prop.property().name() == 0);
370         QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0);
371         QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0);
372         QVERIFY(binding == 0);
373         QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0);
374         QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
375         QVERIFY(expression == 0);
376         QCOMPARE(prop.index(), -1);
377         QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1);
378
379         delete obj;
380     }
381
382     {
383         QDeclarativeProperty prop(&dobject, QString("defaultProperty"));
384
385         QWeakPointer<QDeclarativeBinding> binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext()));
386         binding.data()->setTarget(prop);
387         QVERIFY(binding != 0);
388         QWeakPointer<QDeclarativeExpression> expression(new QDeclarativeExpression());
389         QVERIFY(expression != 0);
390
391         QObject *obj = new QObject;
392
393         QCOMPARE(prop.name(), QString("defaultProperty"));
394         QCOMPARE(prop.read(), QVariant(10));
395         QCOMPARE(prop.write(QVariant()), false);
396         QCOMPARE(prop.hasNotifySignal(), false);
397         QCOMPARE(prop.needsNotifySignal(), true);
398         QCOMPARE(prop.connectNotifySignal(0, SLOT(deleteLater())), false);
399         QCOMPARE(prop.connectNotifySignal(obj, SLOT(deleteLater())), false);
400         QCOMPARE(prop.connectNotifySignal(obj, 0), false);
401         QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
402         QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
403         QCOMPARE(prop.connectNotifySignal(obj, -1), false);
404         QVERIFY(prop.method().signature() == 0);
405         QCOMPARE(prop.type(), QDeclarativeProperty::Property);
406         QCOMPARE(prop.isProperty(), true);
407         QCOMPARE(prop.isWritable(), false);
408         QCOMPARE(prop.isDesignable(), true);
409         QCOMPARE(prop.isResettable(), false);
410         QCOMPARE(prop.isSignalProperty(), false);
411         QCOMPARE(prop.isValid(), true);
412         QCOMPARE(prop.object(), qobject_cast<QObject*>(&dobject));
413         QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::Normal);
414         QCOMPARE(prop.propertyType(), (int)QVariant::Int);
415         QCOMPARE(prop.propertyTypeName(), "int");
416         QCOMPARE(QString(prop.property().name()), QString("defaultProperty"));
417         QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0);
418         QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: Unable to assign null to int");
419         QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0);
420         QVERIFY(binding != 0);
421         QVERIFY(QDeclarativePropertyPrivate::binding(prop) == binding.data());
422         QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0);
423         QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
424         QVERIFY(expression == 0);
425         QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty"));
426         QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1);
427
428         delete obj;
429     }
430
431     {
432         QDeclarativeProperty prop(&dobject, QString("onClicked"));
433
434         QWeakPointer<QDeclarativeBinding> binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext()));
435         binding.data()->setTarget(prop);
436         QVERIFY(binding != 0);
437         QWeakPointer<QDeclarativeExpression> expression(new QDeclarativeExpression());
438         QVERIFY(expression != 0);
439
440         QObject *obj = new QObject;
441
442         QCOMPARE(prop.name(), QString("onClicked"));
443         QCOMPARE(prop.read(), QVariant());
444         QCOMPARE(prop.write(QVariant("Hello")), false);
445         QCOMPARE(prop.hasNotifySignal(), false);
446         QCOMPARE(prop.needsNotifySignal(), false);
447         QCOMPARE(prop.connectNotifySignal(0, SLOT(deleteLater())), false);
448         QCOMPARE(prop.connectNotifySignal(obj, SLOT(deleteLater())), false);
449         QCOMPARE(prop.connectNotifySignal(obj, 0), false);
450         QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
451         QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
452         QCOMPARE(prop.connectNotifySignal(obj, -1), false);
453         QCOMPARE(QString(prop.method().signature()), QString("clicked()"));
454         QCOMPARE(prop.type(), QDeclarativeProperty::SignalProperty);
455         QCOMPARE(prop.isProperty(), false);
456         QCOMPARE(prop.isWritable(), false);
457         QCOMPARE(prop.isDesignable(), false);
458         QCOMPARE(prop.isResettable(), false);
459         QCOMPARE(prop.isSignalProperty(), true);
460         QCOMPARE(prop.isValid(), true);
461         QCOMPARE(prop.object(), qobject_cast<QObject*>(&dobject));
462         QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory);
463         QCOMPARE(prop.propertyType(), 0);
464         QCOMPARE(prop.propertyTypeName(), (const char *)0);
465         QCOMPARE(prop.property().name(), (const char *)0);
466         QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0);
467         QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0);
468         QVERIFY(binding == 0);
469         QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0);
470         QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
471         QVERIFY(expression != 0);
472         QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == expression.data());
473         QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("clicked()"));
474         QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1);
475
476         delete obj;
477     }
478
479     {
480         QDeclarativeProperty prop(&dobject, QString("onPropertyWithNotifyChanged"));
481
482         QWeakPointer<QDeclarativeBinding> binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext()));
483         binding.data()->setTarget(prop);
484         QVERIFY(binding != 0);
485         QWeakPointer<QDeclarativeExpression> expression(new QDeclarativeExpression());
486         QVERIFY(expression != 0);
487
488         QObject *obj = new QObject;
489
490         QCOMPARE(prop.name(), QString("onOddlyNamedNotifySignal"));
491         QCOMPARE(prop.read(), QVariant());
492         QCOMPARE(prop.write(QVariant("Hello")), false);
493         QCOMPARE(prop.hasNotifySignal(), false);
494         QCOMPARE(prop.needsNotifySignal(), false);
495         QCOMPARE(prop.connectNotifySignal(0, SLOT(deleteLater())), false);
496         QCOMPARE(prop.connectNotifySignal(obj, SLOT(deleteLater())), false);
497         QCOMPARE(prop.connectNotifySignal(obj, 0), false);
498         QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
499         QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
500         QCOMPARE(prop.connectNotifySignal(obj, -1), false);
501         QCOMPARE(QString(prop.method().signature()), QString("oddlyNamedNotifySignal()"));
502         QCOMPARE(prop.type(), QDeclarativeProperty::SignalProperty);
503         QCOMPARE(prop.isProperty(), false);
504         QCOMPARE(prop.isWritable(), false);
505         QCOMPARE(prop.isDesignable(), false);
506         QCOMPARE(prop.isResettable(), false);
507         QCOMPARE(prop.isSignalProperty(), true);
508         QCOMPARE(prop.isValid(), true);
509         QCOMPARE(prop.object(), qobject_cast<QObject*>(&dobject));
510         QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory);
511         QCOMPARE(prop.propertyType(), 0);
512         QCOMPARE(prop.propertyTypeName(), (const char *)0);
513         QCOMPARE(prop.property().name(), (const char *)0);
514         QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0);
515         QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0);
516         QVERIFY(binding == 0);
517         QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0);
518         QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
519         QVERIFY(expression != 0);
520         QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == expression.data());
521         QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("oddlyNamedNotifySignal()"));
522         QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1);
523
524         delete obj;
525     }
526 }
527
528 void tst_qdeclarativeproperty::qmlmetaproperty_object_context()
529 {
530     QObject object; // Has no default property
531     PropertyObject dobject; // Has default property
532
533     {
534         QDeclarativeProperty prop(&object, engine.rootContext());
535
536         QWeakPointer<QDeclarativeBinding> binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext()));
537         QVERIFY(binding != 0);
538         QWeakPointer<QDeclarativeExpression> expression(new QDeclarativeExpression());
539         QVERIFY(expression != 0);
540
541         QObject *obj = new QObject;
542
543         QCOMPARE(prop.name(), QString());
544         QCOMPARE(prop.read(), QVariant());
545         QCOMPARE(prop.write(QVariant()), false);
546         QCOMPARE(prop.hasNotifySignal(), false);
547         QCOMPARE(prop.needsNotifySignal(), false);
548         QCOMPARE(prop.connectNotifySignal(0, SLOT(deleteLater())), false);
549         QCOMPARE(prop.connectNotifySignal(obj, SLOT(deleteLater())), false);
550         QCOMPARE(prop.connectNotifySignal(obj, 0), false);
551         QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
552         QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
553         QCOMPARE(prop.connectNotifySignal(obj, -1), false);
554         QVERIFY(prop.method().signature() == 0);
555         QCOMPARE(prop.type(), QDeclarativeProperty::Invalid);
556         QCOMPARE(prop.isProperty(), false);
557         QCOMPARE(prop.isWritable(), false);
558         QCOMPARE(prop.isDesignable(), false);
559         QCOMPARE(prop.isResettable(), false);
560         QCOMPARE(prop.isSignalProperty(), false);
561         QCOMPARE(prop.isValid(), false);
562         QCOMPARE(prop.object(), (QObject *)0);
563         QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory);
564         QCOMPARE(prop.propertyType(), 0);
565         QCOMPARE(prop.propertyTypeName(), (const char *)0);
566         QVERIFY(prop.property().name() == 0);
567         QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0);
568         QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0);
569         QVERIFY(binding == 0);
570         QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0);
571         QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
572         QVERIFY(expression == 0);
573         QCOMPARE(prop.index(), -1);
574         QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1);
575
576         delete obj;
577     }
578
579     {
580         QDeclarativeProperty prop(&dobject, engine.rootContext());
581
582         QWeakPointer<QDeclarativeBinding> binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext()));
583         binding.data()->setTarget(prop);
584         QVERIFY(binding != 0);
585         QWeakPointer<QDeclarativeExpression> expression(new QDeclarativeExpression());
586         QVERIFY(expression != 0);
587
588         QObject *obj = new QObject;
589
590         QCOMPARE(prop.name(), QString("defaultProperty"));
591         QCOMPARE(prop.read(), QVariant(10));
592         QCOMPARE(prop.write(QVariant()), false);
593         QCOMPARE(prop.hasNotifySignal(), false);
594         QCOMPARE(prop.needsNotifySignal(), true);
595         QCOMPARE(prop.connectNotifySignal(0, SLOT(deleteLater())), false);
596         QCOMPARE(prop.connectNotifySignal(obj, SLOT(deleteLater())), false);
597         QCOMPARE(prop.connectNotifySignal(obj, 0), false);
598         QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
599         QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
600         QCOMPARE(prop.connectNotifySignal(obj, -1), false);
601         QVERIFY(prop.method().signature() == 0);
602         QCOMPARE(prop.type(), QDeclarativeProperty::Property);
603         QCOMPARE(prop.isProperty(), true);
604         QCOMPARE(prop.isWritable(), false);
605         QCOMPARE(prop.isDesignable(), true);
606         QCOMPARE(prop.isResettable(), false);
607         QCOMPARE(prop.isSignalProperty(), false);
608         QCOMPARE(prop.isValid(), true);
609         QCOMPARE(prop.object(), qobject_cast<QObject*>(&dobject));
610         QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::Normal);
611         QCOMPARE(prop.propertyType(), (int)QVariant::Int);
612         QCOMPARE(prop.propertyTypeName(), "int");
613         QCOMPARE(QString(prop.property().name()), QString("defaultProperty"));
614         QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0);
615         QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: Unable to assign null to int");
616         QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0);
617         QVERIFY(binding != 0);
618         QVERIFY(QDeclarativePropertyPrivate::binding(prop) == binding.data());
619         QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0);
620         QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
621         QVERIFY(expression == 0);
622         QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty"));
623         QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1);
624
625         delete obj;
626     }
627 }
628
629 void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context()
630 {
631     QObject object; 
632     PropertyObject dobject; 
633
634     {
635         QDeclarativeProperty prop(&object, QString("defaultProperty"), engine.rootContext());
636
637         QWeakPointer<QDeclarativeBinding> binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext()));
638         QVERIFY(binding != 0);
639         QWeakPointer<QDeclarativeExpression> expression(new QDeclarativeExpression());
640         QVERIFY(expression != 0);
641
642         QObject *obj = new QObject;
643
644         QCOMPARE(prop.name(), QString());
645         QCOMPARE(prop.read(), QVariant());
646         QCOMPARE(prop.write(QVariant()), false);
647         QCOMPARE(prop.hasNotifySignal(), false);
648         QCOMPARE(prop.needsNotifySignal(), false);
649         QCOMPARE(prop.connectNotifySignal(0, SLOT(deleteLater())), false);
650         QCOMPARE(prop.connectNotifySignal(obj, SLOT(deleteLater())), false);
651         QCOMPARE(prop.connectNotifySignal(obj, 0), false);
652         QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
653         QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
654         QCOMPARE(prop.connectNotifySignal(obj, -1), false);
655         QVERIFY(prop.method().signature() == 0);
656         QCOMPARE(prop.type(), QDeclarativeProperty::Invalid);
657         QCOMPARE(prop.isProperty(), false);
658         QCOMPARE(prop.isWritable(), false);
659         QCOMPARE(prop.isDesignable(), false);
660         QCOMPARE(prop.isResettable(), false);
661         QCOMPARE(prop.isSignalProperty(), false);
662         QCOMPARE(prop.isValid(), false);
663         QCOMPARE(prop.object(), (QObject *)0);
664         QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory);
665         QCOMPARE(prop.propertyType(), 0);
666         QCOMPARE(prop.propertyTypeName(), (const char *)0);
667         QVERIFY(prop.property().name() == 0);
668         QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0);
669         QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0);
670         QVERIFY(binding == 0);
671         QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0);
672         QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
673         QVERIFY(expression == 0);
674         QCOMPARE(prop.index(), -1);
675         QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1);
676
677         delete obj;
678     }
679
680     {
681         QDeclarativeProperty prop(&dobject, QString("defaultProperty"), engine.rootContext());
682
683         QWeakPointer<QDeclarativeBinding> binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext()));
684         binding.data()->setTarget(prop);
685         QVERIFY(binding != 0);
686         QWeakPointer<QDeclarativeExpression> expression(new QDeclarativeExpression());
687         QVERIFY(expression != 0);
688
689         QObject *obj = new QObject;
690
691         QCOMPARE(prop.name(), QString("defaultProperty"));
692         QCOMPARE(prop.read(), QVariant(10));
693         QCOMPARE(prop.write(QVariant()), false);
694         QCOMPARE(prop.hasNotifySignal(), false);
695         QCOMPARE(prop.needsNotifySignal(), true);
696         QCOMPARE(prop.connectNotifySignal(0, SLOT(deleteLater())), false);
697         QCOMPARE(prop.connectNotifySignal(obj, SLOT(deleteLater())), false);
698         QCOMPARE(prop.connectNotifySignal(obj, 0), false);
699         QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
700         QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
701         QCOMPARE(prop.connectNotifySignal(obj, -1), false);
702         QVERIFY(prop.method().signature() == 0);
703         QCOMPARE(prop.type(), QDeclarativeProperty::Property);
704         QCOMPARE(prop.isProperty(), true);
705         QCOMPARE(prop.isWritable(), false);
706         QCOMPARE(prop.isDesignable(), true);
707         QCOMPARE(prop.isResettable(), false);
708         QCOMPARE(prop.isSignalProperty(), false);
709         QCOMPARE(prop.isValid(), true);
710         QCOMPARE(prop.object(), qobject_cast<QObject*>(&dobject));
711         QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::Normal);
712         QCOMPARE(prop.propertyType(), (int)QVariant::Int);
713         QCOMPARE(prop.propertyTypeName(), "int");
714         QCOMPARE(QString(prop.property().name()), QString("defaultProperty"));
715         QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0);
716         QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: Unable to assign null to int");
717         QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0);
718         QVERIFY(binding != 0);
719         QVERIFY(QDeclarativePropertyPrivate::binding(prop) == binding.data());
720         QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0);
721         QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
722         QVERIFY(expression == 0);
723         QCOMPARE(prop.index(), dobject.metaObject()->indexOfProperty("defaultProperty"));
724         QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1);
725
726         delete obj;
727     }
728
729     {
730         QDeclarativeProperty prop(&dobject, QString("onClicked"), engine.rootContext());
731
732         QWeakPointer<QDeclarativeBinding> binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext()));
733         binding.data()->setTarget(prop);
734         QVERIFY(binding != 0);
735         QWeakPointer<QDeclarativeExpression> expression(new QDeclarativeExpression());
736         QVERIFY(expression != 0);
737
738         QObject *obj = new QObject;
739
740         QCOMPARE(prop.name(), QString("onClicked"));
741         QCOMPARE(prop.read(), QVariant());
742         QCOMPARE(prop.write(QVariant("Hello")), false);
743         QCOMPARE(prop.hasNotifySignal(), false);
744         QCOMPARE(prop.needsNotifySignal(), false);
745         QCOMPARE(prop.connectNotifySignal(0, SLOT(deleteLater())), false);
746         QCOMPARE(prop.connectNotifySignal(obj, SLOT(deleteLater())), false);
747         QCOMPARE(prop.connectNotifySignal(obj, 0), false);
748         QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
749         QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
750         QCOMPARE(prop.connectNotifySignal(obj, -1), false);
751         QCOMPARE(QString(prop.method().signature()), QString("clicked()"));
752         QCOMPARE(prop.type(), QDeclarativeProperty::SignalProperty);
753         QCOMPARE(prop.isProperty(), false);
754         QCOMPARE(prop.isWritable(), false);
755         QCOMPARE(prop.isDesignable(), false);
756         QCOMPARE(prop.isResettable(), false);
757         QCOMPARE(prop.isSignalProperty(), true);
758         QCOMPARE(prop.isValid(), true);
759         QCOMPARE(prop.object(), qobject_cast<QObject*>(&dobject));
760         QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory);
761         QCOMPARE(prop.propertyType(), 0);
762         QCOMPARE(prop.propertyTypeName(), (const char *)0);
763         QCOMPARE(prop.property().name(), (const char *)0);
764         QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0);
765         QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0);
766         QVERIFY(binding == 0);
767         QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0);
768         QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
769         QVERIFY(expression != 0);
770         QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == expression.data());
771         QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("clicked()"));
772         QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1);
773
774         delete obj;
775     }
776
777     {
778         QDeclarativeProperty prop(&dobject, QString("onPropertyWithNotifyChanged"), engine.rootContext());
779
780         QWeakPointer<QDeclarativeBinding> binding(new QDeclarativeBinding(QLatin1String("null"), 0, engine.rootContext()));
781         binding.data()->setTarget(prop);
782         QVERIFY(binding != 0);
783         QWeakPointer<QDeclarativeExpression> expression(new QDeclarativeExpression());
784         QVERIFY(expression != 0);
785
786         QObject *obj = new QObject;
787
788         QCOMPARE(prop.name(), QString("onOddlyNamedNotifySignal"));
789         QCOMPARE(prop.read(), QVariant());
790         QCOMPARE(prop.write(QVariant("Hello")), false);
791         QCOMPARE(prop.hasNotifySignal(), false);
792         QCOMPARE(prop.needsNotifySignal(), false);
793         QCOMPARE(prop.connectNotifySignal(0, SLOT(deleteLater())), false);
794         QCOMPARE(prop.connectNotifySignal(obj, SLOT(deleteLater())), false);
795         QCOMPARE(prop.connectNotifySignal(obj, 0), false);
796         QCOMPARE(prop.connectNotifySignal(0, obj->metaObject()->indexOfMethod("deleteLater()")), false);
797         QCOMPARE(prop.connectNotifySignal(obj, obj->metaObject()->indexOfMethod("deleteLater()")), false);
798         QCOMPARE(prop.connectNotifySignal(obj, -1), false);
799         QCOMPARE(QString(prop.method().signature()), QString("oddlyNamedNotifySignal()"));
800         QCOMPARE(prop.type(), QDeclarativeProperty::SignalProperty);
801         QCOMPARE(prop.isProperty(), false);
802         QCOMPARE(prop.isWritable(), false);
803         QCOMPARE(prop.isDesignable(), false);
804         QCOMPARE(prop.isResettable(), false);
805         QCOMPARE(prop.isSignalProperty(), true);
806         QCOMPARE(prop.isValid(), true);
807         QCOMPARE(prop.object(), qobject_cast<QObject*>(&dobject));
808         QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory);
809         QCOMPARE(prop.propertyType(), 0);
810         QCOMPARE(prop.propertyTypeName(), (const char *)0);
811         QCOMPARE(prop.property().name(), (const char *)0);
812         QVERIFY(QDeclarativePropertyPrivate::binding(prop) == 0);
813         QVERIFY(QDeclarativePropertyPrivate::setBinding(prop, binding.data()) == 0);
814         QVERIFY(binding == 0);
815         QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == 0);
816         QVERIFY(QDeclarativePropertyPrivate::setSignalExpression(prop, expression.data()) == 0);
817         QVERIFY(expression != 0);
818         QVERIFY(QDeclarativePropertyPrivate::signalExpression(prop) == expression.data());
819         QCOMPARE(prop.index(), dobject.metaObject()->indexOfMethod("oddlyNamedNotifySignal()"));
820         QCOMPARE(QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), -1);
821
822         delete obj;
823     }
824 }
825
826 void tst_qdeclarativeproperty::name()
827 {
828     { 
829         QDeclarativeProperty p;
830         QCOMPARE(p.name(), QString());
831     }
832
833     {
834         PropertyObject o;
835         QDeclarativeProperty p(&o);
836         QCOMPARE(p.name(), QString("defaultProperty"));
837     }
838
839     {
840         QObject o;
841         QDeclarativeProperty p(&o, QString("objectName"));
842         QCOMPARE(p.name(), QString("objectName"));
843     }
844
845     {
846         PropertyObject o;
847         QDeclarativeProperty p(&o, "onClicked");
848         QCOMPARE(p.name(), QString("onClicked"));
849     }
850
851     {
852         QObject o;
853         QDeclarativeProperty p(&o, "onClicked");
854         QCOMPARE(p.name(), QString());
855     }
856
857     {
858         PropertyObject o;
859         QDeclarativeProperty p(&o, "onPropertyWithNotifyChanged");
860         QCOMPARE(p.name(), QString("onOddlyNamedNotifySignal"));
861     }
862
863     {
864         QObject o;
865         QDeclarativeProperty p(&o, "onPropertyWithNotifyChanged");
866         QCOMPARE(p.name(), QString());
867     }
868
869     {
870         QObject o;
871         QDeclarativeProperty p(&o, "foo");
872         QCOMPARE(p.name(), QString());
873     }
874
875     {
876         QDeclarativeProperty p(0, "foo");
877         QCOMPARE(p.name(), QString());
878     }
879
880     {
881         PropertyObject o;
882         QDeclarativeProperty p(&o, "rectProperty");
883         QCOMPARE(p.name(), QString("rectProperty"));
884     }
885
886     {
887         PropertyObject o;
888         QDeclarativeProperty p(&o, "rectProperty.x");
889         QCOMPARE(p.name(), QString("rectProperty.x"));
890     }
891
892     {
893         PropertyObject o;
894         QDeclarativeProperty p(&o, "rectProperty.foo");
895         QCOMPARE(p.name(), QString());
896     }
897 }
898
899 void tst_qdeclarativeproperty::read()
900 {
901     // Invalid 
902     {
903         QDeclarativeProperty p;
904         QCOMPARE(p.read(), QVariant());
905     }
906
907     // Default prop
908     {
909         PropertyObject o;
910         QDeclarativeProperty p(&o);
911         QCOMPARE(p.read(), QVariant(10));
912     }
913
914     // Invalid default prop
915     {
916         QObject o;
917         QDeclarativeProperty p(&o);
918         QCOMPARE(p.read(), QVariant());
919     }
920
921     // Value prop by name
922     {
923         QObject o;
924
925         QDeclarativeProperty p(&o, "objectName");
926         QCOMPARE(p.read(), QVariant(QString()));
927
928         o.setObjectName("myName");
929
930         QCOMPARE(p.read(), QVariant("myName"));
931     }
932
933     // Value prop by name (static)
934     {
935         QObject o;
936
937         QCOMPARE(QDeclarativeProperty::read(&o, "objectName"), QVariant(QString()));
938
939         o.setObjectName("myName");
940
941         QCOMPARE(QDeclarativeProperty::read(&o, "objectName"), QVariant("myName"));
942     }
943
944     // Value-type prop
945     {
946         PropertyObject o;
947         QDeclarativeProperty p(&o, "rectProperty.x");
948         QCOMPARE(p.read(), QVariant(10));
949     }
950
951     // Invalid value-type prop
952     {
953         PropertyObject o;
954         QDeclarativeProperty p(&o, "rectProperty.foo");
955         QCOMPARE(p.read(), QVariant());
956     }
957
958     // Signal property
959     {
960         PropertyObject o;
961         QDeclarativeProperty p(&o, "onClicked");
962         QCOMPARE(p.read(), QVariant());
963
964         QVERIFY(0 == QDeclarativePropertyPrivate::setSignalExpression(p, new QDeclarativeExpression()));
965         QVERIFY(0 != QDeclarativePropertyPrivate::signalExpression(p));
966
967         QCOMPARE(p.read(), QVariant());
968     }
969
970     // Automatic signal property 
971     {
972         PropertyObject o;
973         QDeclarativeProperty p(&o, "onPropertyWithNotifyChanged");
974         QCOMPARE(p.read(), QVariant());
975
976         QVERIFY(0 == QDeclarativePropertyPrivate::setSignalExpression(p, new QDeclarativeExpression()));
977         QVERIFY(0 != QDeclarativePropertyPrivate::signalExpression(p));
978
979         QCOMPARE(p.read(), QVariant());
980     }
981
982     // Deleted object
983     {
984         PropertyObject *o = new PropertyObject;
985         QDeclarativeProperty p(o, "rectProperty.x");
986         QCOMPARE(p.read(), QVariant(10));
987         delete o;
988         QCOMPARE(p.read(), QVariant());
989     }
990
991     // Object property
992     {
993         PropertyObject o;
994         QDeclarativeProperty p(&o, "qmlObject");
995         QCOMPARE(p.propertyTypeCategory(), QDeclarativeProperty::Object);
996         QCOMPARE(p.propertyType(), qMetaTypeId<MyQmlObject*>());
997         QVariant v = p.read();
998         QVERIFY(v.userType() == QMetaType::QObjectStar);
999         QVERIFY(qvariant_cast<QObject *>(v) == o.qmlObject());
1000     }
1001     {
1002         QDeclarativeComponent component(&engine, testFileUrl("readSynthesizedObject.qml"));
1003         QObject *object = component.create();
1004         QVERIFY(object != 0);
1005
1006         QDeclarativeProperty p(object, "test", &engine);
1007
1008         QCOMPARE(p.propertyTypeCategory(), QDeclarativeProperty::Object);
1009         QVERIFY(p.propertyType() != QMetaType::QObjectStar);
1010
1011         QVariant v = p.read();
1012         QVERIFY(v.userType() == QMetaType::QObjectStar);
1013         QCOMPARE(qvariant_cast<QObject *>(v)->property("a").toInt(), 10);
1014         QCOMPARE(qvariant_cast<QObject *>(v)->property("b").toInt(), 19);
1015     }
1016     {   // static
1017         QDeclarativeComponent component(&engine, testFileUrl("readSynthesizedObject.qml"));
1018         QObject *object = component.create();
1019         QVERIFY(object != 0);
1020
1021         QVariant v = QDeclarativeProperty::read(object, "test", &engine);
1022         QVERIFY(v.userType() == QMetaType::QObjectStar);
1023         QCOMPARE(qvariant_cast<QObject *>(v)->property("a").toInt(), 10);
1024         QCOMPARE(qvariant_cast<QObject *>(v)->property("b").toInt(), 19);
1025     }
1026
1027     // Attached property
1028     {
1029         QDeclarativeComponent component(&engine);
1030         component.setData("import Test 1.0\nMyContainer { }", QUrl());
1031         QObject *object = component.create();
1032         QVERIFY(object != 0);
1033
1034         QDeclarativeProperty p(object, "MyContainer.foo", qmlContext(object));
1035         QCOMPARE(p.read(), QVariant(13));
1036         delete object;
1037     }
1038     {
1039         QDeclarativeComponent component(&engine);
1040         component.setData("import Test 1.0\nMyContainer { MyContainer.foo: 10 }", QUrl());
1041         QObject *object = component.create();
1042         QVERIFY(object != 0);
1043
1044         QDeclarativeProperty p(object, "MyContainer.foo", qmlContext(object));
1045         QCOMPARE(p.read(), QVariant(10));
1046         delete object;
1047     }
1048     {
1049         QDeclarativeComponent component(&engine);
1050         component.setData("import Test 1.0 as Foo\nFoo.MyContainer { Foo.MyContainer.foo: 10 }", QUrl());
1051         QObject *object = component.create();
1052         QVERIFY(object != 0);
1053
1054         QDeclarativeProperty p(object, "Foo.MyContainer.foo", qmlContext(object));
1055         QCOMPARE(p.read(), QVariant(10));
1056         delete object;
1057     }
1058     {   // static
1059         QDeclarativeComponent component(&engine);
1060         component.setData("import Test 1.0 as Foo\nFoo.MyContainer { Foo.MyContainer.foo: 10 }", QUrl());
1061         QObject *object = component.create();
1062         QVERIFY(object != 0);
1063
1064         QCOMPARE(QDeclarativeProperty::read(object, "Foo.MyContainer.foo", qmlContext(object)), QVariant(10));
1065         delete object;
1066     }
1067 }
1068
1069 void tst_qdeclarativeproperty::write()
1070 {
1071     // Invalid
1072     {
1073         QDeclarativeProperty p;
1074         QCOMPARE(p.write(QVariant(10)), false);
1075     }
1076
1077     // Read-only default prop
1078     {
1079         PropertyObject o;
1080         QDeclarativeProperty p(&o);
1081         QCOMPARE(p.write(QVariant(10)), false);
1082     }
1083
1084     // Invalid default prop
1085     {
1086         QObject o;
1087         QDeclarativeProperty p(&o);
1088         QCOMPARE(p.write(QVariant(10)), false);
1089     }
1090
1091     // Read-only prop by name
1092     {
1093         PropertyObject o;
1094         QDeclarativeProperty p(&o, QString("defaultProperty"));
1095         QCOMPARE(p.write(QVariant(10)), false);
1096     }
1097
1098     // Writable prop by name
1099     {
1100         PropertyObject o;
1101         QDeclarativeProperty p(&o, QString("objectName"));
1102         QCOMPARE(o.objectName(), QString());
1103         QCOMPARE(p.write(QVariant(QString("myName"))), true);
1104         QCOMPARE(o.objectName(), QString("myName"));
1105     }
1106
1107     // Writable prop by name (static)
1108     {
1109         PropertyObject o;
1110         QCOMPARE(QDeclarativeProperty::write(&o, QString("objectName"), QVariant(QString("myName"))), true);
1111         QCOMPARE(o.objectName(), QString("myName"));
1112     }
1113
1114     // Deleted object
1115     {
1116         PropertyObject *o = new PropertyObject;
1117         QDeclarativeProperty p(o, QString("objectName"));
1118         QCOMPARE(p.write(QVariant(QString("myName"))), true);
1119         QCOMPARE(o->objectName(), QString("myName"));
1120
1121         delete o;
1122
1123         QCOMPARE(p.write(QVariant(QString("myName"))), false);
1124     }
1125
1126     // Signal property
1127     {
1128         PropertyObject o;
1129         QDeclarativeProperty p(&o, "onClicked");
1130         QCOMPARE(p.write(QVariant("console.log(1921)")), false);
1131
1132         QVERIFY(0 == QDeclarativePropertyPrivate::setSignalExpression(p, new QDeclarativeExpression()));
1133         QVERIFY(0 != QDeclarativePropertyPrivate::signalExpression(p));
1134
1135         QCOMPARE(p.write(QVariant("console.log(1921)")), false);
1136
1137         QVERIFY(0 != QDeclarativePropertyPrivate::signalExpression(p));
1138     }
1139
1140     // Automatic signal property
1141     {
1142         PropertyObject o;
1143         QDeclarativeProperty p(&o, "onPropertyWithNotifyChanged");
1144         QCOMPARE(p.write(QVariant("console.log(1921)")), false);
1145
1146         QVERIFY(0 == QDeclarativePropertyPrivate::setSignalExpression(p, new QDeclarativeExpression()));
1147         QVERIFY(0 != QDeclarativePropertyPrivate::signalExpression(p));
1148
1149         QCOMPARE(p.write(QVariant("console.log(1921)")), false);
1150
1151         QVERIFY(0 != QDeclarativePropertyPrivate::signalExpression(p));
1152     }
1153
1154     // Value-type property
1155     {
1156         PropertyObject o;
1157         QDeclarativeProperty p(&o, "wrectProperty");
1158
1159         QCOMPARE(o.wrectProperty(), QRect());
1160         QCOMPARE(p.write(QRect(1, 13, 99, 8)), true);
1161         QCOMPARE(o.wrectProperty(), QRect(1, 13, 99, 8));
1162
1163         QDeclarativeProperty p2(&o, "wrectProperty.x");
1164         QCOMPARE(p2.read(), QVariant(1));
1165         QCOMPARE(p2.write(QVariant(6)), true);
1166         QCOMPARE(p2.read(), QVariant(6));
1167         QCOMPARE(o.wrectProperty(), QRect(6, 13, 99, 8));
1168     }
1169
1170     // URL-property
1171     {
1172         PropertyObject o;
1173         QDeclarativeProperty p(&o, "url");
1174
1175         QCOMPARE(p.write(QUrl("main.qml")), true);
1176         QCOMPARE(o.url(), QUrl("main.qml"));
1177
1178         QDeclarativeProperty p2(&o, "url", engine.rootContext());
1179
1180         QUrl result = engine.baseUrl().resolved(QUrl("main.qml"));
1181         QVERIFY(result != QUrl("main.qml"));
1182
1183         QCOMPARE(p2.write(QUrl("main.qml")), true);
1184         QCOMPARE(o.url(), result);
1185     }
1186     {   // static
1187         PropertyObject o;
1188
1189         QCOMPARE(QDeclarativeProperty::write(&o, "url", QUrl("main.qml")), true);
1190         QCOMPARE(o.url(), QUrl("main.qml"));
1191
1192         QUrl result = engine.baseUrl().resolved(QUrl("main.qml"));
1193         QVERIFY(result != QUrl("main.qml"));
1194
1195         QCOMPARE(QDeclarativeProperty::write(&o, "url", QUrl("main.qml"), engine.rootContext()), true);
1196         QCOMPARE(o.url(), result);
1197     }
1198
1199     // Attached property
1200     {
1201         QDeclarativeComponent component(&engine);
1202         component.setData("import Test 1.0\nMyContainer { }", QUrl());
1203         QObject *object = component.create();
1204         QVERIFY(object != 0);
1205
1206         QDeclarativeProperty p(object, "MyContainer.foo", qmlContext(object));
1207         p.write(QVariant(99));
1208         QCOMPARE(p.read(), QVariant(99));
1209         delete object;
1210     }
1211     {
1212         QDeclarativeComponent component(&engine);
1213         component.setData("import Test 1.0 as Foo\nFoo.MyContainer { Foo.MyContainer.foo: 10 }", QUrl());
1214         QObject *object = component.create();
1215         QVERIFY(object != 0);
1216
1217         QDeclarativeProperty p(object, "Foo.MyContainer.foo", qmlContext(object));
1218         p.write(QVariant(99));
1219         QCOMPARE(p.read(), QVariant(99));
1220         delete object;
1221     }
1222 }
1223
1224 void tst_qdeclarativeproperty::reset()
1225 {
1226     // Invalid
1227     {
1228         QDeclarativeProperty p;
1229         QCOMPARE(p.isResettable(), false);
1230         QCOMPARE(p.reset(), false);
1231     }
1232
1233     // Read-only default prop
1234     {
1235         PropertyObject o;
1236         QDeclarativeProperty p(&o);
1237         QCOMPARE(p.isResettable(), false);
1238         QCOMPARE(p.reset(), false);
1239     }
1240
1241     // Invalid default prop
1242     {
1243         QObject o;
1244         QDeclarativeProperty p(&o);
1245         QCOMPARE(p.isResettable(), false);
1246         QCOMPARE(p.reset(), false);
1247     }
1248
1249     // Non-resettable-only prop by name
1250     {
1251         PropertyObject o;
1252         QDeclarativeProperty p(&o, QString("defaultProperty"));
1253         QCOMPARE(p.isResettable(), false);
1254         QCOMPARE(p.reset(), false);
1255     }
1256
1257     // Resettable prop by name
1258     {
1259         PropertyObject o;
1260         QDeclarativeProperty p(&o, QString("resettableProperty"));
1261
1262         QCOMPARE(p.read(), QVariant(9));
1263         QCOMPARE(p.write(QVariant(11)), true);
1264         QCOMPARE(p.read(), QVariant(11));
1265
1266         QCOMPARE(p.isResettable(), true);
1267         QCOMPARE(p.reset(), true);
1268
1269         QCOMPARE(p.read(), QVariant(9));
1270     }
1271
1272     // Deleted object
1273     {
1274         PropertyObject *o = new PropertyObject;
1275
1276         QDeclarativeProperty p(o, QString("resettableProperty"));
1277
1278         QCOMPARE(p.isResettable(), true);
1279         QCOMPARE(p.reset(), true);
1280
1281         delete o;
1282
1283         QCOMPARE(p.isResettable(), false);
1284         QCOMPARE(p.reset(), false);
1285     }
1286
1287     // Signal property
1288     {
1289         PropertyObject o;
1290         QDeclarativeProperty p(&o, "onClicked");
1291
1292         QCOMPARE(p.isResettable(), false);
1293         QCOMPARE(p.reset(), false);
1294     }
1295
1296     // Automatic signal property
1297     {
1298         PropertyObject o;
1299         QDeclarativeProperty p(&o, "onPropertyWithNotifyChanged");
1300
1301         QCOMPARE(p.isResettable(), false);
1302         QCOMPARE(p.reset(), false);
1303     }
1304 }
1305
1306 void tst_qdeclarativeproperty::writeObjectToList()
1307 {
1308     QDeclarativeComponent containerComponent(&engine);
1309     containerComponent.setData("import Test 1.0\nMyContainer { children: MyQmlObject {} }", QUrl());
1310     MyContainer *container = qobject_cast<MyContainer*>(containerComponent.create());
1311     QVERIFY(container != 0);
1312     QDeclarativeListReference list(container, "children");
1313     QVERIFY(list.count() == 1);
1314
1315     MyQmlObject *object = new MyQmlObject;
1316     QDeclarativeProperty prop(container, "children");
1317     prop.write(qVariantFromValue(object));
1318     QCOMPARE(list.count(), 1);
1319     QCOMPARE(list.at(0), qobject_cast<QObject*>(object));
1320 }
1321
1322 Q_DECLARE_METATYPE(QList<QObject *>);
1323 void tst_qdeclarativeproperty::writeListToList()
1324 {
1325     QDeclarativeComponent containerComponent(&engine);
1326     containerComponent.setData("import Test 1.0\nMyContainer { children: MyQmlObject {} }", QUrl());
1327     MyContainer *container = qobject_cast<MyContainer*>(containerComponent.create());
1328     QVERIFY(container != 0);
1329     QDeclarativeListReference list(container, "children");
1330     QVERIFY(list.count() == 1);
1331
1332     QList<QObject*> objList;
1333     objList << new MyQmlObject() << new MyQmlObject() << new MyQmlObject() << new MyQmlObject();
1334     QDeclarativeProperty prop(container, "children");
1335     prop.write(qVariantFromValue(objList));
1336     QCOMPARE(list.count(), 4);
1337
1338     //XXX need to try this with read/write prop (for read-only it correctly doesn't write)
1339     /*QList<MyQmlObject*> typedObjList;
1340     typedObjList << new MyQmlObject();
1341     prop.write(qVariantFromValue(&typedObjList));
1342     QCOMPARE(container->children()->size(), 1);*/
1343 }
1344
1345 void tst_qdeclarativeproperty::urlHandling_data()
1346 {
1347     QTest::addColumn<QByteArray>("input");
1348     QTest::addColumn<QString>("scheme");
1349     QTest::addColumn<QString>("path");
1350     QTest::addColumn<QByteArray>("encoded");
1351
1352     QTest::newRow("unspecifiedFile")
1353         << QByteArray("main.qml")
1354         << QString("")
1355         << QString("main.qml")
1356         << QByteArray("main.qml");
1357
1358     QTest::newRow("specifiedFile")
1359         << QByteArray("file:///main.qml")
1360         << QString("file")
1361         << QString("/main.qml")
1362         << QByteArray("file:///main.qml");
1363
1364     QTest::newRow("httpFile")
1365         << QByteArray("http://www.example.com/main.qml")
1366         << QString("http")
1367         << QString("/main.qml")
1368         << QByteArray("http://www.example.com/main.qml");
1369
1370     QTest::newRow("pathFile")
1371         << QByteArray("http://www.example.com/resources/main.qml")
1372         << QString("http")
1373         << QString("/resources/main.qml")
1374         << QByteArray("http://www.example.com/resources/main.qml");
1375
1376     QTest::newRow("encodableName")
1377         << QByteArray("http://www.example.com/main file.qml")
1378         << QString("http")
1379         << QString("/main file.qml")
1380         << QByteArray("http://www.example.com/main%20file.qml");
1381
1382     QTest::newRow("preencodedName")
1383         << QByteArray("http://www.example.com/resources%7cmain%20file.qml")
1384         << QString("http")
1385         << QString("/resources|main file.qml")
1386         << QByteArray("http://www.example.com/resources%7cmain%20file.qml");
1387
1388     QTest::newRow("encodableQuery")
1389         << QByteArray("http://www.example.com/main.qml?type=text/qml&comment=now working?")
1390         << QString("http")
1391         << QString("/main.qml")
1392         << QByteArray("http://www.example.com/main.qml?type=text/qml&comment=now%20working?");
1393
1394     QTest::newRow("preencodedQuery")
1395         << QByteArray("http://www.example.com/main.qml?type=text%2fqml&comment=now working%3f")
1396         << QString("http")
1397         << QString("/main.qml")
1398         << QByteArray("http://www.example.com/main.qml?type=text%2fqml&comment=now%20working%3f");
1399
1400     QTest::newRow("encodableFragment")
1401         << QByteArray("http://www.example.com/main.qml?type=text/qml#start+30000|volume+50%")
1402         << QString("http")
1403         << QString("/main.qml")
1404         << QByteArray("http://www.example.com/main.qml?type=text/qml#start+30000%7Cvolume+50%25");
1405
1406     QTest::newRow("preencodedFragment")
1407         << QByteArray("http://www.example.com/main.qml?type=text/qml#start+30000%7cvolume%2b50%")
1408         << QString("http")
1409         << QString("/main.qml")
1410         << QByteArray("http://www.example.com/main.qml?type=text/qml#start+30000%7cvolume%2b50%25");
1411 }
1412
1413 void tst_qdeclarativeproperty::urlHandling()
1414 {
1415     QFETCH(QByteArray, input);
1416     QFETCH(QString, scheme);
1417     QFETCH(QString, path);
1418     QFETCH(QByteArray, encoded);
1419
1420     QString inputString(QString::fromUtf8(input));
1421
1422     {
1423         PropertyObject o;
1424         QDeclarativeProperty p(&o, "url");
1425
1426         // Test url written as QByteArray
1427         QCOMPARE(p.write(input), true);
1428         QUrl byteArrayResult(o.url());
1429
1430         QCOMPARE(byteArrayResult.scheme(), scheme);
1431         QCOMPARE(byteArrayResult.path(), path);
1432         QCOMPARE(byteArrayResult.toEncoded(), encoded);
1433     }
1434
1435     {
1436         PropertyObject o;
1437         QDeclarativeProperty p(&o, "url");
1438
1439         // Test url written as QString
1440         QCOMPARE(p.write(inputString), true);
1441         QUrl stringResult(o.url());
1442
1443         QCOMPARE(stringResult.scheme(), scheme);
1444         QCOMPARE(stringResult.path(), path);
1445         QCOMPARE(stringResult.toEncoded(), encoded);
1446     }
1447 }
1448
1449 void tst_qdeclarativeproperty::crashOnValueProperty()
1450 {
1451     QDeclarativeEngine *engine = new QDeclarativeEngine;
1452     QDeclarativeComponent component(engine);
1453
1454     component.setData("import Test 1.0\nPropertyObject { wrectProperty.x: 10 }", QUrl());
1455     PropertyObject *obj = qobject_cast<PropertyObject*>(component.create());
1456     QVERIFY(obj != 0);
1457
1458     QDeclarativeProperty p(obj, "wrectProperty.x", qmlContext(obj));
1459     QCOMPARE(p.name(), QString("wrectProperty.x"));
1460
1461     QCOMPARE(p.read(), QVariant(10));
1462
1463     //don't crash once the engine is deleted
1464     delete engine;
1465     engine = 0;
1466
1467     QCOMPARE(p.propertyTypeName(), "int");
1468     QCOMPARE(p.read(), QVariant(10));
1469     p.write(QVariant(20));
1470     QCOMPARE(p.read(), QVariant(20));
1471 }
1472
1473 // QTBUG-13719
1474 void tst_qdeclarativeproperty::aliasPropertyBindings()
1475 {
1476     QDeclarativeComponent component(&engine, testFileUrl("aliasPropertyBindings.qml"));
1477
1478     QObject *object = component.create();
1479     QVERIFY(object != 0);
1480
1481     QCOMPARE(object->property("realProperty").toReal(), 90.);
1482     QCOMPARE(object->property("aliasProperty").toReal(), 90.);
1483
1484     object->setProperty("test", 10);
1485
1486     QCOMPARE(object->property("realProperty").toReal(), 110.);
1487     QCOMPARE(object->property("aliasProperty").toReal(), 110.);
1488
1489     QDeclarativeProperty realProperty(object, QLatin1String("realProperty"));
1490     QDeclarativeProperty aliasProperty(object, QLatin1String("aliasProperty"));
1491
1492     // Check there is a binding on these two properties
1493     QVERIFY(QDeclarativePropertyPrivate::binding(realProperty) != 0);
1494     QVERIFY(QDeclarativePropertyPrivate::binding(aliasProperty) != 0);
1495
1496     // Check that its the same binding on these two properties
1497     QCOMPARE(QDeclarativePropertyPrivate::binding(realProperty),
1498              QDeclarativePropertyPrivate::binding(aliasProperty));
1499
1500     // Change the binding
1501     object->setProperty("state", QString("switch"));
1502
1503     QVERIFY(QDeclarativePropertyPrivate::binding(realProperty) != 0);
1504     QVERIFY(QDeclarativePropertyPrivate::binding(aliasProperty) != 0);
1505     QCOMPARE(QDeclarativePropertyPrivate::binding(realProperty),
1506              QDeclarativePropertyPrivate::binding(aliasProperty));
1507
1508     QCOMPARE(object->property("realProperty").toReal(), 96.);
1509     QCOMPARE(object->property("aliasProperty").toReal(), 96.);
1510
1511     // Check the old binding really has not effect any more
1512     object->setProperty("test", 4);
1513
1514     QCOMPARE(object->property("realProperty").toReal(), 96.);
1515     QCOMPARE(object->property("aliasProperty").toReal(), 96.);
1516
1517     object->setProperty("test2", 9);
1518
1519     QCOMPARE(object->property("realProperty").toReal(), 288.);
1520     QCOMPARE(object->property("aliasProperty").toReal(), 288.);
1521
1522     // Revert
1523     object->setProperty("state", QString(""));
1524
1525     QVERIFY(QDeclarativePropertyPrivate::binding(realProperty) != 0);
1526     QVERIFY(QDeclarativePropertyPrivate::binding(aliasProperty) != 0);
1527     QCOMPARE(QDeclarativePropertyPrivate::binding(realProperty),
1528              QDeclarativePropertyPrivate::binding(aliasProperty));
1529
1530     QCOMPARE(object->property("realProperty").toReal(), 20.);
1531     QCOMPARE(object->property("aliasProperty").toReal(), 20.);
1532
1533     object->setProperty("test2", 3);
1534
1535     QCOMPARE(object->property("realProperty").toReal(), 20.);
1536     QCOMPARE(object->property("aliasProperty").toReal(), 20.);
1537
1538     delete object;
1539 }
1540
1541 void tst_qdeclarativeproperty::copy()
1542 {
1543     PropertyObject object;
1544
1545     QDeclarativeProperty *property = new QDeclarativeProperty(&object, QLatin1String("defaultProperty"));
1546     QCOMPARE(property->name(), QString("defaultProperty"));
1547     QCOMPARE(property->read(), QVariant(10));
1548     QCOMPARE(property->type(), QDeclarativeProperty::Property);
1549     QCOMPARE(property->propertyTypeCategory(), QDeclarativeProperty::Normal);
1550     QCOMPARE(property->propertyType(), (int)QVariant::Int);
1551
1552     QDeclarativeProperty p1(*property);
1553     QCOMPARE(p1.name(), QString("defaultProperty"));
1554     QCOMPARE(p1.read(), QVariant(10));
1555     QCOMPARE(p1.type(), QDeclarativeProperty::Property);
1556     QCOMPARE(p1.propertyTypeCategory(), QDeclarativeProperty::Normal);
1557     QCOMPARE(p1.propertyType(), (int)QVariant::Int);
1558
1559     QDeclarativeProperty p2(&object, QLatin1String("url"));
1560     QCOMPARE(p2.name(), QString("url"));
1561     p2 = *property;
1562     QCOMPARE(p2.name(), QString("defaultProperty"));
1563     QCOMPARE(p2.read(), QVariant(10));
1564     QCOMPARE(p2.type(), QDeclarativeProperty::Property);
1565     QCOMPARE(p2.propertyTypeCategory(), QDeclarativeProperty::Normal);
1566     QCOMPARE(p2.propertyType(), (int)QVariant::Int);
1567
1568     delete property; property = 0;
1569
1570     QCOMPARE(p1.name(), QString("defaultProperty"));
1571     QCOMPARE(p1.read(), QVariant(10));
1572     QCOMPARE(p1.type(), QDeclarativeProperty::Property);
1573     QCOMPARE(p1.propertyTypeCategory(), QDeclarativeProperty::Normal);
1574     QCOMPARE(p1.propertyType(), (int)QVariant::Int);
1575
1576     QCOMPARE(p2.name(), QString("defaultProperty"));
1577     QCOMPARE(p2.read(), QVariant(10));
1578     QCOMPARE(p2.type(), QDeclarativeProperty::Property);
1579     QCOMPARE(p2.propertyTypeCategory(), QDeclarativeProperty::Normal);
1580     QCOMPARE(p2.propertyType(), (int)QVariant::Int);
1581 }
1582
1583 void tst_qdeclarativeproperty::noContext()
1584 {
1585     QDeclarativeComponent compA(&engine, testFileUrl("NoContextTypeA.qml"));
1586     QDeclarativeComponent compB(&engine, testFileUrl("NoContextTypeB.qml"));
1587
1588     QObject *a = compA.create();
1589     QVERIFY(a != 0);
1590     QObject *b = compB.create();
1591     QVERIFY(b != 0);
1592
1593     QVERIFY(QDeclarativeProperty::write(b, "myTypeA", QVariant::fromValue(a), &engine));
1594
1595     delete a;
1596     delete b;
1597 }
1598
1599 void tst_qdeclarativeproperty::initTestCase()
1600 {
1601     QDeclarativeDataTest::initTestCase();
1602     qmlRegisterType<MyQmlObject>("Test",1,0,"MyQmlObject");
1603     qmlRegisterType<PropertyObject>("Test",1,0,"PropertyObject");
1604     qmlRegisterType<MyContainer>("Test",1,0,"MyContainer");
1605 }
1606
1607 QTEST_MAIN(tst_qdeclarativeproperty)
1608
1609 #include "tst_qdeclarativeproperty.moc"