File indexing completed on 2024-04-14 03:57:05

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2006 David Faure <faure@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "kmainwindow_unittest.h"
0009 
0010 #include <KConfigGroup>
0011 #include <KSharedConfig>
0012 #include <QEventLoopLocker>
0013 #include <QResizeEvent>
0014 #include <QStatusBar>
0015 #include <QTest>
0016 #include <QTimer>
0017 #include <kmainwindow.h>
0018 #include <ktoolbar.h>
0019 
0020 QTEST_MAIN(KMainWindow_UnitTest)
0021 
0022 void KMainWindow_UnitTest::initTestCase()
0023 {
0024     QStandardPaths::setTestModeEnabled(true);
0025     QFile::remove(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + KSharedConfig::openConfig()->name());
0026 }
0027 
0028 void KMainWindow_UnitTest::cleanupTestCase()
0029 {
0030     QFile::remove(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + KSharedConfig::openConfig()->name());
0031 }
0032 
0033 void KMainWindow_UnitTest::testDefaultName()
0034 {
0035     KMainWindow mw;
0036     mw.show();
0037     mw.ensurePolished();
0038     QCOMPARE(mw.objectName(), QStringLiteral("MainWindow#1"));
0039     KMainWindow mw2;
0040     mw2.show();
0041     mw2.ensurePolished();
0042     QCOMPARE(mw2.objectName(), QStringLiteral("MainWindow#2"));
0043 }
0044 
0045 void KMainWindow_UnitTest::testFixedName()
0046 {
0047     KMainWindow mw;
0048     mw.setObjectName(QStringLiteral("mymainwindow"));
0049     mw.show();
0050     mw.ensurePolished();
0051     QCOMPARE(mw.objectName(), QStringLiteral("mymainwindow"));
0052     KMainWindow mw2;
0053     mw2.setObjectName(QStringLiteral("mymainwindow"));
0054     mw2.show();
0055     mw2.ensurePolished();
0056     QCOMPARE(mw2.objectName(), QStringLiteral("mymainwindow2"));
0057 }
0058 
0059 void KMainWindow_UnitTest::testNameWithHash()
0060 {
0061     KMainWindow mw;
0062     mw.setObjectName(QStringLiteral("composer#"));
0063     mw.show();
0064     mw.ensurePolished();
0065     QCOMPARE(mw.objectName(), QStringLiteral("composer#1"));
0066     KMainWindow mw2;
0067     mw2.setObjectName(QStringLiteral("composer#"));
0068     mw2.show();
0069     mw2.ensurePolished();
0070     QCOMPARE(mw2.objectName(), QStringLiteral("composer#2"));
0071     KMainWindow mw4;
0072     mw4.setObjectName(QStringLiteral("composer#4"));
0073     mw4.show();
0074     mw4.ensurePolished();
0075     QCOMPARE(mw4.objectName(), QStringLiteral("composer#4"));
0076 }
0077 
0078 void KMainWindow_UnitTest::testNameWithSpecialChars()
0079 {
0080     KMainWindow mw;
0081     mw.setObjectName(QStringLiteral("a#@_test/"));
0082     mw.show();
0083     mw.ensurePolished();
0084     QCOMPARE(mw.dbusName(), QStringLiteral("/kmainwindow_unittest/a___test_"));
0085     KMainWindow mw2;
0086     mw2.setObjectName(QStringLiteral("a#@_test/"));
0087     mw2.show();
0088     mw2.ensurePolished();
0089     QCOMPARE(mw2.dbusName(), QStringLiteral("/kmainwindow_unittest/a___test_2"));
0090 }
0091 
0092 static bool s_mainWindowDeleted;
0093 class MyMainWindow : public KMainWindow
0094 {
0095 public:
0096     MyMainWindow()
0097         : KMainWindow()
0098         , m_queryClosedCalled(false)
0099     {
0100     }
0101     bool queryClose() override
0102     {
0103         m_queryClosedCalled = true;
0104         return true;
0105     }
0106     ~MyMainWindow() override
0107     {
0108         s_mainWindowDeleted = true;
0109     }
0110     bool m_queryClosedCalled;
0111 
0112     void reallyResize(int width, int height)
0113     {
0114         const QSize oldSize = size();
0115 
0116         resize(width, height);
0117 
0118         // Send the pending resize event (resize() only sets Qt::WA_PendingResizeEvent)
0119         QResizeEvent e(size(), oldSize);
0120         QApplication::sendEvent(this, &e);
0121 
0122         QCOMPARE(this->width(), width);
0123         QCOMPARE(this->height(), height);
0124     }
0125 };
0126 
0127 // Here we test
0128 // - that queryClose is called
0129 // - that autodeletion happens
0130 void KMainWindow_UnitTest::testDeleteOnClose()
0131 {
0132     QEventLoopLocker locker; // don't let the deref in KMainWindow quit the app.
0133     s_mainWindowDeleted = false;
0134     MyMainWindow *mw = new MyMainWindow;
0135     QVERIFY(mw->testAttribute(Qt::WA_DeleteOnClose));
0136     mw->close();
0137     QVERIFY(mw->m_queryClosedCalled);
0138     qApp->sendPostedEvents(mw, QEvent::DeferredDelete);
0139     QVERIFY(s_mainWindowDeleted);
0140 }
0141 
0142 void KMainWindow_UnitTest::testSaveWindowSize()
0143 {
0144     QCOMPARE(KSharedConfig::openConfig()->name(), QStringLiteral("kmainwindow_unittestrc"));
0145     KConfigGroup cfg(KSharedConfig::openConfig(), QStringLiteral("TestWindowSize"));
0146 
0147     {
0148         MyMainWindow mw;
0149         mw.show();
0150         KToolBar *tb = new KToolBar(&mw); // we need a toolbar to trigger an old bug in saveMainWindowSettings
0151         tb->setObjectName(QStringLiteral("testtb"));
0152         mw.reallyResize(800, 600);
0153         QTRY_COMPARE(mw.size(), QSize(800, 600));
0154         QTRY_COMPARE(mw.windowHandle()->size(), QSize(800, 600));
0155         mw.saveMainWindowSettings(cfg);
0156         mw.close();
0157     }
0158 
0159     KMainWindow mw2;
0160     mw2.show();
0161     KToolBar *tb = new KToolBar(&mw2);
0162     tb->setObjectName(QStringLiteral("testtb"));
0163     mw2.resize(500, 500);
0164     mw2.applyMainWindowSettings(cfg);
0165 
0166     QTRY_COMPARE(mw2.size(), QSize(800, 600));
0167 }
0168 
0169 void KMainWindow_UnitTest::testSaveWindowSizeInStateConfig()
0170 {
0171     QCOMPARE(KSharedConfig::openConfig()->name(), QStringLiteral("kmainwindow_unittestrc"));
0172     KConfigGroup cfg(KSharedConfig::openConfig(), QStringLiteral("testSaveWindowSizeInStateConfig"));
0173     cfg.deleteGroup();
0174     QVERIFY(cfg.isValid());
0175 
0176     {
0177         MyMainWindow mw;
0178         mw.show();
0179         mw.reallyResize(800, 600);
0180         mw.setStateConfigGroup(QStringLiteral("StateConfigGroup"));
0181         mw.saveMainWindowSettings(cfg);
0182         mw.close();
0183     }
0184 
0185     const KConfigGroup stateGrp = KSharedConfig::openStateConfig()->group(QStringLiteral("StateConfigGroup"));
0186     QVERIFY(stateGrp.exists());
0187     QVERIFY(stateGrp.hasKey("State"));
0188     QVERIFY(!cfg.hasKey("State"));
0189 }
0190 
0191 void KMainWindow_UnitTest::testAutoSaveSettings()
0192 {
0193     const QString group(QStringLiteral("AutoSaveTestGroup"));
0194 
0195     {
0196         MyMainWindow mw;
0197         mw.show();
0198         KToolBar *tb = new KToolBar(&mw); // we need a toolbar to trigger an old bug in saveMainWindowSettings
0199         tb->setObjectName(QStringLiteral("testtb"));
0200         mw.setStateConfigGroup(group);
0201         mw.setAutoSaveSettings(group);
0202         mw.reallyResize(800, 600);
0203         QVERIFY(mw.autoSaveSettings());
0204 
0205         // Ensure we save the settings in the correct place
0206         const auto hasWidthAndHightSaved = [](const QStringList &keys) {
0207             const auto containsKey = [&keys](const QLatin1String &keyToCheck) {
0208                 return std::any_of(keys.begin(), keys.end(), [&keyToCheck](const QString &key) {
0209                     return key.contains(keyToCheck);
0210                 });
0211             };
0212             return containsKey(QLatin1String("Width")) && containsKey(QLatin1String("Height"));
0213         };
0214         QTRY_VERIFY(hasWidthAndHightSaved(mw.stateConfigGroup().keyList()));
0215         QTRY_VERIFY(!hasWidthAndHightSaved(mw.autoSaveConfigGroup().keyList()));
0216         mw.close();
0217     }
0218 
0219     KMainWindow mw2;
0220     mw2.show();
0221     KToolBar *tb = new KToolBar(&mw2);
0222     tb->setObjectName(QStringLiteral("testtb"));
0223     mw2.setStateConfigGroup(group);
0224     mw2.setAutoSaveSettings(group);
0225     QTRY_COMPARE(mw2.size(), QSize(800, 600));
0226 }
0227 
0228 void KMainWindow_UnitTest::testNoAutoSave()
0229 {
0230     const QString group(QStringLiteral("AutoSaveTestGroup"));
0231 
0232     {
0233         // A mainwindow with autosaving, but not of the window size.
0234         MyMainWindow mw;
0235         mw.show();
0236         mw.setStateConfigGroup(group);
0237         mw.setAutoSaveSettings(group, false);
0238         mw.reallyResize(750, 550);
0239         mw.close();
0240     }
0241 
0242     KMainWindow mw2;
0243     mw2.show();
0244     mw2.setStateConfigGroup(group);
0245     mw2.setAutoSaveSettings(group, false);
0246     // NOT 750, 550! (the 800,600 comes from testAutoSaveSettings)
0247     QTRY_COMPARE(mw2.size(), QSize(800, 600));
0248 }
0249 
0250 void KMainWindow_UnitTest::testWidgetWithStatusBar()
0251 {
0252     // KMainWindow::statusBar() should not find any indirect QStatusBar child
0253     // (e.g. in a case like konqueror, with one statusbar per frame)
0254     MyMainWindow mw;
0255     QWidget *frame1 = new QWidget(&mw);
0256     QStatusBar *frameStatusBar = new QStatusBar(frame1);
0257     QVERIFY(mw.statusBar() != frameStatusBar);
0258 }
0259 
0260 #include "moc_kmainwindow_unittest.cpp"