File indexing completed on 2024-05-12 05:46:54
0001 /* 0002 Copyright (c) 2014 Alexander Richardson <alex.richardson@gmx.de> 0003 0004 Permission is hereby granted, free of charge, to any person obtaining a copy 0005 of this software and associated documentation files (the "Software"), to deal 0006 in the Software without restriction, including without limitation the rights 0007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 0008 copies of the Software, and to permit persons to whom the Software is 0009 furnished to do so, subject to the following conditions: 0010 0011 The above copyright notice and this permission notice shall be included in 0012 all copies or substantial portions of the Software. 0013 0014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 0015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 0016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 0017 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 0018 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 0019 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 0020 */ 0021 0022 #include "signals_test_singleton.h" 0023 #include "signals_test_no_singleton.h" 0024 #include "signals_test_singleton_dpointer.h" 0025 #include "signals_test_no_singleton_dpointer.h" 0026 #include <QtTestGui> 0027 #include <QSignalSpy> 0028 #include <QSharedPointer> 0029 #include <QtGlobal> 0030 #include <QDebug> 0031 #include <QTemporaryFile> 0032 #include <QFileInfo> 0033 #include <functional> 0034 0035 class KConfigCompiler_Test_Signals : public QObject 0036 { 0037 Q_OBJECT 0038 private Q_SLOTS: 0039 void testSetters(); 0040 void testSetters_data(); 0041 void testSetProperty(); 0042 void testSetProperty_data(); 0043 void initTestCase(); 0044 void cleanupTestCase(); 0045 }; 0046 0047 static SignalsTestNoSingleton* noSingleton; 0048 static SignalsTestNoSingletonDpointer* noSingletonDpointer; 0049 0050 void KConfigCompiler_Test_Signals::initTestCase() 0051 { 0052 // These tests do a lot quite a few I/O operations, speed that up by using a QTemporaryFile. 0053 // At least on Linux this is often a tmpfs which means only RAM operations 0054 QTemporaryFile* tempFile1 = new QTemporaryFile(this); 0055 QTemporaryFile* tempFile2 = new QTemporaryFile(this); 0056 QTemporaryFile* tempFile3 = new QTemporaryFile(this); 0057 QTemporaryFile* tempFile4 = new QTemporaryFile(this); 0058 QVERIFY(tempFile1->open()); 0059 QVERIFY(tempFile2->open()); 0060 QVERIFY(tempFile3->open()); 0061 QVERIFY(tempFile4->open()); 0062 0063 SignalsTestSingleton::instance(QFileInfo(*tempFile1).absoluteFilePath()); 0064 SignalsTestSingletonDpointer::instance(QFileInfo(*tempFile2).absoluteFilePath()); 0065 noSingleton = new SignalsTestNoSingleton( 0066 KSharedConfig::openConfig(QFileInfo(*tempFile3).absoluteFilePath(), KConfig::SimpleConfig)); 0067 noSingletonDpointer = new SignalsTestNoSingletonDpointer( 0068 KSharedConfig::openConfig(QFileInfo(*tempFile4).absoluteFilePath(), KConfig::SimpleConfig)); 0069 } 0070 0071 void KConfigCompiler_Test_Signals::cleanupTestCase() 0072 { 0073 //ensure these instances are deleted before the temporary files are closed 0074 delete noSingleton; 0075 delete noSingletonDpointer; 0076 delete SignalsTestSingleton::self(); 0077 delete SignalsTestSingletonDpointer::self(); 0078 } 0079 0080 struct TestSettersArg { 0081 // default constructor required for Q_DECLARE_METATYPE 0082 TestSettersArg() : obj(nullptr) {} 0083 template<typename T> 0084 TestSettersArg(T* object) : obj(object) { 0085 // we can also call static methods using object->foo() so this works for all four cases 0086 getter = [object]() { return object->foo(); }; 0087 defaultGetter = [object]() { return object->defaultFooValue(); }; 0088 setter = [object](const QString& s) { object->setFoo(s); }; 0089 } 0090 KCoreConfigSkeleton* obj; 0091 std::function<QString()> getter; 0092 std::function<QString()> defaultGetter; 0093 std::function<void(const QString&)> setter; 0094 }; 0095 0096 Q_DECLARE_METATYPE(TestSettersArg) // so that QFETCH works 0097 0098 void KConfigCompiler_Test_Signals::testSetters_data() 0099 { 0100 QTest::addColumn<TestSettersArg>("params"); 0101 QTest::newRow("singleton") << TestSettersArg(SignalsTestSingleton::self()); 0102 QTest::newRow("singleton dpointer") << TestSettersArg(SignalsTestSingletonDpointer::self()); 0103 QTest::newRow("non-singleton") << TestSettersArg(noSingleton); 0104 QTest::newRow("non-singleton dpointer") << TestSettersArg(noSingleton); 0105 } 0106 0107 /** Ensure that a signal is emitted whenever the data is changed by using the generated setters */ 0108 void KConfigCompiler_Test_Signals::testSetters() 0109 { 0110 QFETCH(TestSettersArg, params); 0111 const char* signal = SIGNAL(fooChanged(QString)); 0112 const QString defaultValue = QStringLiteral("default"); 0113 const QString changedValue = QStringLiteral("changed"); 0114 0115 // make sure we are in the default state 0116 params.obj->setDefaults(); 0117 params.obj->save(); 0118 0119 QList<QVariant> args; 0120 QSignalSpy spy(params.obj, signal); 0121 QVERIFY2(spy.isValid(), signal); 0122 0123 //change value via setter, should get signal 0124 QCOMPARE(params.getter(), defaultValue); 0125 QCOMPARE(defaultValue, params.defaultGetter()); 0126 QCOMPARE(params.getter(), params.defaultGetter()); 0127 QVERIFY(changedValue != params.getter()); 0128 params.setter(changedValue); 0129 QCOMPARE(params.getter(), changedValue); 0130 QCOMPARE(spy.count(), 0); //should have no change yet, only after save() 0131 params.obj->save(); 0132 QCOMPARE(spy.count(), 1); 0133 args = spy.takeFirst(); 0134 QCOMPARE(args.size(), 1); 0135 QCOMPARE(args[0].toString(), changedValue); 0136 0137 //reset to default values via setDefaults() 0138 QVERIFY(params.getter() != params.defaultGetter()); 0139 QVERIFY(params.getter() != defaultValue); 0140 QCOMPARE(params.getter(), changedValue); 0141 params.obj->setDefaults(); 0142 QCOMPARE(params.getter(), params.defaultGetter()); 0143 QCOMPARE(params.getter(), defaultValue); 0144 0145 QCOMPARE(spy.count(), 0); //should have no change yet, only after save() 0146 params.obj->save(); 0147 //TODO: This currently fails since setDefaults() does not yet cause emitting a signal 0148 QCOMPARE(spy.count(), 1); 0149 args = spy.takeFirst(); 0150 QCOMPARE(args.size(), 1); 0151 QCOMPARE(args[0].value<QString>(), defaultValue); 0152 } 0153 0154 Q_DECLARE_METATYPE(KCoreConfigSkeleton*) 0155 0156 void KConfigCompiler_Test_Signals::testSetProperty_data() 0157 { 0158 QTest::addColumn<KCoreConfigSkeleton*>("obj"); 0159 QTest::newRow("singleton") << static_cast<KCoreConfigSkeleton*>(SignalsTestSingleton::self()); 0160 QTest::newRow("singleton dpointer") << static_cast<KCoreConfigSkeleton*>(SignalsTestSingletonDpointer::self()); 0161 QTest::newRow("non-singleton") << static_cast<KCoreConfigSkeleton*>(noSingleton); 0162 QTest::newRow("non-singleton dpointer") << static_cast<KCoreConfigSkeleton*>(noSingletonDpointer); 0163 } 0164 0165 /** Test that the signal is emitted when modifying the values using the underlying KConfigSkeletonItem (bypassing the setters) */ 0166 void KConfigCompiler_Test_Signals::testSetProperty() 0167 { 0168 QFETCH(KCoreConfigSkeleton*, obj); 0169 const char* signal = SIGNAL(fooChanged(QString)); 0170 const QString propertyName = QStringLiteral("foo"); 0171 const QString defaultValue = QStringLiteral("default"); 0172 const QString newValue = QStringLiteral("changed"); 0173 obj->setDefaults(); 0174 obj->save(); 0175 0176 KConfigSkeletonItem* item = obj->findItem(propertyName); 0177 QVERIFY2(item, "Item must exist"); 0178 QVERIFY2(!item->isImmutable(), "Item must not be immutable"); 0179 QVERIFY2(!obj->isImmutable(propertyName), "Item must not be immutable"); 0180 0181 //listen for all expected signals 0182 QSignalSpy spy(obj, signal); 0183 QVERIFY2(spy.isValid(), signal); 0184 0185 QVERIFY(item->isEqual(defaultValue)); 0186 QVERIFY(!item->isEqual(newValue)); 0187 0188 item->setProperty(newValue); //change value now 0189 //should have no change yet, only after save() 0190 QCOMPARE(spy.count(), 0); 0191 obj->save(); 0192 //now check for the signal emissions 0193 QCOMPARE(spy.count(), 1); 0194 QList<QVariant> args = spy.takeFirst(); 0195 QCOMPARE(args.size(), 1); 0196 QVERIFY(item->isEqual(args[0])); 0197 0198 //now reset to default 0199 QVERIFY(!item->isEqual(defaultValue)); 0200 item->setDefault(); 0201 QVERIFY(item->isEqual(defaultValue)); 0202 //should have no change yet, only after save() 0203 QCOMPARE(spy.count(), 0); 0204 obj->save(); 0205 //now check for the signal emissions 0206 QCOMPARE(spy.count(), 1); 0207 args = spy.takeFirst(); 0208 QCOMPARE(args.size(), 1); 0209 QVERIFY(item->isEqual(args[0])); 0210 } 0211 0212 QTEST_MAIN(KConfigCompiler_Test_Signals) 0213 0214 #include "kconfigcompiler_test_signals.moc"