Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / tests / auto / qtquick2 / qquickaccessible / tst_qquickaccessible.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42
43 #include <QtTest/QtTest>
44 #include "QtTest/qtestaccessible.h"
45
46 #include <QtGui/qaccessible.h>
47
48 #include <QtQuick/qquickview.h>
49 #include <QtQuick/qquickitem.h>
50
51 #include <QtDeclarative/qdeclarativeengine.h>
52 #include <QtDeclarative/qdeclarativeproperty.h>
53 #include <QtQuick/private/qquickaccessibleattached_p.h>
54
55 #include "../../shared/util.h"
56
57
58 typedef QSharedPointer<QAccessibleInterface> QAI;
59
60 #define EXPECT(cond) \
61     do { \
62         if (!errorAt && !(cond)) { \
63             errorAt = __LINE__; \
64             qWarning("level: %d, middle: %d, role: %d (%s)", treelevel, middle, iface->role(), #cond); \
65         } \
66     } while (0)
67
68 static int verifyHierarchy(QAccessibleInterface *iface)
69 {
70     int errorAt = 0;
71     static int treelevel = 0;   // for error diagnostics
72     QAccessibleInterface *middleChild, *if2;
73     middleChild = 0;
74     ++treelevel;
75     int middle = iface->childCount()/2 + 1;
76     if (iface->childCount() >= 2) {
77         middleChild = iface->child(middle - 1);
78     }
79     for (int i = 0; i < iface->childCount() && !errorAt; ++i) {
80         if2 = iface->child(i);
81         EXPECT(if2 != 0);
82         // navigate Ancestor...
83         QAccessibleInterface *parent = if2->parent();
84         EXPECT(iface->object() == parent->object());
85         delete parent;
86
87         // verify children...
88         if (!errorAt)
89             errorAt = verifyHierarchy(if2);
90         delete if2;
91     }
92     delete middleChild;
93
94     --treelevel;
95     return errorAt;
96 }
97
98
99 //TESTED_FILES=
100
101 class tst_QQuickAccessible : public QDeclarativeDataTest
102 {
103     Q_OBJECT
104 public:
105     tst_QQuickAccessible();
106     virtual ~tst_QQuickAccessible();
107
108 private slots:
109     void commonTests_data();
110     void commonTests();
111
112     void declarativeAttachedProperties();
113     void basicPropertiesTest();
114     void hitTest();
115     void checkableTest();
116 };
117
118 tst_QQuickAccessible::tst_QQuickAccessible()
119 {
120
121 }
122
123 tst_QQuickAccessible::~tst_QQuickAccessible()
124 {
125
126 }
127
128 void tst_QQuickAccessible::commonTests_data()
129 {
130     QTest::addColumn<QString>("accessibleRoleFileName");
131
132     QTest::newRow("StaticText") << SRCDIR "/data/statictext.qml";
133     QTest::newRow("PushButton") << SRCDIR "/data/pushbutton.qml";
134 }
135
136 void tst_QQuickAccessible::commonTests()
137 {
138     QFETCH(QString, accessibleRoleFileName);
139
140     qDebug() << "testing" << accessibleRoleFileName;
141
142     QQuickView *view = new QQuickView();
143 //    view->setFixedSize(240,320);
144     view->setSource(QUrl::fromLocalFile(accessibleRoleFileName));
145     view->show();
146 //    view->setFocus();
147     QVERIFY(view->rootObject() != 0);
148
149     QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(view);
150     QVERIFY(iface);
151
152     delete iface;
153     delete view;
154 }
155
156
157
158 QString eventName(const int ev)
159 {
160     switch (ev) {
161     case 0x0001: return "SoundPlayed";
162     case 0x0002: return "Alert";
163     case 0x0003: return "ForegroundChanged";
164     case 0x0004: return "MenuStart";
165     case 0x0005: return "MenuEnd";
166     case 0x0006: return "PopupMenuStart";
167     case 0x0007: return "PopupMenuEnd";
168     case 0x000C: return "ContextHelpStart";
169     case 0x000D: return "ContextHelpEnd";
170     case 0x000E: return "DragDropStart";
171     case 0x000F: return "DragDropEnd";
172     case 0x0010: return "DialogStart";
173     case 0x0011: return "DialogEnd";
174     case 0x0012: return "ScrollingStart";
175     case 0x0013: return "ScrollingEnd";
176     case 0x0018: return "MenuCommand";
177     case 0x8000: return "ObjectCreated";
178     case 0x8001: return "ObjectDestroyed";
179     case 0x8002: return "ObjectShow";
180     case 0x8003: return "ObjectHide";
181     case 0x8004: return "ObjectReorder";
182     case 0x8005: return "Focus";
183     case 0x8006: return "Selection";
184     case 0x8007: return "SelectionAdd";
185     case 0x8008: return "SelectionRemove";
186     case 0x8009: return "SelectionWithin";
187     case 0x800A: return "StateChanged";
188     case 0x800B: return "LocationChanged";
189     case 0x800C: return "NameChanged";
190     case 0x800D: return "DescriptionChanged";
191     case 0x800E: return "ValueChanged";
192     case 0x800F: return "ParentChanged";
193     case 0x80A0: return "HelpChanged";
194     case 0x80B0: return "DefaultActionChanged";
195     case 0x80C0: return "AcceleratorChanged";
196     default: return "Unknown Event";
197     }
198 }
199
200 void tst_QQuickAccessible::declarativeAttachedProperties()
201 {
202     {
203         QDeclarativeEngine engine;
204         QDeclarativeComponent component(&engine);
205         component.setData("import QtQuick 2.0\nItem {\n"
206                                 "}", QUrl());
207         QObject *object = component.create();
208         QVERIFY(object != 0);
209
210         QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(object);
211         QCOMPARE(attachedObject, static_cast<QObject*>(0));
212         delete object;
213     }
214
215     // Attached property
216     {
217         QObject parent;
218         QQuickAccessibleAttached *attachedObj = new QQuickAccessibleAttached(&parent);
219
220         attachedObj->name();
221
222         QVariant pp = attachedObj->property("name");
223         QDeclarativeEngine engine;
224         QDeclarativeComponent component(&engine);
225         component.setData("import QtQuick 2.0\nItem {\n"
226                                 "Accessible.role: Accessible.Button\n"
227                                 "}", QUrl());
228         QObject *object = component.create();
229         QVERIFY(object != 0);
230
231         QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(object);
232         QVERIFY(attachedObject);
233         if (attachedObject) {
234             QVariant p = attachedObject->property("role");
235             QCOMPARE(p.isNull(), false);
236             QCOMPARE(p.toInt(), int(QAccessible::PushButton));
237             p = attachedObject->property("name");
238             QCOMPARE(p.isNull(), true);
239             p = attachedObject->property("description");
240             QCOMPARE(p.isNull(), true);
241         }
242         delete object;
243     }
244
245     // Attached property
246     {
247         QDeclarativeEngine engine;
248         QDeclarativeComponent component(&engine);
249         component.setData("import QtQuick 2.0\nItem {\n"
250                                 "Accessible.role: Accessible.Button\n"
251                                 "Accessible.name: \"Donald\"\n"
252                                 "Accessible.description: \"Duck\"\n"
253                                 "}", QUrl());
254         QObject *object = component.create();
255         QVERIFY(object != 0);
256
257         QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(object);
258         QVERIFY(attachedObject);
259         if (attachedObject) {
260             QVariant p = attachedObject->property("role");
261             QCOMPARE(p.isNull(), false);
262             QCOMPARE(p.toInt(), int(QAccessible::PushButton));
263             p = attachedObject->property("name");
264             QCOMPARE(p.isNull(), false);
265             QCOMPARE(p.toString(), QLatin1String("Donald"));
266             p = attachedObject->property("description");
267             QCOMPARE(p.isNull(), false);
268             QCOMPARE(p.toString(), QLatin1String("Duck"));
269         }
270         delete object;
271     }
272 }
273
274
275 void tst_QQuickAccessible::basicPropertiesTest()
276 {
277     QAI app = QAI(QAccessible::queryAccessibleInterface(qApp));
278     QCOMPARE(app->childCount(), 0);
279
280     QQuickView *canvas = new QQuickView();
281     canvas->setSource(testFileUrl("statictext.qml"));
282     canvas->show();
283     QCOMPARE(app->childCount(), 1);
284
285     QAI iface = QAI(QAccessible::queryAccessibleInterface(canvas));
286     QVERIFY(iface.data());
287     QCOMPARE(iface->childCount(), 1);
288
289     QAI item = QAI(iface->child(0));
290     QVERIFY(item.data());
291     QCOMPARE(item->childCount(), 2);
292     QCOMPARE(item->rect().size(), QSize(400, 400));
293     QCOMPARE(item->role(), QAccessible::Pane);
294     QCOMPARE(iface->indexOfChild(item.data()), 0);
295
296     QAI text = QAI(item->child(0));
297     QVERIFY(text.data());
298     QCOMPARE(text->childCount(), 0);
299
300     QCOMPARE(text->text(QAccessible::Name), QLatin1String("Hello Accessibility"));
301     QCOMPARE(text->rect().size(), QSize(200, 50));
302     QCOMPARE(text->rect().x(), item->rect().x() + 100);
303     QCOMPARE(text->rect().y(), item->rect().y() + 20);
304     QCOMPARE(text->role(), QAccessible::StaticText);
305     QCOMPARE(item->indexOfChild(text.data()), 0);
306
307     QAI text2 = QAI(item->child(1));
308     QVERIFY(text2.data());
309     QCOMPARE(text2->childCount(), 0);
310
311     QCOMPARE(text2->text(QAccessible::Name), QLatin1String("The Hello 2 accessible text"));
312     QCOMPARE(text2->rect().size(), QSize(100, 40));
313     QCOMPARE(text2->rect().x(), item->rect().x() + 100);
314     QCOMPARE(text2->rect().y(), item->rect().y() + 40);
315     QCOMPARE(text2->role(), QAccessible::StaticText);
316     QCOMPARE(item->indexOfChild(text2.data()), 1);
317
318     QCOMPARE(iface->indexOfChild(text2.data()), -1);
319     QCOMPARE(text2->indexOfChild(item.data()), -1);
320
321     delete canvas;
322 }
323
324 QAI topLevelChildAt(QAccessibleInterface *iface, int x, int y)
325 {
326     QAI child = QAI(iface->childAt(x, y));
327     if (!child)
328         return QAI();
329
330     QAI childOfChild;
331     while (childOfChild = QAI(child->childAt(x, y))) {
332         child = childOfChild;
333     }
334     return child;
335 }
336
337 void tst_QQuickAccessible::hitTest()
338 {
339     QQuickView *canvas = new QQuickView;
340     canvas->setSource(testFileUrl("hittest.qml"));
341     canvas->show();
342
343     QAI iface = QAI(QAccessible::queryAccessibleInterface(canvas));
344     QVERIFY(iface.data());
345     QAI rootItem = QAI(iface->child(0));
346     QRect rootRect = rootItem->rect();
347
348     // hit the root item
349     QAI itemHit(iface->childAt(rootRect.x() + 200, rootRect.y() + 50));
350     QVERIFY(itemHit);
351     QCOMPARE(rootRect, itemHit->rect());
352
353     // hit rect1
354     QAI rect1(rootItem->child(1));
355     QRect rect1Rect = rect1->rect();
356     itemHit = QAI(rootItem->childAt(rect1Rect.x() + 10, rect1Rect.y() + 10));
357     QVERIFY(itemHit);
358     QCOMPARE(rect1Rect, itemHit->rect());
359     QCOMPARE(itemHit->text(QAccessible::Name), QLatin1String("rect1"));
360
361     // should also work from top level (app)
362     QAI app(QAccessible::queryAccessibleInterface(qApp));
363     QAI itemHit2(topLevelChildAt(app.data(), rect1Rect.x() + 10, rect1Rect.y() + 10));
364     QVERIFY(itemHit2);
365     QCOMPARE(itemHit2->rect(), rect1Rect);
366     QCOMPARE(itemHit2->text(QAccessible::Name), QLatin1String("rect1"));
367
368     // hit rect201
369     QAI rect2(rootItem->child(2));
370     QAI rect20(rect2->child(1));
371     QAI rect201(rect20->child(2));
372     QVERIFY(rect201);
373
374     QRect rect201Rect = rect201->rect();
375     itemHit = QAI(iface->childAt(rect201Rect.x() + 20, rect201Rect.y() + 20));
376     QVERIFY(itemHit);
377     QCOMPARE(itemHit->rect(), rect201Rect);
378     QCOMPARE(itemHit->text(QAccessible::Name), QLatin1String("rect201"));
379
380     delete canvas;
381 }
382
383 void tst_QQuickAccessible::checkableTest()
384 {
385     QQuickView *canvas = new QQuickView();
386     canvas->setSource(testFileUrl("checkbuttons.qml"));
387     canvas->show();
388
389     QAI iface = QAI(QAccessible::queryAccessibleInterface(canvas));
390     QVERIFY(iface.data());
391     QAI root = QAI(iface->child(0));
392
393     QAI button1 = QAI(root->child(0));
394     QCOMPARE(button1->role(), QAccessible::Button);
395     QVERIFY(!(button1->state().checked));
396     QAI button2 = QAI(root->child(1));
397     QVERIFY(!(button2->state().checked));
398     QAI button3 = QAI(root->child(2));
399     QVERIFY(button3->state().checked);
400
401     QAI checkBox1 = QAI(root->child(3));
402     QCOMPARE(checkBox1->role(), QAccessible::CheckBox);
403     QVERIFY((checkBox1->state().checked));
404     QAI checkBox2 = QAI(root->child(4));
405     QVERIFY(!(checkBox2->state().checked));
406 }
407
408 QTEST_MAIN(tst_QQuickAccessible)
409
410 #include "tst_qquickaccessible.moc"