Improve invalidate() testcase.

Test number of:
* events
* setGeometry() calls
* invalidate() calls
(cherry picked from commit b8b4e6fe141d99c4639d492a546226cdc3fc06c5)
This commit is contained in:
Jan-Arve Sæther 2011-03-18 10:52:03 +01:00 committed by Thierry Bastian
parent 913ff73200
commit f76acd935d

View File

@ -96,6 +96,14 @@ void tst_QGraphicsLayout::sizeHints()
} }
enum FunctionType {
SetGeometry = 0,
Invalidate,
NumFunctionTypes
};
class TestGraphicsWidget : public QGraphicsWidget { class TestGraphicsWidget : public QGraphicsWidget {
public: public:
TestGraphicsWidget(QGraphicsWidget *parent = 0) : QGraphicsWidget(parent) TestGraphicsWidget(QGraphicsWidget *parent = 0) : QGraphicsWidget(parent)
@ -109,9 +117,28 @@ public:
int eventCount(QEvent::Type type) { int eventCount(QEvent::Type type) {
return m_eventCount.value(int(type)); return m_eventCount.value(int(type));
} }
void clearEventCount() { void clearEventCount() {
m_eventCount.clear(); m_eventCount.clear();
} }
void clearCounters() {
m_eventCount.clear();
functionCount.clear();
}
void setGeometry(const QRectF &rect)
{
QGraphicsWidget::setGeometry(rect);
++(functionCount[SetGeometry]);
}
void callUpdateGeometry()
{
// updateGeometry() is protected
QGraphicsWidget::updateGeometry();
}
QMap<FunctionType, int> functionCount;
private: private:
QMap<int, int> m_eventCount; QMap<int, int> m_eventCount;
}; };
@ -123,6 +150,8 @@ void tst_QGraphicsLayout::compressLayoutRequest()
TestGraphicsWidget *tw = new TestGraphicsWidget(); TestGraphicsWidget *tw = new TestGraphicsWidget();
scene.addItem(tw); scene.addItem(tw);
view.show(); view.show();
QTest::qWaitForWindowShown(&view);
QGraphicsLinearLayout *lout = new QGraphicsLinearLayout(tw); QGraphicsLinearLayout *lout = new QGraphicsLinearLayout(tw);
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
QGraphicsWidget *gw = new QGraphicsWidget(tw); QGraphicsWidget *gw = new QGraphicsWidget(tw);
@ -218,23 +247,27 @@ class TestLayout : public QGraphicsLinearLayout
TestLayout(QGraphicsLayoutItem *parent = 0) TestLayout(QGraphicsLayoutItem *parent = 0)
: QGraphicsLinearLayout(parent) : QGraphicsLinearLayout(parent)
{ {
m_count = 0; setContentsMargins(0,0,0,0);
m_invalidateCount = 0; setSpacing(0);
} }
void setGeometry(const QRectF &rect) { void setGeometry(const QRectF &rect)
{
++m_count; ++(functionCount[SetGeometry]);
QGraphicsLinearLayout::setGeometry(rect); QGraphicsLinearLayout::setGeometry(rect);
} }
void invalidate() { void invalidate()
++m_invalidateCount; {
++(functionCount[Invalidate]);
QGraphicsLinearLayout::invalidate(); QGraphicsLinearLayout::invalidate();
} }
int m_invalidateCount; void clearCounters() {
int m_count; functionCount.clear();
}
QMap<FunctionType, int> functionCount;
}; };
void tst_QGraphicsLayout::verifyActivate() void tst_QGraphicsLayout::verifyActivate()
@ -249,15 +282,47 @@ void tst_QGraphicsLayout::verifyActivate()
lout->addItem(w); lout->addItem(w);
window->setLayout(lout); window->setLayout(lout);
QCOMPARE(lout->m_count, 0); QCOMPARE(lout->functionCount[SetGeometry], 0);
window->setVisible(false); window->setVisible(false);
QCOMPARE(lout->m_count, 0); QCOMPARE(lout->functionCount[SetGeometry], 0);
window->setVisible(true); window->setVisible(true);
// on polish or the first time a widget is shown, the widget is resized. // on polish or the first time a widget is shown, the widget is resized.
QCOMPARE(lout->m_count, 1); QCOMPARE(lout->functionCount[SetGeometry], 1);
} }
static void clearAllCounters(TestGraphicsWidget *widget)
{
if (!widget)
return;
widget->clearCounters();
TestLayout *layout = static_cast<TestLayout *>(widget->layout());
if (layout) {
layout->clearCounters();
for (int i = layout->count() - 1; i >=0; --i) {
QGraphicsLayoutItem *item = layout->itemAt(i);
if (item->isLayout()) {
// ### Not used ATM
//TestLayout *lay = static_cast<TestLayout*>(static_cast<QGraphicsLayout*>(item));
//clearAllCounters(lay);
} else {
TestGraphicsWidget *wid = static_cast<TestGraphicsWidget *>(item);
clearAllCounters(wid);
}
}
}
}
static void activateAndReset(TestGraphicsWidget *widget)
{
QApplication::sendPostedEvents();
QApplication::processEvents();
if (widget->layout())
widget->layout()->activate();
clearAllCounters(widget);
}
void tst_QGraphicsLayout::invalidate() void tst_QGraphicsLayout::invalidate()
{ {
QGraphicsLayout::setInstantInvalidatePropagation(true); QGraphicsLayout::setInstantInvalidatePropagation(true);
@ -265,76 +330,228 @@ void tst_QGraphicsLayout::invalidate()
QGraphicsView view(&scene); QGraphicsView view(&scene);
TestGraphicsWidget *a = new TestGraphicsWidget; TestGraphicsWidget *a = new TestGraphicsWidget;
a->setData(0, QString("a"));
scene.addItem(a); scene.addItem(a);
TestLayout *alay = new TestLayout(a); TestLayout *alay = new TestLayout(a);
TestGraphicsWidget *b = new TestGraphicsWidget; TestGraphicsWidget *b = new TestGraphicsWidget;
b->setData(0, QString("b"));
alay->addItem(b); alay->addItem(b);
TestLayout *blay = new TestLayout(b); TestLayout *blay = new TestLayout(b);
TestGraphicsWidget *e = new TestGraphicsWidget; TestGraphicsWidget *e = new TestGraphicsWidget;
e->setData(0, QString("e"));
blay->addItem(e); blay->addItem(e);
TestGraphicsWidget *c = new TestGraphicsWidget; TestGraphicsWidget *c = new TestGraphicsWidget;
c->setData(0, QString("c"));
alay->addItem(c); alay->addItem(c);
TestLayout *clay = new TestLayout(c); TestLayout *clay = new TestLayout(c);
TestGraphicsWidget *f = new TestGraphicsWidget; TestGraphicsWidget *f = new TestGraphicsWidget;
f->setData(0, QString("f"));
clay->addItem(f); clay->addItem(f);
TestGraphicsWidget *d = new TestGraphicsWidget; TestGraphicsWidget *d = new TestGraphicsWidget;
d->setData(0, QString("d"));
alay->addItem(d); alay->addItem(d);
TestLayout *dlay = new TestLayout(d); TestLayout *dlay = new TestLayout(d);
TestGraphicsWidget *g = new TestGraphicsWidget; TestGraphicsWidget *g = new TestGraphicsWidget;
g->setData(0, QString("g"));
dlay->addItem(g); dlay->addItem(g);
view.show(); view.show();
alay->m_invalidateCount = 0; {
blay->m_invalidateCount = 0; clearAllCounters(a);
clay->m_invalidateCount = 0;
dlay->m_invalidateCount = 0;
QCoreApplication::sendPostedEvents(); QCoreApplication::sendPostedEvents();
QCoreApplication::processEvents(); QCoreApplication::processEvents();
alay->activate(); alay->activate();
QCOMPARE(alay->isActivated(), true); QCOMPARE(alay->isActivated(), true);
QCOMPARE(blay->isActivated(), true); QCOMPARE(blay->isActivated(), true);
QCOMPARE(clay->isActivated(), true); QCOMPARE(clay->isActivated(), true);
qDebug() << "alay->m_invalidateCount:" << alay->m_invalidateCount; QCOMPARE(dlay->isActivated(), true);
qDebug() << "blay->m_invalidateCount:" << blay->m_invalidateCount; }
qDebug() << "clay->m_invalidateCount:" << clay->m_invalidateCount;
qDebug() << "dlay->m_invalidateCount:" << dlay->m_invalidateCount;
a->clearEventCount(); {
b->clearEventCount(); clearAllCounters(a);
c->clearEventCount(); e->callUpdateGeometry();
QCOMPARE(alay->isActivated(), false);
QCOMPARE(blay->isActivated(), false);
QCOMPARE(clay->isActivated(), true);
QCOMPARE(dlay->isActivated(), true);
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 0);
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0);
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
blay->invalidate(); // should only invalidate ascendants of e
QCOMPARE(alay->isActivated(), false); QCOMPARE(blay->functionCount[Invalidate], 1);
QCOMPARE(blay->isActivated(), false); QCOMPARE(alay->functionCount[Invalidate], 1);
QCOMPARE(clay->isActivated(), true); // not siblings
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 0); QCOMPARE(clay->functionCount[Invalidate], 0);
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); QCOMPARE(dlay->functionCount[Invalidate], 0);
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
QApplication::sendPostedEvents();
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 1);
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
}
alay->m_invalidateCount = 0; {
blay->m_invalidateCount = 0; activateAndReset(a);
clay->m_invalidateCount = 0; f->callUpdateGeometry();
dlay->m_invalidateCount = 0; QCOMPARE(alay->isActivated(), false);
clay->invalidate(); QCOMPARE(blay->isActivated(), true);
QCOMPARE(alay->isActivated(), false); QCOMPARE(clay->isActivated(), false);
QCOMPARE(blay->isActivated(), false); QCOMPARE(dlay->isActivated(), true);
QCOMPARE(clay->isActivated(), false);
QCoreApplication::sendPostedEvents(); QCoreApplication::sendPostedEvents();
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0);
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1);
qDebug() << "alay->m_invalidateCount:" << alay->m_invalidateCount; QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
qDebug() << "blay->m_invalidateCount:" << blay->m_invalidateCount;
qDebug() << "clay->m_invalidateCount:" << clay->m_invalidateCount; QCOMPARE(a->functionCount[SetGeometry], 1);
qDebug() << "dlay->m_invalidateCount:" << dlay->m_invalidateCount; QCOMPARE(alay->functionCount[SetGeometry], 1);
QCOMPARE(b->functionCount[SetGeometry], 1);
QCOMPARE(c->functionCount[SetGeometry], 1);
QCOMPARE(d->functionCount[SetGeometry], 1);
// Since nothing really changed, blay and dlay don't need
// to be resized.
QCOMPARE(blay->functionCount[SetGeometry], 0);
QCOMPARE(clay->functionCount[SetGeometry], 1);
QCOMPARE(dlay->functionCount[SetGeometry], 0);
QCOMPARE(f->functionCount[SetGeometry], 1);
QCOMPARE(a->size(), QSizeF(150, 50));
}
{
activateAndReset(a);
f->setPreferredSize(QSizeF(60,50));
QCOMPARE(alay->isActivated(), false);
QCOMPARE(blay->isActivated(), true);
QCOMPARE(clay->isActivated(), false);
QCOMPARE(dlay->isActivated(), true);
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
QCoreApplication::sendPostedEvents();
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0);
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1);
QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
QCOMPARE(a->functionCount[SetGeometry], 1);
QCOMPARE(alay->functionCount[SetGeometry], 1);
QCOMPARE(b->functionCount[SetGeometry], 1);
QCOMPARE(c->functionCount[SetGeometry], 1);
QCOMPARE(d->functionCount[SetGeometry], 1);
// f actually got wider, need to rearrange its siblings
QCOMPARE(blay->functionCount[SetGeometry], 1);
QCOMPARE(clay->functionCount[SetGeometry], 1);
QCOMPARE(dlay->functionCount[SetGeometry], 1);
QCOMPARE(e->functionCount[SetGeometry], 1);
QCOMPARE(f->functionCount[SetGeometry], 1);
QCOMPARE(g->functionCount[SetGeometry], 1);
QVERIFY(e->size().width() < f->size().width());
QVERIFY(g->size().width() < f->size().width());
}
{
// resize f so much that it'll force a resize of the top widget
// this will currently generate two setGeometry() calls on the child layout
// of the top widget.
activateAndReset(a);
f->setPreferredSize(QSizeF());
f->setMinimumSize(QSizeF(200,50));
QCOMPARE(alay->isActivated(), false);
QCOMPARE(blay->isActivated(), true);
QCOMPARE(clay->isActivated(), false);
QCOMPARE(dlay->isActivated(), true);
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
QCoreApplication::sendPostedEvents();
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0);
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1);
QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
QCOMPARE(a->functionCount[SetGeometry], 1);
/* well, ideally one call to setGeometry(), but it will currently
* get two calls to setGeometry():
* 1. The first LayoutRequest will call activate() - that will call
* setGeometry() on the layout. This geometry will be based on
* the widget geometry which is not correct at this moment.
* (it is still 150 wide)
* 2. Next, we check if the widget is top level, and then we call
* parentWidget->resize(parentWidget->size());
* This will be adjusted to be minimum 200 pixels wide.
* The new size will then be propagated down to the layout
*
*/
QCOMPARE(alay->functionCount[SetGeometry], 2);
QCOMPARE(b->functionCount[SetGeometry], 2);
QCOMPARE(c->functionCount[SetGeometry], 2);
QCOMPARE(d->functionCount[SetGeometry], 2);
// f actually got wider, need to rearrange its siblings
QCOMPARE(blay->functionCount[SetGeometry], 1);
QCOMPARE(clay->functionCount[SetGeometry], 1);
QCOMPARE(dlay->functionCount[SetGeometry], 1);
QCOMPARE(e->functionCount[SetGeometry], 1);
QCOMPARE(f->functionCount[SetGeometry], 1);
QCOMPARE(g->functionCount[SetGeometry], 1);
QVERIFY(e->size().width() < f->size().width());
QVERIFY(g->size().width() < f->size().width());
}
{
f->setPreferredSize(QSizeF());
f->setMinimumSize(QSizeF());
a->adjustSize();
activateAndReset(a);
// update two different leaf widgets,
// eventCount and functionCount should never be >= 2
e->callUpdateGeometry();
g->callUpdateGeometry();
QCOMPARE(alay->isActivated(), false);
QCOMPARE(blay->isActivated(), false);
QCOMPARE(clay->isActivated(), true);
QCOMPARE(dlay->isActivated(), false);
QCoreApplication::sendPostedEvents();
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 1);
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
QCOMPARE(d->eventCount(QEvent::LayoutRequest), 1);
QCOMPARE(a->functionCount[SetGeometry], 1);
QCOMPARE(alay->functionCount[SetGeometry], 1);
QCOMPARE(b->functionCount[SetGeometry], 1);
QCOMPARE(c->functionCount[SetGeometry], 1);
QCOMPARE(d->functionCount[SetGeometry], 1);
// f actually got wider, need to rearrange its siblings
QCOMPARE(blay->functionCount[SetGeometry], 1);
QCOMPARE(clay->functionCount[SetGeometry], 0);
QCOMPARE(dlay->functionCount[SetGeometry], 1);
QCOMPARE(e->functionCount[SetGeometry], 1);
QCOMPARE(f->functionCount[SetGeometry], 0);
QCOMPARE(g->functionCount[SetGeometry], 1);
}
QGraphicsLayout::setInstantInvalidatePropagation(false); QGraphicsLayout::setInstantInvalidatePropagation(false);
} }