diff options
Diffstat (limited to 'autotests/kconfig_compiler')
9 files changed, 305 insertions, 12 deletions
| diff --git a/autotests/kconfig_compiler/CMakeLists.txt b/autotests/kconfig_compiler/CMakeLists.txt index a2ebb945..289e9583 100644 --- a/autotests/kconfig_compiler/CMakeLists.txt +++ b/autotests/kconfig_compiler/CMakeLists.txt @@ -3,14 +3,19 @@  #	../kconfig_compiler_kf5 $(srcdir)/test5.kcfg $(srcdir)/test5.kcfgc  macro(GEN_KCFG_TEST_SOURCE _testName _srcs) +   cmake_parse_arguments(ARG "" "KCFG" "" ${ARGN} ) +   set(_kcfgFile ${ARG_KCFG}) +   if (NOT _kcfgFile) +      set(_kcfgFile "${_testName}.kcfg") +   endif()     add_custom_command(        OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_testName}.cpp ${CMAKE_CURRENT_BINARY_DIR}/${_testName}.h -      COMMAND ${KConfig_KCFGC_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/${_testName}.kcfg ${CMAKE_CURRENT_SOURCE_DIR}/${_testName}.kcfgc -      DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_testName}.kcfg ${CMAKE_CURRENT_SOURCE_DIR}/${_testName}.kcfgc kconfig_compiler_kf5) +      COMMAND ${KConfig_KCFGC_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/${_kcfgFile} ${CMAKE_CURRENT_SOURCE_DIR}/${_testName}.kcfgc +      DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_kcfgFile} ${CMAKE_CURRENT_SOURCE_DIR}/${_testName}.kcfgc kconfig_compiler_kf5) -#   set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${_testName}.h PROPERTIES GENERATED TRUE) +   # set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${_testName}.h PROPERTIES GENERATED TRUE)     qt5_generate_moc(${CMAKE_CURRENT_BINARY_DIR}/${_testName}.h ${CMAKE_CURRENT_BINARY_DIR}/${_testName}.moc ) -# do not run automoc on the generated file +   # do not run automoc on the generated file     set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${_testName}.cpp PROPERTIES SKIP_AUTOMOC TRUE)     set( ${_srcs} ${${_srcs}} ${CMAKE_CURRENT_BINARY_DIR}/${_testName}.cpp ${CMAKE_CURRENT_BINARY_DIR}/${_testName}.h ) @@ -197,6 +202,18 @@ target_link_libraries(test_signal KF5::ConfigGui)  ########### next target ############### +set(kconfigcompiler_test_signals_SRCS kconfigcompiler_test_signals.cpp) +gen_kcfg_test_source(signals_test_singleton kconfigcompiler_test_signals_SRCS KCFG signals_test.kcfg) +gen_kcfg_test_source(signals_test_no_singleton kconfigcompiler_test_signals_SRCS KCFG signals_test.kcfg) +gen_kcfg_test_source(signals_test_singleton_dpointer kconfigcompiler_test_signals_SRCS KCFG signals_test.kcfg) +gen_kcfg_test_source(signals_test_no_singleton_dpointer kconfigcompiler_test_signals_SRCS KCFG signals_test.kcfg) +add_executable(kconfigcompiler_test_signals ${kconfigcompiler_test_signals_SRCS}) +ecm_mark_as_test(kconfigcompiler_test_signals) +target_link_libraries(kconfigcompiler_test_signals Qt5::Test KF5::ConfigGui) +add_test(kconfig-kconfigcompiler-signals kconfigcompiler_test_signals) + +########### next target ############### +  set(kconfigcompiler_test_SRCS kconfigcompiler_test.cpp )  add_executable(kconfigcompiler_test ${kconfigcompiler_test_SRCS})  ecm_mark_as_test(kconfigcompiler_test) 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" diff --git a/autotests/kconfig_compiler/signals_test.kcfg b/autotests/kconfig_compiler/signals_test.kcfg new file mode 100644 index 00000000..766c56eb --- /dev/null +++ b/autotests/kconfig_compiler/signals_test.kcfg @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Author: Alex Richardson --> +<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0" +      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +      xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0 +      http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" > +  <kcfgfile arg="true"/> +  <signal name="fooChanged"> +    <argument type="String">foo</argument> +  </signal> +  <group name="Something"> +    <entry key="foo" type="String"> +      <default>default</default> +      <emit signal="fooChanged" /> +    </entry> +  </group> +</kcfg> diff --git a/autotests/kconfig_compiler/signals_test_no_singleton.kcfgc b/autotests/kconfig_compiler/signals_test_no_singleton.kcfgc new file mode 100644 index 00000000..4d096e08 --- /dev/null +++ b/autotests/kconfig_compiler/signals_test_no_singleton.kcfgc @@ -0,0 +1,9 @@ +File=signals_test.kcfg +ClassName=SignalsTestNoSingleton +Singleton=false +Mutators=true +MemberVariables=private +GlobalEnums=false +UseEnumTypes=false +ItemAccessors=false +DefaultValueGetters=true diff --git a/autotests/kconfig_compiler/signals_test_no_singleton_dpointer.kcfgc b/autotests/kconfig_compiler/signals_test_no_singleton_dpointer.kcfgc new file mode 100644 index 00000000..11b7c435 --- /dev/null +++ b/autotests/kconfig_compiler/signals_test_no_singleton_dpointer.kcfgc @@ -0,0 +1,9 @@ +File=signals_test.kcfg +ClassName=SignalsTestNoSingletonDpointer +Singleton=false +Mutators=true +MemberVariables=dpointer +GlobalEnums=false +UseEnumTypes=false +ItemAccessors=false +DefaultValueGetters=true diff --git a/autotests/kconfig_compiler/signals_test_singleton.kcfgc b/autotests/kconfig_compiler/signals_test_singleton.kcfgc new file mode 100644 index 00000000..59e04452 --- /dev/null +++ b/autotests/kconfig_compiler/signals_test_singleton.kcfgc @@ -0,0 +1,9 @@ +File=signals_test.kcfg +ClassName=SignalsTestSingleton +Singleton=true +Mutators=true +MemberVariables=private +GlobalEnums=false +UseEnumTypes=false +ItemAccessors=false +DefaultValueGetters=true diff --git a/autotests/kconfig_compiler/signals_test_singleton_dpointer.kcfgc b/autotests/kconfig_compiler/signals_test_singleton_dpointer.kcfgc new file mode 100644 index 00000000..1f13493a --- /dev/null +++ b/autotests/kconfig_compiler/signals_test_singleton_dpointer.kcfgc @@ -0,0 +1,9 @@ +File=signals_test.kcfg +ClassName=SignalsTestSingletonDpointer +Singleton=true +Mutators=true +MemberVariables=dpointer +GlobalEnums=false +UseEnumTypes=false +ItemAccessors=false +DefaultValueGetters=true diff --git a/autotests/kconfig_compiler/test_signal.cpp.ref b/autotests/kconfig_compiler/test_signal.cpp.ref index fd2d4bc9..35b5cba2 100644 --- a/autotests/kconfig_compiler/test_signal.cpp.ref +++ b/autotests/kconfig_compiler/test_signal.cpp.ref @@ -30,19 +30,21 @@ TestSignal::TestSignal(  )  {    Q_ASSERT(!s_globalTestSignal()->q);    s_globalTestSignal()->q = this; +  KConfigCompilerSignallingItem::NotifyFunction notifyFunction = static_cast<KConfigCompilerSignallingItem::NotifyFunction>(&TestSignal::itemChanged); +    setCurrentGroup( QLatin1String( "Appearance" ) ); -  KConfigSkeleton::ItemString  *itemEmoticonTheme; -  itemEmoticonTheme = new KConfigSkeleton::ItemString( currentGroup(), QLatin1String( "emoticonTheme" ), mEmoticonTheme, QLatin1String( "Default" ) ); +  KConfigCompilerSignallingItem  *itemEmoticonTheme; +  itemEmoticonTheme = new KConfigCompilerSignallingItem(new KConfigSkeleton::ItemString( currentGroup(), QLatin1String( "emoticonTheme" ), mEmoticonTheme, QLatin1String( "Default" ) ), this, notifyFunction, signalEmoticonSettingsChanged);    addItem( itemEmoticonTheme, QLatin1String( "emoticonTheme" ) ); -  KConfigSkeleton::ItemBool  *itemUseEmoticon; -  itemUseEmoticon = new KConfigSkeleton::ItemBool( currentGroup(), QLatin1String( "useEmoticon" ), mUseEmoticon, true ); +  KConfigCompilerSignallingItem  *itemUseEmoticon; +  itemUseEmoticon = new KConfigCompilerSignallingItem(new KConfigSkeleton::ItemBool( currentGroup(), QLatin1String( "useEmoticon" ), mUseEmoticon, true ), this, notifyFunction, signalEmoticonSettingsChanged);    addItem( itemUseEmoticon, QLatin1String( "useEmoticon" ) ); -  KConfigSkeleton::ItemBool  *itemEmoticonRequireSpace; -  itemEmoticonRequireSpace = new KConfigSkeleton::ItemBool( currentGroup(), QLatin1String( "emoticonRequireSpace" ), mEmoticonRequireSpace, true ); +  KConfigCompilerSignallingItem  *itemEmoticonRequireSpace; +  itemEmoticonRequireSpace = new KConfigCompilerSignallingItem(new KConfigSkeleton::ItemBool( currentGroup(), QLatin1String( "emoticonRequireSpace" ), mEmoticonRequireSpace, true ), this, notifyFunction, signalEmoticonSettingsChanged);    addItem( itemEmoticonRequireSpace, QLatin1String( "emoticonRequireSpace" ) ); -  KConfigSkeleton::ItemString  *itemStylePath; -  itemStylePath = new KConfigSkeleton::ItemString( currentGroup(), QLatin1String( "stylePath" ), mStylePath ); +  KConfigCompilerSignallingItem  *itemStylePath; +  itemStylePath = new KConfigCompilerSignallingItem(new KConfigSkeleton::ItemString( currentGroup(), QLatin1String( "stylePath" ), mStylePath ), this, notifyFunction, signalStyleChanged);    addItem( itemStylePath, QLatin1String( "stylePath" ) );    KConfigSkeleton::ItemString  *itemStyleCSSVariant;    itemStyleCSSVariant = new KConfigSkeleton::ItemString( currentGroup(), QLatin1String( "styleVariant" ), mStyleCSSVariant ); @@ -69,5 +71,9 @@ bool TestSignal::usrWriteConfig()    return true;  } +void TestSignal::itemChanged(quint64 flags) { +  mSettingsChanged |= flags; +} +  #include "test_signal.moc" diff --git a/autotests/kconfig_compiler/test_signal.h.ref b/autotests/kconfig_compiler/test_signal.h.ref index 737718d0..19b8b400 100644 --- a/autotests/kconfig_compiler/test_signal.h.ref +++ b/autotests/kconfig_compiler/test_signal.h.ref @@ -132,6 +132,9 @@ class TestSignal : public KConfigSkeleton      */      void styleChanged(const QString & stylePath, const QString & StyleCSSVariant); +  private: +    void itemChanged(quint64 flags); +    protected:      TestSignal();      friend class TestSignalHelper; | 
