From 75dfebae4a14ca37346e5867881f21d0f66f0fdb Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 12 Jun 2015 11:17:14 +0200 Subject: [PATCH] tst_gridlayout: Fix visible top level widget leaks. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gather member variables testWidget, testLayout, w1..w3 and sp used in getItemPosition() and itemAtPosition() in Helper class ItemTestWidget. Remove member variables m_grid, m_toplevel and instantiate the top level widget on the stack in minMaxSize(). Remove empty slots and functions. Add a cleanup() test checking that no visible top levels are leaked with explanatory comment about data driven tests. Change-Id: Ia30120d78144dab3b7c73864c6fbcef606cb19d3 Reviewed-by: Jan Arve Sæther --- .../kernel/qgridlayout/tst_qgridlayout.cpp | 176 +++++++++--------- 1 file changed, 83 insertions(+), 93 deletions(-) diff --git a/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp b/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp index 7f3c289fb4..1e67c675ef 100644 --- a/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp +++ b/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp @@ -60,18 +60,9 @@ class tst_QGridLayout : public QObject { Q_OBJECT -public: - tst_QGridLayout(); - virtual ~tst_QGridLayout(); - - -public slots: - void initTestCase(); - void cleanupTestCase(); - void init(); - void cleanup(); - private slots: + void initTestCase(); + void cleanup(); void getItemPosition(); void itemAtPosition(); void badDistributionBug(); @@ -97,76 +88,72 @@ private slots: void taskQTBUG_40609_addingLayoutToItself(); void replaceWidget(); void dontCrashWhenExtendsToEnd(); - -private: - QWidget *testWidget; - QGridLayout *testLayout; - QWidget *w1; - QWidget *w2; - QWidget *w3; - QSpacerItem *sp; - - QGridLayout *m_grid; - QWidget *m_toplevel; }; - -tst_QGridLayout::tst_QGridLayout() -{ - m_grid = 0; - m_toplevel = 0; -} - -tst_QGridLayout::~tst_QGridLayout() -{ - delete m_toplevel; -} - void tst_QGridLayout::initTestCase() { #ifdef Q_OS_WINCE //disable magic for WindowsCE qApp->setAutoMaximizeThreshold(-1); #endif - // Create the test class - testWidget = new QWidget(0); - - testLayout = new QGridLayout(testWidget); - - w1 = new QWidget(testWidget); - w1->setPalette(QPalette(Qt::red)); - testLayout->addWidget(w1, 0, 0); - - w2 = new QWidget(testWidget); - testLayout->addWidget(w2, 1, 1, 2, 2); - w2->setPalette(QPalette(Qt::green)); - - w3 = new QWidget(testWidget); - testLayout->addWidget(w3, 0, 1, 1, 2); - w3->setPalette(QPalette(Qt::blue)); - - sp = new QSpacerItem(4, 4); - testLayout->addItem(sp, 1, 3, 2, 1); - - testWidget->resize( 200, 200 ); - testWidget->show(); } -void tst_QGridLayout::cleanupTestCase() -{ - delete testWidget; - testWidget = 0; -} - -void tst_QGridLayout::init() +static inline int visibleTopLevelWidgetCount() { + int result= 0; + foreach (const QWidget *topLevel, QApplication::topLevelWidgets()) { + if (topLevel->isVisible()) + ++result; + } + return result; } void tst_QGridLayout::cleanup() { + // Verify that no visible top levels are leaked. Cannot check for + // topLevelWidgets().isEmpty() here since the data driven test layoutSpacing() + // will appear to "leak" top levels due to it creating widgets in the test data. + QCOMPARE(visibleTopLevelWidgetCount(), 0); +} + +class ItemTestWidget : public QWidget { +public: + ItemTestWidget(); + + QGridLayout *testLayout; + QWidget *w1; + QWidget *w2; + QWidget *w3; + QSpacerItem *sp; +}; + +ItemTestWidget::ItemTestWidget() + : testLayout(new QGridLayout(this)) + , w1(new QWidget(this)) + , w2(new QWidget(this)) + , w3(new QWidget(this)) + , sp(new QSpacerItem(4, 4)) +{ + setObjectName("testWidget"); + setWindowTitle(QTest::currentTestFunction()); + + w1->setPalette(QPalette(Qt::red)); + testLayout->addWidget(w1, 0, 0); + + testLayout->addWidget(w2, 1, 1, 2, 2); + w2->setPalette(QPalette(Qt::green)); + + testLayout->addWidget(w3, 0, 1, 1, 2); + w3->setPalette(QPalette(Qt::blue)); + + testLayout->addItem(sp, 1, 3, 2, 1); } void tst_QGridLayout::getItemPosition() { + ItemTestWidget testWidget; + testWidget.resize(200, 200); + testWidget.show(); + QLayoutItem *item; int counter = 0; @@ -175,28 +162,28 @@ void tst_QGridLayout::getItemPosition() bool seenW3 = false; bool seenSpacer = false; - while ((item = testLayout->itemAt(counter))) { + while ((item = testWidget.testLayout->itemAt(counter))) { QWidget *w = item->widget(); int r,c,rs,cs; - testLayout->getItemPosition(counter, &r, &c, &rs, &cs); + testWidget.testLayout->getItemPosition(counter, &r, &c, &rs, &cs); // qDebug() << "item" << counter << "has" <itemAtPosition(row, col); + QLayoutItem *item = testWidget.testLayout->itemAtPosition(row, col); QVERIFY(item == table[row][col] || (item && item->widget() == table[row][col])); } @@ -860,32 +851,31 @@ void tst_QGridLayout::minMaxSize() } } QApplication::setStyle(style); - if (!m_grid) - m_grid = new QGridLayout(); - if (!m_toplevel) { - m_toplevel = new QWidget(); - setFrameless(m_toplevel); - } + QWidget toplevel; + toplevel.setWindowTitle(QLatin1String(QTest::currentTestFunction()) + + QLatin1Char(' ') + QLatin1String(QTest::currentDataTag())); + setFrameless(&toplevel); + QGridLayout *grid = new QGridLayout; if (fixedSize.isValid()) { - m_toplevel->setFixedSize(fixedSize); + toplevel.setFixedSize(fixedSize); } else { - m_toplevel->setMinimumSize(QSize(0,0)); - m_toplevel->setMaximumSize(QSize(QWIDGETSIZE_MAX,QWIDGETSIZE_MAX)); + toplevel.setMinimumSize(QSize(0,0)); + toplevel.setMaximumSize(QSize(QWIDGETSIZE_MAX,QWIDGETSIZE_MAX)); } // Do a two-pass one using the real testdata, the other pass enables heightForWidth // on the widget, but the heightForWidth() function just return sizeHint().width() for (int pass = 0; pass < 2; ++pass) { - m_toplevel->hide(); + toplevel.hide(); QApplication::processEvents(); QTest::qWait(20); // Test if removeItem uninitializes data properly - while (m_grid->count()) { - QLayoutItem *item = m_grid->itemAt(0); - m_grid->removeItem(item); + while (grid->count()) { + QLayoutItem *item = grid->itemAt(0); + grid->removeItem(item); delete item->widget(); delete item; } - m_toplevel->setLayout(m_grid); + toplevel.setLayout(grid); // a layout with a top-level parent widget QList > sizehinters; @@ -899,29 +889,29 @@ void tst_QGridLayout::minMaxSize() QSizePolicy sp = sh->sizePolicy(); sp.setHorizontalPolicy((QSizePolicy::Policy)sizePolicy); sh->setSizePolicy(sp); - sh->setParent(m_toplevel); + sh->setParent(&toplevel); if (si.minSize.isValid()) sh->setMinimumSize(si.minSize); if (si.maxSize.isValid()) sh->setMaximumSize(si.maxSize); sizehinters.append(sh); - m_grid->addWidget(sh, i, j); + grid->addWidget(sh, i, j); } } - m_toplevel->show(); - QVERIFY(QTest::qWaitForWindowExposed(m_toplevel)); - m_toplevel->adjustSize(); + toplevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&toplevel)); + toplevel.adjustSize(); QTest::qWait(240); // wait for the implicit adjustSize // If the following fails we might have to wait longer. // If that does not help there is likely a problem with the implicit adjustSize in show() if (!fixedSize.isValid()) { // Note that this can fail if the desktop has large fonts on windows. - QTRY_COMPARE(m_toplevel->size(), m_toplevel->sizeHint()); + QTRY_COMPARE(toplevel.size(), toplevel.sizeHint()); } // We are relying on the order here... for (int pi = 0; pi < sizehinters.count(); ++pi) { - QPoint pt = sizehinters.at(pi)->mapTo(m_toplevel, QPoint(0, 0)); + QPoint pt = sizehinters.at(pi)->mapTo(&toplevel, QPoint(0, 0)); QCOMPARE(pt, sizeinfos.at(pi).expectedPos); } }