Fix test fails related to QTBUG-22237
[profile/ivi/qtdeclarative.git] / tests / auto / declarative / qquickfocusscope / tst_qquickfocusscope.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 #include <qtest.h>
42 #include <QSignalSpy>
43 #include <QtDeclarative/qdeclarativeengine.h>
44 #include <QtDeclarative/qdeclarativecomponent.h>
45 #include <QtDeclarative/qquickview.h>
46 #include <private/qquickrectangle_p.h>
47 #include <private/qquicktextedit_p.h>
48 #include <private/qquicktext_p.h>
49 #include <QtDeclarative/private/qquickfocusscope_p.h>
50 #include "../shared/util.h"
51
52 class tst_qquickfocusscope : public QObject
53 {
54     Q_OBJECT
55 public:
56     tst_qquickfocusscope() {}
57
58     template<typename T>
59     T *findItem(QQuickItem *parent, const QString &id);
60
61 private slots:
62     void initTestCase();
63     void cleanupTestCase();
64     void basic();
65     void nested();
66     void noFocus();
67     void textEdit();
68     void forceFocus();
69     void noParentFocus();
70     void signalEmission();
71     void qtBug13380();
72     void forceActiveFocus();
73     void canvasFocus();
74 };
75 void tst_qquickfocusscope::initTestCase()
76 {
77 }
78
79 void tst_qquickfocusscope::cleanupTestCase()
80 {
81
82 }
83
84 /*
85    Find an item with the specified id.
86 */
87 template<typename T>
88 T *tst_qquickfocusscope::findItem(QQuickItem *parent, const QString &objectName)
89 {
90     const QMetaObject &mo = T::staticMetaObject;
91     QList<QQuickItem *> children = parent->childItems();
92     for (int i = 0; i < children.count(); ++i) {
93         QQuickItem *item = children.at(i);
94         if (item) {
95             if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
96                 return static_cast<T*>(item);
97             }
98             item = findItem<T>(item, objectName);
99             if (item)
100                 return static_cast<T*>(item);
101         }
102     }
103     return 0;
104 }
105
106 void tst_qquickfocusscope::basic()
107 {
108     QQuickView *view = new QQuickView;
109     view->setSource(QUrl::fromLocalFile(TESTDATA("test.qml")));
110
111     QQuickFocusScope *item0 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item0"));
112     QQuickRectangle *item1 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item1"));
113     QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2"));
114     QQuickRectangle *item3 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item3"));
115     QVERIFY(item0 != 0);
116     QVERIFY(item1 != 0);
117     QVERIFY(item2 != 0);
118     QVERIFY(item3 != 0);
119
120     view->show();
121     view->requestActivateWindow();
122
123     QTest::qWaitForWindowShown(view);
124
125     QVERIFY(view->isTopLevel());
126     QVERIFY(item0->hasActiveFocus() == true);
127     QVERIFY(item1->hasActiveFocus() == true);
128     QVERIFY(item2->hasActiveFocus() == false);
129     QVERIFY(item3->hasActiveFocus() == false);
130
131     QTest::keyClick(view, Qt::Key_Right);
132     QTest::qWait(50);
133     QVERIFY(item0->hasActiveFocus() == true);
134     QVERIFY(item1->hasActiveFocus() == false);
135     QVERIFY(item2->hasActiveFocus() == true);
136     QVERIFY(item3->hasActiveFocus() == false);
137
138     QTest::keyClick(view, Qt::Key_Down);
139     QTest::qWait(50);
140     QVERIFY(item0->hasActiveFocus() == false);
141     QVERIFY(item1->hasActiveFocus() == false);
142     QVERIFY(item2->hasActiveFocus() == false);
143     QVERIFY(item3->hasActiveFocus() == true);
144
145     delete view;
146 }
147
148 void tst_qquickfocusscope::nested()
149 {
150     QQuickView *view = new QQuickView;
151     view->setSource(QUrl::fromLocalFile(TESTDATA("test2.qml")));
152
153     QQuickFocusScope *item1 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item1"));
154     QQuickFocusScope *item2 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item2"));
155     QQuickFocusScope *item3 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item3"));
156     QQuickFocusScope *item4 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item4"));
157     QQuickFocusScope *item5 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item5"));
158     QVERIFY(item1 != 0);
159     QVERIFY(item2 != 0);
160     QVERIFY(item3 != 0);
161     QVERIFY(item4 != 0);
162     QVERIFY(item5 != 0);
163
164     view->show();
165     view->requestActivateWindow();
166
167     QTest::qWaitForWindowShown(view);
168
169     QVERIFY(item1->hasActiveFocus() == true);
170     QVERIFY(item2->hasActiveFocus() == true);
171     QVERIFY(item3->hasActiveFocus() == true);
172     QVERIFY(item4->hasActiveFocus() == true);
173     QVERIFY(item5->hasActiveFocus() == true);
174     delete view;
175 }
176
177 void tst_qquickfocusscope::noFocus()
178 {
179     QQuickView *view = new QQuickView;
180     view->setSource(QUrl::fromLocalFile(TESTDATA("test4.qml")));
181
182     QQuickRectangle *item0 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item0"));
183     QQuickRectangle *item1 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item1"));
184     QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2"));
185     QQuickRectangle *item3 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item3"));
186     QVERIFY(item0 != 0);
187     QVERIFY(item1 != 0);
188     QVERIFY(item2 != 0);
189     QVERIFY(item3 != 0);
190
191     view->show();
192     view->requestActivateWindow();
193     QTest::qWaitForWindowShown(view);
194
195     QVERIFY(item0->hasActiveFocus() == false);
196     QVERIFY(item1->hasActiveFocus() == false);
197     QVERIFY(item2->hasActiveFocus() == false);
198     QVERIFY(item3->hasActiveFocus() == false);
199
200     QTest::keyClick(view, Qt::Key_Right);
201     QVERIFY(item0->hasActiveFocus() == false);
202     QVERIFY(item1->hasActiveFocus() == false);
203     QVERIFY(item2->hasActiveFocus() == false);
204     QVERIFY(item3->hasActiveFocus() == false);
205
206     QTest::keyClick(view, Qt::Key_Down);
207     QVERIFY(item0->hasActiveFocus() == false);
208     QVERIFY(item1->hasActiveFocus() == false);
209     QVERIFY(item2->hasActiveFocus() == false);
210     QVERIFY(item3->hasActiveFocus() == false);
211
212     delete view;
213 }
214
215 void tst_qquickfocusscope::textEdit()
216 {
217     QQuickView *view = new QQuickView;
218     view->setSource(QUrl::fromLocalFile(TESTDATA("test5.qml")));
219
220     QQuickFocusScope *item0 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item0"));
221     QQuickTextEdit *item1 = findItem<QQuickTextEdit>(view->rootObject(), QLatin1String("item1"));
222     QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2"));
223     QQuickTextEdit *item3 = findItem<QQuickTextEdit>(view->rootObject(), QLatin1String("item3"));
224     QVERIFY(item0 != 0);
225     QVERIFY(item1 != 0);
226     QVERIFY(item2 != 0);
227     QVERIFY(item3 != 0);
228
229     view->show();
230     view->requestActivateWindow();
231
232     QTest::qWaitForWindowShown(view);
233
234     QTRY_VERIFY(view == qGuiApp->focusWindow());
235     QVERIFY(item0->hasActiveFocus() == true);
236     QVERIFY(item1->hasActiveFocus() == true);
237     QVERIFY(item2->hasActiveFocus() == false);
238     QVERIFY(item3->hasActiveFocus() == false);
239
240     QTest::keyClick(view, Qt::Key_Right);
241     QVERIFY(item0->hasActiveFocus() == true);
242     QVERIFY(item1->hasActiveFocus() == true);
243     QVERIFY(item2->hasActiveFocus() == false);
244     QVERIFY(item3->hasActiveFocus() == false);
245
246     QTest::keyClick(view, Qt::Key_Right);
247     QTest::keyClick(view, Qt::Key_Right);
248     QTest::keyClick(view, Qt::Key_Right);
249     QTest::keyClick(view, Qt::Key_Right);
250     QTest::keyClick(view, Qt::Key_Right);
251     QVERIFY(item0->hasActiveFocus() == true);
252     QVERIFY(item1->hasActiveFocus() == false);
253     QVERIFY(item2->hasActiveFocus() == true);
254     QVERIFY(item3->hasActiveFocus() == false);
255
256     QTest::keyClick(view, Qt::Key_Down);
257     QVERIFY(item0->hasActiveFocus() == false);
258     QVERIFY(item1->hasActiveFocus() == false);
259     QVERIFY(item2->hasActiveFocus() == false);
260     QVERIFY(item3->hasActiveFocus() == true);
261
262     delete view;
263 }
264
265 void tst_qquickfocusscope::forceFocus()
266 {
267     QQuickView *view = new QQuickView;
268     view->setSource(QUrl::fromLocalFile(TESTDATA("forcefocus.qml")));
269
270     QQuickFocusScope *item0 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item0"));
271     QQuickRectangle *item1 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item1"));
272     QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2"));
273     QQuickFocusScope *item3 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item3"));
274     QQuickRectangle *item4 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item4"));
275     QQuickRectangle *item5 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item5"));
276     QVERIFY(item0 != 0);
277     QVERIFY(item1 != 0);
278     QVERIFY(item2 != 0);
279     QVERIFY(item3 != 0);
280     QVERIFY(item4 != 0);
281     QVERIFY(item5 != 0);
282
283     view->show();
284     view->requestActivateWindow();
285     QTest::qWaitForWindowShown(view);
286
287     QVERIFY(item0->hasActiveFocus() == true);
288     QVERIFY(item1->hasActiveFocus() == true);
289     QVERIFY(item2->hasActiveFocus() == false);
290     QVERIFY(item3->hasActiveFocus() == false);
291     QVERIFY(item4->hasActiveFocus() == false);
292     QVERIFY(item5->hasActiveFocus() == false);
293
294     QTest::keyClick(view, Qt::Key_4);
295     QVERIFY(item0->hasActiveFocus() == true);
296     QVERIFY(item1->hasActiveFocus() == true);
297     QVERIFY(item2->hasActiveFocus() == false);
298     QVERIFY(item3->hasActiveFocus() == false);
299     QVERIFY(item4->hasActiveFocus() == false);
300     QVERIFY(item5->hasActiveFocus() == false);
301
302     QTest::keyClick(view, Qt::Key_5);
303     QVERIFY(item0->hasActiveFocus() == false);
304     QVERIFY(item1->hasActiveFocus() == false);
305     QVERIFY(item2->hasActiveFocus() == false);
306     QVERIFY(item3->hasActiveFocus() == true);
307     QVERIFY(item4->hasActiveFocus() == false);
308     QVERIFY(item5->hasActiveFocus() == true);
309
310     delete view;
311 }
312
313 void tst_qquickfocusscope::noParentFocus()
314 {
315     QQuickView *view = new QQuickView;
316     view->setSource(QUrl::fromLocalFile(TESTDATA("chain.qml")));
317     QVERIFY(view->rootObject());
318
319     view->show();
320     view->requestActivateWindow();
321     qApp->processEvents();
322
323 #ifdef Q_WS_X11
324     // to be safe and avoid failing setFocus with window managers
325     qt_x11_wait_for_window_manager(view);
326 #endif
327
328     QVERIFY(view->rootObject()->property("focus1") == false);
329     QVERIFY(view->rootObject()->property("focus2") == false);
330     QVERIFY(view->rootObject()->property("focus3") == true);
331     QVERIFY(view->rootObject()->property("focus4") == true);
332     QVERIFY(view->rootObject()->property("focus5") == true);
333
334     delete view;
335 }
336
337 void tst_qquickfocusscope::signalEmission()
338 {
339     QQuickView *view = new QQuickView;
340     view->setSource(QUrl::fromLocalFile(TESTDATA("signalEmission.qml")));
341
342     QQuickRectangle *item1 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item1"));
343     QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2"));
344     QQuickRectangle *item3 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item3"));
345     QQuickRectangle *item4 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item4"));
346     QVERIFY(item1 != 0);
347     QVERIFY(item2 != 0);
348     QVERIFY(item3 != 0);
349     QVERIFY(item4 != 0);
350
351     view->show();
352     view->requestActivateWindow();
353
354     QTest::qWaitForWindowShown(view);
355
356     QVariant blue(QColor("blue"));
357     QVariant red(QColor("red"));
358
359     item1->setFocus(true);
360     QCOMPARE(item1->property("color"), red);
361     QCOMPARE(item2->property("color"), blue);
362     QCOMPARE(item3->property("color"), blue);
363     QCOMPARE(item4->property("color"), blue);
364
365     item2->setFocus(true);
366     QCOMPARE(item1->property("color"), blue);
367     QCOMPARE(item2->property("color"), red);
368     QCOMPARE(item3->property("color"), blue);
369     QCOMPARE(item4->property("color"), blue);
370
371     item3->setFocus(true);
372     QCOMPARE(item1->property("color"), blue);
373     QCOMPARE(item2->property("color"), red);
374     QCOMPARE(item3->property("color"), red);
375     QCOMPARE(item4->property("color"), blue);
376
377     item4->setFocus(true);
378     QCOMPARE(item1->property("color"), blue);
379     QCOMPARE(item2->property("color"), red);
380     QCOMPARE(item3->property("color"), blue);
381     QCOMPARE(item4->property("color"), red);
382
383     item4->setFocus(false);
384     QCOMPARE(item1->property("color"), blue);
385     QCOMPARE(item2->property("color"), red);
386     QCOMPARE(item3->property("color"), blue);
387     QCOMPARE(item4->property("color"), blue);
388
389     delete view;
390 }
391
392 void tst_qquickfocusscope::qtBug13380()
393 {
394     QQuickView *view = new QQuickView;
395     view->setSource(QUrl::fromLocalFile(TESTDATA("qtBug13380.qml")));
396
397     view->show();
398     QVERIFY(view->rootObject());
399     view->requestActivateWindow();
400     qApp->processEvents();
401
402     QTest::qWaitForWindowShown(view);
403
404     QTRY_VERIFY(view == qGuiApp->focusWindow());
405     QVERIFY(view->rootObject()->property("noFocus").toBool());
406
407     view->rootObject()->setProperty("showRect", true);
408     QVERIFY(view->rootObject()->property("noFocus").toBool());
409
410     delete view;
411 }
412
413 void tst_qquickfocusscope::forceActiveFocus()
414 {
415     QQuickView *view = new QQuickView;
416     view->setSource(QUrl::fromLocalFile(TESTDATA("forceActiveFocus.qml")));
417
418     view->show();
419     view->requestActivateWindow();
420     qApp->processEvents();
421
422 #ifdef Q_WS_X11
423     // to be safe and avoid failing setFocus with window managers
424     qt_x11_wait_for_window_manager(view);
425 #endif
426
427     QQuickItem *rootObject = view->rootObject();
428     QVERIFY(rootObject);
429
430     QQuickItem *scope = findItem<QQuickItem>(rootObject, QLatin1String("scope"));
431     QQuickItem *itemA1 = findItem<QQuickItem>(rootObject, QLatin1String("item-a1"));
432     QQuickItem *scopeA = findItem<QQuickItem>(rootObject, QLatin1String("scope-a"));
433     QQuickItem *itemA2 = findItem<QQuickItem>(rootObject, QLatin1String("item-a2"));
434     QQuickItem *itemB1 = findItem<QQuickItem>(rootObject, QLatin1String("item-b1"));
435     QQuickItem *scopeB = findItem<QQuickItem>(rootObject, QLatin1String("scope-b"));
436     QQuickItem *itemB2 = findItem<QQuickItem>(rootObject, QLatin1String("item-b2"));
437
438     QVERIFY(scope);
439     QVERIFY(itemA1);
440     QVERIFY(scopeA);
441     QVERIFY(itemA2);
442     QVERIFY(itemB1);
443     QVERIFY(scopeB);
444     QVERIFY(itemB2);
445
446     QSignalSpy rootSpy(rootObject, SIGNAL(activeFocusChanged(bool)));
447     QSignalSpy scopeSpy(scope, SIGNAL(activeFocusChanged(bool)));
448     QSignalSpy scopeASpy(scopeA, SIGNAL(activeFocusChanged(bool)));
449     QSignalSpy scopeBSpy(scopeB, SIGNAL(activeFocusChanged(bool)));
450
451     // First, walk the focus from item-a1 down to item-a2 and back again
452     itemA1->forceActiveFocus();
453     QVERIFY(itemA1->hasActiveFocus());
454     QVERIFY(!rootObject->hasActiveFocus());
455     QCOMPARE(rootSpy.count(), 0);
456     QCOMPARE(scopeSpy.count(), 1);
457
458     scopeA->forceActiveFocus();
459     QVERIFY(!itemA1->hasActiveFocus());
460     QVERIFY(scopeA->hasActiveFocus());
461     QCOMPARE(scopeASpy.count(), 1);
462     QCOMPARE(rootSpy.count(), 0);
463     QCOMPARE(scopeSpy.count(), 1);
464
465     itemA2->forceActiveFocus();
466     QVERIFY(!itemA1->hasActiveFocus());
467     QVERIFY(itemA2->hasActiveFocus());
468     QVERIFY(scopeA->hasActiveFocus());
469     QCOMPARE(scopeASpy.count(), 1);
470     QCOMPARE(rootSpy.count(), 0);
471     QCOMPARE(scopeSpy.count(), 1);
472
473     scopeA->forceActiveFocus();
474     QVERIFY(!itemA1->hasActiveFocus());
475     QVERIFY(itemA2->hasActiveFocus());
476     QVERIFY(scopeA->hasActiveFocus());
477     QCOMPARE(scopeASpy.count(), 1);
478     QCOMPARE(rootSpy.count(), 0);
479     QCOMPARE(scopeSpy.count(), 1);
480
481     itemA1->forceActiveFocus();
482     QVERIFY(itemA1->hasActiveFocus());
483     QVERIFY(!scopeA->hasActiveFocus());
484     QVERIFY(!itemA2->hasActiveFocus());
485     QCOMPARE(scopeASpy.count(), 2);
486     QCOMPARE(rootSpy.count(), 0);
487     QCOMPARE(scopeSpy.count(), 1);
488
489     // Then jump back and forth between branch 'a' and 'b'
490     itemB1->forceActiveFocus();
491     QVERIFY(itemB1->hasActiveFocus());
492     QCOMPARE(rootSpy.count(), 0);
493     QCOMPARE(scopeSpy.count(), 1);
494
495     scopeA->forceActiveFocus();
496     QVERIFY(!itemA1->hasActiveFocus());
497     QVERIFY(!itemB1->hasActiveFocus());
498     QVERIFY(scopeA->hasActiveFocus());
499     QCOMPARE(scopeASpy.count(), 3);
500     QCOMPARE(rootSpy.count(), 0);
501     QCOMPARE(scopeSpy.count(), 1);
502
503     scopeB->forceActiveFocus();
504     QVERIFY(!scopeA->hasActiveFocus());
505     QVERIFY(!itemB1->hasActiveFocus());
506     QVERIFY(scopeB->hasActiveFocus());
507     QCOMPARE(scopeASpy.count(), 4);
508     QCOMPARE(scopeBSpy.count(), 1);
509     QCOMPARE(rootSpy.count(), 0);
510     QCOMPARE(scopeSpy.count(), 1);
511
512     itemA2->forceActiveFocus();
513     QVERIFY(!scopeB->hasActiveFocus());
514     QVERIFY(itemA2->hasActiveFocus());
515     QCOMPARE(scopeASpy.count(), 5);
516     QCOMPARE(scopeBSpy.count(), 2);
517     QCOMPARE(rootSpy.count(), 0);
518     QCOMPARE(scopeSpy.count(), 1);
519
520     itemB2->forceActiveFocus();
521     QVERIFY(!itemA2->hasActiveFocus());
522     QVERIFY(itemB2->hasActiveFocus());
523     QCOMPARE(scopeASpy.count(), 6);
524     QCOMPARE(scopeBSpy.count(), 3);
525     QCOMPARE(rootSpy.count(), 0);
526     QCOMPARE(scopeSpy.count(), 1);
527
528     delete view;
529 }
530
531 void tst_qquickfocusscope::canvasFocus()
532 {
533     QQuickView *view = new QQuickView;
534     view->setSource(QUrl::fromLocalFile(TESTDATA("canvasFocus.qml")));
535
536     QQuickItem *rootObject = view->rootObject();
537     QVERIFY(rootObject);
538
539     QQuickItem *rootItem = view->rootItem();
540     QQuickItem *scope1 = findItem<QQuickItem>(rootObject, QLatin1String("scope1"));
541     QQuickItem *item1 = findItem<QQuickItem>(rootObject, QLatin1String("item1"));
542     QQuickItem *scope2 = findItem<QQuickItem>(rootObject, QLatin1String("scope2"));
543     QQuickItem *item2 = findItem<QQuickItem>(rootObject, QLatin1String("item2"));
544
545     QVERIFY(scope1);
546     QVERIFY(item1);
547     QVERIFY(scope2);
548     QVERIFY(item2);
549
550     QSignalSpy rootFocusSpy(rootItem, SIGNAL(focusChanged(bool)));
551     QSignalSpy scope1FocusSpy(scope1, SIGNAL(focusChanged(bool)));
552     QSignalSpy item1FocusSpy(item1, SIGNAL(focusChanged(bool)));
553     QSignalSpy scope2FocusSpy(scope2, SIGNAL(focusChanged(bool)));
554     QSignalSpy item2FocusSpy(item2, SIGNAL(focusChanged(bool)));
555     QSignalSpy rootActiveFocusSpy(rootItem, SIGNAL(activeFocusChanged(bool)));
556     QSignalSpy scope1ActiveFocusSpy(scope1, SIGNAL(activeFocusChanged(bool)));
557     QSignalSpy item1ActiveFocusSpy(item1, SIGNAL(activeFocusChanged(bool)));
558     QSignalSpy scope2ActiveFocusSpy(scope2, SIGNAL(activeFocusChanged(bool)));
559     QSignalSpy item2ActiveFocusSpy(item2, SIGNAL(activeFocusChanged(bool)));
560
561     QEXPECT_FAIL("", "QTBUG-21054 - Root item hasFocus returns true already", Abort);
562
563     QCOMPARE(rootItem->hasFocus(), false);
564     QCOMPARE(rootItem->hasActiveFocus(), false);
565     QCOMPARE(scope1->hasFocus(), true);
566     QCOMPARE(scope1->hasActiveFocus(), false);
567     QCOMPARE(item1->hasFocus(), true);
568     QCOMPARE(item1->hasActiveFocus(), false);
569     QCOMPARE(scope2->hasFocus(), false);
570     QCOMPARE(scope2->hasActiveFocus(), false);
571     QCOMPARE(item2->hasFocus(), false);
572     QCOMPARE(item2->hasActiveFocus(), false);
573
574     view->show();
575     view->requestActivateWindow();
576
577     QTest::qWaitForWindowShown(view);
578
579     // Now the canvas has focus, active focus given to item1
580     QCOMPARE(rootItem->hasFocus(), true);
581     QCOMPARE(rootItem->hasActiveFocus(), true);
582     QCOMPARE(scope1->hasFocus(), true);
583     QCOMPARE(scope1->hasActiveFocus(), true);
584     QCOMPARE(item1->hasFocus(), true);
585     QCOMPARE(item1->hasActiveFocus(), true);
586     QCOMPARE(scope2->hasFocus(), false);
587     QCOMPARE(scope2->hasActiveFocus(), false);
588     QCOMPARE(item2->hasFocus(), false);
589     QCOMPARE(item2->hasActiveFocus(), false);
590     QCOMPARE(rootFocusSpy.count(), 1);
591     QCOMPARE(rootActiveFocusSpy.count(), 1);
592     QCOMPARE(scope1FocusSpy.count(), 0);
593     QCOMPARE(scope1ActiveFocusSpy.count(), 1);
594     QCOMPARE(item1FocusSpy.count(), 0);
595     QCOMPARE(item1ActiveFocusSpy.count(), 1);
596
597
598     view->hide();
599     QCOMPARE(rootItem->hasFocus(), false);
600     QCOMPARE(rootItem->hasActiveFocus(), false);
601     QCOMPARE(scope1->hasFocus(), true);
602     QCOMPARE(scope1->hasActiveFocus(), false);
603     QCOMPARE(item1->hasFocus(), true);
604     QCOMPARE(item1->hasActiveFocus(), false);
605     QCOMPARE(rootFocusSpy.count(), 2);
606     QCOMPARE(rootActiveFocusSpy.count(), 2);
607     QCOMPARE(scope1FocusSpy.count(), 0);
608     QCOMPARE(scope1ActiveFocusSpy.count(), 2);
609     QCOMPARE(item1FocusSpy.count(), 0);
610     QCOMPARE(item1ActiveFocusSpy.count(), 2);
611
612     // canvas does not have focus, so item2 will not get active focus
613     item2->forceActiveFocus();
614
615     QCOMPARE(rootItem->hasFocus(), false);
616     QCOMPARE(rootItem->hasActiveFocus(), false);
617     QCOMPARE(scope1->hasFocus(), false);
618     QCOMPARE(scope1->hasActiveFocus(), false);
619     QCOMPARE(item1->hasFocus(), true);
620     QCOMPARE(item1->hasActiveFocus(), false);
621     QCOMPARE(scope2->hasFocus(), true);
622     QCOMPARE(scope2->hasActiveFocus(), false);
623     QCOMPARE(item2->hasFocus(), true);
624     QCOMPARE(item2->hasActiveFocus(), false);
625
626     QCOMPARE(rootFocusSpy.count(), 2);
627     QCOMPARE(rootActiveFocusSpy.count(), 2);
628     QCOMPARE(scope1FocusSpy.count(), 1);
629     QCOMPARE(scope1ActiveFocusSpy.count(), 2);
630     QCOMPARE(item1FocusSpy.count(), 0);
631     QCOMPARE(item1ActiveFocusSpy.count(), 2);
632     QCOMPARE(scope2FocusSpy.count(), 1);
633     QCOMPARE(scope2ActiveFocusSpy.count(), 0);
634     QCOMPARE(item2FocusSpy.count(), 1);
635     QCOMPARE(item2ActiveFocusSpy.count(), 0);
636
637     // give the canvas focus, and item2 will get active focus
638     view->show();
639
640     QCOMPARE(rootItem->hasFocus(), true);
641     QCOMPARE(rootItem->hasActiveFocus(), true);
642     QCOMPARE(scope2->hasFocus(), true);
643     QCOMPARE(scope2->hasActiveFocus(), true);
644     QCOMPARE(item2->hasFocus(), true);
645     QCOMPARE(item2->hasActiveFocus(), true);
646     QCOMPARE(rootFocusSpy.count(), 3);
647     QCOMPARE(rootActiveFocusSpy.count(), 3);
648     QCOMPARE(scope2FocusSpy.count(), 1);
649     QCOMPARE(scope2ActiveFocusSpy.count(), 1);
650     QCOMPARE(item2FocusSpy.count(), 1);
651     QCOMPARE(item2ActiveFocusSpy.count(), 1);
652
653     delete view;
654 }
655
656 QTEST_MAIN(tst_qquickfocusscope)
657
658 #include "tst_qquickfocusscope.moc"