1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28#include <qtest.h>
29#include <QtTest/QSignalSpy>
30#include <QtQml/qqmlcomponent.h>
31#include <QtQml/qqmlcontext.h>
32#include <QtQuick/qquickview.h>
33#include <QtQuick/qquickitem.h>
34#include "../../shared/util.h"
35#include <QtGui/QWindow>
36#include <QtCore/QDebug>
37#include <QtQml/qqmlengine.h>
38
39#include "../shared/geometrytestutil.h"
40
41class tst_QQuickView : public QQmlDataTest
42{
43 Q_OBJECT
44public:
45 tst_QQuickView();
46
47private slots:
48 void resizemodeitem();
49 void errors();
50 void engine();
51 void findChild();
52 void setInitialProperties();
53};
54
55
56tst_QQuickView::tst_QQuickView()
57{
58}
59
60void tst_QQuickView::resizemodeitem()
61{
62 QWindow window;
63 window.setGeometry(posx: 0, posy: 0, w: 400, h: 400);
64
65 QQuickView *view = new QQuickView(&window);
66 QVERIFY(view);
67 view->setResizeMode(QQuickView::SizeRootObjectToView);
68 QCOMPARE(QSize(0,0), view->initialSize());
69 view->setSource(testFileUrl(fileName: "resizemodeitem.qml"));
70 QQuickItem* item = qobject_cast<QQuickItem*>(object: view->rootObject());
71 QVERIFY(item);
72 window.show();
73
74 view->showNormal();
75
76 // initial size from root object
77 QCOMPARE(item->width(), 200.0);
78 QCOMPARE(item->height(), 200.0);
79 QCOMPARE(view->size(), QSize(200, 200));
80 QCOMPARE(view->size(), view->sizeHint());
81 QCOMPARE(view->size(), view->initialSize());
82
83 // size update from view
84 view->resize(newSize: QSize(80,100));
85
86 QTRY_COMPARE(item->width(), 80.0);
87 QCOMPARE(item->height(), 100.0);
88 QCOMPARE(view->size(), QSize(80, 100));
89 QCOMPARE(view->size(), view->sizeHint());
90
91 view->setResizeMode(QQuickView::SizeViewToRootObject);
92
93 // size update from view disabled
94 view->resize(newSize: QSize(60,80));
95 QCOMPARE(item->width(), 80.0);
96 QCOMPARE(item->height(), 100.0);
97 QTest::qWait(ms: 50);
98 QCOMPARE(view->size(), QSize(60, 80));
99
100 // size update from root object
101 item->setWidth(250);
102 item->setHeight(350);
103 QCOMPARE(item->width(), 250.0);
104 QCOMPARE(item->height(), 350.0);
105 QTRY_COMPARE(view->size(), QSize(250, 350));
106 QCOMPARE(view->size(), QSize(250, 350));
107 QCOMPARE(view->size(), view->sizeHint());
108
109 // reset window
110 window.hide();
111 delete view;
112 view = new QQuickView(&window);
113 QVERIFY(view);
114 view->setResizeMode(QQuickView::SizeViewToRootObject);
115 view->setSource(testFileUrl(fileName: "resizemodeitem.qml"));
116 item = qobject_cast<QQuickItem*>(object: view->rootObject());
117 QVERIFY(item);
118 window.show();
119
120 view->showNormal();
121
122 // initial size for root object
123 QCOMPARE(item->width(), 200.0);
124 QCOMPARE(item->height(), 200.0);
125 QCOMPARE(view->size(), view->sizeHint());
126 QCOMPARE(view->size(), view->initialSize());
127
128 // size update from root object
129 item->setWidth(80);
130 item->setHeight(100);
131 QCOMPARE(item->width(), 80.0);
132 QCOMPARE(item->height(), 100.0);
133 QTRY_COMPARE(view->size(), QSize(80, 100));
134 QCOMPARE(view->size(), view->sizeHint());
135
136 // size update from root object disabled
137 view->setResizeMode(QQuickView::SizeRootObjectToView);
138 item->setWidth(60);
139 item->setHeight(80);
140 QCOMPARE(view->width(), 80);
141 QCOMPARE(view->height(), 100);
142 QCOMPARE(QSize(item->width(), item->height()), view->sizeHint());
143
144 // size update from view
145 QCoreApplication::processEvents(); // make sure the last resize events are gone
146 QSizeChangeListener sizeListener(item);
147 view->resize(newSize: QSize(200,300));
148 QTRY_COMPARE(item->width(), 200.0);
149
150 for (int i = 0; i < sizeListener.count(); ++i) {
151 // Check that we have the correct geometry on all signals
152 QCOMPARE(sizeListener.at(i), view->size());
153 }
154
155 QCOMPARE(item->height(), 300.0);
156 QCOMPARE(view->size(), QSize(200, 300));
157 QCOMPARE(view->size(), view->sizeHint());
158
159 window.hide();
160 delete view;
161
162 // if we set a specific size for the view then it should keep that size
163 // for SizeRootObjectToView mode.
164 view = new QQuickView(&window);
165 view->resize(w: 300, h: 300);
166 view->setResizeMode(QQuickView::SizeRootObjectToView);
167 QCOMPARE(QSize(0,0), view->initialSize());
168 view->setSource(testFileUrl(fileName: "resizemodeitem.qml"));
169 view->resize(w: 300, h: 300);
170 item = qobject_cast<QQuickItem*>(object: view->rootObject());
171 QVERIFY(item);
172 window.show();
173
174 view->showNormal();
175 QTest::qWait(ms: 50);
176
177 // initial size from root object
178 QCOMPARE(item->width(), 300.0);
179 QCOMPARE(item->height(), 300.0);
180 QCOMPARE(view->size(), QSize(300, 300));
181 QCOMPARE(view->size(), view->sizeHint());
182 QCOMPARE(view->initialSize(), QSize(200, 200)); // initial object size
183
184 delete view;
185}
186
187void tst_QQuickView::errors()
188{
189 {
190 QQuickView view;
191 QVERIFY(view.errors().isEmpty()); // don't crash
192 }
193 {
194 QQuickView view;
195 QQmlTestMessageHandler messageHandler;
196 view.setSource(testFileUrl(fileName: "error1.qml"));
197 QCOMPARE(view.status(), QQuickView::Error);
198 QCOMPARE(view.errors().count(), 1);
199 }
200
201 {
202 QQuickView view;
203 QQmlTestMessageHandler messageHandler;
204 view.setSource(testFileUrl(fileName: "error2.qml"));
205 QCOMPARE(view.status(), QQuickView::Error);
206 QCOMPARE(view.errors().count(), 1);
207 view.show();
208 }
209}
210
211void tst_QQuickView::engine()
212{
213 QQmlEngine *engine = new QQmlEngine;
214 QVERIFY(!engine->incubationController());
215
216 QQuickView *view = new QQuickView(engine, nullptr);
217 QVERIFY(view);
218 QCOMPARE(engine->incubationController(), view->incubationController());
219
220 QQuickView *view2 = new QQuickView(engine, nullptr);
221 QVERIFY(view);
222 QCOMPARE(engine->incubationController(), view->incubationController());
223 delete view;
224 QVERIFY(!engine->incubationController());
225
226 engine->setIncubationController(view2->incubationController());
227 QCOMPARE(engine->incubationController(), view2->incubationController());
228 delete view2;
229 QVERIFY(!engine->incubationController());
230
231 QQuickView *view3 = new QQuickView;
232 QQuickView *view4 = new QQuickView(view3->engine(), nullptr);
233
234 QVERIFY(view3->engine());
235 QVERIFY(view4->engine());
236 QCOMPARE(view3->engine(), view4->engine());
237 delete view3;
238 QVERIFY(!view4->engine());
239 QTest::ignoreMessage(type: QtWarningMsg, message: "QQuickView: invalid qml engine.");
240 view4->setSource(QUrl());
241
242 QCOMPARE(view4->status(), QQuickView::Error);
243 QVERIFY(!view4->errors().isEmpty());
244 QCOMPARE(view4->errors().back().description(), QLatin1String("QQuickView: invalid qml engine."));
245 delete view4;
246}
247
248void tst_QQuickView::findChild()
249{
250 QQuickView view;
251 view.setSource(testFileUrl(fileName: "findChild.qml"));
252
253 // QQuickView
254 // |_ QQuickWindow::contentItem
255 // | |_ QQuickView::rootObject: QML Item("rootObject") (findChild.qml)
256 // | | |_ QML Item("rootObjectChild") (findChild.qml)
257 // | |_ QObject("contentItemChild")
258 // |_ QObject("viewChild")
259
260 QObject *viewChild = new QObject(&view);
261 viewChild->setObjectName("viewChild");
262
263 QObject *contentItemChild = new QObject(view.contentItem());
264 contentItemChild->setObjectName("contentItemChild");
265
266 QObject *rootObject = view.rootObject();
267 QVERIFY(rootObject);
268
269 QObject *rootObjectChild = rootObject->findChild<QObject *>(aName: "rootObjectChild");
270 QVERIFY(rootObjectChild);
271
272 QCOMPARE(view.findChild<QObject *>("viewChild"), viewChild);
273 QCOMPARE(view.findChild<QObject *>("contentItemChild"), contentItemChild);
274 QCOMPARE(view.findChild<QObject *>("rootObject"), rootObject);
275 QCOMPARE(view.findChild<QObject *>("rootObjectChild"), rootObjectChild);
276
277 QVERIFY(!view.contentItem()->findChild<QObject *>("viewChild")); // sibling
278 QCOMPARE(view.contentItem()->findChild<QObject *>("contentItemChild"), contentItemChild);
279 QCOMPARE(view.contentItem()->findChild<QObject *>("rootObject"), rootObject);
280 QCOMPARE(view.contentItem()->findChild<QObject *>("rootObjectChild"), rootObjectChild);
281
282 QVERIFY(!view.rootObject()->findChild<QObject *>("viewChild")); // ancestor
283 QVERIFY(!view.rootObject()->findChild<QObject *>("contentItemChild")); // cousin
284 QVERIFY(!view.rootObject()->findChild<QObject *>("rootObject")); // self
285}
286
287void tst_QQuickView::setInitialProperties()
288{
289 QQuickView view;
290 view.setInitialProperties({{"z", 4}, {"width", 100}});
291 view.setSource(testFileUrl(fileName: "resizemodeitem.qml"));
292 QObject *rootObject = view.rootObject();
293 QVERIFY(rootObject);
294 QCOMPARE(rootObject->property("z").toInt(), 4);
295 QCOMPARE(rootObject->property("width").toInt(), 100);
296}
297
298QTEST_MAIN(tst_QQuickView)
299
300#include "tst_qquickview.moc"
301

source code of qtdeclarative/tests/auto/quick/qquickview/tst_qquickview.cpp