Emit destruction signal before child contexts are destroyed.
[profile/ivi/qtdeclarative.git] / tests / auto / declarative / qdeclarativecontext / tst_qdeclarativecontext.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 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
42 #include <qtest.h>
43 #include <QDebug>
44 #include <QDeclarativeEngine>
45 #include <QDeclarativeContext>
46 #include <QDeclarativeComponent>
47 #include <QDeclarativeExpression>
48 #include <private/qdeclarativecontext_p.h>
49 #include "../shared/util.h"
50
51 inline QUrl TEST_FILE(const QString &filename)
52 {
53     return QUrl::fromLocalFile(TESTDATA(filename));
54 }
55
56 inline QUrl TEST_FILE(const char *filename)
57 {
58     return TEST_FILE(QLatin1String(filename));
59 }
60
61 class tst_qdeclarativecontext : public QObject
62 {
63     Q_OBJECT
64 public:
65     tst_qdeclarativecontext() {}
66
67 private slots:
68     void baseUrl();
69     void resolvedUrl();
70     void engineMethod();
71     void parentContext();
72     void setContextProperty();
73     void setContextObject();
74     void destruction();
75     void idAsContextProperty();
76     void readOnlyContexts();
77     void nameForObject();
78
79     void refreshExpressions();
80     void refreshExpressionsCrash();
81     void refreshExpressionsRootContext();
82
83     void qtbug_22535();
84 private:
85     QDeclarativeEngine engine;
86 };
87
88 void tst_qdeclarativecontext::baseUrl()
89 {
90     QDeclarativeContext ctxt(&engine);
91
92     QCOMPARE(ctxt.baseUrl(), QUrl());
93
94     ctxt.setBaseUrl(QUrl("http://www.nokia.com/"));
95
96     QCOMPARE(ctxt.baseUrl(), QUrl("http://www.nokia.com/"));
97 }
98
99 void tst_qdeclarativecontext::resolvedUrl()
100 {
101     // Relative to the component
102     {
103         QDeclarativeContext ctxt(&engine);
104         ctxt.setBaseUrl(QUrl("http://www.nokia.com/"));
105
106         QCOMPARE(ctxt.resolvedUrl(QUrl("main.qml")), QUrl("http://www.nokia.com/main.qml"));
107     }
108
109     // Relative to a parent
110     {
111         QDeclarativeContext ctxt(&engine);
112         ctxt.setBaseUrl(QUrl("http://www.nokia.com/"));
113
114         QDeclarativeContext ctxt2(&ctxt);
115         QCOMPARE(ctxt2.resolvedUrl(QUrl("main2.qml")), QUrl("http://www.nokia.com/main2.qml"));
116     }
117
118     // Relative to the engine
119     {
120         QDeclarativeContext ctxt(&engine);
121         QCOMPARE(ctxt.resolvedUrl(QUrl("main.qml")), engine.baseUrl().resolved(QUrl("main.qml")));
122     }
123
124     // Relative to a deleted parent
125     {
126         QDeclarativeContext *ctxt = new QDeclarativeContext(&engine);
127         ctxt->setBaseUrl(QUrl("http://www.nokia.com/"));
128
129         QDeclarativeContext ctxt2(ctxt);
130         QCOMPARE(ctxt2.resolvedUrl(QUrl("main2.qml")), QUrl("http://www.nokia.com/main2.qml"));
131
132         delete ctxt; ctxt = 0;
133
134         QCOMPARE(ctxt2.resolvedUrl(QUrl("main2.qml")), QUrl());
135     }
136
137     // Absolute
138     {
139         QDeclarativeContext ctxt(&engine);
140
141         QCOMPARE(ctxt.resolvedUrl(QUrl("http://www.nokia.com/main2.qml")), QUrl("http://www.nokia.com/main2.qml"));
142         QCOMPARE(ctxt.resolvedUrl(QUrl("file:///main2.qml")), QUrl("file:///main2.qml"));
143     }
144 }
145
146 void tst_qdeclarativecontext::engineMethod()
147 {
148     QDeclarativeEngine *engine = new QDeclarativeEngine;
149
150     QDeclarativeContext ctxt(engine);
151     QDeclarativeContext ctxt2(&ctxt);
152     QDeclarativeContext ctxt3(&ctxt2);
153     QDeclarativeContext ctxt4(&ctxt2);
154
155     QCOMPARE(ctxt.engine(), engine);
156     QCOMPARE(ctxt2.engine(), engine);
157     QCOMPARE(ctxt3.engine(), engine);
158     QCOMPARE(ctxt4.engine(), engine);
159
160     delete engine; engine = 0;
161
162     QCOMPARE(ctxt.engine(), engine);
163     QCOMPARE(ctxt2.engine(), engine);
164     QCOMPARE(ctxt3.engine(), engine);
165     QCOMPARE(ctxt4.engine(), engine);
166 }
167
168 void tst_qdeclarativecontext::parentContext()
169 {
170     QDeclarativeEngine *engine = new QDeclarativeEngine;
171
172     QCOMPARE(engine->rootContext()->parentContext(), (QDeclarativeContext *)0);
173
174     QDeclarativeContext *ctxt = new QDeclarativeContext(engine);
175     QDeclarativeContext *ctxt2 = new QDeclarativeContext(ctxt);
176     QDeclarativeContext *ctxt3 = new QDeclarativeContext(ctxt2);
177     QDeclarativeContext *ctxt4 = new QDeclarativeContext(ctxt2);
178     QDeclarativeContext *ctxt5 = new QDeclarativeContext(ctxt);
179     QDeclarativeContext *ctxt6 = new QDeclarativeContext(engine);
180     QDeclarativeContext *ctxt7 = new QDeclarativeContext(engine->rootContext());
181
182     QCOMPARE(ctxt->parentContext(), engine->rootContext());
183     QCOMPARE(ctxt2->parentContext(), ctxt);
184     QCOMPARE(ctxt3->parentContext(), ctxt2);
185     QCOMPARE(ctxt4->parentContext(), ctxt2);
186     QCOMPARE(ctxt5->parentContext(), ctxt);
187     QCOMPARE(ctxt6->parentContext(), engine->rootContext());
188     QCOMPARE(ctxt7->parentContext(), engine->rootContext());
189
190     delete ctxt2; ctxt2 = 0;
191
192     QCOMPARE(ctxt->parentContext(), engine->rootContext());
193     QCOMPARE(ctxt3->parentContext(), (QDeclarativeContext *)0);
194     QCOMPARE(ctxt4->parentContext(), (QDeclarativeContext *)0);
195     QCOMPARE(ctxt5->parentContext(), ctxt);
196     QCOMPARE(ctxt6->parentContext(), engine->rootContext());
197     QCOMPARE(ctxt7->parentContext(), engine->rootContext());
198
199     delete engine; engine = 0;
200
201     QCOMPARE(ctxt->parentContext(), (QDeclarativeContext *)0);
202     QCOMPARE(ctxt3->parentContext(), (QDeclarativeContext *)0);
203     QCOMPARE(ctxt4->parentContext(), (QDeclarativeContext *)0);
204     QCOMPARE(ctxt5->parentContext(), (QDeclarativeContext *)0);
205     QCOMPARE(ctxt6->parentContext(), (QDeclarativeContext *)0);
206     QCOMPARE(ctxt7->parentContext(), (QDeclarativeContext *)0);
207
208     delete ctxt7;
209     delete ctxt6;
210     delete ctxt5;
211     delete ctxt4;
212     delete ctxt3;
213     delete ctxt;
214 }
215
216 class TestObject : public QObject
217 {
218     Q_OBJECT
219     Q_PROPERTY(int a READ a NOTIFY aChanged)
220     Q_PROPERTY(int b READ b NOTIFY bChanged)
221     Q_PROPERTY(int c READ c NOTIFY cChanged)
222
223 public:
224     TestObject() : _a(10), _b(10), _c(10) {}
225
226     int a() const { return _a; }
227     void setA(int a) { _a = a; emit aChanged(); }
228
229     int b() const { return _b; }
230     void setB(int b) { _b = b; emit bChanged(); }
231
232     int c() const { return _c; }
233     void setC(int c) { _c = c; emit cChanged(); }
234
235 signals:
236     void aChanged();
237     void bChanged();
238     void cChanged();
239
240 private:
241     int _a;
242     int _b;
243     int _c;
244 };
245
246 #define TEST_CONTEXT_PROPERTY(ctxt, name, value) \
247 { \
248     QDeclarativeComponent component(&engine); \
249     component.setData("import QtQuick 1.0; QtObject { property variant test: " #name " }", QUrl()); \
250 \
251     QObject *obj = component.create(ctxt); \
252 \
253     QCOMPARE(obj->property("test"), value); \
254 \
255     delete obj; \
256
257
258 void tst_qdeclarativecontext::setContextProperty()
259 {
260     QDeclarativeContext ctxt(&engine);
261     QDeclarativeContext ctxt2(&ctxt);
262
263     TestObject obj1;
264     obj1.setA(3345);
265     TestObject obj2;
266     obj2.setA(-19);
267
268     // Static context properties
269     ctxt.setContextProperty("a", QVariant(10));
270     ctxt.setContextProperty("b", QVariant(9));
271     ctxt2.setContextProperty("d", &obj2);
272     ctxt2.setContextProperty("b", QVariant(19));
273     ctxt2.setContextProperty("c", QVariant(QString("Hello World!")));
274     ctxt.setContextProperty("d", &obj1);
275     ctxt.setContextProperty("e", &obj1);
276
277     TEST_CONTEXT_PROPERTY(&ctxt2, a, QVariant(10));
278     TEST_CONTEXT_PROPERTY(&ctxt2, b, QVariant(19));
279     TEST_CONTEXT_PROPERTY(&ctxt2, c, QVariant(QString("Hello World!")));
280     TEST_CONTEXT_PROPERTY(&ctxt2, d.a, QVariant(-19));
281     TEST_CONTEXT_PROPERTY(&ctxt2, e.a, QVariant(3345));
282
283     ctxt.setContextProperty("a", QVariant(13));
284     ctxt.setContextProperty("b", QVariant(4));
285     ctxt2.setContextProperty("b", QVariant(8));
286     ctxt2.setContextProperty("c", QVariant(QString("Hi World!")));
287     ctxt2.setContextProperty("d", &obj1);
288     obj1.setA(12);
289
290     TEST_CONTEXT_PROPERTY(&ctxt2, a, QVariant(13));
291     TEST_CONTEXT_PROPERTY(&ctxt2, b, QVariant(8));
292     TEST_CONTEXT_PROPERTY(&ctxt2, c, QVariant(QString("Hi World!")));
293     TEST_CONTEXT_PROPERTY(&ctxt2, d.a, QVariant(12));
294     TEST_CONTEXT_PROPERTY(&ctxt2, e.a, QVariant(12));
295
296     // Changes in context properties
297     {
298         QDeclarativeComponent component(&engine); 
299         component.setData("import QtQuick 1.0; QtObject { property variant test: a }", QUrl());
300
301         QObject *obj = component.create(&ctxt2); 
302
303         QCOMPARE(obj->property("test"), QVariant(13)); 
304         ctxt.setContextProperty("a", QVariant(19));
305         QCOMPARE(obj->property("test"), QVariant(19)); 
306
307         delete obj; 
308     }
309     {
310         QDeclarativeComponent component(&engine); 
311         component.setData("import QtQuick 1.0; QtObject { property variant test: b }", QUrl());
312
313         QObject *obj = component.create(&ctxt2); 
314
315         QCOMPARE(obj->property("test"), QVariant(8)); 
316         ctxt.setContextProperty("b", QVariant(5));
317         QCOMPARE(obj->property("test"), QVariant(8)); 
318         ctxt2.setContextProperty("b", QVariant(1912));
319         QCOMPARE(obj->property("test"), QVariant(1912)); 
320
321         delete obj; 
322     }
323     {
324         QDeclarativeComponent component(&engine); 
325         component.setData("import QtQuick 1.0; QtObject { property variant test: e.a }", QUrl());
326
327         QObject *obj = component.create(&ctxt2); 
328
329         QCOMPARE(obj->property("test"), QVariant(12)); 
330         obj1.setA(13);
331         QCOMPARE(obj->property("test"), QVariant(13)); 
332
333         delete obj; 
334     }
335
336     // New context properties
337     {
338         QDeclarativeComponent component(&engine); 
339         component.setData("import QtQuick 1.0; QtObject { property variant test: a }", QUrl());
340
341         QObject *obj = component.create(&ctxt2); 
342
343         QCOMPARE(obj->property("test"), QVariant(19)); 
344         ctxt2.setContextProperty("a", QVariant(1945));
345         QCOMPARE(obj->property("test"), QVariant(1945)); 
346
347         delete obj; 
348     }
349
350     // Setting an object-variant context property
351     {
352         QDeclarativeComponent component(&engine);
353         component.setData("import QtQuick 1.0; QtObject { id: root; property int a: 10; property int test: ctxtProp.a; property variant obj: root; }", QUrl());
354
355         QDeclarativeContext ctxt(engine.rootContext());
356         ctxt.setContextProperty("ctxtProp", QVariant());
357
358         QTest::ignoreMessage(QtWarningMsg, "<Unknown File>:1: TypeError: Cannot read property 'a' of undefined");
359         QObject *obj = component.create(&ctxt);
360
361         QVariant v = obj->property("obj");
362
363         ctxt.setContextProperty("ctxtProp", v);
364
365         QCOMPARE(obj->property("test"), QVariant(10));
366
367         delete obj;
368     }
369 }
370
371 void tst_qdeclarativecontext::setContextObject()
372 {
373     QDeclarativeContext ctxt(&engine);
374
375     TestObject to;
376
377     to.setA(2);
378     to.setB(192);
379     to.setC(18);
380
381     ctxt.setContextObject(&to);
382     ctxt.setContextProperty("c", QVariant(9));
383
384     // Static context properties
385     TEST_CONTEXT_PROPERTY(&ctxt, a, QVariant(2));
386     TEST_CONTEXT_PROPERTY(&ctxt, b, QVariant(192));
387     TEST_CONTEXT_PROPERTY(&ctxt, c, QVariant(9));
388
389     to.setA(12);
390     to.setB(100);
391     to.setC(7);
392     ctxt.setContextProperty("c", QVariant(3));
393
394     TEST_CONTEXT_PROPERTY(&ctxt, a, QVariant(12));
395     TEST_CONTEXT_PROPERTY(&ctxt, b, QVariant(100));
396     TEST_CONTEXT_PROPERTY(&ctxt, c, QVariant(3));
397
398     // Changes in context properties
399     {
400         QDeclarativeComponent component(&engine); 
401         component.setData("import QtQuick 1.0; QtObject { property variant test: a }", QUrl());
402
403         QObject *obj = component.create(&ctxt); 
404
405         QCOMPARE(obj->property("test"), QVariant(12)); 
406         to.setA(14);
407         QCOMPARE(obj->property("test"), QVariant(14)); 
408
409         delete obj; 
410     }
411 }
412
413 void tst_qdeclarativecontext::destruction()
414 {
415     QDeclarativeContext *ctxt = new QDeclarativeContext(&engine);
416
417     QObject obj;
418     QDeclarativeEngine::setContextForObject(&obj, ctxt);
419     QDeclarativeExpression expr(ctxt, 0, "a");
420
421     QCOMPARE(ctxt, QDeclarativeEngine::contextForObject(&obj));
422     QCOMPARE(ctxt, expr.context());
423
424     delete ctxt; ctxt = 0;
425
426     QCOMPARE(ctxt, QDeclarativeEngine::contextForObject(&obj));
427     QCOMPARE(ctxt, expr.context());
428 }
429
430 void tst_qdeclarativecontext::idAsContextProperty()
431 {
432     QDeclarativeComponent component(&engine);
433     component.setData("import QtQuick 1.0; QtObject { property variant a; a: QtObject { id: myObject } }", QUrl());
434
435     QObject *obj = component.create();
436     QVERIFY(obj);
437
438     QVariant a = obj->property("a");
439     QVERIFY(a.userType() == QMetaType::QObjectStar);
440
441     QVariant ctxt = qmlContext(obj)->contextProperty("myObject");
442     QVERIFY(ctxt.userType() == QMetaType::QObjectStar);
443
444     QVERIFY(a == ctxt);
445
446     delete obj;
447 }
448
449 // Internal contexts should be read-only
450 void tst_qdeclarativecontext::readOnlyContexts()
451 {
452     QDeclarativeComponent component(&engine);
453     component.setData("import QtQuick 1.0; QtObject { id: me }", QUrl());
454
455     QObject *obj = component.create();
456     QVERIFY(obj);
457
458     QDeclarativeContext *context = qmlContext(obj);
459     QVERIFY(context);
460
461     QVERIFY(qvariant_cast<QObject*>(context->contextProperty("me")) == obj);
462     QVERIFY(context->contextObject() == obj);
463
464     QTest::ignoreMessage(QtWarningMsg, "QDeclarativeContext: Cannot set property on internal context.");
465     context->setContextProperty("hello", 12);
466     QVERIFY(context->contextProperty("hello") == QVariant());
467
468     QTest::ignoreMessage(QtWarningMsg, "QDeclarativeContext: Cannot set property on internal context.");
469     context->setContextProperty("hello", obj);
470     QVERIFY(context->contextProperty("hello") == QVariant());
471
472     QTest::ignoreMessage(QtWarningMsg, "QDeclarativeContext: Cannot set context object for internal context.");
473     context->setContextObject(0);
474     QVERIFY(context->contextObject() == obj);
475
476     delete obj;
477 }
478
479 void tst_qdeclarativecontext::nameForObject()
480 {
481     QObject o1;
482     QObject o2;
483     QObject o3;
484
485     QDeclarativeEngine engine;
486
487     // As a context property
488     engine.rootContext()->setContextProperty("o1", &o1);
489     engine.rootContext()->setContextProperty("o2", &o2);
490     engine.rootContext()->setContextProperty("o1_2", &o1);
491
492     QCOMPARE(engine.rootContext()->nameForObject(&o1), QString("o1"));
493     QCOMPARE(engine.rootContext()->nameForObject(&o2), QString("o2"));
494     QCOMPARE(engine.rootContext()->nameForObject(&o3), QString());
495
496     // As an id
497     QDeclarativeComponent component(&engine);
498     component.setData("import QtQuick 1.0; QtObject { id: root; property QtObject o: QtObject { id: nested } }", QUrl());
499
500     QObject *o = component.create();
501     QVERIFY(o != 0);
502
503     QCOMPARE(qmlContext(o)->nameForObject(o), QString("root"));
504     QCOMPARE(qmlContext(o)->nameForObject(qvariant_cast<QObject*>(o->property("o"))), QString("nested"));
505     QCOMPARE(qmlContext(o)->nameForObject(&o1), QString());
506
507     delete o;
508 }
509
510 class DeleteCommand : public QObject
511 {
512 Q_OBJECT
513 public:
514     DeleteCommand() : object(0) {}
515
516     QObject *object;
517
518 public slots:
519     void doCommand() { if (object) delete object; object = 0; }
520 };
521
522 // Calling refresh expressions would crash if an expression or context was deleted during
523 // the refreshing
524 void tst_qdeclarativecontext::refreshExpressionsCrash()
525 {
526     {
527     QDeclarativeEngine engine;
528
529     DeleteCommand command;
530     engine.rootContext()->setContextProperty("deleteCommand", &command);
531     // We use a fresh context here to bypass any root-context optimizations in
532     // the engine
533     QDeclarativeContext ctxt(engine.rootContext());
534
535     QDeclarativeComponent component(&engine);
536     component.setData("import QtQuick 2.0; QtObject { property var binding: deleteCommand.doCommand() }", QUrl());
537     QVERIFY(component.isReady());
538
539     QObject *o1 = component.create(&ctxt);
540     QObject *o2 = component.create(&ctxt);
541
542     command.object = o2;
543
544     QDeclarativeContextData::get(&ctxt)->refreshExpressions();
545
546     delete o1;
547     }
548     {
549     QDeclarativeEngine engine;
550
551     DeleteCommand command;
552     engine.rootContext()->setContextProperty("deleteCommand", &command);
553     // We use a fresh context here to bypass any root-context optimizations in
554     // the engine
555     QDeclarativeContext ctxt(engine.rootContext());
556
557     QDeclarativeComponent component(&engine);
558     component.setData("import QtQuick 2.0; QtObject { property var binding: deleteCommand.doCommand() }", QUrl());
559     QVERIFY(component.isReady());
560
561     QObject *o1 = component.create(&ctxt);
562     QObject *o2 = component.create(&ctxt);
563
564     command.object = o1;
565
566     QDeclarativeContextData::get(&ctxt)->refreshExpressions();
567
568     delete o2;
569     }
570 }
571
572 class CountCommand : public QObject
573 {
574 Q_OBJECT
575 public:
576     CountCommand() : count(0) {}
577
578     int count;
579
580 public slots:
581     void doCommand() { ++count; }
582 };
583
584
585 // Test that calling refresh expressions causes all the expressions to refresh
586 void tst_qdeclarativecontext::refreshExpressions()
587 {
588     QDeclarativeEngine engine;
589     QDeclarativeComponent component(&engine, TEST_FILE("refreshExpressions.qml"));
590     QDeclarativeComponent component2(&engine, TEST_FILE("RefreshExpressionsType.qml"));
591
592     CountCommand command;
593     engine.rootContext()->setContextProperty("countCommand", &command);
594
595     // We use a fresh context here to bypass any root-context optimizations in
596     // the engine
597     QDeclarativeContext context(engine.rootContext());
598     QDeclarativeContext context2(&context);
599
600     QObject *o1 = component.create(&context);
601     QObject *o2 = component.create(&context2);
602     QObject *o3 = component2.create(&context);
603
604     QCOMPARE(command.count, 5);
605
606     QDeclarativeContextData::get(&context)->refreshExpressions();
607
608     QCOMPARE(command.count, 10);
609
610     delete o3;
611     delete o2;
612     delete o1;
613 }
614
615 // Test that updating the root context, only causes expressions in contexts with an
616 // unresolved name to reevaluate
617 void tst_qdeclarativecontext::refreshExpressionsRootContext()
618 {
619     QDeclarativeEngine engine;
620
621     CountCommand command;
622     engine.rootContext()->setContextProperty("countCommand", &command);
623
624     QDeclarativeComponent component(&engine, TEST_FILE("refreshExpressions.qml"));
625     QDeclarativeComponent component2(&engine, TEST_FILE("refreshExpressionsRootContext.qml"));
626
627     QDeclarativeContext context(engine.rootContext());
628     QDeclarativeContext context2(engine.rootContext());
629
630     QString warning = component2.url().toString() + QLatin1String(":4: ReferenceError: Can't find variable: unresolvedName");
631
632     QObject *o1 = component.create(&context);
633
634     QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
635     QObject *o2 = component2.create(&context2);
636
637     QCOMPARE(command.count, 3);
638
639     QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
640     QDeclarativeContextData::get(engine.rootContext())->refreshExpressions();
641
642     QCOMPARE(command.count, 4);
643
644     delete o2;
645     delete o1;
646 }
647
648 void tst_qdeclarativecontext::qtbug_22535()
649 {
650     QDeclarativeEngine engine;
651     QDeclarativeComponent component(&engine, TEST_FILE("qtbug_22535.qml"));
652     QDeclarativeContext context(engine.rootContext());
653
654     QObject *o = component.create(&context);
655
656     // Don't crash!
657     delete o;
658 }
659
660 QTEST_MAIN(tst_qdeclarativecontext)
661
662 #include "tst_qdeclarativecontext.moc"