File indexing completed on 2024-04-28 15:29:18
0001 /* 0002 SPDX-FileCopyrightText: 2007 David Faure <faure@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "parttest.h" 0008 #include <qtest_widgets.h> 0009 0010 #include <KSharedConfig> 0011 #include <QSignalSpy> 0012 #include <QTest> 0013 #include <QWidget> 0014 #include <kparts/openurlarguments.h> 0015 #include <kparts/readonlypart.h> 0016 0017 QTEST_MAIN(PartTest) 0018 0019 class TestPart : public KParts::ReadOnlyPart 0020 { 0021 public: 0022 TestPart(QObject *parent, QWidget *parentWidget) 0023 : KParts::ReadOnlyPart(parent) 0024 , m_openFileCalled(false) 0025 { 0026 setWidget(new QWidget(parentWidget)); 0027 connect(this, &KParts::ReadOnlyPart::urlChanged, this, &TestPart::logUrlChanged); 0028 } 0029 0030 bool openFileCalled() const 0031 { 0032 return m_openFileCalled; 0033 } 0034 0035 void logUrlChanged(const QUrl &url) 0036 { 0037 qDebug() << "url changed: " << url; 0038 } 0039 0040 protected: 0041 bool openFile() override 0042 { 0043 m_openFileCalled = true; 0044 return true; 0045 } 0046 0047 private: 0048 bool m_openFileCalled; 0049 }; 0050 0051 void PartTest::testAutoDeletePart() 0052 { 0053 KParts::Part *part = new TestPart(nullptr, nullptr); 0054 QPointer<KParts::Part> partPointer(part); 0055 delete part->widget(); 0056 QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); 0057 QVERIFY(partPointer.isNull()); 0058 } 0059 0060 void PartTest::testAutoDeleteWidget() 0061 { 0062 KParts::Part *part = new TestPart(nullptr, nullptr); 0063 QPointer<KParts::Part> partPointer(part); 0064 QPointer<QWidget> widgetPointer(part->widget()); 0065 delete part; 0066 QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); 0067 QVERIFY(widgetPointer.isNull()); 0068 } 0069 0070 void PartTest::testNoAutoDeletePart() 0071 { 0072 KParts::Part *part = new TestPart(nullptr, nullptr); 0073 part->setAutoDeletePart(false); 0074 QPointer<KParts::Part> partPointer(part); 0075 delete part->widget(); 0076 QVERIFY(part->widget() == nullptr); 0077 QCOMPARE(static_cast<KParts::Part *>(partPointer), part); 0078 delete part; 0079 } 0080 0081 void PartTest::testNoAutoDeleteWidget() 0082 { 0083 KParts::Part *part = new TestPart(nullptr, nullptr); 0084 part->setAutoDeleteWidget(false); 0085 QWidget *widget = part->widget(); 0086 QVERIFY(widget); 0087 QPointer<QWidget> widgetPointer(part->widget()); 0088 delete part; 0089 QCOMPARE(static_cast<QWidget *>(widgetPointer), widget); 0090 delete widget; 0091 } 0092 0093 // There is no operator== in OpenUrlArguments because it's only useful in unit tests 0094 static bool compareArgs(const KParts::OpenUrlArguments &arg1, const KParts::OpenUrlArguments &arg2) 0095 { 0096 return arg1.mimeType() == arg2.mimeType() && // 0097 arg1.xOffset() == arg2.xOffset() && // 0098 arg1.yOffset() == arg2.yOffset() && // 0099 arg1.reload() == arg2.reload(); 0100 } 0101 0102 void PartTest::testOpenUrlArguments() 0103 { 0104 TestPart *part = new TestPart(nullptr, nullptr); 0105 QVERIFY(part->closeUrl()); // nothing to do, no error 0106 QVERIFY(part->arguments().mimeType().isEmpty()); 0107 KParts::OpenUrlArguments args; 0108 args.setMimeType(QStringLiteral("application/xml")); 0109 args.setXOffset(50); 0110 args.setYOffset(10); 0111 args.setReload(true); 0112 part->setArguments(args); 0113 QVERIFY(compareArgs(args, part->arguments())); 0114 part->openUrl(QUrl::fromLocalFile(QFINDTESTDATA("parttest.cpp"))); 0115 QVERIFY(part->openFileCalled()); 0116 QVERIFY(compareArgs(args, part->arguments())); 0117 0118 // Explicit call to closeUrl: arguments are cleared 0119 part->closeUrl(); 0120 QVERIFY(part->arguments().mimeType().isEmpty()); 0121 0122 // Calling openUrl with local file: mimetype is determined 0123 part->openUrl(QUrl::fromLocalFile(QFINDTESTDATA("parttest.cpp"))); 0124 QCOMPARE(part->arguments().mimeType(), QStringLiteral("text/x-c++src")); 0125 // (for a remote url it would be determined during downloading) 0126 0127 delete part; 0128 } 0129 0130 void PartTest::testAutomaticMimeType() 0131 { 0132 TestPart *part = new TestPart(nullptr, nullptr); 0133 QVERIFY(part->closeUrl()); // nothing to do, no error 0134 QVERIFY(part->arguments().mimeType().isEmpty()); 0135 // open a file, and test the detected mimetype 0136 part->openUrl(QUrl::fromLocalFile(QFINDTESTDATA("notepad.desktop"))); 0137 QCOMPARE(part->arguments().mimeType(), QString::fromLatin1("application/x-desktop")); 0138 0139 // manually closing, no mimetype should be stored now 0140 part->closeUrl(); 0141 QVERIFY(part->arguments().mimeType().isEmpty()); 0142 0143 // open a new file, and test again its (autdetected) mimetype 0144 part->openUrl(QUrl::fromLocalFile(QFINDTESTDATA("parttest.cpp"))); 0145 QCOMPARE(part->arguments().mimeType(), QStringLiteral("text/x-c++src")); 0146 0147 // open a new file, but without explicitly close the first 0148 part->openUrl(QUrl::fromLocalFile(QFINDTESTDATA("notepad.desktop"))); 0149 // test again its (autdetected) mimetype 0150 QCOMPARE(part->arguments().mimeType(), QString::fromLatin1("application/x-desktop")); 0151 0152 // open a new file, but manually forcing a mimetype 0153 KParts::OpenUrlArguments args; 0154 args.setMimeType(QStringLiteral("application/xml")); 0155 part->setArguments(args); 0156 QVERIFY(compareArgs(args, part->arguments())); 0157 part->openUrl(QUrl::fromLocalFile(QFINDTESTDATA("parttest.cpp"))); 0158 QCOMPARE(part->arguments().mimeType(), QString::fromLatin1("application/xml")); 0159 0160 // clear the args and open a new file, reactivating the automatic mimetype detection again 0161 part->setArguments(KParts::OpenUrlArguments()); 0162 part->openUrl(QUrl::fromLocalFile(QFINDTESTDATA("notepad.desktop"))); 0163 // test again its (autdetected) mimetype 0164 QCOMPARE(part->arguments().mimeType(), QString::fromLatin1("application/x-desktop")); 0165 0166 delete part; 0167 } 0168 0169 void PartTest::testEmptyUrlAfterCloseUrl() 0170 { 0171 TestPart *part = new TestPart(nullptr, nullptr); 0172 0173 QVERIFY(part->openUrl(QUrl::fromLocalFile(QFINDTESTDATA("notepad.desktop")))); 0174 QSignalSpy spy(part, &KParts::ReadOnlyPart::urlChanged); 0175 QVERIFY(part->openUrl(QUrl::fromLocalFile(QFINDTESTDATA("parttest.cpp")))); 0176 QVERIFY(!part->url().isEmpty()); 0177 QCOMPARE(spy.count(), 1); 0178 spy.clear(); 0179 QVERIFY(part->closeUrl()); 0180 QVERIFY(part->url().isEmpty()); 0181 QCOMPARE(spy.count(), 1); 0182 0183 delete part; 0184 } 0185 0186 #include <KConfigGroup> 0187 #include <KToggleToolBarAction> 0188 #include <KToolBar> 0189 #include <kparts/mainwindow.h> 0190 class MyMainWindow : public KParts::MainWindow 0191 { 0192 public: 0193 MyMainWindow() 0194 : KParts::MainWindow() 0195 { 0196 tb = new KToolBar(this); 0197 tb->setObjectName(QStringLiteral("testtbvisibility")); 0198 } 0199 0200 // createGUI and saveAutoSaveSettings are protected, so the whole test is here: 0201 void testToolbarVisibility() 0202 { 0203 QVERIFY(tb->isVisible()); 0204 0205 TestPart *part = new TestPart(nullptr, nullptr); 0206 // TODO define xml with a toolbar for the part 0207 // and put some saved settings into qttestrc in order to test 0208 // r347935+r348051, i.e. the fact that KParts::MainWindow::createGUI 0209 // will apply the toolbar settings (and that they won't have been 0210 // erased by the previous call to saveMainWindowSettings...) 0211 this->createGUI(part); 0212 0213 QVERIFY(tb->isVisible()); 0214 this->saveAutoSaveSettings(); 0215 0216 // Hide the toolbar using the action (so that setSettingsDirty is called, too) 0217 KToggleToolBarAction action(tb, QString(), nullptr); 0218 action.trigger(); 0219 QVERIFY(!tb->isVisible()); 0220 0221 // Switch the active part, and check that 0222 // the toolbar doesn't magically reappear, 0223 // as it did when createGUI was calling applyMainWindowSettings 0224 this->createGUI(nullptr); 0225 QVERIFY(!tb->isVisible()); 0226 this->createGUI(part); 0227 QVERIFY(!tb->isVisible()); 0228 0229 // All ok, show it again so that test can be run again :) 0230 action.trigger(); 0231 QVERIFY(tb->isVisible()); 0232 close(); 0233 } 0234 0235 private: 0236 KToolBar *tb; 0237 }; 0238 0239 // A KParts::MainWindow unit test 0240 void PartTest::testToolbarVisibility() 0241 { 0242 // The bug was: hide a toolbar in konqueror, 0243 // then switch tabs -> the toolbar shows again 0244 // (unless you waited for the autosave timer to kick in) 0245 MyMainWindow window; 0246 KConfigGroup cg(KSharedConfig::openConfig(), "kxmlgui_unittest"); 0247 window.setAutoSaveSettings(cg.name()); 0248 window.show(); 0249 window.testToolbarVisibility(); 0250 } 0251 0252 void PartTest::testShouldNotCrashAfterDelete() 0253 { 0254 TestPart *part = new TestPart(nullptr, nullptr); 0255 QVERIFY(part->openUrl(QUrl::fromLocalFile(QFINDTESTDATA("notepad.desktop")))); 0256 QVERIFY(part->openFileCalled()); 0257 delete part; 0258 } 0259 0260 #include "moc_parttest.cpp"