diff options
Diffstat (limited to 'tier1/kconfig/autotests/kconfigtest.cpp')
-rw-r--r-- | tier1/kconfig/autotests/kconfigtest.cpp | 1634 |
1 files changed, 0 insertions, 1634 deletions
diff --git a/tier1/kconfig/autotests/kconfigtest.cpp b/tier1/kconfig/autotests/kconfigtest.cpp deleted file mode 100644 index 1aed5151..00000000 --- a/tier1/kconfig/autotests/kconfigtest.cpp +++ /dev/null @@ -1,1634 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 1997 Matthias Kalle Dalheimer (kalle@kde.org) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// Qt5 TODO: re-enable. No point in doing it before, it breaks on QString::fromUtf8(QByteArray), which exists in qt5. -#undef QT_NO_CAST_FROM_BYTEARRAY - -#include "kconfigtest.h" - -#include <QtTest/QtTest> -#include <qtemporarydir.h> -#include <QStandardPaths> -#include <kdesktopfile.h> - -#include <ksharedconfig.h> -#include <kconfiggroup.h> - -#ifdef Q_OS_UNIX -#include <utime.h> -#endif -#ifndef Q_OS_WIN -#include <unistd.h> // gethostname -#endif - -KCONFIGGROUP_DECLARE_ENUM_QOBJECT(KConfigTest,Testing) -KCONFIGGROUP_DECLARE_FLAGS_QOBJECT(KConfigTest,Flags) - -QTEST_MAIN( KConfigTest ) - -#define BOOLENTRY1 true -#define BOOLENTRY2 false -#define STRINGENTRY1 "hello" -#define STRINGENTRY2 " hello" -#define STRINGENTRY3 "hello " -#define STRINGENTRY4 " hello " -#define STRINGENTRY5 " " -#define STRINGENTRY6 "" -#define UTF8BITENTRY "Hello äöü" -#define TRANSLATEDSTRINGENTRY1 "bonjour" -#define BYTEARRAYENTRY QByteArray( "\x00\xff\x7f\x3c abc\x00\x00", 10 ) -#define ESCAPEKEY " []\0017[]==]" -#define ESCAPEENTRY "[]\170[]]=3=]\\] " -#define DOUBLEENTRY 123456.78912345 -#define FLOATENTRY 123.567f -#define POINTENTRY QPoint( 4351, 1235 ) -#define SIZEENTRY QSize( 10, 20 ) -#define RECTENTRY QRect( 10, 23, 5321, 13 ) -#define DATETIMEENTRY QDateTime( QDate( 2002, 06, 23 ), QTime( 12, 55, 40 ) ) -#define STRINGLISTENTRY (QStringList( "Hello," ) << " World") -#define STRINGLISTEMPTYENTRY QStringList() -#define STRINGLISTJUSTEMPTYELEMENT QStringList(QString()) -#define STRINGLISTEMPTYTRAINLINGELEMENT (QStringList( "Hi" ) << QString()) -#define STRINGLISTESCAPEODDENTRY (QStringList( "Hello\\\\\\" ) << "World") -#define STRINGLISTESCAPEEVENENTRY (QStringList( "Hello\\\\\\\\" ) << "World") -#define STRINGLISTESCAPECOMMAENTRY (QStringList( "Hel\\\\\\,\\\\,\\,\\\\\\\\,lo" ) << "World") -#define INTLISTENTRY1 QList<int>() << 1 << 2 << 3 << 4 -#define BYTEARRAYLISTENTRY1 QList<QByteArray>() << "" << "1,2" << "end" -#define VARIANTLISTENTRY (QVariantList() << true << false << QString("joe") << 10023) -#define VARIANTLISTENTRY2 (QVariantList() << POINTENTRY << SIZEENTRY) -#define HOMEPATH QString(QDir::homePath()+"/foo") -#define HOMEPATHESCAPE QString(QDir::homePath()+"/foo/$HOME") -#define DOLLARGROUP "$i" - -void KConfigTest::initTestCase() -{ - // ensure we don't use files in the real config directory - QStandardPaths::setTestModeEnabled(true); - QString testConfigDir = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation); - - // to make sure all files from a previous failed run are deleted - cleanupTestCase(); - - - KConfig sc( "kconfigtest" ); - - KConfigGroup cg(&sc, "AAA"); - cg.writeEntry("stringEntry1", STRINGENTRY1, - KConfig::Persistent|KConfig::Global); - cg.deleteEntry("stringEntry2", KConfig::Global); - - cg = KConfigGroup(&sc, "Hello"); - cg.writeEntry( "boolEntry1", BOOLENTRY1 ); - cg.writeEntry( "boolEntry2", BOOLENTRY2 ); - - QByteArray data( UTF8BITENTRY ); - QCOMPARE( data.size(), 12 ); // the source file is in utf8 - QCOMPARE( QString::fromUtf8(data).length(), 9 ); - cg.writeEntry ("Test", data); - cg.writeEntry( "bytearrayEntry", BYTEARRAYENTRY ); - cg.writeEntry( ESCAPEKEY, ESCAPEENTRY ); - cg.writeEntry( "emptyEntry", ""); - cg.writeEntry( "stringEntry1", STRINGENTRY1 ); - cg.writeEntry( "stringEntry2", STRINGENTRY2 ); - cg.writeEntry( "stringEntry3", STRINGENTRY3 ); - cg.writeEntry( "stringEntry4", STRINGENTRY4 ); - cg.writeEntry( "stringEntry5", STRINGENTRY5 ); - cg.writeEntry( "urlEntry1", QUrl("http://qt-project.org") ); - cg.writeEntry( "keywith=equalsign", STRINGENTRY1 ); - cg.deleteEntry( "stringEntry5" ); - cg.deleteEntry( "stringEntry6" ); // deleting a nonexistent entry - cg.writeEntry( "byteArrayEntry1", QByteArray( STRINGENTRY1 ), - KConfig::Global|KConfig::Persistent ); - cg.writeEntry( "doubleEntry1", DOUBLEENTRY ); - cg.writeEntry( "floatEntry1", FLOATENTRY ); - - sc.deleteGroup("deleteMe"); // deleting a nonexistent group - - cg = KConfigGroup(&sc, "Complex Types"); - cg.writeEntry( "rectEntry", RECTENTRY ); - cg.writeEntry( "pointEntry", POINTENTRY ); - cg.writeEntry( "sizeEntry", SIZEENTRY ); - cg.writeEntry( "dateTimeEntry", DATETIMEENTRY ); - cg.writeEntry( "dateEntry", DATETIMEENTRY.date() ); - - KConfigGroup ct = cg; - cg = KConfigGroup(&ct, "Nested Group 1"); - cg.writeEntry("stringentry1", STRINGENTRY1); - - cg = KConfigGroup(&ct, "Nested Group 2"); - cg.writeEntry( "stringEntry2", STRINGENTRY2 ); - - cg = KConfigGroup(&cg, "Nested Group 2.1"); - cg.writeEntry( "stringEntry3", STRINGENTRY3 ); - - cg = KConfigGroup(&ct, "Nested Group 3"); - cg.writeEntry( "stringEntry3", STRINGENTRY3 ); - - cg = KConfigGroup(&sc, "List Types" ); - cg.writeEntry( "listOfIntsEntry1", INTLISTENTRY1 ); - cg.writeEntry( "listOfByteArraysEntry1", BYTEARRAYLISTENTRY1 ); - cg.writeEntry( "stringListEntry", STRINGLISTENTRY ); - cg.writeEntry( "stringListEmptyEntry", STRINGLISTEMPTYENTRY ); - cg.writeEntry( "stringListJustEmptyElement", STRINGLISTJUSTEMPTYELEMENT ); - cg.writeEntry( "stringListEmptyTrailingElement", STRINGLISTEMPTYTRAINLINGELEMENT ); - cg.writeEntry( "stringListEscapeOddEntry", STRINGLISTESCAPEODDENTRY ); - cg.writeEntry( "stringListEscapeEvenEntry", STRINGLISTESCAPEEVENENTRY ); - cg.writeEntry( "stringListEscapeCommaEntry", STRINGLISTESCAPECOMMAENTRY ); - cg.writeEntry( "variantListEntry", VARIANTLISTENTRY ); - - cg = KConfigGroup(&sc, "Path Type" ); - cg.writePathEntry( "homepath", HOMEPATH ); - cg.writePathEntry( "homepathescape", HOMEPATHESCAPE ); - - cg = KConfigGroup(&sc, "Enum Types" ); - writeEntry( cg, "enum-10", Tens ); - writeEntry( cg, "enum-100", Hundreds ); - writeEntry( cg, "flags-bit0", Flags(bit0)); - writeEntry( cg, "flags-bit0-bit1", Flags(bit0|bit1) ); - - cg = KConfigGroup(&sc, "ParentGroup" ); - KConfigGroup cg1(&cg, "SubGroup1" ); - cg1.writeEntry( "somestring", "somevalue" ); - cg.writeEntry( "parentgrpstring", "somevalue" ); - KConfigGroup cg2(&cg, "SubGroup2" ); - cg2.writeEntry( "substring", "somevalue" ); - KConfigGroup cg3(&cg, "SubGroup/3"); - cg3.writeEntry( "sub3string", "somevalue" ); - - QVERIFY(sc.isDirty()); - QVERIFY(sc.sync()); - QVERIFY(!sc.isDirty()); - - QVERIFY2(QFile::exists(testConfigDir + QStringLiteral("/kconfigtest")), - qPrintable(testConfigDir + QStringLiteral("/kconfigtest must exist"))); - QVERIFY2(QFile::exists(testConfigDir + QStringLiteral("/kdeglobals")), - qPrintable(testConfigDir + QStringLiteral("/kdeglobals must exist"))); - - - KConfig sc1("kdebugrc", KConfig::SimpleConfig); - KConfigGroup sg0(&sc1, "0"); - sg0.writeEntry("AbortFatal", false); - sg0.writeEntry("WarnOutput", 0); - sg0.writeEntry("FatalOutput", 0); - QVERIFY(sc1.sync()); - - //Setup stuff to test KConfig::addConfigSources() - KConfig devcfg("specificrc"); - KConfigGroup devonlygrp(&devcfg, "Specific Only Group"); - devonlygrp.writeEntry("ExistingEntry", "DevValue"); - KConfigGroup devandbasegrp(&devcfg, "Shared Group"); - devandbasegrp.writeEntry("SomeSharedEntry", "DevValue"); - devandbasegrp.writeEntry("SomeSpecificOnlyEntry", "DevValue"); - QVERIFY(devcfg.sync()); - KConfig basecfg("baserc"); - KConfigGroup basegrp(&basecfg, "Base Only Group"); - basegrp.writeEntry("ExistingEntry", "BaseValue"); - KConfigGroup baseanddevgrp(&basecfg, "Shared Group"); - baseanddevgrp.writeEntry("SomeSharedEntry", "BaseValue"); - baseanddevgrp.writeEntry("SomeBaseOnlyEntry", "BaseValue"); - QVERIFY(basecfg.sync()); - - KConfig gecfg("groupescapetest", KConfig::SimpleConfig); - cg = KConfigGroup(&gecfg, DOLLARGROUP); - cg.writeEntry( "entry", "doesntmatter" ); - -} - -void KConfigTest::cleanupTestCase() -{ - //ensure we don't delete the real directory - QStandardPaths::setTestModeEnabled(true); - QDir localConfig(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)); - //qDebug() << "Erasing" << localConfig; - localConfig.removeRecursively(); - QVERIFY(!localConfig.exists()); -} - - -static QList<QByteArray> readLinesFrom(const QString& path) -{ - QFile file(path); - const bool opened = file.open(QIODevice::ReadOnly|QIODevice::Text); - Q_ASSERT(opened); - Q_UNUSED(opened); - QList<QByteArray> lines; - QByteArray line; - do { - line = file.readLine(); - if (!line.isEmpty()) - lines.append(line); - } while(!line.isEmpty()); - return lines; -} - -static QList<QByteArray> readLines(const char* fileName = "kconfigtest") -{ - const QString path = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + '/' + fileName; - Q_ASSERT(!path.isEmpty()); - return readLinesFrom(path); -} - -// see also testDefaults, which tests reverting with a defaults (global) file available -void KConfigTest::testDirtyAfterRevert() -{ - KConfig sc( "kconfigtest_revert" ); - - KConfigGroup cg(&sc, "Hello"); - cg.revertToDefault( "does_not_exist" ); - QVERIFY(!sc.isDirty()); - cg.writeEntry("Test", "Correct"); - QVERIFY(sc.isDirty()); - sc.sync(); - QVERIFY(!sc.isDirty()); - - cg.revertToDefault("Test"); - QVERIFY(sc.isDirty()); - QVERIFY(sc.sync()); - QVERIFY(!sc.isDirty()); - - cg.revertToDefault("Test"); - QVERIFY(!sc.isDirty()); -} - -void KConfigTest::testRevertAllEntries() -{ - // this tests the case were we revert (delete) all entries in a file, - // leaving a blank file - { - KConfig sc( "konfigtest2", KConfig::SimpleConfig ); - KConfigGroup cg( &sc, "Hello" ); - cg.writeEntry( "Test", "Correct" ); - } - - { - KConfig sc( "konfigtest2", KConfig::SimpleConfig ); - KConfigGroup cg( &sc, "Hello" ); - QCOMPARE( cg.readEntry( "Test", "Default" ), QString("Correct") ); - cg.revertToDefault( "Test" ); - } - - KConfig sc( "konfigtest2", KConfig::SimpleConfig ); - KConfigGroup cg( &sc, "Hello" ); - QCOMPARE( cg.readEntry( "Test", "Default" ), QString("Default") ); -} - -void KConfigTest::testSimple() -{ - // kdeglobals (which was created in initTestCase) must be found this way: - const QStringList kdeglobals = QStandardPaths::locateAll(QStandardPaths::GenericConfigLocation, QLatin1String("kdeglobals")); - QVERIFY(!kdeglobals.isEmpty()); - - KConfig sc2( "kconfigtest" ); - QCOMPARE(sc2.name(), QString("kconfigtest")); - - // make sure groupList() isn't returning something it shouldn't - Q_FOREACH(const QString& group, sc2.groupList()) { - QVERIFY(!group.isEmpty() && group != "<default>"); - QVERIFY(!group.contains(QChar(0x1d))); - } - - KConfigGroup sc3( &sc2, "AAA"); - - QVERIFY( sc3.hasKey( "stringEntry1" ) ); // from kdeglobals - QVERIFY( !sc3.isEntryImmutable("stringEntry1") ); - QCOMPARE( sc3.readEntry( "stringEntry1" ), QString( STRINGENTRY1 ) ); - - QVERIFY( !sc3.hasKey( "stringEntry2" ) ); - QCOMPARE( sc3.readEntry( "stringEntry2", QString("bla") ), QString( "bla" ) ); - - QVERIFY( !sc3.hasDefault( "stringEntry1" ) ); - - sc3 = KConfigGroup(&sc2, "Hello"); - QCOMPARE( sc3.readEntry( "Test", QByteArray() ), QByteArray( UTF8BITENTRY ) ); - QCOMPARE( sc3.readEntry( "bytearrayEntry", QByteArray() ), BYTEARRAYENTRY ); - QCOMPARE( sc3.readEntry( ESCAPEKEY ), QString( ESCAPEENTRY ) ); - QCOMPARE( sc3.readEntry( "Test", QString() ), QString::fromUtf8( UTF8BITENTRY ) ); - QCOMPARE( sc3.readEntry( "emptyEntry"/*, QString("Fietsbel")*/), QString("") ); - QCOMPARE( sc3.readEntry("emptyEntry", QString("Fietsbel")).isEmpty(), true ); - QCOMPARE( sc3.readEntry( "stringEntry1" ), QString( STRINGENTRY1 ) ); - QCOMPARE( sc3.readEntry( "stringEntry2" ), QString( STRINGENTRY2 ) ); - QCOMPARE( sc3.readEntry( "stringEntry3" ), QString( STRINGENTRY3 ) ); - QCOMPARE( sc3.readEntry( "stringEntry4" ), QString( STRINGENTRY4 ) ); - QVERIFY( !sc3.hasKey( "stringEntry5" ) ); - QCOMPARE( sc3.readEntry( "stringEntry5", QString("test") ), QString( "test" ) ); - QVERIFY( !sc3.hasKey( "stringEntry6" ) ); - QCOMPARE( sc3.readEntry( "stringEntry6", QString("foo") ), QString( "foo" ) ); - QCOMPARE( sc3.readEntry( "urlEntry1", QUrl() ), QUrl("http://qt-project.org") ); - QCOMPARE( sc3.readEntry( "boolEntry1", BOOLENTRY1 ), BOOLENTRY1 ); - QCOMPARE( sc3.readEntry( "boolEntry2", false ), BOOLENTRY2 ); - QCOMPARE( sc3.readEntry("keywith=equalsign", QString("wrong")), QString(STRINGENTRY1)); - QCOMPARE( sc3.readEntry( "byteArrayEntry1", QByteArray() ), - QByteArray( STRINGENTRY1 ) ); - QCOMPARE( sc3.readEntry( "doubleEntry1", 0.0 ), DOUBLEENTRY ); - QCOMPARE( sc3.readEntry( "floatEntry1", 0.0f ), FLOATENTRY ); -} - -void KConfigTest::testDefaults() -{ - KConfig config("defaulttest", KConfig::NoGlobals); - const QString defaultsFile = "defaulttest.defaults"; - KConfig defaults(defaultsFile, KConfig::SimpleConfig); - - const QString Default("Default"); - const QString NotDefault("Not Default"); - const QString Value1(STRINGENTRY1); - const QString Value2(STRINGENTRY2); - - KConfigGroup group = defaults.group("any group"); - group.writeEntry("entry1", Default); - QVERIFY(group.sync()); - - group = config.group("any group"); - group.writeEntry("entry1", Value1); - group.writeEntry("entry2", Value2); - QVERIFY(group.sync()); - - config.addConfigSources(QStringList() << QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + '/' + defaultsFile); - - config.setReadDefaults(true); - QCOMPARE(group.readEntry("entry1", QString()), Default); - QCOMPARE(group.readEntry("entry2", NotDefault), NotDefault); // no default for entry2 - - config.setReadDefaults(false); - QCOMPARE(group.readEntry("entry1", Default), Value1); - QCOMPARE(group.readEntry("entry2", NotDefault), Value2); - - group.revertToDefault("entry1"); - QCOMPARE(group.readEntry("entry1", QString()), Default); - group.revertToDefault("entry2"); - QCOMPARE(group.readEntry("entry2", QString()), QString()); - - // TODO test reverting localized entries - - Q_ASSERT(config.isDirty()); - group.sync(); - - // Check that everything is OK on disk, too - KConfig reader("defaulttest", KConfig::NoGlobals); - reader.addConfigSources(QStringList() << QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + '/' + defaultsFile); - KConfigGroup readerGroup = reader.group("any group"); - QCOMPARE(readerGroup.readEntry("entry1", QString()), Default); - QCOMPARE(readerGroup.readEntry("entry2", QString()), QString()); -} - -void KConfigTest::testLocale() -{ - KConfig config("kconfigtest.locales", KConfig::SimpleConfig); - const QString Translated(TRANSLATEDSTRINGENTRY1); - const QString Untranslated(STRINGENTRY1); - - KConfigGroup group = config.group("Hello"); - group.writeEntry("stringEntry1", Untranslated); - config.setLocale("fr"); - group.writeEntry("stringEntry1", Translated, KConfig::Localized|KConfig::Persistent); - QVERIFY(config.sync()); - - QCOMPARE(group.readEntry("stringEntry1", QString()), Translated); - QCOMPARE(group.readEntryUntranslated("stringEntry1"), Untranslated); - - config.setLocale("C"); // strings written in the "C" locale are written as nonlocalized - group.writeEntry("stringEntry1", Untranslated, KConfig::Localized|KConfig::Persistent); - QVERIFY(config.sync()); - - QCOMPARE(group.readEntry("stringEntry1", QString()), Untranslated); -} - -void KConfigTest::testEncoding() -{ - QString groupstr = QString::fromUtf8("UTF-8:\xc3\xb6l"); - - KConfig c( "kconfigtestencodings" ); - KConfigGroup cg(&c, groupstr); - cg.writeEntry("key", "value"); - QVERIFY(c.sync()); - - QList<QByteArray> lines = readLines("kconfigtestencodings"); - QCOMPARE(lines.count(), 2); - QCOMPARE(lines.first(), QByteArray("[UTF-8:\xc3\xb6l]\n")); - - KConfig c2( "kconfigtestencodings" ); - KConfigGroup cg2(&c2, groupstr); - QVERIFY(cg2.readEntry("key") == QByteArray("value")); - - QVERIFY(c2.groupList().contains(groupstr)); -} - -void KConfigTest::testLists() -{ - KConfig sc2( "kconfigtest" ); - KConfigGroup sc3(&sc2, "List Types"); - - QCOMPARE( sc3.readEntry( QString("stringListEntry"), QStringList()), - STRINGLISTENTRY ); - - QCOMPARE( sc3.readEntry( QString("stringListEmptyEntry"), QStringList("wrong") ), - STRINGLISTEMPTYENTRY ); - - QCOMPARE( sc3.readEntry( QString("stringListJustEmptyElement"), QStringList() ), - STRINGLISTJUSTEMPTYELEMENT ); - - QCOMPARE( sc3.readEntry( QString("stringListEmptyTrailingElement"), QStringList() ), - STRINGLISTEMPTYTRAINLINGELEMENT ); - - QCOMPARE( sc3.readEntry( QString("stringListEscapeOddEntry"), QStringList()), - STRINGLISTESCAPEODDENTRY ); - - QCOMPARE( sc3.readEntry( QString("stringListEscapeEvenEntry"), QStringList()), - STRINGLISTESCAPEEVENENTRY ); - - QCOMPARE( sc3.readEntry( QString("stringListEscapeCommaEntry"), QStringList()), - STRINGLISTESCAPECOMMAENTRY ); - - QCOMPARE( sc3.readEntry( "listOfIntsEntry1" ), QString::fromLatin1( "1,2,3,4" ) ); - QList<int> expectedIntList = INTLISTENTRY1; - QVERIFY( sc3.readEntry( "listOfIntsEntry1", QList<int>() ) == expectedIntList ); - - QCOMPARE( QVariant(sc3.readEntry( "variantListEntry", VARIANTLISTENTRY )).toStringList(), - QVariant(VARIANTLISTENTRY).toStringList() ); - - QCOMPARE( sc3.readEntry( "listOfByteArraysEntry1", QList<QByteArray>()), BYTEARRAYLISTENTRY1 ); -} - -void KConfigTest::testPath() -{ - KConfig sc2( "kconfigtest" ); - KConfigGroup sc3(&sc2, "Path Type"); - QCOMPARE( sc3.readPathEntry( "homepath", QString() ), HOMEPATH ); - QCOMPARE( sc3.readPathEntry( "homepathescape", QString() ), HOMEPATHESCAPE ); - QCOMPARE( sc3.entryMap()["homepath"], HOMEPATH ); - - { - QFile file(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/pathtest"); - file.open(QIODevice::WriteOnly|QIODevice::Text); - QTextStream out(&file); - out.setCodec("UTF-8"); - out << "[Test Group]" << endl - << "homePath=$HOME/foo" << endl - << "homePath2=file://$HOME/foo" << endl - << "withBraces[$e]=file://${HOME}/foo" << endl - << "URL[$e]=file://${HOME}/foo" << endl - << "hostname[$e]=$(hostname)" << endl - << "noeol=foo"; // no EOL - } - KConfig cf2("pathtest"); - KConfigGroup group = cf2.group("Test Group"); - QVERIFY(group.hasKey("homePath")); - QCOMPARE(group.readPathEntry("homePath", QString()), HOMEPATH); - QVERIFY(group.hasKey("homePath2")); - QCOMPARE(group.readPathEntry("homePath2", QString()), QString("file://" + HOMEPATH) ); - QVERIFY(group.hasKey("withBraces")); - QCOMPARE(group.readPathEntry("withBraces", QString()), QString("file://" + HOMEPATH) ); - QVERIFY(group.hasKey("URL")); - QCOMPARE(group.readEntry("URL", QString()), QString("file://" + HOMEPATH) ); -#if !defined(Q_OS_WIN32) && !defined(Q_OS_MAC) - // I don't know if this will work on windows - // This test hangs on OS X - QVERIFY(group.hasKey("hostname")); - char hostname[256]; - QVERIFY(::gethostname(hostname, sizeof(hostname)) == 0); - QCOMPARE(group.readEntry("hostname", QString()), QString::fromLatin1(hostname)); -#endif - QVERIFY(group.hasKey("noeol")); - QCOMPARE(group.readEntry("noeol", QString()), QString("foo")); -} - -void KConfigTest::testPersistenceOfExpandFlagForPath() -{ - // This test checks that a path entry starting with $HOME is still flagged - // with the expand flag after the config was altered without rewriting the - // path entry. - - // 1st step: Open the config, add a new dummy entry and then sync the config - // back to the storage. - { - KConfig sc2( "kconfigtest" ); - KConfigGroup sc3(&sc2, "Path Type"); - sc3.writeEntry( "dummy", "dummy" ); - QVERIFY(sc2.sync()); - } - - // 2nd step: Call testPath() again. Rewriting the config must not break - // the testPath() test. - testPath(); -} - -void KConfigTest::testComplex() -{ - KConfig sc2( "kconfigtest" ); - KConfigGroup sc3(&sc2, "Complex Types"); - - QCOMPARE( sc3.readEntry( "pointEntry", QPoint() ), POINTENTRY ); - QCOMPARE( sc3.readEntry( "sizeEntry", SIZEENTRY ), SIZEENTRY); - QCOMPARE( sc3.readEntry( "rectEntry", QRect(1,2,3,4) ), RECTENTRY ); - QCOMPARE( sc3.readEntry( "dateTimeEntry", QDateTime() ).toString(Qt::ISODate), - DATETIMEENTRY.toString(Qt::ISODate) ); - QCOMPARE( sc3.readEntry( "dateEntry", QDate() ).toString(Qt::ISODate), - DATETIMEENTRY.date().toString(Qt::ISODate) ); - QCOMPARE( sc3.readEntry( "dateTimeEntry", QDate() ), DATETIMEENTRY.date() ); -} - -void KConfigTest::testEnums() -{ - KConfig sc("kconfigtest"); - KConfigGroup sc3(&sc, "Enum Types" ); - - QCOMPARE( sc3.readEntry( "enum-10" ), QString("Tens")); - QVERIFY( readEntry( sc3, "enum-100", Ones) != Ones); - QVERIFY( readEntry( sc3, "enum-100", Ones) != Tens); - - QCOMPARE( sc3.readEntry( "flags-bit0" ), QString("bit0")); - QVERIFY( readEntry( sc3, "flags-bit0", Flags() ) == bit0 ); - - int eid = staticMetaObject.indexOfEnumerator( "Flags" ); - QVERIFY( eid != -1 ); - QMetaEnum me = staticMetaObject.enumerator( eid ); - Flags bitfield = bit0|bit1; - - QCOMPARE( sc3.readEntry( "flags-bit0-bit1" ), QString( me.valueToKeys(bitfield) ) ); - QVERIFY( readEntry( sc3, "flags-bit0-bit1", Flags() ) == bitfield ); -} - -void KConfigTest::testEntryMap() -{ - KConfig sc("kconfigtest"); - KConfigGroup cg(&sc, "Hello"); - QMap<QString, QString> entryMap = cg.entryMap(); - qDebug() << entryMap.keys(); - QCOMPARE(entryMap.value("stringEntry1"), QString(STRINGENTRY1)); - QCOMPARE(entryMap.value("stringEntry2"), QString(STRINGENTRY2)); - QCOMPARE(entryMap.value("stringEntry3"), QString(STRINGENTRY3)); - QCOMPARE(entryMap.value("stringEntry4"), QString(STRINGENTRY4)); - QVERIFY(!entryMap.contains("stringEntry5")); - QVERIFY(!entryMap.contains("stringEntry6")); - QCOMPARE(entryMap.value("Test"), QString::fromUtf8(UTF8BITENTRY)); - QCOMPARE(entryMap.value("bytearrayEntry"), QString::fromUtf8(BYTEARRAYENTRY)); - QCOMPARE(entryMap.value("emptyEntry"), QString()); - QVERIFY(entryMap.contains("emptyEntry")); - QCOMPARE(entryMap.value("boolEntry1"), QString(BOOLENTRY1?"true":"false")); - QCOMPARE(entryMap.value("boolEntry2"), QString(BOOLENTRY2?"true":"false")); - QCOMPARE(entryMap.value("keywith=equalsign"), QString(STRINGENTRY1)); - QCOMPARE(entryMap.value("byteArrayEntry1"), QString(STRINGENTRY1)); - QCOMPARE(entryMap.value("doubleEntry1"), QString::number(DOUBLEENTRY, 'g', 15)); - QCOMPARE(entryMap.value("floatEntry1"), QString::number(FLOATENTRY, 'g', 8)); -} - -void KConfigTest::testInvalid() -{ - KConfig sc( "kconfigtest" ); - - // all of these should print a message to the kdebug.dbg file - KConfigGroup sc3(&sc, "Invalid Types" ); - sc3.writeEntry( "badList", VARIANTLISTENTRY2 ); - - QList<int> list; - - // 1 element list - list << 1; - sc3.writeEntry( QString("badList"), list); - - QVERIFY( sc3.readEntry( "badList", QPoint() ) == QPoint() ); - QVERIFY( sc3.readEntry( "badList", QRect() ) == QRect() ); - QVERIFY( sc3.readEntry( "badList", QSize() ) == QSize() ); - QVERIFY( sc3.readEntry( "badList", QDate() ) == QDate() ); - QVERIFY( sc3.readEntry( "badList", QDateTime() ) == QDateTime() ); - - // 2 element list - list << 2; - sc3.writeEntry( "badList", list); - - QVERIFY( sc3.readEntry( "badList", QRect() ) == QRect() ); - QVERIFY( sc3.readEntry( "badList", QDate() ) == QDate() ); - QVERIFY( sc3.readEntry( "badList", QDateTime() ) == QDateTime() ); - - // 3 element list - list << 303; - sc3.writeEntry( "badList", list); - - QVERIFY( sc3.readEntry( "badList", QPoint() ) == QPoint() ); - QVERIFY( sc3.readEntry( "badList", QRect() ) == QRect() ); - QVERIFY( sc3.readEntry( "badList", QSize() ) == QSize() ); - QVERIFY( sc3.readEntry( "badList", QDate() ) == QDate() ); // out of bounds - QVERIFY( sc3.readEntry( "badList", QDateTime() ) == QDateTime() ); - - // 4 element list - list << 4; - sc3.writeEntry( "badList", list ); - - QVERIFY( sc3.readEntry( "badList", QPoint() ) == QPoint() ); - QVERIFY( sc3.readEntry( "badList", QSize() ) == QSize() ); - QVERIFY( sc3.readEntry( "badList", QDate() ) == QDate() ); - QVERIFY( sc3.readEntry( "badList", QDateTime() ) == QDateTime() ); - - // 5 element list - list[2] = 3; - list << 5; - sc3.writeEntry( "badList", list); - - QVERIFY( sc3.readEntry( "badList", QPoint() ) == QPoint() ); - QVERIFY( sc3.readEntry( "badList", QRect() ) == QRect() ); - QVERIFY( sc3.readEntry( "badList", QSize() ) == QSize() ); - QVERIFY( sc3.readEntry( "badList", QDate() ) == QDate() ); - QVERIFY( sc3.readEntry( "badList", QDateTime() ) == QDateTime() ); - - // 6 element list - list << 6; - sc3.writeEntry( "badList", list); - - QVERIFY( sc3.readEntry( "badList", QPoint() ) == QPoint() ); - QVERIFY( sc3.readEntry( "badList", QRect() ) == QRect() ); - QVERIFY( sc3.readEntry( "badList", QSize() ) == QSize() ); -} - -void KConfigTest::testChangeGroup() -{ - KConfig sc( "kconfigtest" ); - KConfigGroup sc3(&sc, "Hello"); - QCOMPARE(sc3.name(), QString("Hello")); - KConfigGroup newGroup(sc3); -#ifndef KDE_NO_DEPRECATED - newGroup.changeGroup("FooBar"); // deprecated! - QCOMPARE(newGroup.name(), QString("FooBar")); - QCOMPARE(sc3.name(), QString("Hello")); // unchanged - - // Write into the "changed group" and check that it works - newGroup.writeEntry("InFooBar", "FB"); - QCOMPARE(KConfigGroup(&sc, "FooBar").entryMap().value("InFooBar"), QString("FB")); - QCOMPARE(KConfigGroup(&sc, "Hello").entryMap().value("InFooBar"), QString()); -#endif - - KConfigGroup rootGroup(sc.group("")); - QCOMPARE(rootGroup.name(), QString("<default>")); - KConfigGroup sc32(rootGroup.group("Hello")); - QCOMPARE(sc32.name(), QString("Hello")); - KConfigGroup newGroup2(sc32); -#ifndef KDE_NO_DEPRECATED - newGroup2.changeGroup("FooBar"); // deprecated! - QCOMPARE(newGroup2.name(), QString("FooBar")); - QCOMPARE(sc32.name(), QString("Hello")); // unchanged -#endif -} - -// Simple test for deleteEntry -void KConfigTest::testDeleteEntry() -{ - const char* configFile = "kconfigdeletetest"; - { - KConfig conf(configFile); - conf.group("Hello").writeEntry("DelKey", "ToBeDeleted"); - } - const QList<QByteArray> lines = readLines(configFile); - Q_ASSERT(lines.contains("[Hello]\n")); - Q_ASSERT(lines.contains("DelKey=ToBeDeleted\n")); - - KConfig sc(configFile); - KConfigGroup group(&sc, "Hello"); - - group.deleteEntry("DelKey"); - QCOMPARE( group.readEntry("DelKey", QString("Fietsbel")), QString("Fietsbel") ); - - QVERIFY(group.sync()); - Q_ASSERT(!readLines(configFile).contains("DelKey=ToBeDeleted\n")); - QCOMPARE( group.readEntry("DelKey", QString("still deleted")), QString("still deleted") ); -} - -void KConfigTest::testDelete() -{ - KConfig sc( "kconfigtest" ); - - KConfigGroup ct(&sc, "Complex Types"); - - // First delete a nested group - KConfigGroup delgr(&ct, "Nested Group 3"); - QVERIFY(delgr.exists()); - QVERIFY(ct.hasGroup("Nested Group 3")); - delgr.deleteGroup(); - QVERIFY(!delgr.exists()); - QVERIFY(!ct.hasGroup("Nested Group 3")); - QVERIFY(ct.groupList().contains("Nested Group 3")); - - KConfigGroup ng(&ct, "Nested Group 2"); - QVERIFY(sc.hasGroup("Complex Types")); - QVERIFY(!sc.hasGroup("Does not exist")); - sc.deleteGroup("Complex Types"); - QCOMPARE(sc.group("Complex Types").keyList().count(), 0); - QVERIFY(!sc.hasGroup("Complex Types")); // #192266 - QVERIFY(!sc.group("Complex Types").exists()); - QVERIFY(!ct.hasGroup("Nested Group 1")); - - QCOMPARE(ct.group("Nested Group 1").keyList().count(), 0); - QCOMPARE(ct.group("Nested Group 2").keyList().count(), 0); - QCOMPARE(ng.group("Nested Group 2.1").keyList().count(), 0); - - KConfigGroup cg(&sc , "AAA" ); - cg.deleteGroup(); - QVERIFY( sc.entryMap("Complex Types").isEmpty() ); - QVERIFY( sc.entryMap("AAA").isEmpty() ); - QVERIFY( !sc.entryMap("Hello").isEmpty() ); //not deleted group - QVERIFY( sc.entryMap("FooBar").isEmpty() ); //inexistant group - - QVERIFY(cg.sync()); - // Check what happens on disk - const QList<QByteArray> lines = readLines(); - //qDebug() << lines; - QVERIFY(!lines.contains("[Complex Types]\n")); - QVERIFY(!lines.contains("[Complex Types][Nested Group 1]\n")); - QVERIFY(!lines.contains("[Complex Types][Nested Group 2]\n")); - QVERIFY(!lines.contains("[Complex Types][Nested Group 2.1]\n")); - QVERIFY(!lines.contains("[AAA]\n")); - QVERIFY(lines.contains("[Hello]\n")); // a group that was not deleted - - // test for entries that are marked as deleted when there is no default - KConfig cf("kconfigtest", KConfig::SimpleConfig); // make sure there are no defaults - cg = cf.group("Portable Devices"); - cg.writeEntry("devices|manual|(null)", "whatever"); - cg.writeEntry("devices|manual|/mnt/ipod", "/mnt/ipod"); - QVERIFY(cf.sync()); - - int count=0; - Q_FOREACH(const QByteArray& item, readLines()) - if (item.startsWith("devices|")) // krazy:exclude=strings - count++; - QCOMPARE(count, 2); - cg.deleteEntry("devices|manual|/mnt/ipod"); - QVERIFY(cf.sync()); - Q_FOREACH(const QByteArray& item, readLines()) - QVERIFY(!item.contains("ipod")); -} - -void KConfigTest::testDefaultGroup() -{ - KConfig sc( "kconfigtest" ); - KConfigGroup defaultGroup(&sc, "<default>"); - QCOMPARE(defaultGroup.name(), QString("<default>")); - QVERIFY(!defaultGroup.exists()); - defaultGroup.writeEntry("TestKey", "defaultGroup"); - QVERIFY(defaultGroup.exists()); - QCOMPARE(defaultGroup.readEntry("TestKey", QString()), QString("defaultGroup")); - QVERIFY(sc.sync()); - - { - // Test reading it - KConfig sc2("kconfigtest"); - KConfigGroup defaultGroup2(&sc2, "<default>"); - QCOMPARE(defaultGroup2.name(), QString("<default>")); - QVERIFY(defaultGroup2.exists()); - QCOMPARE(defaultGroup2.readEntry("TestKey", QString()), QString("defaultGroup")); - } - { - // Test reading it - KConfig sc2("kconfigtest"); - KConfigGroup emptyGroup(&sc2, ""); - QCOMPARE(emptyGroup.name(), QString("<default>")); - QVERIFY(emptyGroup.exists()); - QCOMPARE(emptyGroup.readEntry("TestKey", QString()), QString("defaultGroup")); - } - - QList<QByteArray> lines = readLines(); - QVERIFY(!lines.contains("[]\n")); - QCOMPARE(lines.first(), QByteArray("TestKey=defaultGroup\n")); - - // Now that the group exists make sure it isn't returned from groupList() - Q_FOREACH(const QString& group, sc.groupList()) { - QVERIFY(!group.isEmpty() && group != "<default>"); - } - - defaultGroup.deleteGroup(); - QVERIFY(sc.sync()); - - // Test if deleteGroup worked - lines = readLines(); - QVERIFY(lines.first() != QByteArray("TestKey=defaultGroup\n")); -} - -void KConfigTest::testEmptyGroup() -{ - KConfig sc( "kconfigtest" ); - KConfigGroup emptyGroup(&sc, ""); - QCOMPARE(emptyGroup.name(), QString("<default>")); // confusing, heh? - QVERIFY(!emptyGroup.exists()); - emptyGroup.writeEntry("TestKey", "emptyGroup"); - QVERIFY(emptyGroup.exists()); - QCOMPARE(emptyGroup.readEntry("TestKey", QString()), QString("emptyGroup")); - QVERIFY(sc.sync()); - - { - // Test reading it - KConfig sc2("kconfigtest"); - KConfigGroup defaultGroup(&sc2, "<default>"); - QCOMPARE(defaultGroup.name(), QString("<default>")); - QVERIFY(defaultGroup.exists()); - QCOMPARE(defaultGroup.readEntry("TestKey", QString()), QString("emptyGroup")); - } - { - // Test reading it - KConfig sc2("kconfigtest"); - KConfigGroup emptyGroup2(&sc2, ""); - QCOMPARE(emptyGroup2.name(), QString("<default>")); - QVERIFY(emptyGroup2.exists()); - QCOMPARE(emptyGroup2.readEntry("TestKey", QString()), QString("emptyGroup")); - } - - QList<QByteArray> lines = readLines(); - QVERIFY(!lines.contains("[]\n")); // there's no support for the [] group, in fact. - QCOMPARE(lines.first(), QByteArray("TestKey=emptyGroup\n")); - - // Now that the group exists make sure it isn't returned from groupList() - Q_FOREACH(const QString& group, sc.groupList()) { - QVERIFY(!group.isEmpty() && group != "<default>"); - } - emptyGroup.deleteGroup(); - QVERIFY(sc.sync()); - - // Test if deleteGroup worked - lines = readLines(); - QVERIFY(lines.first() != QByteArray("TestKey=defaultGroup\n")); -} - -void KConfigTest::testCascadingWithLocale() -{ - // This test relies on XDG_CONFIG_DIRS, which only has effect on Unix. - // Cascading (more than two levels) isn't available at all on Windows. -#ifdef Q_OS_UNIX - QTemporaryDir middleDir; - QTemporaryDir globalDir; - qputenv("XDG_CONFIG_DIRS", qPrintable(middleDir.path() + QString(":") + globalDir.path())); - - const QString globalConfigDir = globalDir.path(); - QVERIFY(QDir().mkpath(globalConfigDir)); - QFile global(globalConfigDir + "/foo.desktop"); - QVERIFY(global.open(QIODevice::WriteOnly|QIODevice::Text)); - QTextStream globalOut(&global); - globalOut << "[Group]" << endl - << "FromGlobal=true" << endl - << "FromGlobal[fr]=vrai" << endl - << "Name=Testing" << endl - << "Name[fr]=FR" << endl - << "Other=Global" << endl - << "Other[fr]=Global_FR" << endl; - global.close(); - - const QString middleConfigDir = middleDir.path(); - QVERIFY(QDir().mkpath(middleConfigDir)); - QFile local(middleConfigDir + "/foo.desktop"); - QVERIFY(local.open(QIODevice::WriteOnly|QIODevice::Text)); - QTextStream out(&local); - out << "[Group]" << endl - << "FromLocal=true" << endl - << "FromLocal[fr]=vrai" << endl - << "Name=Local Testing" << endl - << "Name[fr]=FR" << endl - << "Other=English Only" << endl; - local.close(); - - KConfig config("foo.desktop"); - KConfigGroup group = config.group("Group"); - QCOMPARE(group.readEntry("FromGlobal"), QString("true")); - QCOMPARE(group.readEntry("FromLocal"), QString("true")); - QCOMPARE(group.readEntry("Name"), QString("Local Testing")); - config.setLocale("fr"); - QCOMPARE(group.readEntry("FromGlobal"), QString("vrai")); - QCOMPARE(group.readEntry("FromLocal"), QString("vrai")); - QCOMPARE(group.readEntry("Name"), QString("FR")); - QCOMPARE(group.readEntry("Other"), QString("English Only")); // Global_FR is locally overriden -#endif -} - -void KConfigTest::testMerge() -{ - KConfig config("mergetest", KConfig::SimpleConfig); - - KConfigGroup cg = config.group("some group"); - cg.writeEntry("entry", " random entry"); - cg.writeEntry("another entry", "blah blah blah"); - - { // simulate writing by another process - QFile file(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/mergetest"); - file.open(QIODevice::WriteOnly|QIODevice::Text); - QTextStream out(&file); - out.setCodec("UTF-8"); - out << "[Merged Group]" << endl - << "entry1=Testing" << endl - << "entry2=More Testing" << endl - << "[some group]" << endl - << "entry[fr]=French" << endl - << "entry[es]=Spanish" << endl - << "entry[de]=German" << endl; - } - QVERIFY(config.sync()); - - { - QList<QByteArray> lines; - // this is what the file should look like - lines << "[Merged Group]\n" - << "entry1=Testing\n" - << "entry2=More Testing\n" - << "\n" - << "[some group]\n" - << "another entry=blah blah blah\n" - << "entry=\\srandom entry\n" - << "entry[de]=German\n" - << "entry[es]=Spanish\n" - << "entry[fr]=French\n"; - QFile file(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/mergetest"); - file.open(QIODevice::ReadOnly|QIODevice::Text); - Q_FOREACH (const QByteArray& line, lines) { - QCOMPARE(line, file.readLine()); - } - } -} - -void KConfigTest::testImmutable() -{ - { - QFile file(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/immutabletest"); - file.open(QIODevice::WriteOnly|QIODevice::Text); - QTextStream out(&file); - out.setCodec("UTF-8"); - out << "[$i]" << endl - << "entry1=Testing" << endl - << "[group][$i]" << endl - << "[group][subgroup][$i]" << endl; - } - - KConfig config("immutabletest", KConfig::SimpleConfig); - QVERIFY(config.isGroupImmutable(QByteArray())); - KConfigGroup cg = config.group(QByteArray()); - QVERIFY(cg.isEntryImmutable("entry1")); - KConfigGroup cg1 = config.group("group"); - QVERIFY(cg1.isImmutable()); - KConfigGroup cg1a = cg.group("group"); - QVERIFY(cg1a.isImmutable()); - KConfigGroup cg2 = cg1.group("subgroup"); - QVERIFY(cg2.isImmutable()); -} - -void KConfigTest::testOptionOrder() -{ - { - QFile file(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/doubleattrtest"); - file.open(QIODevice::WriteOnly|QIODevice::Text); - QTextStream out(&file); - out.setCodec("UTF-8"); - out << "[group3]" << endl - << "entry2=unlocalized" << endl - << "entry2[$i][de_DE]=t2" << endl; - } - KConfig config("doubleattrtest", KConfig::SimpleConfig); - config.setLocale("de_DE"); - KConfigGroup cg3 = config.group("group3"); - QVERIFY(!cg3.isImmutable()); - QCOMPARE(cg3.readEntry("entry2",""), QString("t2")); - QVERIFY(cg3.isEntryImmutable("entry2")); - config.setLocale("C"); - QCOMPARE(cg3.readEntry("entry2",""), QString("unlocalized")); - QVERIFY(!cg3.isEntryImmutable("entry2")); - cg3.writeEntry("entry2","modified"); - QVERIFY(config.sync()); - - { - QList<QByteArray> lines; - // this is what the file should look like - lines << "[group3]\n" - << "entry2=modified\n" - << "entry2[de_DE][$i]=t2\n"; - - QFile file(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/doubleattrtest"); - file.open(QIODevice::ReadOnly|QIODevice::Text); - Q_FOREACH (const QByteArray& line, lines) { - QCOMPARE(line, file.readLine()); - } - } -} - - -void KConfigTest::testGroupEscape() -{ - KConfig config("groupescapetest", KConfig::SimpleConfig); - QVERIFY( config.group(DOLLARGROUP).exists() ); -} - -void KConfigTest::testSubGroup() -{ - KConfig sc( "kconfigtest" ); - KConfigGroup cg( &sc, "ParentGroup" ); - QCOMPARE(cg.readEntry( "parentgrpstring", ""), QString("somevalue") ); - KConfigGroup subcg1( &cg, "SubGroup1"); - QCOMPARE(subcg1.name(), QString("SubGroup1")); - QCOMPARE(subcg1.readEntry( "somestring", ""), QString("somevalue") ); - KConfigGroup subcg2( &cg, "SubGroup2"); - QCOMPARE(subcg2.name(), QString("SubGroup2")); - QCOMPARE(subcg2.readEntry( "substring", ""), QString("somevalue") ); - KConfigGroup subcg3( &cg, "SubGroup/3"); - QCOMPARE(subcg3.readEntry( "sub3string", ""), QString("somevalue") ); - QCOMPARE(subcg3.name(), QString("SubGroup/3")); - KConfigGroup rcg( &sc, "" ); - KConfigGroup srcg( &rcg, "ParentGroup" ); - QCOMPARE(srcg.readEntry( "parentgrpstring", ""), QString("somevalue") ); - - QStringList groupList = cg.groupList(); - groupList.sort(); // comes from QSet, so order is undefined - QCOMPARE(groupList, (QStringList() << "SubGroup/3" << "SubGroup1" << "SubGroup2")); - - const QStringList expectedSubgroup3Keys = (QStringList() << "sub3string"); - QCOMPARE(subcg3.keyList(), expectedSubgroup3Keys); - const QStringList expectedParentGroupKeys(QStringList() << "parentgrpstring"); - - QCOMPARE(cg.keyList(), expectedParentGroupKeys); - - QCOMPARE(QStringList(cg.entryMap().keys()), expectedParentGroupKeys); - QCOMPARE(QStringList(subcg3.entryMap().keys()), expectedSubgroup3Keys); - - // Create A group containing only other groups. We want to make sure it - // shows up in groupList of sc - KConfigGroup neg(&sc, "NoEntryGroup"); - KConfigGroup negsub1(&neg, "NEG Child1"); - negsub1.writeEntry( "entry", "somevalue" ); - KConfigGroup negsub2(&neg, "NEG Child2"); - KConfigGroup negsub3(&neg, "NEG Child3"); - KConfigGroup negsub31(&negsub3, "NEG Child3-1"); - KConfigGroup negsub4(&neg, "NEG Child4"); - KConfigGroup negsub41(&negsub4, "NEG Child4-1"); - negsub41.writeEntry( "entry", "somevalue" ); - - // A group exists if it has content - QVERIFY(negsub1.exists()); - - // But it doesn't exist if it has no content - // Ossi and David say: this is how it's supposed to work. - // However you could add a dummy entry for now, or we could add a "Persist" feature to kconfig groups - // which would make it written out, much like "immutable" already makes them persistent. - QVERIFY(!negsub2.exists()); - - // A subgroup does not qualify as content if it is also empty - QVERIFY(!negsub3.exists()); - - // A subgroup with content is ok - QVERIFY(negsub4.exists()); - - // Only subgroups with content show up in groupList() - //QEXPECT_FAIL("", "Empty subgroups do not show up in groupList()", Continue); - //QCOMPARE(neg.groupList(), QStringList() << "NEG Child1" << "NEG Child2" << "NEG Child3" << "NEG Child4"); - // This is what happens - QStringList groups = neg.groupList(); - groups.sort(); // Qt5 made the ordering unreliable, due to QHash - QCOMPARE(groups, QStringList() << "NEG Child1" << "NEG Child4"); - - // make sure groupList() isn't returning something it shouldn't - Q_FOREACH(const QString& group, sc.groupList()) { - QVERIFY(!group.isEmpty() && group != "<default>"); - QVERIFY(!group.contains(QChar(0x1d))); - QVERIFY(!group.contains("subgroup")); - QVERIFY(!group.contains("SubGroup")); - } - - QVERIFY(sc.sync()); - - // Check that the empty groups are not written out. - const QList<QByteArray> lines = readLines(); - QVERIFY(lines.contains("[NoEntryGroup][NEG Child1]\n")); - QVERIFY(!lines.contains("[NoEntryGroup][NEG Child2]\n")); - QVERIFY(!lines.contains("[NoEntryGroup][NEG Child3]\n")); - QVERIFY(!lines.contains("[NoEntryGroup][NEG Child4]\n")); // implicit group, not written out - QVERIFY(lines.contains("[NoEntryGroup][NEG Child4][NEG Child4-1]\n")); -} - -void KConfigTest::testAddConfigSources() -{ - KConfig cf("specificrc"); - - cf.addConfigSources(QStringList() << QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/baserc"); - cf.reparseConfiguration(); - - KConfigGroup specificgrp(&cf, "Specific Only Group"); - QCOMPARE(specificgrp.readEntry("ExistingEntry", ""), QString("DevValue")); - - KConfigGroup sharedgrp(&cf, "Shared Group"); - QCOMPARE(sharedgrp.readEntry("SomeSpecificOnlyEntry",""), QString("DevValue")); - QCOMPARE(sharedgrp.readEntry("SomeBaseOnlyEntry",""), QString("BaseValue")); - QCOMPARE(sharedgrp.readEntry("SomeSharedEntry",""), QString("DevValue")); - - KConfigGroup basegrp(&cf, "Base Only Group"); - QCOMPARE(basegrp.readEntry("ExistingEntry", ""), QString("BaseValue")); - basegrp.writeEntry("New Entry Base Only", "SomeValue"); - - KConfigGroup newgrp(&cf, "New Group"); - newgrp.writeEntry("New Entry", "SomeValue"); - - QVERIFY(cf.sync()); - - KConfig plaincfg("specificrc"); - - KConfigGroup newgrp2(&plaincfg, "New Group"); - QCOMPARE(newgrp2.readEntry("New Entry", ""), QString("SomeValue")); - - KConfigGroup basegrp2(&plaincfg, "Base Only Group"); - QCOMPARE(basegrp2.readEntry("New Entry Base Only", ""), QString("SomeValue")); -} - -void KConfigTest::testGroupCopyTo() -{ - KConfig cf1("kconfigtest"); - KConfigGroup original = cf1.group("Enum Types"); - - KConfigGroup copy = cf1.group("Enum Types Copy"); - original.copyTo(©); // copy from one group to another - QCOMPARE(copy.entryMap(), original.entryMap()); - - KConfig cf2("copy_of_kconfigtest", KConfig::SimpleConfig); - QVERIFY(!cf2.hasGroup(original.name())); - QVERIFY(!cf2.hasGroup(copy.name())); - - KConfigGroup newGroup = cf2.group(original.name()); - original.copyTo(&newGroup); // copy from one file to another - QVERIFY(cf2.hasGroup(original.name())); - QVERIFY(!cf2.hasGroup(copy.name())); // make sure we didn't copy more than we wanted - QCOMPARE(newGroup.entryMap(), original.entryMap()); -} - -void KConfigTest::testConfigCopyToSync() -{ - KConfig cf1("kconfigtest"); - // Prepare source file - KConfigGroup group(&cf1, "CopyToTest"); - group.writeEntry("Type", "Test"); - QVERIFY(cf1.sync()); - - // Copy to "destination" - const QString destination = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kconfigcopytotest"; - QFile::remove(destination); - - KConfig cf2("kconfigcopytotest"); - KConfigGroup group2(&cf2, "CopyToTest"); - - group.copyTo(&group2); - - QString testVal = group2.readEntry("Type"); - QCOMPARE(testVal, QString("Test")); - // should write to disk the copied data from group - QVERIFY(cf2.sync()); - QVERIFY(QFile::exists(destination)); -} - -void KConfigTest::testConfigCopyTo() -{ - KConfig cf1("kconfigtest"); - { - // Prepare source file - KConfigGroup group(&cf1, "CopyToTest"); - group.writeEntry("Type", "Test"); - QVERIFY(cf1.sync()); - } - - { - // Copy to "destination" - const QString destination = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kconfigcopytotest"; - QFile::remove(destination); - KConfig cf2; - cf1.copyTo(destination, &cf2); - KConfigGroup group2(&cf2, "CopyToTest"); - QString testVal = group2.readEntry("Type"); - QCOMPARE(testVal, QString("Test")); - QVERIFY(cf2.sync()); - QVERIFY(QFile::exists(destination)); - } - - // Check copied config file on disk - KConfig cf3("kconfigcopytotest"); - KConfigGroup group3(&cf3, "CopyToTest"); - QString testVal = group3.readEntry("Type"); - QCOMPARE(testVal, QString("Test")); -} - -void KConfigTest::testReparent() -{ - KConfig cf("kconfigtest"); - const QString name("Enum Types"); - KConfigGroup group = cf.group(name); - const QMap<QString, QString> originalMap = group.entryMap(); - KConfigGroup parent = cf.group("Parent Group"); - - QVERIFY(!parent.hasGroup(name)); - - QVERIFY(group.entryMap() == originalMap); - - group.reparent(&parent); // see if it can be made a sub-group of another group - QVERIFY(parent.hasGroup(name)); - QCOMPARE(group.entryMap(), originalMap); - - group.reparent(&cf); // see if it can make it a top-level group again -// QVERIFY(!parent.hasGroup(name)); - QCOMPARE(group.entryMap(), originalMap); -} - -static void ageTimeStamp(const QString& path, int nsec) -{ -#ifdef Q_OS_UNIX - QDateTime mtime = QFileInfo(path).lastModified().addSecs(-nsec); - struct utimbuf utbuf; - utbuf.actime = mtime.toTime_t(); - utbuf.modtime = utbuf.actime; - utime(QFile::encodeName(path), &utbuf); -#else - QTest::qSleep(nsec * 1000); -#endif -} - -void KConfigTest::testWriteOnSync() -{ - QDateTime oldStamp, newStamp; - KConfig sc("kconfigtest", KConfig::IncludeGlobals); - - // Age the timestamp of global config file a few sec, and collect it. - QString globFile = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kdeglobals"; - ageTimeStamp(globFile, 2); // age 2 sec - oldStamp = QFileInfo(globFile).lastModified(); - - // Add a local entry and sync the config. - // Should not rewrite the global config file. - KConfigGroup cgLocal(&sc, "Locals"); - cgLocal.writeEntry("someLocalString", "whatever"); - QVERIFY(sc.sync()); - - // Verify that the timestamp of global config file didn't change. - newStamp = QFileInfo(globFile).lastModified(); - QCOMPARE(newStamp, oldStamp); - - // Age the timestamp of local config file a few sec, and collect it. - QString locFile = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kconfigtest"; - ageTimeStamp(locFile, 2); // age 2 sec - oldStamp = QFileInfo(locFile).lastModified(); - - // Add a global entry and sync the config. - // Should not rewrite the local config file. - KConfigGroup cgGlobal(&sc, "Globals"); - cgGlobal.writeEntry("someGlobalString", "whatever", - KConfig::Persistent|KConfig::Global); - QVERIFY(sc.sync()); - - // Verify that the timestamp of local config file didn't change. - newStamp = QFileInfo(locFile).lastModified(); - QCOMPARE(newStamp, oldStamp); -} - -void KConfigTest::testFailOnReadOnlyFileSync() -{ - KConfig sc("kconfigfailonreadonlytest"); - KConfigGroup cgLocal(&sc, "Locals"); - - cgLocal.writeEntry("someLocalString", "whatever"); - QVERIFY(cgLocal.sync()); - - QFile f(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + '/' + sc.name()); - QVERIFY(f.exists()); - QVERIFY(f.setPermissions(QFileDevice::ReadOwner)); - - cgLocal.writeEntry("someLocalString", "whatever2"); - QVERIFY(!cgLocal.sync()); - - QVERIFY(f.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner)); - QVERIFY(f.remove()); -} - -void KConfigTest::testDirtyOnEqual() -{ - QDateTime oldStamp, newStamp; - KConfig sc("kconfigtest"); - - // Initialize value - KConfigGroup cgLocal(&sc, "random"); - cgLocal.writeEntry("theKey", "whatever"); - QVERIFY(sc.sync()); - - // Age the timestamp of local config file a few sec, and collect it. - QString locFile = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kconfigtest"; - ageTimeStamp(locFile, 2); // age 2 sec - oldStamp = QFileInfo(locFile).lastModified(); - - // Write exactly the same again - cgLocal.writeEntry("theKey", "whatever"); - // This should be a no-op - QVERIFY(sc.sync()); - - // Verify that the timestamp of local config file didn't change. - newStamp = QFileInfo(locFile).lastModified(); - QCOMPARE(newStamp, oldStamp); -} - -void KConfigTest::testDirtyOnEqualOverdo() -{ - QByteArray val1("\0""one", 4); - QByteArray val2("\0""two", 4); - QByteArray defvalr; - - KConfig sc("kconfigtest"); - KConfigGroup cgLocal(&sc, "random"); - cgLocal.writeEntry("someKey", val1); - QCOMPARE(cgLocal.readEntry("someKey", defvalr), val1); - cgLocal.writeEntry("someKey", val2); - QCOMPARE(cgLocal.readEntry("someKey", defvalr), val2); -} - - -void KConfigTest::testCreateDir() -{ - // Test auto-creating the parent directory when needed (KConfigIniBackend::createEnclosing) - QString kdehome = QDir::home().canonicalPath() + "/.kde-unit-test"; - QString subdir = kdehome + "/newsubdir"; - QString file = subdir + "/foo.desktop"; - QFile::remove(file); - QDir().rmdir(subdir); - QVERIFY(!QDir().exists(subdir)); - KDesktopFile desktopFile(file); - desktopFile.desktopGroup().writeEntry("key", "value"); - QVERIFY(desktopFile.sync()); - QVERIFY(QFile::exists(file)); - - // Cleanup - QFile::remove(file); - QDir().rmdir(subdir); -} - -void KConfigTest::testSyncOnExit() -{ - // Often, the KGlobalPrivate global static's destructor ends up calling ~KConfig -> - // KConfig::sync ... and if that code triggers KGlobal code again then things could crash. - // So here's a test for modifying KSharedConfig::openConfig() and not syncing, the process exit will sync. - KConfigGroup grp(KSharedConfig::openConfig(), "syncOnExit"); - grp.writeEntry("key", "value"); -} - -void KConfigTest::testSharedConfig() -{ - // Can I use a KConfigGroup even after the KSharedConfigPtr goes out of scope? - KConfigGroup myConfigGroup; - { - KSharedConfigPtr config = KSharedConfig::openConfig("kconfigtest"); - myConfigGroup = KConfigGroup(config, "Hello"); - } - QCOMPARE(myConfigGroup.readEntry("stringEntry1"), QString(STRINGENTRY1)); -} - -void KConfigTest::testLocaleConfig() -{ - // Initialize the testdata - QDir dir; - QString subdir = QDir::home().canonicalPath() + "/.kde-unit-test/"; - dir.mkpath(subdir); - QString file = subdir + "/localized.test"; - QFile::remove(file); - QFile f(file); - QVERIFY(f.open(QIODevice::WriteOnly)); - QTextStream ts(&f); - ts << "[Test_Wrong]\n"; - ts << "foo[ca]=5\n"; - ts << "foostring[ca]=nice\n"; - ts << "foobool[ca]=true\n"; - ts << "[Test_Right]\n"; - ts << "foo=5\n"; - ts << "foo[ca]=5\n"; - ts << "foostring=primary\n"; - ts << "foostring[ca]=nice\n"; - ts << "foobool=primary\n"; - ts << "foobool[ca]=true\n"; - f.close(); - - // Load the testdata - QVERIFY(QFile::exists(file)); - KConfig config(file); - config.setLocale("ca"); - - // This group has only localized values. That is not supported. The values - // should be dropped on loading. - KConfigGroup cg(&config, "Test_Wrong"); - QEXPECT_FAIL("", "The localized values are not dropped", Continue); - QVERIFY(!cg.hasKey("foo")); - QEXPECT_FAIL("", "The localized values are not dropped", Continue); - QVERIFY(!cg.hasKey("foostring")); - QEXPECT_FAIL("", "The localized values are not dropped", Continue); - QVERIFY(!cg.hasKey("foobool")); - - // Now check the correct config group - KConfigGroup cg2(&config, "Test_Right"); - QCOMPARE(cg2.readEntry("foo"), QString("5")); - QCOMPARE(cg2.readEntry("foo", 3), 5); - QCOMPARE(cg2.readEntry("foostring"), QString("nice")); - QCOMPARE(cg2.readEntry("foostring", "ugly"), QString("nice")); - QCOMPARE(cg2.readEntry("foobool"), QString("true")); - QCOMPARE(cg2.readEntry("foobool", false), true); - - // Clean up after the testcase - QFile::remove(file); -} - - -void KConfigTest::testDeleteWhenLocalized() -{ - // Initialize the testdata - QDir dir; - QString subdir = QDir::home().canonicalPath() + "/.kde-unit-test/"; - dir.mkpath(subdir); - QString file = subdir + "/localized_delete.test"; - QFile::remove(file); - QFile f(file); - QVERIFY(f.open(QIODevice::WriteOnly)); - QTextStream ts(&f); - ts << "[Test4711]\n"; - ts << "foo=3\n"; - ts << "foo[ca]=5\n"; - ts << "foo[de]=7\n"; - ts << "foostring=ugly\n"; - ts << "foostring[ca]=nice\n"; - ts << "foostring[de]=schoen\n"; - ts << "foobool=false\n"; - ts << "foobool[ca]=true\n"; - ts << "foobool[de]=true\n"; - f.close(); - - // Load the testdata. We start in locale "ca". - QVERIFY(QFile::exists(file)); - KConfig config(file); - config.setLocale("ca"); - KConfigGroup cg(&config, "Test4711"); - - // Delete a value. Once with localized, once with Normal - cg.deleteEntry("foostring", KConfigBase::Persistent | KConfigBase::Localized); - cg.deleteEntry("foobool"); - QVERIFY(config.sync()); - - // The value is now gone. The others are still there. Everything correct - // here. - QVERIFY(!cg.hasKey("foostring")); - QVERIFY(!cg.hasKey("foobool")); - QVERIFY(cg.hasKey("foo")); - - // The current state is: (Just return before this comment.) - // [...] - // foobool[ca]=true - // foobool[de]=wahr - // foostring=ugly - // foostring[de]=schoen - - // Now switch the locale to "de" and repeat the checks. Results should be - // the same. But they currently are not. The localized value are - // independent of each other. All values are still there in "de". - config.setLocale("de"); - QEXPECT_FAIL("", "Currently localized values are not deleted correctly", Continue); - QVERIFY(!cg.hasKey("foostring")); - QEXPECT_FAIL("", "Currently localized values are not deleted correctly", Continue); - QVERIFY(!cg.hasKey("foobool")); - QVERIFY(cg.hasKey("foo")); - // Check where the wrong values come from. - // We get the "de" value. - QCOMPARE(cg.readEntry("foostring", "nothing"), QString("schoen")); - // We get the "de" value. - QCOMPARE(cg.readEntry("foobool", false), true); - - // Now switch the locale back "ca" and repeat the checks. Results are - // again different. - config.setLocale("ca"); - // This line worked above. But now it fails. - QEXPECT_FAIL("", "Currently localized values are not deleted correctly", Continue); - QVERIFY(!cg.hasKey("foostring")); - // This line worked above too. - QEXPECT_FAIL("", "Currently localized values are not deleted correctly", Continue); - QVERIFY(!cg.hasKey("foobool")); - QVERIFY(cg.hasKey("foo")); - // Check where the wrong values come from. - // We get the primary value because the "ca" value was deleted. - QCOMPARE(cg.readEntry("foostring", "nothing"), QString("ugly")); - // We get the "ca" value. - QCOMPARE(cg.readEntry("foobool", false), true); - - // Now test the deletion of a group. - cg.deleteGroup(); - QVERIFY(config.sync()); - - // Current state: [ca] and [de] entries left... oops. - //qDebug() << readLinesFrom(file); - - // Bug: The group still exists [because of the localized entries]... - QVERIFY(cg.exists()); - QVERIFY(!cg.hasKey("foo")); - QVERIFY(!cg.hasKey("foostring")); - QEXPECT_FAIL("", "Currently localized values are not deleted correctly", Continue); - QVERIFY(!cg.hasKey("foobool")); - - // Now switch the locale to "de" and repeat the checks. All values - // still here because only the primary values are deleted. - config.setLocale("de"); - QEXPECT_FAIL("", "Currently localized values are not deleted correctly", Continue); - QVERIFY(!cg.hasKey("foo")); - QEXPECT_FAIL("", "Currently localized values are not deleted correctly", Continue); - QVERIFY(!cg.hasKey("foostring")); - QEXPECT_FAIL("", "Currently localized values are not deleted correctly", Continue); - QVERIFY(!cg.hasKey("foobool")); - // Check where the wrong values come from. - // We get the "de" value. - QCOMPARE(cg.readEntry("foostring", "nothing"), QString("schoen")); - // We get the "de" value. - QCOMPARE(cg.readEntry("foobool", false), true); - // We get the "de" value. - QCOMPARE(cg.readEntry("foo", 0), 7); - - // Now switch the locale to "ca" and repeat the checks - // "foostring" is now really gone because both the primary value and the - // "ca" value are deleted. - config.setLocale("ca"); - QEXPECT_FAIL("", "Currently localized values are not deleted correctly", Continue); - QVERIFY(!cg.hasKey("foo")); - QVERIFY(!cg.hasKey("foostring")); - QEXPECT_FAIL("", "Currently localized values are not deleted correctly", Continue); - QVERIFY(!cg.hasKey("foobool")); - // Check where the wrong values come from. - // We get the "ca" value. - QCOMPARE(cg.readEntry("foobool", false), true); - // We get the "ca" value. - QCOMPARE(cg.readEntry("foo", 0), 5); - - // Cleanup - QFile::remove(file); -} - - -void KConfigTest::testKdeGlobals() -{ - { - KConfig glob("kdeglobals"); - KConfigGroup general(&glob, "General"); - general.writeEntry("testKG", "1"); - QVERIFY(glob.sync()); - } - - KConfig globRead("kdeglobals"); - const KConfigGroup general(&globRead, "General"); - QCOMPARE(general.readEntry("testKG"), QString("1")); - - // Check we wrote into kdeglobals - const QList<QByteArray> lines = readLines("kdeglobals"); - QVERIFY(lines.contains("[General]\n")); - QVERIFY(lines.contains("testKG=1\n")); - - // Writing using NoGlobals - { - KConfig glob("kdeglobals", KConfig::NoGlobals); - KConfigGroup general(&glob, "General"); - general.writeEntry("testKG", "2"); - QVERIFY(glob.sync()); - } - globRead.reparseConfiguration(); - QCOMPARE(general.readEntry("testKG"), QString("2")); - - // Reading using NoGlobals - { - KConfig globReadNoGlob("kdeglobals", KConfig::NoGlobals); - const KConfigGroup generalNoGlob(&globReadNoGlob, "General"); - QCOMPARE(generalNoGlob.readEntry("testKG"), QString("2")); - } - - // TODO now use kconfigtest and writeEntry(,Global) -> should go into kdeglobals -} - -void KConfigTest::testAnonymousConfig() -{ - KConfig anonConfig(QString(), KConfig::SimpleConfig); - KConfigGroup general(&anonConfig, "General"); - QCOMPARE(general.readEntry("testKG"), QString()); // no kdeglobals merging - general.writeEntry("Foo", "Bar"); - QCOMPARE(general.readEntry("Foo"), QString("Bar")); -} - -#include <QThreadPool> -#include <qtconcurrentrun.h> - -// To find multithreading bugs: valgrind --tool=helgrind --track-lockorders=no ./kconfigtest testThreads -void KConfigTest::testThreads() -{ - QThreadPool::globalInstance()->setMaxThreadCount(6); - QList<QFuture<void> > futures; - // Run in parallel some tests that work on different config files, - // otherwise unexpected things might indeed happen. - futures << QtConcurrent::run(this, &KConfigTest::testAddConfigSources); - futures << QtConcurrent::run(this, &KConfigTest::testSimple); - futures << QtConcurrent::run(this, &KConfigTest::testDefaults); - // QEXPECT_FAIL triggers race conditions, it should be fixed to use QThreadStorage... - //futures << QtConcurrent::run(this, &KConfigTest::testDeleteWhenLocalized); - //futures << QtConcurrent::run(this, &KConfigTest::testEntryMap); - Q_FOREACH(QFuture<void> f, futures) // krazy:exclude=foreach - f.waitForFinished(); -} |