aboutsummaryrefslogtreecommitdiff
path: root/autotests/kconfig_compiler/kconfigcompiler_test_signals.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'autotests/kconfig_compiler/kconfigcompiler_test_signals.cpp')
-rw-r--r--autotests/kconfig_compiler/kconfigcompiler_test_signals.cpp214
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"