diff options
Diffstat (limited to 'autotests/kconfig_compiler/kconfigcompiler_test_signals.cpp')
-rw-r--r-- | autotests/kconfig_compiler/kconfigcompiler_test_signals.cpp | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/autotests/kconfig_compiler/kconfigcompiler_test_signals.cpp b/autotests/kconfig_compiler/kconfigcompiler_test_signals.cpp new file mode 100644 index 00000000..3017fe2f --- /dev/null +++ b/autotests/kconfig_compiler/kconfigcompiler_test_signals.cpp @@ -0,0 +1,214 @@ +/* +Copyright (c) 2014 Alexander Richardson <alex.richardson@gmx.de> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "signals_test_singleton.h" +#include "signals_test_no_singleton.h" +#include "signals_test_singleton_dpointer.h" +#include "signals_test_no_singleton_dpointer.h" +#include <QtTest/QtTestGui> +#include <QtTest/QSignalSpy> +#include <QtCore/QSharedPointer> +#include <QtCore/QtGlobal> +#include <QtCore/QDebug> +#include <QTemporaryFile> +#include <QFileInfo> +#include <functional> + +class KConfigCompiler_Test_Signals : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void testSetters(); + void testSetters_data(); + void testSetProperty(); + void testSetProperty_data(); + void initTestCase(); + void cleanupTestCase(); +}; + +static SignalsTestNoSingleton* noSingleton; +static SignalsTestNoSingletonDpointer* noSingletonDpointer; + +void KConfigCompiler_Test_Signals::initTestCase() +{ + // These tests do a lot quite a few I/O operations, speed that up by using a QTemporaryFile. + // At least on Linux this is often a tmpfs which means only RAM operations + QTemporaryFile* tempFile1 = new QTemporaryFile(this); + QTemporaryFile* tempFile2 = new QTemporaryFile(this); + QTemporaryFile* tempFile3 = new QTemporaryFile(this); + QTemporaryFile* tempFile4 = new QTemporaryFile(this); + QVERIFY(tempFile1->open()); + QVERIFY(tempFile2->open()); + QVERIFY(tempFile3->open()); + QVERIFY(tempFile4->open()); + + SignalsTestSingleton::instance(QFileInfo(*tempFile1).absoluteFilePath()); + SignalsTestSingletonDpointer::instance(QFileInfo(*tempFile2).absoluteFilePath()); + noSingleton = new SignalsTestNoSingleton( + KSharedConfig::openConfig(QFileInfo(*tempFile3).absoluteFilePath(), KConfig::SimpleConfig)); + noSingletonDpointer = new SignalsTestNoSingletonDpointer( + KSharedConfig::openConfig(QFileInfo(*tempFile4).absoluteFilePath(), KConfig::SimpleConfig)); +} + +void KConfigCompiler_Test_Signals::cleanupTestCase() +{ + //ensure these instances are deleted before the temporary files are closed + delete noSingleton; + delete noSingletonDpointer; + delete SignalsTestSingleton::self(); + delete SignalsTestSingletonDpointer::self(); +} + +struct TestSettersArg { + // default constructor required for Q_DECLARE_METATYPE + TestSettersArg() : obj(nullptr) {} + template<typename T> + TestSettersArg(T* object) : obj(object) { + // we can also call static methods using object->foo() so this works for all four cases + getter = [object]() { return object->foo(); }; + defaultGetter = [object]() { return object->defaultFooValue(); }; + setter = [object](const QString& s) { object->setFoo(s); }; + } + KCoreConfigSkeleton* obj; + std::function<QString()> getter; + std::function<QString()> defaultGetter; + std::function<void(const QString&)> setter; +}; + +Q_DECLARE_METATYPE(TestSettersArg); // so that QFETCH works + +void KConfigCompiler_Test_Signals::testSetters_data() +{ + QTest::addColumn<TestSettersArg>("params"); + QTest::newRow("singleton") << TestSettersArg(SignalsTestSingleton::self()); + QTest::newRow("singleton dpointer") << TestSettersArg(SignalsTestSingletonDpointer::self()); + QTest::newRow("non-singleton") << TestSettersArg(noSingleton); + QTest::newRow("non-singleton dpointer") << TestSettersArg(noSingleton); +} + +/** Ensure that a signal is emitted whenever the data is changed by using the generated setters */ +void KConfigCompiler_Test_Signals::testSetters() +{ + QFETCH(TestSettersArg, params); + const char* signal = SIGNAL(fooChanged(QString)); + const QString defaultValue = QStringLiteral("default"); + const QString changedValue = QStringLiteral("changed"); + + // make sure we are in the default state + params.obj->setDefaults(); + params.obj->writeConfig(); + + QList<QVariant> args; + QSignalSpy spy(params.obj, signal); + QVERIFY2(spy.isValid(), signal); + + //change value via setter, should get signal + QCOMPARE(params.getter(), defaultValue); + QCOMPARE(defaultValue, params.defaultGetter()); + QCOMPARE(params.getter(), params.defaultGetter()); + QVERIFY(changedValue != params.getter()); + params.setter(changedValue); + QCOMPARE(params.getter(), changedValue); + QCOMPARE(spy.count(), 0); //should have no change yet, only after writeConfig() + params.obj->writeConfig(); + QCOMPARE(spy.count(), 1); + args = spy.takeFirst(); + QCOMPARE(args.size(), 1); + QCOMPARE(args[0].value<QString>(), changedValue); + + //reset to default values via setDefaults() + QVERIFY(params.getter() != params.defaultGetter()); + QVERIFY(params.getter() != defaultValue); + QCOMPARE(params.getter(), changedValue); + params.obj->setDefaults(); + QCOMPARE(params.getter(), params.defaultGetter()); + QCOMPARE(params.getter(), defaultValue); + + QCOMPARE(spy.count(), 0); //should have no change yet, only after writeConfig() + params.obj->writeConfig(); + //TODO: This currently fails since setDefaults() does not yet cause emitting a signal + QCOMPARE(spy.count(), 1); + args = spy.takeFirst(); + QCOMPARE(args.size(), 1); + QCOMPARE(args[0].value<QString>(), defaultValue); +} + +Q_DECLARE_METATYPE(KCoreConfigSkeleton*); + +void KConfigCompiler_Test_Signals::testSetProperty_data() +{ + QTest::addColumn<KCoreConfigSkeleton*>("obj"); + QTest::newRow("singleton") << static_cast<KCoreConfigSkeleton*>(SignalsTestSingleton::self()); + QTest::newRow("singleton dpointer") << static_cast<KCoreConfigSkeleton*>(SignalsTestSingletonDpointer::self()); + QTest::newRow("non-singleton") << static_cast<KCoreConfigSkeleton*>(noSingleton); + QTest::newRow("non-singleton dpointer") << static_cast<KCoreConfigSkeleton*>(noSingletonDpointer); +} + +/** Test that the signal is emitted when modifying the values using the underlying KConfigSkeletonItem (bypassing the setters) */ +void KConfigCompiler_Test_Signals::testSetProperty() +{ + QFETCH(KCoreConfigSkeleton*, obj); + const char* signal = SIGNAL(fooChanged(QString)); + const QString propertyName = QStringLiteral("foo"); + const QString defaultValue = QStringLiteral("default"); + const QString newValue = QStringLiteral("changed"); + obj->setDefaults(); + obj->writeConfig(); + + KConfigSkeletonItem* item = obj->findItem(propertyName); + QVERIFY2(item, "Item must exist"); + QVERIFY2(!item->isImmutable(), "Item must not be immutable"); + QVERIFY2(!obj->isImmutable(propertyName), "Item must not be immutable"); + + //listen for all expected signals + QSignalSpy spy(obj, signal); + QVERIFY2(spy.isValid(), signal); + + QVERIFY(item->isEqual(defaultValue)); + QVERIFY(!item->isEqual(newValue)); + + item->setProperty(newValue); //change value now + //should have no change yet, only after writeConfig() + QCOMPARE(spy.count(), 0); + obj->writeConfig(); + //now check for the signal emissions + QCOMPARE(spy.count(), 1); + QList<QVariant> args = spy.takeFirst(); + QCOMPARE(args.size(), 1); + QVERIFY(item->isEqual(args[0])); + + //now reset to default + QVERIFY(!item->isEqual(defaultValue)); + item->setDefault(); + QVERIFY(item->isEqual(defaultValue)); + //should have no change yet, only after writeConfig() + QCOMPARE(spy.count(), 0); + obj->writeConfig(); + //now check for the signal emissions + QCOMPARE(spy.count(), 1); + args = spy.takeFirst(); + QCOMPARE(args.size(), 1); + QVERIFY(item->isEqual(args[0])); +} + +QTEST_MAIN(KConfigCompiler_Test_Signals) + +#include "kconfigcompiler_test_signals.moc" |