1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
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 http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42
43 #include <QtTest/QtTest>
44 #include <qgraphicslayoutitem.h>
45 #include <float.h>
46 #include <limits.h>
47 #include <QtGui/qgraphicswidget.h>
48
49 class tst_QGraphicsLayoutItem : public QObject {
50 Q_OBJECT
51
52 public slots:
53 void initTestCase();
54 void cleanupTestCase();
55 void init();
56 void cleanup();
57
58 private slots:
59 void qgraphicslayoutitem();
60
61 void contentsRect();
62 void effectiveSizeHint_data();
63 void effectiveSizeHint();
64 void effectiveSizeHint2_data();
65 void effectiveSizeHint2();
66 void getContentsMargins();
67 void isLayout_data();
68 void isLayout();
69 void maximumSize();
70 void minimumSize();
71 void parentLayoutItem_data();
72 void parentLayoutItem();
73 void preferredSize();
74 void setMaximumSize_data();
75 void setMaximumSize();
76 void setMinimumSize_data();
77 void setMinimumSize();
78 void setPreferredSize_data();
79 void setPreferredSize();
80 void setSizePolicy_data();
81 void setPreferredSize2();
82 void setSizePolicy();
83 };
84
85 // Subclass that exposes the protected functions.
86 class SubQGraphicsLayoutItem : public QGraphicsLayoutItem {
87 public:
SubQGraphicsLayoutItem(QGraphicsLayoutItem * par=0,bool layout=false)88 SubQGraphicsLayoutItem(QGraphicsLayoutItem *par = 0, bool layout = false)
89 : QGraphicsLayoutItem(par, layout), updateGeometryCalled(0)
90 {}
91
92 // QGraphicsLayoutItem::geometry is a pure virtual function
geometry() const93 QRectF geometry() const
94 { return QRectF(); }
95
96 // QGraphicsLayoutItem::setGeometry is a pure virtual function
setGeometry(QRectF const & rect)97 void setGeometry(QRectF const& rect)
98 { Q_UNUSED(rect); }
99
100 // QGraphicsLayoutItem::sizeHint is a pure virtual function
sizeHint(Qt::SizeHint which,QSizeF const & constraint=QSizeF ()) const101 QSizeF sizeHint(Qt::SizeHint which, QSizeF const& constraint = QSizeF()) const
102 { Q_UNUSED(which); Q_UNUSED(constraint); return QSizeF(); }
103
updateGeometry()104 void updateGeometry()
105 { updateGeometryCalled++; QGraphicsLayoutItem::updateGeometry(); }
106 int updateGeometryCalled;
107
108 };
109
110 class RectWidget : public QGraphicsWidget
111 {
112 public:
RectWidget(QGraphicsItem * parent=0)113 RectWidget(QGraphicsItem *parent = 0) : QGraphicsWidget(parent), m_fnConstraint(fn2000_div_w) {}
114
115
sizeHint(Qt::SizeHint which,const QSizeF & constraint=QSizeF ()) const116 QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const
117 {
118 if (constraint.width() < 0 && constraint.height() < 0 && m_sizeHints[which].isValid()) {
119 return m_sizeHints[which];
120 }
121 if (m_fnConstraint) {
122 return m_fnConstraint(which, constraint);
123 }
124 return QGraphicsWidget::sizeHint(which, constraint);
125 }
126
setSizeHint(Qt::SizeHint which,const QSizeF & size)127 void setSizeHint(Qt::SizeHint which, const QSizeF &size) {
128 m_sizeHints[which] = size;
129 updateGeometry();
130 }
131
setConstraintFunction(QSizeF (* fnConstraint)(Qt::SizeHint,const QSizeF &))132 void setConstraintFunction(QSizeF (*fnConstraint)(Qt::SizeHint, const QSizeF &)) {
133 m_fnConstraint = fnConstraint;
134 }
135
136 QSizeF m_sizeHints[Qt::NSizeHints];
137 QSizeF (*m_fnConstraint)(Qt::SizeHint, const QSizeF &);
138
fn2000_div_w(Qt::SizeHint,const QSizeF & constraint=QSizeF ())139 static QSizeF fn2000_div_w(Qt::SizeHint /*which*/, const QSizeF &constraint = QSizeF()) {
140 return QSizeF(constraint.width(), 2000.0/constraint.width());
141 }
142 };
143
144 // This will be called before the first test function is executed.
145 // It is only called once.
initTestCase()146 void tst_QGraphicsLayoutItem::initTestCase()
147 {
148 }
149
150 // This will be called after the last test function is executed.
151 // It is only called once.
cleanupTestCase()152 void tst_QGraphicsLayoutItem::cleanupTestCase()
153 {
154 }
155
156 // This will be called before each test function is executed.
init()157 void tst_QGraphicsLayoutItem::init()
158 {
159 }
160
161 // This will be called after every test function.
cleanup()162 void tst_QGraphicsLayoutItem::cleanup()
163 {
164 }
165
qgraphicslayoutitem()166 void tst_QGraphicsLayoutItem::qgraphicslayoutitem()
167 {
168 SubQGraphicsLayoutItem layoutItem;
169 layoutItem.contentsRect();
170 layoutItem.effectiveSizeHint(Qt::MinimumSize);
171 layoutItem.geometry();
172 QCOMPARE(layoutItem.isLayout(), false);
173 layoutItem.maximumSize();
174 layoutItem.minimumSize();
175 QCOMPARE(layoutItem.parentLayoutItem(), (QGraphicsLayoutItem*)0);
176 layoutItem.preferredSize();
177 layoutItem.sizePolicy();
178 layoutItem.sizeHint(Qt::MinimumSize);
179 }
180
181 // QRectF contentsRect() const public
contentsRect()182 void tst_QGraphicsLayoutItem::contentsRect()
183 {
184 SubQGraphicsLayoutItem layoutItem;
185 QRectF f = layoutItem.contentsRect();
186 QCOMPARE(f, QRectF(QPoint(), QSizeF(0, 0)));
187 }
Q_DECLARE_METATYPE(Qt::SizeHint)188 Q_DECLARE_METATYPE(Qt::SizeHint)
189 void tst_QGraphicsLayoutItem::effectiveSizeHint_data()
190 {
191 QTest::addColumn<Qt::SizeHint>("sizeHint");
192 QTest::addColumn<QSizeF>("constraint");
193 for (int i = 0; i < 15; ++i) {
194 QTestData &data = QTest::newRow(QString("%1").arg(i).toLatin1());
195 switch(i % 5) {
196 case 0: data << Qt::MinimumSize; break;
197 case 1: data << Qt::PreferredSize; break;
198 case 2: data << Qt::MaximumSize; break;
199 case 3: data << Qt::MinimumDescent; break;
200 case 4: data << Qt::NSizeHints; break;
201 }
202 switch(i % 3) {
203 case 0: data << QSizeF(-1, -1); break;
204 case 1: data << QSizeF(0, 0); break;
205 case 2: data << QSizeF(10, 10); break;
206 }
207 }
208 }
209
210 // QSizeF effectiveSizeHint(Qt::SizeHint which, QSizeF const& constraint = QSize()) const public
effectiveSizeHint()211 void tst_QGraphicsLayoutItem::effectiveSizeHint()
212 {
213 QFETCH(Qt::SizeHint, sizeHint);
214 QFETCH(QSizeF, constraint);
215 SubQGraphicsLayoutItem layoutItem;
216 QSizeF r = layoutItem.effectiveSizeHint(sizeHint, constraint);
217 if (constraint.width() != -1)
218 QCOMPARE(r.width(), constraint.width());
219 if (constraint.height() != -1)
220 QCOMPARE(r.height(), constraint.height());
221 }
222
223
effectiveSizeHint2_data()224 void tst_QGraphicsLayoutItem::effectiveSizeHint2_data()
225 {
226 QTest::addColumn<QSizeF>("minimumSize");
227 QTest::addColumn<QSizeF>("preferredSize");
228 QTest::addColumn<QSizeF>("maximumSize");
229 QTest::addColumn<QSizeF>("minimumSizeHint");
230 QTest::addColumn<QSizeF>("preferredSizeHint");
231 QTest::addColumn<QSizeF>("maximumSizeHint");
232
233 QTest::addColumn<QSizeF>("inputConstraint");
234 QTest::addColumn<QSizeF>("expectedMinimumESH");
235 QTest::addColumn<QSizeF>("expectedPreferredESH");
236 QTest::addColumn<QSizeF>("expectedMaximumESH");
237
238 QTest::newRow("P1-a")
239 << QSizeF( 6, 4) << QSizeF( 60, 40) << QSizeF( 600, 400)
240 << QSizeF( -1, -1) << QSizeF( -1, -1) << QSizeF( -1, -1)
241 << QSizeF(-1, -1)
242 << QSizeF(6, 4) << QSizeF( 60, 40) << QSizeF(600, 400);
243
244 QTest::newRow("P1-hfw-1")
245 << QSizeF( -1, -1) << QSizeF( -1, -1) << QSizeF( -1, -1)
246 << QSizeF( 6, 4) << QSizeF( 60, 40) << QSizeF(600, 400)
247 << QSizeF(200, -1)
248 << QSizeF(200, 10) << QSizeF(200, 10) << QSizeF(200, 10);
249
250 QTest::newRow("P1-hfw-2")
251 << QSizeF( 6, -1) << QSizeF( 60, -1) << QSizeF(600, -1)
252 << QSizeF( -1, -1) << QSizeF( -1, -1) << QSizeF( -1, -1)
253 << QSizeF(200, -1)
254 << QSizeF(200, 10) << QSizeF(200, 10) << QSizeF(200, 10);
255
256 // constraint is bigger than max width
257 QTest::newRow("P1-hfw-3")
258 << QSizeF( 5, -1) << QSizeF( 50, -1) << QSizeF(500, -1)
259 << QSizeF( -1, -1) << QSizeF( -1, -1) << QSizeF( -1, -1)
260 << QSizeF(600, -1)
261 << QSizeF(500, 4) << QSizeF(500, 4) << QSizeF(500, 4);
262
263 }
264
effectiveSizeHint2()265 void tst_QGraphicsLayoutItem::effectiveSizeHint2()
266 {
267 QFETCH(QSizeF, minimumSize);
268 QFETCH(QSizeF, preferredSize);
269 QFETCH(QSizeF, maximumSize);
270 QFETCH(QSizeF, minimumSizeHint);
271 QFETCH(QSizeF, preferredSizeHint);
272 QFETCH(QSizeF, maximumSizeHint);
273
274 QFETCH(QSizeF, inputConstraint);
275 QFETCH(QSizeF, expectedMinimumESH);
276 QFETCH(QSizeF, expectedPreferredESH);
277 QFETCH(QSizeF, expectedMaximumESH);
278
279 RectWidget *item = new RectWidget;
280 item->setMinimumSize(minimumSize);
281 item->setPreferredSize(preferredSize);
282 item->setMaximumSize(maximumSize);
283 item->setSizeHint(Qt::MinimumSize, minimumSizeHint);
284 item->setSizeHint(Qt::PreferredSize, preferredSizeHint);
285 item->setSizeHint(Qt::MaximumSize, maximumSizeHint);
286
287 QCOMPARE(item->effectiveSizeHint(Qt::MinimumSize, inputConstraint), expectedMinimumESH);
288 QCOMPARE(item->effectiveSizeHint(Qt::PreferredSize, inputConstraint), expectedPreferredESH);
289 QCOMPARE(item->effectiveSizeHint(Qt::MaximumSize, inputConstraint), expectedMaximumESH);
290
291 }
292
293
294 // void getContentsMargins(qreal* left, qreal* top, qreal* right, qreal* bottom) const public
getContentsMargins()295 void tst_QGraphicsLayoutItem::getContentsMargins()
296 {
297 SubQGraphicsLayoutItem layoutItem;
298 qreal left;
299 qreal top;
300 qreal right;
301 qreal bottom;
302 layoutItem.getContentsMargins(&left, &top, &right, &bottom);
303 QCOMPARE(left, (qreal)0);
304 QCOMPARE(top, (qreal)0);
305 QCOMPARE(right, (qreal)0);
306 QCOMPARE(bottom, (qreal)0);
307 }
308
isLayout_data()309 void tst_QGraphicsLayoutItem::isLayout_data()
310 {
311 QTest::addColumn<bool>("isLayout");
312 QTest::newRow("no") << false;
313 QTest::newRow("yes") << true;
314 }
315
316 // bool isLayout() const public
isLayout()317 void tst_QGraphicsLayoutItem::isLayout()
318 {
319 QFETCH(bool, isLayout);
320 SubQGraphicsLayoutItem layoutItem(0, isLayout);
321 QCOMPARE(layoutItem.isLayout(), isLayout);
322 }
323
324 // QSizeF maximumSize() const public
maximumSize()325 void tst_QGraphicsLayoutItem::maximumSize()
326 {
327 SubQGraphicsLayoutItem layoutItem;
328 QCOMPARE(layoutItem.maximumSize(), QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
329 // layoutItem.effectiveSizeHint(Qt::MaximumSize);
330 }
331
332 // QSizeF minimumSize() const public
minimumSize()333 void tst_QGraphicsLayoutItem::minimumSize()
334 {
335 SubQGraphicsLayoutItem layoutItem;
336 QCOMPARE(layoutItem.minimumSize(), QSizeF(0, 0));
337 // layoutItem.effectiveSizeHint(Qt::MinimumSize);
338 }
339
parentLayoutItem_data()340 void tst_QGraphicsLayoutItem::parentLayoutItem_data()
341 {
342 QTest::addColumn<bool>("parent");
343 QTest::newRow("no") << false;
344 QTest::newRow("yes") << true;
345 }
346
347 // QGraphicsLayoutItem* parentLayoutItem() const public
parentLayoutItem()348 void tst_QGraphicsLayoutItem::parentLayoutItem()
349 {
350 QFETCH(bool, parent);
351 SubQGraphicsLayoutItem parentLayout;
352 SubQGraphicsLayoutItem layoutItem(parent ? &parentLayout : 0);
353 QCOMPARE(layoutItem.parentLayoutItem(), static_cast<QGraphicsLayoutItem*>( parent ? &parentLayout : 0));
354 }
355
356 // QSizeF preferredSize() const public
preferredSize()357 void tst_QGraphicsLayoutItem::preferredSize()
358 {
359 SubQGraphicsLayoutItem layoutItem;
360 QCOMPARE(layoutItem.preferredSize(), QSizeF(0, 0));
361 // layoutItem.effectiveSizeHint(Qt::PreferredSize));
362 }
363
setMaximumSize_data()364 void tst_QGraphicsLayoutItem::setMaximumSize_data()
365 {
366 QTest::addColumn<QSizeF>("size");
367 QTest::addColumn<QSizeF>("outputSize");
368 QTest::newRow("-1") << QSizeF(-1, -1) << QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
369 QTest::newRow("0") << QSizeF(0, 0) << QSizeF(0, 0);
370 QTest::newRow("10") << QSizeF(10, 10) << QSizeF(10, 10);
371 }
372
373 // void setMaximumSize(QSizeF const& size) public
setMaximumSize()374 void tst_QGraphicsLayoutItem::setMaximumSize()
375 {
376 QFETCH(QSizeF, size);
377 QFETCH(QSizeF, outputSize);
378 SubQGraphicsLayoutItem layoutItem;
379 QSizeF oldSize = layoutItem.maximumSize();
380 layoutItem.setMaximumSize(size);
381 if (size.isValid())
382 QCOMPARE(layoutItem.updateGeometryCalled, (oldSize == size) ? 0 : 1);
383 else
384 QVERIFY(!layoutItem.updateGeometryCalled);
385 layoutItem.setMinimumSize(1, 1);
386
387 QVERIFY(layoutItem.maximumSize().width() <= outputSize.width());
388 QVERIFY(layoutItem.maximumSize().height() <= outputSize.height());
389 QVERIFY(layoutItem.minimumSize().width() <= outputSize.width());
390 QVERIFY(layoutItem.minimumSize().height() <= outputSize.height());
391 QVERIFY(layoutItem.preferredSize().width() <= outputSize.width());
392 QVERIFY(layoutItem.preferredSize().height() <= outputSize.height());
393 }
394
setMinimumSize_data()395 void tst_QGraphicsLayoutItem::setMinimumSize_data()
396 {
397 QTest::addColumn<QSizeF>("size");
398 QTest::addColumn<QSizeF>("outputSize");
399 QTest::newRow("-1") << QSizeF(-1, -1) << QSizeF(0, 0);
400 QTest::newRow("0") << QSizeF(0, 0) << QSizeF(0, 0);
401 QTest::newRow("10") << QSizeF(10, 10) << QSizeF(10, 10);
402 }
403
404 // void setMinimumSize(QSizeF const& size) public
setMinimumSize()405 void tst_QGraphicsLayoutItem::setMinimumSize()
406 {
407 QFETCH(QSizeF, size);
408 QFETCH(QSizeF, outputSize);
409 SubQGraphicsLayoutItem layoutItem;
410 QSizeF oldSize = layoutItem.minimumSize();
411
412 layoutItem.setMinimumSize(size);
413 if (size.isValid()) {
414 QEXPECT_FAIL("0", "updateGeometry() is called when it doesn't have to be.", Continue);
415 QCOMPARE(layoutItem.updateGeometryCalled, (oldSize == size) ? 0 : 1);
416 } else {
417 QVERIFY(!layoutItem.updateGeometryCalled);
418 }
419 layoutItem.setMaximumSize(5, 5);
420 QEXPECT_FAIL("10", "layoutItem.maximumSize().width() < size.width()", Abort);
421 QVERIFY(layoutItem.maximumSize().width() >= size.width());
422 QVERIFY(layoutItem.maximumSize().height() >= size.height());
423 QVERIFY(layoutItem.minimumSize().width() >= size.width());
424 QVERIFY(layoutItem.minimumSize().height() >= size.height());
425 QVERIFY(layoutItem.preferredSize().width() >= size.width());
426 QVERIFY(layoutItem.preferredSize().height() >= size.height());
427 }
428
setPreferredSize_data()429 void tst_QGraphicsLayoutItem::setPreferredSize_data()
430 {
431 QTest::addColumn<QSizeF>("size");
432 QTest::newRow("-1") << QSizeF(-1, -1);
433 QTest::newRow("0") << QSizeF(0, 0);
434 QTest::newRow("10") << QSizeF(10, 10);
435 }
436
437 // void setPreferredSize(QSizeF const& size) public
setPreferredSize()438 void tst_QGraphicsLayoutItem::setPreferredSize()
439 {
440 QFETCH(QSizeF, size);
441 SubQGraphicsLayoutItem layoutItem;
442 QSizeF oldSize = layoutItem.preferredSize();
443 layoutItem.setPreferredSize(size);
444 if (size.isValid())
445 QCOMPARE(layoutItem.preferredSize(), size);
446
447 if (size.isValid()) {
448 QEXPECT_FAIL("0", "updateGeometry() is called when it doesn't have to be.", Continue);
449 QCOMPARE(layoutItem.updateGeometryCalled, (oldSize == size) ? 0 : 1);
450 } else {
451 QVERIFY(!layoutItem.updateGeometryCalled);
452 }
453 }
454
setPreferredSize2()455 void tst_QGraphicsLayoutItem::setPreferredSize2()
456 {
457 SubQGraphicsLayoutItem layoutItem;
458 layoutItem.setPreferredSize(QSizeF(30, -1));
459 QCOMPARE(layoutItem.preferredWidth(), qreal(30));
460 }
461
setSizePolicy_data()462 void tst_QGraphicsLayoutItem::setSizePolicy_data()
463 {
464 QTest::addColumn<QSizePolicy>("policy");
465 QTest::newRow("default") << QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed, QSizePolicy::DefaultType);
466 QTest::newRow("rand") << QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
467 }
468
469 // void setSizePolicy(QSizePolicy const& policy) public
setSizePolicy()470 void tst_QGraphicsLayoutItem::setSizePolicy()
471 {
472 QFETCH(QSizePolicy, policy);
473 SubQGraphicsLayoutItem layoutItem;
474 QSizePolicy defaultPolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::DefaultType);
475 QCOMPARE(layoutItem.sizePolicy(), defaultPolicy);
476
477 layoutItem.setSizePolicy(policy);
478 QCOMPARE(layoutItem.sizePolicy(), policy);
479 QCOMPARE(layoutItem.updateGeometryCalled, (defaultPolicy == policy) ? 0 : 1);
480 }
481
482 QTEST_MAIN(tst_QGraphicsLayoutItem)
483 #include "tst_qgraphicslayoutitem.moc"
484
485