File indexing completed on 2025-01-26 05:09:26
0001 /* 0002 * This file is part of the KDE wacomtablet project. For copyright 0003 * information and license terms see the AUTHORS and COPYING files 0004 * in the top-level directory of this distribution. 0005 * 0006 * This program is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU General Public License as 0008 * published by the Free Software Foundation; either version 2 of 0009 * the License, or (at your option) any later version. 0010 * 0011 * This program is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 * GNU General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU General Public License 0017 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0018 */ 0019 0020 #include "../kdedtestutils.h" 0021 #include "../tabletbackendmock.h" 0022 0023 #include "common/screensinfo.h" 0024 #include "common/tabletinformation.h" 0025 #include "kded/tabletbackendfactory.h" 0026 #include "kded/tablethandler.h" 0027 0028 #include <QtTest> 0029 0030 using namespace Wacom; 0031 0032 /** 0033 * @file testdbustabletservice.cpp 0034 * 0035 * @test UnitTest for ... 0036 * @todo use QSignalSpy? 0037 */ 0038 class TestTabletHandler : public QObject 0039 { 0040 Q_OBJECT 0041 0042 public Q_SLOTS: 0043 void onNotify(const QString &eventId, const QString &title, const QString &message, bool suggestConfigure); 0044 void onProfileChanged(const QString &tabletID, const QString &profile); 0045 void onTabletAdded(const TabletInformation &info); 0046 void onTabletRemoved(const QString &tabletID); 0047 0048 private slots: 0049 void initTestCase(); 0050 void test(); 0051 void cleanupTestCase(); 0052 0053 private: 0054 void testListProfiles(); 0055 void testOnScreenRotated(); 0056 void testOnTabletAdded(); 0057 void testOnTabletRemoved(); 0058 void testOnTogglePenMode(); 0059 void testOnToggleTouch(); 0060 void testSetProfile(); 0061 void testSetProperty(); 0062 0063 QString m_notifyEventId; 0064 QString m_notifyTitle; 0065 QString m_notifyMessage; 0066 0067 QString m_profileChanged; 0068 0069 TabletInformation m_tabletAddedInformation; 0070 bool m_tabletAdded; 0071 bool m_tabletRemoved; 0072 0073 TabletHandler *m_tabletHandler; 0074 TabletBackendMock *m_backendMock; 0075 }; 0076 0077 QTEST_MAIN(TestTabletHandler) 0078 0079 void TestTabletHandler::onNotify(const QString &eventId, const QString &title, const QString &message, bool suggestConfigure) 0080 { 0081 Q_UNUSED(suggestConfigure) 0082 0083 m_notifyEventId = eventId; 0084 m_notifyTitle = title; 0085 m_notifyMessage = message; 0086 } 0087 0088 void TestTabletHandler::onProfileChanged(const QString &tabletID, const QString &profile) 0089 { 0090 Q_UNUSED(tabletID) 0091 0092 m_profileChanged = profile; 0093 } 0094 0095 void TestTabletHandler::onTabletAdded(const TabletInformation &info) 0096 { 0097 m_tabletRemoved = false; 0098 m_tabletAdded = true; 0099 m_tabletAddedInformation = info; 0100 } 0101 0102 void TestTabletHandler::onTabletRemoved(const QString &tabletID) 0103 { 0104 Q_UNUSED(tabletID) 0105 0106 m_tabletAdded = false; 0107 m_tabletRemoved = true; 0108 } 0109 0110 void TestTabletHandler::initTestCase() 0111 { 0112 m_tabletAdded = false; 0113 m_tabletRemoved = false; 0114 m_backendMock = nullptr; 0115 0116 TabletBackendFactory::setUnitTest(true); 0117 0118 QString profilePath = KdedTestUtils::getAbsolutePath(QLatin1String("testtablethandler.profilesrc")); 0119 QString configPath = KdedTestUtils::getAbsolutePath(QLatin1String("testtablethandler.configrc")); 0120 m_tabletHandler = new TabletHandler(profilePath, configPath); 0121 0122 connect(m_tabletHandler, &TabletHandler::notify, this, &TestTabletHandler::onNotify); 0123 connect(m_tabletHandler, &TabletHandler::profileChanged, this, &TestTabletHandler::onProfileChanged); 0124 connect(m_tabletHandler, &TabletHandler::tabletAdded, this, &TestTabletHandler::onTabletAdded); 0125 connect(m_tabletHandler, &TabletHandler::tabletRemoved, this, &TestTabletHandler::onTabletRemoved); 0126 } 0127 0128 void TestTabletHandler::cleanupTestCase() 0129 { 0130 delete m_tabletHandler; 0131 } 0132 0133 void TestTabletHandler::test() 0134 { 0135 // only one test method as the test has to be executed in a specific order 0136 testOnTabletAdded(); 0137 0138 testSetProperty(); 0139 0140 testListProfiles(); 0141 0142 testSetProfile(); 0143 0144 testOnTogglePenMode(); 0145 0146 testOnToggleTouch(); 0147 0148 testOnScreenRotated(); 0149 0150 testOnTabletRemoved(); 0151 } 0152 0153 void TestTabletHandler::testListProfiles() 0154 { 0155 QStringList profiles = m_tabletHandler->listProfiles(QLatin1String("4321")); 0156 0157 QCOMPARE(profiles.size(), 2); 0158 QVERIFY(profiles.contains(QLatin1String("default"))); 0159 QVERIFY(profiles.contains(QLatin1String("test"))); 0160 0161 QWARN("testListProfiles(): PASSED!"); 0162 } 0163 0164 void TestTabletHandler::testOnScreenRotated() 0165 { 0166 m_tabletHandler->onMapToScreen1(); 0167 // reset screen rotation 0168 m_tabletHandler->setProperty(QLatin1String("4321"), DeviceType::Stylus, Property::Rotate, ScreenRotation::NONE.key()); 0169 m_tabletHandler->setProperty(QLatin1String("4321"), DeviceType::Eraser, Property::Rotate, ScreenRotation::NONE.key()); 0170 m_tabletHandler->setProperty(QLatin1String("4321"), DeviceType::Touch, Property::Rotate, ScreenRotation::NONE.key()); 0171 0172 // we need the test profile set as it has the required property 0173 QCOMPARE(m_profileChanged, QLatin1String("test")); 0174 0175 // compare start parameters 0176 QCOMPARE(m_tabletHandler->getProperty(QLatin1String("4321"), DeviceType::Eraser, Property::Rotate), ScreenRotation::NONE.key()); 0177 QCOMPARE(m_tabletHandler->getProperty(QLatin1String("4321"), DeviceType::Stylus, Property::Rotate), ScreenRotation::NONE.key()); 0178 QCOMPARE(m_tabletHandler->getProperty(QLatin1String("4321"), DeviceType::Touch, Property::Rotate), ScreenRotation::NONE.key()); 0179 0180 // rotate screen 0181 m_tabletHandler->onScreenRotated(ScreensInfo::getPrimaryScreenName(), Qt::InvertedLandscapeOrientation); 0182 0183 // validate result 0184 QCOMPARE(m_tabletHandler->getProperty(QLatin1String("4321"), DeviceType::Eraser, Property::Rotate), ScreenRotation::HALF.key()); 0185 QCOMPARE(m_tabletHandler->getProperty(QLatin1String("4321"), DeviceType::Stylus, Property::Rotate), ScreenRotation::HALF.key()); 0186 QCOMPARE(m_tabletHandler->getProperty(QLatin1String("4321"), DeviceType::Touch, Property::Rotate), ScreenRotation::HALF.key()); 0187 0188 QWARN("testOnScreenRotated(): PASSED!"); 0189 } 0190 0191 void TestTabletHandler::testOnTabletAdded() 0192 { 0193 QVERIFY(!m_tabletAdded); 0194 QVERIFY(!m_tabletRemoved); 0195 0196 // Do not initialize the factory yet so it can not return a backend. 0197 TabletInformation basicInfo; 0198 m_notifyEventId.clear(); 0199 m_notifyMessage.clear(); 0200 m_notifyTitle.clear(); 0201 0202 // if the tablet backend factory returns NULL adding a tablet should fail 0203 TabletBackendFactory::setUnitTest(true); 0204 TabletBackendFactory::setTabletBackendMock(NULL); 0205 0206 m_tabletHandler->onTabletAdded(basicInfo); 0207 0208 QVERIFY(!m_tabletAdded); 0209 QVERIFY(!m_tabletRemoved); 0210 QVERIFY(m_notifyEventId.isEmpty()); 0211 QVERIFY(m_notifyMessage.isEmpty()); 0212 QVERIFY(m_notifyTitle.isEmpty()); 0213 QVERIFY(m_profileChanged.isEmpty()); 0214 0215 // create a valid backend for the factory to return 0216 m_backendMock = new TabletBackendMock(); 0217 0218 m_backendMock->m_tabletInformation.set(TabletInfo::TabletSerial, QLatin1String("123")); 0219 m_backendMock->m_tabletInformation.set(TabletInfo::CompanyId, QLatin1String("1234")); 0220 m_backendMock->m_tabletInformation.set(TabletInfo::CompanyName, QLatin1String("Company")); 0221 m_backendMock->m_tabletInformation.set(TabletInfo::TabletId, QLatin1String("4321")); 0222 m_backendMock->m_tabletInformation.set(TabletInfo::TabletModel, QLatin1String("Tablet Model")); 0223 m_backendMock->m_tabletInformation.set(TabletInfo::TabletName, QLatin1String("Bamboo Create")); 0224 m_backendMock->m_tabletInformation.set(TabletInfo::NumPadButtons, QLatin1String("4")); 0225 m_backendMock->m_tabletInformation.setAvailable(true); 0226 0227 DeviceInformation devInfoEraser(DeviceType::Eraser, QLatin1String("Eraser Device")); 0228 DeviceInformation devInfoStylus(DeviceType::Stylus, QLatin1String("Stylus Device")); 0229 DeviceInformation devInfoTouch(DeviceType::Touch, QLatin1String("Touch Device")); 0230 0231 m_backendMock->m_tabletInformation.setDevice(devInfoEraser); 0232 m_backendMock->m_tabletInformation.setDevice(devInfoStylus); 0233 m_backendMock->m_tabletInformation.setDevice(devInfoTouch); 0234 0235 TabletBackendFactory::setTabletBackendMock(m_backendMock); 0236 0237 // add a tablet 0238 m_tabletHandler->onTabletAdded(m_backendMock->getInformation()); 0239 0240 QVERIFY(!m_tabletRemoved); 0241 QVERIFY(m_tabletAdded); 0242 QVERIFY(!m_notifyEventId.isEmpty()); 0243 QVERIFY(!m_notifyMessage.isEmpty()); 0244 QVERIFY(!m_notifyTitle.isEmpty()); 0245 QVERIFY(!m_profileChanged.isEmpty()); 0246 QCOMPARE(m_profileChanged, QLatin1String("test")); 0247 QCOMPARE(m_backendMock->m_tabletProfile.getName(), QLatin1String("test")); 0248 0249 m_tabletAdded = false; 0250 m_notifyEventId.clear(); 0251 m_notifyMessage.clear(); 0252 m_notifyTitle.clear(); 0253 m_profileChanged.clear(); 0254 0255 // add the tablet again 0256 m_tabletHandler->onTabletAdded(m_backendMock->getInformation()); 0257 0258 QVERIFY(!m_tabletRemoved); 0259 QVERIFY(!m_tabletAdded); 0260 QVERIFY(m_notifyEventId.isEmpty()); 0261 QVERIFY(m_notifyMessage.isEmpty()); 0262 QVERIFY(m_notifyTitle.isEmpty()); 0263 QVERIFY(m_profileChanged.isEmpty()); 0264 0265 QWARN("testOnTabletAdded(): PASSED!"); 0266 0267 // prepare for the next test 0268 m_tabletAdded = true; 0269 } 0270 0271 void TestTabletHandler::testOnTabletRemoved() 0272 { 0273 QVERIFY(!m_tabletRemoved); 0274 QVERIFY(m_tabletAdded); 0275 0276 m_notifyEventId.clear(); 0277 m_notifyMessage.clear(); 0278 m_notifyTitle.clear(); 0279 0280 TabletInformation info; 0281 0282 // removing a different tablet then the one handled by the backend should do nothing 0283 info.set(TabletInfo::TabletSerial, QLatin1String("12")); 0284 m_tabletHandler->onTabletRemoved(info); 0285 0286 QVERIFY(!m_tabletRemoved); 0287 QVERIFY(m_tabletAdded); 0288 QVERIFY(m_notifyEventId.isEmpty()); 0289 QVERIFY(m_notifyMessage.isEmpty()); 0290 QVERIFY(m_notifyTitle.isEmpty()); 0291 0292 // remove the currently managed tablet 0293 // this should emit a signal and notify the user 0294 info.set(TabletInfo::TabletSerial, QLatin1String("123")); 0295 info.set(TabletInfo::TabletId, QLatin1String("4321")); 0296 m_tabletHandler->onTabletRemoved(info); 0297 0298 QVERIFY(m_tabletRemoved); 0299 QVERIFY(!m_tabletAdded); 0300 QVERIFY(!m_notifyEventId.isEmpty()); 0301 QVERIFY(!m_notifyMessage.isEmpty()); 0302 QVERIFY(!m_notifyTitle.isEmpty()); 0303 0304 m_backendMock = NULL; // no longer valid, as tablet was removed 0305 0306 // remove the device again. 0307 m_tabletRemoved = false; 0308 m_notifyEventId.clear(); 0309 m_notifyMessage.clear(); 0310 m_notifyTitle.clear(); 0311 0312 m_tabletHandler->onTabletRemoved(info); 0313 0314 QVERIFY(!m_tabletRemoved); 0315 QVERIFY(!m_tabletAdded); 0316 QVERIFY(m_notifyEventId.isEmpty()); 0317 QVERIFY(m_notifyMessage.isEmpty()); 0318 QVERIFY(m_notifyTitle.isEmpty()); 0319 0320 QWARN("testOnTabletRemoved(): PASSED!"); 0321 } 0322 0323 void TestTabletHandler::testOnTogglePenMode() 0324 { 0325 m_backendMock->setProperty(DeviceType::Stylus, Property::Mode, QLatin1String("Absolute")); 0326 m_backendMock->setProperty(DeviceType::Eraser, Property::Mode, QLatin1String("Absolute")); 0327 0328 QCOMPARE(m_backendMock->getProperty(DeviceType::Eraser, Property::Mode), QLatin1String("Absolute")); 0329 QCOMPARE(m_backendMock->getProperty(DeviceType::Stylus, Property::Mode), QLatin1String("Absolute")); 0330 0331 m_tabletHandler->onTogglePenMode(); 0332 0333 QCOMPARE(m_backendMock->getProperty(DeviceType::Eraser, Property::Mode), QLatin1String("relative")); 0334 QCOMPARE(m_backendMock->getProperty(DeviceType::Stylus, Property::Mode), QLatin1String("relative")); 0335 0336 m_tabletHandler->onTogglePenMode(); 0337 0338 QCOMPARE(m_backendMock->getProperty(DeviceType::Eraser, Property::Mode), QLatin1String("absolute")); 0339 QCOMPARE(m_backendMock->getProperty(DeviceType::Stylus, Property::Mode), QLatin1String("absolute")); 0340 0341 QWARN("testOnTogglePenMode(): PASSED!"); 0342 } 0343 0344 void TestTabletHandler::testOnToggleTouch() 0345 { 0346 m_tabletHandler->setProperty(QLatin1String("4321"), DeviceType::Touch, Property::Touch, QLatin1String("off")); 0347 0348 QCOMPARE(m_backendMock->getProperty(DeviceType::Touch, Property::Touch), QLatin1String("off")); 0349 QCOMPARE(m_tabletHandler->getProperty(QLatin1String("4321"), DeviceType::Touch, Property::Touch), QLatin1String("off")); 0350 0351 m_tabletHandler->onToggleTouch(); 0352 0353 QCOMPARE(m_backendMock->getProperty(DeviceType::Touch, Property::Touch), QLatin1String("on")); 0354 0355 m_tabletHandler->onToggleTouch(); 0356 0357 QCOMPARE(m_backendMock->getProperty(DeviceType::Touch, Property::Touch), QLatin1String("off")); 0358 0359 QWARN("testOnToggleTouch(): PASSED!"); 0360 } 0361 0362 void TestTabletHandler::testSetProfile() 0363 { 0364 m_profileChanged.clear(); 0365 m_notifyEventId.clear(); 0366 m_notifyMessage.clear(); 0367 m_notifyTitle.clear(); 0368 0369 // set invalid profile first 0370 m_tabletHandler->setProfile(QLatin1String("4321"), QLatin1String("InvalidProfile")); 0371 0372 QVERIFY(!m_profileChanged.isEmpty()); 0373 QCOMPARE(m_profileChanged, m_tabletHandler->listProfiles(QLatin1String("4321")).first()); 0374 QVERIFY(!m_notifyEventId.isEmpty()); 0375 QVERIFY(!m_notifyMessage.isEmpty()); 0376 QVERIFY(!m_notifyTitle.isEmpty()); 0377 0378 // set a valid profile 0379 m_notifyEventId.clear(); 0380 m_notifyMessage.clear(); 0381 m_notifyTitle.clear(); 0382 0383 m_tabletHandler->setProfile(QLatin1String("4321"), QLatin1String("default")); 0384 0385 QVERIFY(m_notifyEventId.isEmpty()); 0386 QVERIFY(m_notifyMessage.isEmpty()); 0387 QVERIFY(m_notifyTitle.isEmpty()); 0388 QCOMPARE(m_profileChanged, QLatin1String("default")); 0389 QCOMPARE(m_backendMock->m_tabletProfile.getName(), QLatin1String("default")); 0390 0391 // set the profile back to "test" so we can run this tests 0392 // multiple times in a row. Otherwise the test will fail as 0393 // cmake copies our test data only once. 0394 m_tabletHandler->setProfile(QLatin1String("4321"), QLatin1String("test")); 0395 0396 QWARN("testSetProfile(): PASSED!"); 0397 } 0398 0399 void TestTabletHandler::testSetProperty() 0400 { 0401 QVERIFY(m_tabletAdded); 0402 0403 m_tabletHandler->setProperty(QLatin1String("4321"), DeviceType::Stylus, Property::Button1, Property::Button1.key()); 0404 QCOMPARE(m_backendMock->getProperty(DeviceType::Stylus, Property::Button1), Property::Button1.key()); 0405 QCOMPARE(m_tabletHandler->getProperty(QLatin1String("4321"), DeviceType::Stylus, Property::Button1), Property::Button1.key()); 0406 0407 QWARN("testSetProperty(): PASSED!"); 0408 } 0409 0410 #include "testtablethandler.moc"