OSDN Git Service

add QBoxLayout test
authorIvailo Monev <xakepa10@gmail.com>
Sun, 19 Sep 2021 13:38:54 +0000 (16:38 +0300)
committerIvailo Monev <xakepa10@gmail.com>
Sun, 19 Sep 2021 13:38:54 +0000 (16:38 +0300)
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
tests/auto/qboxlayout/CMakeLists.txt [new file with mode: 0644]
tests/auto/qboxlayout/tst_qboxlayout.cpp [new file with mode: 0644]

diff --git a/tests/auto/qboxlayout/CMakeLists.txt b/tests/auto/qboxlayout/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e88a175
--- /dev/null
@@ -0,0 +1,3 @@
+katie_gui_test(tst_qboxlayout
+    ${CMAKE_CURRENT_SOURCE_DIR}/tst_qboxlayout.cpp
+)
diff --git a/tests/auto/qboxlayout/tst_qboxlayout.cpp b/tests/auto/qboxlayout/tst_qboxlayout.cpp
new file mode 100644 (file)
index 0000000..078102c
--- /dev/null
@@ -0,0 +1,482 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 Ivailo Monev
+**
+** This file is part of the test suite of the Katie Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+**
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <QtGui>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QBoxLayout : public QObject
+{
+    Q_OBJECT
+
+public:
+    tst_QBoxLayout();
+    virtual ~tst_QBoxLayout();
+
+public slots:
+    void initTestCase();
+    void cleanupTestCase();
+    void init();
+    void cleanup();
+
+private slots:
+    void insertSpacerItem();
+    void insertLayout();
+    void sizeHint();
+    void sizeConstraints();
+    void setGeometry();
+    void setStyleShouldChangeSpacing();
+
+    void testLayoutEngine_data();
+    void testLayoutEngine();
+
+    void taskQTBUG_7103_minMaxWidthNotRespected();
+    void taskQTBUG_27420_takeAtShouldUnparentLayout();
+};
+
+class CustomLayoutStyle : public QWindowsStyle
+{
+    Q_OBJECT
+public:
+    CustomLayoutStyle() : QWindowsStyle()
+    {
+        hspacing = 5;
+        vspacing = 10;
+    }
+
+    virtual int pixelMetric(PixelMetric metric, const QStyleOption * option = 0,
+                            const QWidget * widget = 0 ) const;
+
+    int hspacing;
+    int vspacing;
+};
+
+int CustomLayoutStyle::pixelMetric(PixelMetric metric, const QStyleOption * option /*= 0*/,
+                                   const QWidget * widget /*= 0*/ ) const
+{
+    switch (metric) {
+        case PM_LayoutLeftMargin:
+            return 0;
+        case PM_LayoutTopMargin:
+            return 3;
+        case PM_LayoutRightMargin:
+            return 6;
+        case PM_LayoutBottomMargin:
+            return 9;
+        case PM_LayoutHorizontalSpacing:
+            return hspacing;
+        case PM_LayoutVerticalSpacing:
+            return vspacing;
+        default:
+            break;
+    }
+    return QWindowsStyle::pixelMetric(metric, option, widget);
+}
+
+
+tst_QBoxLayout::tst_QBoxLayout()
+{
+}
+
+tst_QBoxLayout::~tst_QBoxLayout()
+{
+}
+
+void tst_QBoxLayout::initTestCase()
+{
+}
+
+void tst_QBoxLayout::cleanupTestCase()
+{
+}
+
+void tst_QBoxLayout::init()
+{
+}
+
+void tst_QBoxLayout::cleanup()
+{
+}
+
+void tst_QBoxLayout::insertSpacerItem()
+{
+    QWidget *window = new QWidget;
+
+    QSpacerItem *spacer1 = new QSpacerItem(20, 10, QSizePolicy::Expanding, QSizePolicy::Expanding);
+    QSpacerItem *spacer2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+    QBoxLayout *layout = new QHBoxLayout;
+    layout->addWidget(new QLineEdit("Foooooooooooooooooooooooooo"));
+    layout->addSpacerItem(spacer1);
+    layout->addWidget(new QLineEdit("Baaaaaaaaaaaaaaaaaaaaaaaaar"));
+    layout->insertSpacerItem(0, spacer2);
+    window->setLayout(layout);
+
+    QVERIFY(layout->itemAt(0) == spacer2);
+    QVERIFY(layout->itemAt(2) == spacer1);
+
+    window->show();
+}
+
+void tst_QBoxLayout::insertLayout()
+{
+    QWidget *window = new QWidget;
+    QVBoxLayout *vbox = new QVBoxLayout(window);
+    QVBoxLayout *dummyParentLayout = new QVBoxLayout;
+    QHBoxLayout *subLayout = new QHBoxLayout;
+    dummyParentLayout->addLayout(subLayout);
+    QCOMPARE(subLayout->parent(), dummyParentLayout);
+    QCOMPARE(dummyParentLayout->count(), 1);
+
+    // add subLayout to another layout
+    QTest::ignoreMessage(QtWarningMsg, "QLayout::addChildLayout: layout \"\" already has a parent");
+    vbox->addLayout(subLayout);
+    QCOMPARE((subLayout->parent() == vbox), (vbox->count() == 1));
+
+    delete dummyParentLayout;
+    delete window;
+}
+
+
+void tst_QBoxLayout::sizeHint()
+{
+    QWidget *window = new QWidget;
+    QHBoxLayout *lay1 = new QHBoxLayout;
+    QHBoxLayout *lay2 = new QHBoxLayout;
+    QLabel *label = new QLabel("widget twooooooooooooooooooooooooooooooooooooooooooooooooooooooo");
+    lay2->addWidget(label);
+    lay1->addLayout(lay2);
+    window->setLayout(lay1);
+    window->show();
+    label->setText("foooooooo baaaaaaar");
+    QSize sh = lay1->sizeHint();
+    QApplication::processEvents();
+    // Note that this is not strictly required behaviour - actually
+    // the preferred behaviour would be that sizeHint returns
+    // the same value regardless of what's lying in the event queue.
+    // (i.e. we would check for equality here instead)
+    QVERIFY(lay1->sizeHint() != sh);
+}
+
+void tst_QBoxLayout::sizeConstraints()
+{
+    QWidget *window = new QWidget;
+    QHBoxLayout *lay = new QHBoxLayout;
+    lay->addWidget(new QLabel("foooooooooooooooooooooooooooooooooooo"));
+    lay->addWidget(new QLabel("baaaaaaaaaaaaaaaaaaaaaaaaaaaaaar"));
+    lay->setSizeConstraint(QLayout::SetFixedSize);
+    window->setLayout(lay);
+    window->show();
+    QApplication::processEvents();
+    QSize sh = window->sizeHint();
+    lay->takeAt(1);
+    QVERIFY(sh.width() >= window->sizeHint().width() &&
+            sh.height() >= window->sizeHint().height());
+
+}
+
+void tst_QBoxLayout::setGeometry()
+{
+    QWidget toplevel;
+    QWidget w(&toplevel);
+    QVBoxLayout *lay = new QVBoxLayout;
+    lay->setMargin(0);
+    lay->setSpacing(0);
+    QHBoxLayout *lay2 = new QHBoxLayout;
+    QDial *dial = new QDial;
+    lay2->addWidget(dial);
+    lay2->setAlignment(Qt::AlignTop);
+    lay2->setAlignment(Qt::AlignRight);
+    lay->addLayout(lay2);
+    w.setLayout(lay);
+    toplevel.show();
+
+    QRect newGeom(0, 0, 70, 70);
+    lay2->setGeometry(newGeom);
+    QVERIFY2(newGeom.contains(dial->geometry()), "dial->geometry() should be smaller and within newGeom");
+}
+
+void tst_QBoxLayout::setStyleShouldChangeSpacing()
+{
+
+    QWidget *window = new QWidget;
+    QHBoxLayout *hbox = new QHBoxLayout(window);
+    QPushButton *pb1 = new QPushButton(tr("The spacing between this"));
+    QPushButton *pb2 = new QPushButton(tr("and this button should depend on the style of the parent widget"));;
+    pb1->setAttribute(Qt::WA_LayoutUsesWidgetRect);
+    pb2->setAttribute(Qt::WA_LayoutUsesWidgetRect);
+    hbox->addWidget(pb1);
+    hbox->addWidget(pb2);
+    CustomLayoutStyle *style1 = new CustomLayoutStyle;
+    style1->hspacing = 6;
+    window->setStyle(style1);
+    window->show();
+
+    QTest::qWait(100);
+    int spacing = pb2->geometry().left() - pb1->geometry().right() - 1;
+    QCOMPARE(spacing, 6);
+
+    CustomLayoutStyle *style2 = new CustomLayoutStyle();
+    style2->hspacing = 10;
+    window->setStyle(style2);
+    QTest::qWait(100);
+    spacing = pb2->geometry().left() - pb1->geometry().right() - 1;
+    QCOMPARE(spacing, 10);
+
+    delete window;
+    delete style1;
+    delete style2;
+}
+
+void tst_QBoxLayout::taskQTBUG_7103_minMaxWidthNotRespected()
+{
+    QLabel *label = new QLabel("Qt uses standard C++, but makes extensive use of the C pre-processor to enrich the language. Qt can also be used in several other programming languages via language bindings. It runs on all major platforms, and has extensive internationalization support. Non-GUI features include SQL database access, XML parsing, thread management, network support and a unified cross-platform API for file handling.");
+    label->setWordWrap(true);
+    label->setFixedWidth(200);
+
+    QVBoxLayout *layout = new QVBoxLayout;
+    layout->addWidget(label);
+    layout->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Fixed, QSizePolicy::Expanding));
+
+    QWidget widget;
+    widget.setLayout(layout);
+    widget.show();
+    QTest::qWaitForWindowShown(&widget);
+
+    int height = label->height();
+
+    QRect g = widget.geometry();
+    g.setWidth(600);
+    widget.setGeometry(g);
+
+    QTest::qWait(50);
+
+    QCOMPARE(label->height(), height);
+}
+
+void tst_QBoxLayout::taskQTBUG_27420_takeAtShouldUnparentLayout()
+{
+    QSharedPointer<QHBoxLayout> outer(new QHBoxLayout);
+    QPointer<QVBoxLayout> inner = new QVBoxLayout;
+
+    outer->addLayout(inner);
+    QCOMPARE(outer->count(), 1);
+    QCOMPARE(inner->parent(), outer.data());
+
+    QLayoutItem *item = outer->takeAt(0);
+    QCOMPARE(item->layout(), inner.data());
+    QVERIFY(!item->layout()->parent());
+
+    outer.clear();
+
+    if (inner)
+        delete item; // success: a taken item/layout should not be deleted when the old parent is deleted
+    else
+        QVERIFY(!inner.isNull());
+}
+
+
+struct Descr
+{
+    Descr(int min, int sh, int max = -1, bool exp= false, int _stretch = 0, bool _empty = false)
+        :minimumSize(min), sizeHint(sh), maximumSize(max < 0 ? QLAYOUTSIZE_MAX : max),
+         expanding(exp), stretch(_stretch), empty(_empty)
+        {}
+
+    int minimumSize;
+    int sizeHint;
+    int maximumSize;
+    bool expanding;
+
+    int stretch;
+
+    bool empty;
+};
+
+
+typedef QList<Descr> DescrList;
+Q_DECLARE_METATYPE(DescrList);
+
+typedef QList<int> SizeList;
+Q_DECLARE_METATYPE(SizeList);
+
+typedef QList<int> PosList;
+
+
+
+class LayoutItem : public QLayoutItem
+{
+public:
+    LayoutItem(const Descr &descr) :m_descr(descr) {}
+
+    QSize sizeHint() const { return QSize(m_descr.sizeHint, 100); }
+    QSize minimumSize() const { return QSize(m_descr.minimumSize, 0); }
+    QSize maximumSize() const { return QSize(m_descr.maximumSize, QLAYOUTSIZE_MAX); }
+    Qt::Orientations expandingDirections() const
+        { return m_descr.expanding ? Qt::Horizontal :  Qt::Orientations(0); }
+    void setGeometry(const QRect &r) { m_pos = r.x(); m_size = r.width();}
+    QRect geometry() const { return QRect(m_pos, 0, m_size, 100); }
+    bool isEmpty() const { return m_descr.empty; }
+
+private:
+    Descr m_descr;
+    int m_pos;
+    int m_size;
+};
+
+void tst_QBoxLayout::testLayoutEngine_data()
+{
+    // (int min, int sh, int max = -1, bool exp= false, int _stretch = 0, bool _empty = false)
+    QTest::addColumn<DescrList>("itemDescriptions");
+    QTest::addColumn<int>("size");
+    QTest::addColumn<int>("spacing");
+    QTest::addColumn<PosList>("expectedPositions");
+    QTest::addColumn<SizeList>("expectedSizes");
+
+    QTest::newRow("Just one")
+        << (DescrList() << Descr(0, 100))
+        << 200
+        << 0
+        << (PosList() << 0)
+        << (SizeList() << 200);
+
+    QTest::newRow("Two non-exp")
+        << (DescrList() << Descr(0, 100) << Descr(0,100))
+        << 400
+        << 0
+        << (PosList() << 0 << 200)
+        << (SizeList() << 200 << 200);
+
+    QTest::newRow("Exp + non-exp")
+        << (DescrList() << Descr(0, 100, -1, true) << Descr(0,100))
+        << 400
+        << 0
+        << (PosList() << 0 << 300)
+        << (SizeList() << 300 << 100);
+
+
+    QTest::newRow("Stretch")
+        << (DescrList() << Descr(0, 100, -1, false, 1) << Descr(0,100, -1, false, 2))
+        << 300
+        << 0
+        << (PosList() << 0 << 100)
+        << (SizeList() << 100 << 200);
+
+
+    QTest::newRow("Spacing")
+        << (DescrList() << Descr(0, 100) << Descr(0,100))
+        << 400
+        << 10
+        << (PosList() << 0 << 205)
+        << (SizeList() << 195 << 195);
+
+
+    QTest::newRow("Less than minimum")
+        << (DescrList() << Descr(100, 100, 100, false) << Descr(50, 100, 100, false))
+        << 100
+        << 0
+        << (PosList() << 0 << 50)
+        << (SizeList() << 50 << 50);
+
+
+    QTest::newRow("Less than sizehint")
+        << (DescrList() << Descr(100, 200, 100, false) << Descr(50, 200, 100, false))
+        << 200
+        << 0
+        << (PosList() << 0 << 100)
+        << (SizeList() << 100 << 100);
+
+    QTest::newRow("Too much space")
+        << (DescrList() << Descr(0, 100, 100, false) << Descr(0, 100, 100, false))
+        << 500
+        << 0
+        << (PosList() << 100 << 300)
+        << (SizeList() << 100 << 100);
+
+    QTest::newRow("Empty")
+        << (DescrList() << Descr(0, 100, 100) << Descr(0,0,-1, false, 0, true) << Descr(0, 100, 100) )
+        << 500
+        << 0
+        << (PosList() << 100 << 300 << 300)
+        << (SizeList() << 100 << 0 << 100);
+
+    QTest::newRow("QTBUG-33104")
+        << (DescrList() << Descr(11, 75, 75, true) << Descr(75, 75))
+        << 200
+        << 0
+        << (PosList() << 0 << 75)
+        << (SizeList() << 75 << 125);
+
+    QTest::newRow("Expanding with maximumSize")
+        << (DescrList() << Descr(11, 75, 100, true) << Descr(75, 75))
+        << 200
+        << 0
+        << (PosList() << 0 << 100)
+        << (SizeList() << 100 << 100);
+
+    QTest::newRow("Stretch with maximumSize")
+        << (DescrList() << Descr(11, 75, 100, false, 1) << Descr(75, 75))
+        << 200
+        << 0
+        << (PosList() << 0 << 100)
+        << (SizeList() << 100 << 100);
+
+    QTest::newRow("Stretch with maximumSize last")
+        << (DescrList()  << Descr(75, 75) << Descr(11, 75, 100, false, 1))
+        << 200
+        << 0
+        << (PosList() << 0 << 100)
+        << (SizeList() << 100 << 100);
+}
+
+void tst_QBoxLayout::testLayoutEngine()
+{
+    QFETCH(DescrList, itemDescriptions);
+    QFETCH(int, size);
+    QFETCH(int, spacing);
+    QFETCH(PosList, expectedPositions);
+    QFETCH(SizeList, expectedSizes);
+
+    QHBoxLayout box;
+    box.setSpacing(spacing);
+    int i;
+    for (i = 0; i < itemDescriptions.count(); ++i) {
+         Descr descr = itemDescriptions.at(i);
+         LayoutItem *li = new LayoutItem(descr);
+         box.addItem(li);
+         box.setStretch(i, descr.stretch);
+    }
+    box.setGeometry(QRect(0,0,size,100));
+    for (i = 0; i < expectedSizes.count(); ++i) {
+        int xSize = expectedSizes.at(i);
+        int xPos = expectedPositions.at(i);
+        QLayoutItem *item = box.itemAt(i);
+        QCOMPARE(item->geometry().width(), xSize);
+        QCOMPARE(item->geometry().x(), xPos);
+    }
+}
+
+QTEST_MAIN(tst_QBoxLayout)
+
+#include "moc_tst_qboxlayout.cpp"