File indexing completed on 2024-04-21 14:55:14
0001 /* This file is part of the KDE libraries 0002 0003 Copyright (c) 2010 Romain Perier <mrpouet@gentoo.org> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License as published by the Free Software Foundation; either 0008 version 2 of the License, or (at your option) any later version. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Library General Public License for more details. 0014 0015 You should have received a copy of the GNU Library General Public License 0016 along with this library; see the file COPYING.LIB. If not, write to 0017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include <QApplication> 0022 #include <QCheckBox> 0023 #include <QSignalSpy> 0024 #include <kdialog.h> 0025 #include <QPushButton> 0026 #include <QPointer> 0027 #include <QTest> 0028 0029 Q_DECLARE_METATYPE(KDialog::ButtonCode) 0030 0031 class KDialog_UnitTest : public QObject 0032 { 0033 Q_OBJECT 0034 public: 0035 KDialog_UnitTest() 0036 { 0037 qRegisterMetaType<KDialog::ButtonCode>("KDialog::ButtonCode"); 0038 } 0039 0040 private: // helper methods 0041 void checkOtherButtonsAreNotDefault(KDialog &dialog, KDialog::ButtonCode id) 0042 { 0043 KDialog::ButtonCode codes[] = { KDialog::Ok, KDialog::Apply, KDialog::Cancel, 0044 KDialog::No, KDialog::Yes 0045 }; 0046 for (int i = 0; i < 5; i++) { 0047 if (codes[i] == id) { 0048 continue; 0049 } 0050 QVERIFY(!dialog.button(codes[i])->isDefault()); 0051 } 0052 } 0053 0054 void checkSetDefaultButton(KDialog &dialog, KDialog::ButtonCode id) 0055 { 0056 dialog.setDefaultButton(id); 0057 QCOMPARE(dialog.defaultButton(), id); 0058 QVERIFY(dialog.button(id)->isDefault()); 0059 checkOtherButtonsAreNotDefault(dialog, id); 0060 } 0061 0062 private Q_SLOTS: 0063 // Test if buttons are correctly stored 0064 // in the KDialog, then try to get back them. 0065 // (only common buttons are tested) 0066 void testDefaultButton() 0067 { 0068 KDialog dialog; 0069 dialog.setButtons(KDialog::Ok | KDialog::Apply 0070 | KDialog::Cancel | KDialog::No | KDialog::Yes); 0071 checkSetDefaultButton(dialog, KDialog::Ok); 0072 checkSetDefaultButton(dialog, KDialog::Apply); 0073 checkSetDefaultButton(dialog, KDialog::Cancel); 0074 checkSetDefaultButton(dialog, KDialog::No); 0075 dialog.setDefaultButton(KDialog::NoDefault); 0076 checkOtherButtonsAreNotDefault(dialog, KDialog::NoDefault); 0077 checkSetDefaultButton(dialog, KDialog::Yes); 0078 dialog.setDefaultButton(KDialog::None); // #148969 0079 checkOtherButtonsAreNotDefault(dialog, KDialog::None); 0080 } 0081 0082 void testFutureDefaultButton() 0083 { 0084 // Test setting a default button that doesn't exist yet 0085 KDialog dialog; 0086 KDialog::ButtonCode id = KDialog::Apply; 0087 dialog.setDefaultButton(id); 0088 QCOMPARE(dialog.defaultButton(), id); 0089 QCOMPARE(dialog.button(id), static_cast<QPushButton *>(nullptr)); 0090 0091 dialog.setButtons(KDialog::Ok | KDialog::Apply 0092 | KDialog::Cancel | KDialog::No | KDialog::Yes); 0093 QCOMPARE(dialog.defaultButton(), KDialog::Apply); 0094 QVERIFY(dialog.button(id)->isDefault()); 0095 QVERIFY(!dialog.button(KDialog::Ok)->isDefault()); 0096 } 0097 0098 // Test what happens with giving focus to widgets before the window is shown 0099 // This is mostly Qt experimentation, unrelated to KDialog's own code 0100 void testFocus() 0101 { 0102 KDialog dialog; 0103 dialog.setButtons(KDialog::Ok | KDialog::Cancel); 0104 QCheckBox *checkBox = new QCheckBox("Hello world !", &dialog); 0105 QPushButton *okButton = dialog.button(KDialog::Ok); 0106 okButton->setFocus(); 0107 QVERIFY(!okButton->hasFocus()); // confusing, heh? 0108 QCOMPARE(dialog.focusWidget(), static_cast<QWidget *>(okButton)); 0109 checkBox->setFocus(); 0110 QVERIFY(!checkBox->hasFocus()); // confusing, heh? 0111 QCOMPARE(dialog.focusWidget(), static_cast<QWidget *>(checkBox)); 0112 } 0113 0114 // Ensure that only the defaultButton() receives the keyEvent 0115 // (it should get the focus) 0116 void testKeyPressEvents() 0117 { 0118 KDialog dialog; 0119 QSignalSpy qCancelClickedSpy(&dialog, SIGNAL(cancelClicked())); 0120 QSignalSpy qOkClickedSpy(&dialog, SIGNAL(okClicked())); 0121 dialog.setButtons(KDialog::Ok | KDialog::Cancel); 0122 dialog.setDefaultButton(KDialog::Cancel); 0123 dialog.show(); 0124 // Necessary after show(), otherwise dialog.focusWidget() returns NULL 0125 QApplication::setActiveWindow(&dialog); 0126 QVERIFY(dialog.focusWidget()); 0127 // Graphically always the focused widget receives the keyEvent 0128 // (otherwises it does not make sense) 0129 QTest::keyClick(dialog.focusWidget(), Qt::Key_Return); 0130 QCOMPARE(qCancelClickedSpy.count(), 1); 0131 QCOMPARE(qOkClickedSpy.count(), 0); 0132 } 0133 0134 void testCheckBoxKeepsFocus() 0135 { 0136 KDialog dialog; 0137 QCheckBox checkBox("Hello world !", &dialog); 0138 QSignalSpy qCancelClickedSpy(&dialog, SIGNAL(cancelClicked())); 0139 dialog.setButtons(KDialog::Ok | KDialog::Cancel); 0140 checkBox.setFocus(); 0141 dialog.setMainWidget(&checkBox); 0142 dialog.setDefaultButton(KDialog::Cancel); 0143 dialog.show(); 0144 QApplication::setActiveWindow(&dialog); 0145 QVERIFY(checkBox.hasFocus()); 0146 QVERIFY(!dialog.button(KDialog::Cancel)->hasFocus()); 0147 QCOMPARE(dialog.focusWidget(), static_cast<QWidget *>(&checkBox)); 0148 QTest::keyClick(dialog.focusWidget(), Qt::Key_Return); 0149 QCOMPARE(qCancelClickedSpy.count(), 1); 0150 } 0151 0152 // Test if buttons labels are correctly handled 0153 // assuming that testButtonDefault() passed 0154 void testButtonText() 0155 { 0156 KDialog dialog; 0157 KDialog::ButtonCode id = KDialog::Ok; 0158 QString text = "it's okay !"; 0159 dialog.setButtons(id); 0160 dialog.setButtonText(id, text); 0161 QCOMPARE(dialog.buttonText(id), text); 0162 QCOMPARE(dialog.button(id)->text(), text); 0163 } 0164 0165 void testButtonToolTip() 0166 { 0167 KDialog dialog; 0168 KDialog::ButtonCode id = KDialog::Ok; 0169 QString tooltip = "This is okay button"; 0170 dialog.setButtons(id); 0171 dialog.setButtonToolTip(id, tooltip); 0172 QCOMPARE(dialog.buttonToolTip(id), tooltip); 0173 QCOMPARE(dialog.button(id)->toolTip(), tooltip); 0174 } 0175 0176 void testButtonWhatsThis() 0177 { 0178 KDialog dialog; 0179 KDialog::ButtonCode id = KDialog::Ok; 0180 QString whatsthis = "A simple button to press okay"; 0181 dialog.setButtons(id); 0182 dialog.setButtonWhatsThis(id, whatsthis); 0183 QCOMPARE(dialog.buttonWhatsThis(id), whatsthis); 0184 QCOMPARE(dialog.button(id)->whatsThis(), whatsthis); 0185 } 0186 0187 void testDeleteOnClose_data() 0188 { 0189 QTest::addColumn<KDialog::ButtonCode>("button"); 0190 QTest::addColumn<int>("emitAccepted"); 0191 QTest::addColumn<int>("emitRejected"); 0192 0193 QTest::newRow("Ok") << KDialog::Ok << 1 << 0; 0194 QTest::newRow("Cancel") << KDialog::Cancel << 0 << 1; 0195 QTest::newRow("Close") << KDialog::Close << 0 << 0; 0196 } 0197 0198 void testDeleteOnClose() 0199 { 0200 QFETCH(KDialog::ButtonCode, button); 0201 QFETCH(int, emitAccepted); 0202 QFETCH(int, emitRejected); 0203 0204 KDialog *dialog = new KDialog; 0205 QPointer<KDialog> dialogPointer(dialog); 0206 dialog->setAttribute(Qt::WA_DeleteOnClose); 0207 dialog->setButtons(KDialog::Ok | button); 0208 QSignalSpy qAcceptedSpy(dialog, SIGNAL(accepted())); 0209 QSignalSpy qRejectedSpy(dialog, SIGNAL(rejected())); 0210 dialog->show(); // KDialog::closeEvent tests for isHidden 0211 dialog->button(button)->click(); 0212 QCOMPARE(qAcceptedSpy.count(), emitAccepted); 0213 QCOMPARE(qRejectedSpy.count(), emitRejected); 0214 QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); 0215 QVERIFY(dialogPointer.isNull()); // deletion happened 0216 } 0217 0218 // Closing the dialog using the window manager button 0219 void testCloseDialogWithDeleteOnClose_data() 0220 { 0221 QTest::addColumn<KDialog::ButtonCode>("button"); 0222 QTest::addColumn<int>("emitRejected"); 0223 QTest::addColumn<QString>("signal"); 0224 0225 QTest::newRow("Cancel") << KDialog::Cancel << 1 << SIGNAL(cancelClicked()); 0226 QTest::newRow("Close") << KDialog::Close << 0 << SIGNAL(closeClicked()); 0227 } 0228 0229 void testCloseDialogWithDeleteOnClose() 0230 { 0231 QFETCH(KDialog::ButtonCode, button); 0232 QFETCH(int, emitRejected); 0233 QFETCH(QString, signal); 0234 0235 KDialog *dialog = new KDialog; 0236 QPointer<KDialog> dialogPointer(dialog); 0237 dialog->setAttribute(Qt::WA_DeleteOnClose); 0238 dialog->setButtons(KDialog::Ok | button); 0239 QSignalSpy qCancelOrCloseClickedSpy(dialog, signal.toLatin1().constData()); 0240 QSignalSpy qRejectedSpy(dialog, SIGNAL(rejected())); 0241 dialog->show(); // KDialog::closeEvent tests for isHidden 0242 dialog->close(); 0243 if (qRejectedSpy.isEmpty() && emitRejected) { 0244 QVERIFY(qRejectedSpy.wait(5000)); 0245 } 0246 if (qCancelOrCloseClickedSpy.isEmpty()) { 0247 QVERIFY(qCancelOrCloseClickedSpy.wait(5000)); 0248 } 0249 QCOMPARE(qRejectedSpy.count(), emitRejected); // and then rejected is emitted as well 0250 QCOMPARE(qCancelOrCloseClickedSpy.count(), 1); // KDialog emulated cancel or close being clicked 0251 qApp->sendPostedEvents(); // DeferredDelete 0252 QVERIFY(dialogPointer.isNull()); // deletion happened 0253 } 0254 }; 0255 0256 QTEST_MAIN(KDialog_UnitTest) 0257 #include "kdialog_unittest.moc"