tests/auto/qsettings/tst_qsettings.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <qdebug.h>
       
    44 #include <QtTest/QtTest>
       
    45 
       
    46 #include <QtCore/QSettings>
       
    47 #include <private/qsettings_p.h>
       
    48 //#include <QtGui/QApplication>
       
    49 #include <QtCore/QCoreApplication>
       
    50 #include <QtCore/QtGlobal>
       
    51 #include <QtCore/QMetaType>
       
    52 #include <QtCore/QtDebug>
       
    53 #include <QtCore/QString>
       
    54 
       
    55 #if !defined(Q_OS_SYMBIAN)
       
    56 # include <cctype>
       
    57 #endif
       
    58 #if defined(Q_OS_WIN) && defined(Q_CC_GNU)
       
    59 // need for unlink on mingw
       
    60 #include <io.h>
       
    61 #endif
       
    62 
       
    63 #ifndef QSETTINGS_P_H_VERSION
       
    64 #define QSETTINGS_P_H_VERSION 1
       
    65 #endif
       
    66 
       
    67 //TESTED_FILES=
       
    68 
       
    69 QT_FORWARD_DECLARE_CLASS(QSettings)
       
    70 QT_FORWARD_DECLARE_CLASS(QSettings)
       
    71 
       
    72 class tst_QSettings : public QObject
       
    73 {
       
    74     Q_OBJECT
       
    75 
       
    76 public:
       
    77     tst_QSettings();
       
    78 
       
    79 public slots:
       
    80     void init();
       
    81     void cleanup();
       
    82 private slots:
       
    83     void getSetCheck();
       
    84     void ctor_data();
       
    85     void ctor();
       
    86     void beginGroup();
       
    87     void setValue();
       
    88     void remove();
       
    89     void contains();
       
    90     void sync();
       
    91     void setFallbacksEnabled();
       
    92     void setFallbacksEnabled_data();
       
    93     void fromFile_data();
       
    94     void fromFile();
       
    95     void setIniCodec();
       
    96     void testArrays_data();
       
    97     void testArrays();
       
    98     void testEscapes();
       
    99     void testCompatFunctions();
       
   100     void testCaseSensitivity_data();
       
   101     void testCaseSensitivity();
       
   102     void testErrorHandling_data();
       
   103     void testErrorHandling();
       
   104     void testIniParsing_data();
       
   105     void testIniParsing();
       
   106     void testChildKeysAndGroups_data();
       
   107     void testChildKeysAndGroups();
       
   108     void testUpdateRequestEvent();
       
   109     void testThreadSafety();
       
   110     void testNormalizedKey_data();
       
   111     void testNormalizedKey();
       
   112     void testEmptyData();
       
   113     void testResourceFiles();
       
   114     void fileName();
       
   115     void isWritable_data();
       
   116     void isWritable();
       
   117     void childGroups_data();
       
   118     void childGroups();
       
   119     void childKeys_data();
       
   120     void childKeys();
       
   121     void allKeys_data();
       
   122     void allKeys();
       
   123     void registerFormat();
       
   124     void setPath();
       
   125     void setDefaultFormat();
       
   126     void dontCreateNeedlessPaths();
       
   127 #if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
       
   128     void dontReorderIniKeysNeedlessly();
       
   129 #endif
       
   130 
       
   131     /*
       
   132         These tests were developed for the Qt 3 QSettings class.
       
   133     */
       
   134 #ifdef QT3_SUPPORT
       
   135     void oldWriteEntryIni_data();
       
   136     void oldWriteEntryIni();
       
   137     void oldReadEntryIni_data();
       
   138     void oldReadEntryIni();
       
   139     void oldBeginGroup_data();
       
   140     void oldBeginGroup();
       
   141     void oldEndGroup_data();
       
   142     void oldEndGroup();
       
   143     void oldResetGroup_data();
       
   144     void oldResetGroup();
       
   145     void oldEntryList_data();
       
   146     void oldEntryList();
       
   147     void oldWriteEntry_QString_bool_data();
       
   148     void oldWriteEntry_QString_bool();
       
   149     void oldWriteEntry_QString_double_data();
       
   150     void oldWriteEntry_QString_double();
       
   151     void oldWriteEntry_QString_int_data();
       
   152     void oldWriteEntry_QString_int();
       
   153     void oldWriteEntry_QString_QString_data();
       
   154     void oldWriteEntry_QString_QString();
       
   155     void oldWriteEntry_QString_QStringList_data();
       
   156     void oldWriteEntry_QString_QStringList();
       
   157     void oldWriteEntry_QString_QStringList_QChar_data();
       
   158     void oldWriteEntry_QString_QStringList_QChar();
       
   159     void oldReadListEntry_QString();
       
   160     void oldReadListEntry_QString_QChar();
       
   161     void oldReadEntry();
       
   162     void oldReadNumEntry();
       
   163     void oldReadDoubleEntry();
       
   164     void oldReadBoolEntry();
       
   165     void oldGlobalVersusLocal();
       
   166     void oldRemoveEntry();
       
   167 #endif
       
   168 
       
   169     void testVariantTypes_data();
       
   170     void testVariantTypes();
       
   171     void rainersSyncBugOnMac_data();
       
   172     void rainersSyncBugOnMac();
       
   173     void recursionBug();
       
   174 #ifdef QT3_SUPPORT
       
   175     void setPathBug();
       
   176 #endif
       
   177 
       
   178     void testByteArray_data();
       
   179     void testByteArray();
       
   180 
       
   181 private:
       
   182     void oldWriteEntry_data();
       
   183     void oldReadEntry_data();
       
   184     void oldWriteEntryHelper(QSettings &settings);
       
   185     void oldReadEntryHelper(QSettings &settings);
       
   186 };
       
   187 
       
   188 // Testing get/set functions
       
   189 void tst_QSettings::getSetCheck()
       
   190 {
       
   191     QSettings obj1;
       
   192     // bool QSettings::fallbacksEnabled()
       
   193     // void QSettings::setFallbacksEnabled(bool)
       
   194     obj1.setFallbacksEnabled(false);
       
   195     QCOMPARE(false, obj1.fallbacksEnabled());
       
   196     obj1.setFallbacksEnabled(true);
       
   197     QCOMPARE(true, obj1.fallbacksEnabled());
       
   198 }
       
   199 
       
   200 //using namespace std;
       
   201 
       
   202 //#include <qapplication.h>
       
   203 #include <qcoreapplication.h>
       
   204 #include <qdir.h>
       
   205 #include <qregexp.h>
       
   206 #include <qthread.h>
       
   207 #include <stdlib.h>
       
   208 #ifndef Q_OS_WIN
       
   209 #include <unistd.h>
       
   210 #endif
       
   211 
       
   212 Q_DECLARE_METATYPE(QSettings::Format)
       
   213 
       
   214 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
       
   215 static void removePath(const QString& _path)
       
   216 {
       
   217     QString path = _path;
       
   218     QDir dir(path);
       
   219     if (!dir.exists())
       
   220         return;
       
   221     QStringList entries = dir.entryList();
       
   222     foreach(QString name, entries) {
       
   223         QString absolute = path + name;
       
   224         if (QFileInfo(absolute).isDir())
       
   225             removePath(absolute+"\\");
       
   226         else
       
   227             QFile::remove(absolute);
       
   228     }
       
   229     dir.cdUp();
       
   230     if (path[path.size()-1] == '\\')
       
   231         path = path.left(path.size()-1);
       
   232     dir.rmdir(path.mid(path.lastIndexOf('\\')+1));
       
   233 }
       
   234 #endif
       
   235 
       
   236 static QString settingsPath(const char *path = "")
       
   237 {
       
   238     // Temporary path for files that are specified explictly in the constructor.
       
   239     QString tempPath = QDir::tempPath();
       
   240     if (tempPath.endsWith("/"))
       
   241 	tempPath.truncate(tempPath.size() - 1);
       
   242     return QDir::toNativeSeparators(tempPath + "/tst_QSettings/" + QLatin1String(path));
       
   243 }
       
   244 
       
   245 static bool readCustom1File(QIODevice &device, QSettings::SettingsMap &map)
       
   246 {
       
   247     QDataStream in(&device);
       
   248     quint32 magic;
       
   249     in >> magic;
       
   250     in >> map;
       
   251     return (magic == 0x01010101 && in.status() == QDataStream::Ok);
       
   252 }
       
   253 
       
   254 static bool writeCustom1File(QIODevice &device, const QSettings::SettingsMap &map)
       
   255 {
       
   256     QDataStream out(&device);
       
   257     out << quint32(0x01010101);
       
   258     out << map;
       
   259     return out.status() == QDataStream::Ok;
       
   260 }
       
   261 
       
   262 static bool readCustom2File(QIODevice &device, QSettings::SettingsMap &map)
       
   263 {
       
   264     QDataStream in(&device);
       
   265     quint64 magic;
       
   266     in >> magic;
       
   267     in >> map;
       
   268     return (magic == Q_UINT64_C(0x0202020202020202) && in.status() == QDataStream::Ok);
       
   269 }
       
   270 
       
   271 static bool writeCustom2File(QIODevice &device, const QSettings::SettingsMap &map)
       
   272 {
       
   273     QDataStream out(&device);
       
   274     out << Q_UINT64_C(0x0202020202020202);
       
   275     out << map;
       
   276     return out.status() == QDataStream::Ok;
       
   277 }
       
   278 
       
   279 static bool readCustom3File(QIODevice &device, QSettings::SettingsMap &map)
       
   280 {
       
   281     QTextStream in(&device);
       
   282     QString tag;
       
   283     in >> tag;
       
   284     if (tag == "OK") {
       
   285         map.insert("retval", "OK");
       
   286         return true;
       
   287     } else {
       
   288         return false;
       
   289     }
       
   290 }
       
   291 
       
   292 static bool writeCustom3File(QIODevice &device, const QSettings::SettingsMap &map)
       
   293 {
       
   294     QTextStream out(&device);
       
   295     if (map.value("retval") != "OK")
       
   296         return false;
       
   297 
       
   298     out << "OK";
       
   299     return true;
       
   300 }
       
   301 
       
   302 static void populateWithFormats()
       
   303 {
       
   304     QTest::addColumn<QSettings::Format>("format");
       
   305 
       
   306     QTest::newRow("native") << QSettings::NativeFormat;
       
   307     QTest::newRow("ini") << QSettings::IniFormat;
       
   308     QTest::newRow("custom1") << QSettings::CustomFormat1;
       
   309     QTest::newRow("custom2") << QSettings::CustomFormat2;
       
   310 }
       
   311 
       
   312 tst_QSettings::tst_QSettings()
       
   313 {
       
   314     QSettings::Format custom1 = QSettings::registerFormat("custom1", readCustom1File, writeCustom1File);
       
   315     QSettings::Format custom2 = QSettings::registerFormat("custom2", readCustom2File, writeCustom2File
       
   316 #ifndef QT_QSETTINGS_ALWAYS_CASE_SENSITIVE_AND_FORGET_ORIGINAL_KEY_ORDER
       
   317                                                           , Qt::CaseInsensitive
       
   318 #endif
       
   319                                                           );
       
   320     QVERIFY(custom1 == QSettings::CustomFormat1);
       
   321     QVERIFY(custom2 == QSettings::CustomFormat2);
       
   322 }
       
   323 
       
   324 void tst_QSettings::init()
       
   325 {
       
   326     QSettings::setSystemIniPath(settingsPath("__system__"));
       
   327     QSettings::setUserIniPath(settingsPath("__user__"));
       
   328 
       
   329 #if defined(Q_OS_WIN)
       
   330     QSettings("HKEY_CURRENT_USER\\Software\\software.org", QSettings::NativeFormat).clear();
       
   331     QSettings("HKEY_LOCAL_MACHINE\\Software\\software.org", QSettings::NativeFormat).clear();
       
   332     QSettings("HKEY_CURRENT_USER\\Software\\other.software.org", QSettings::NativeFormat).clear();
       
   333     QSettings("HKEY_LOCAL_MACHINE\\Software\\other.software.org", QSettings::NativeFormat).clear();
       
   334     QSettings("HKEY_CURRENT_USER\\Software\\foo", QSettings::NativeFormat).clear();
       
   335     QSettings("HKEY_CURRENT_USER\\Software\\bar", QSettings::NativeFormat).clear();
       
   336     QSettings("HKEY_CURRENT_USER\\Software\\bat", QSettings::NativeFormat).clear();
       
   337     QSettings("HKEY_CURRENT_USER\\Software\\baz", QSettings::NativeFormat).clear();
       
   338     QSettings("HKEY_LOCAL_MACHINE\\Software\\foo", QSettings::NativeFormat).clear();
       
   339     QSettings("HKEY_LOCAL_MACHINE\\Software\\bar", QSettings::NativeFormat).clear();
       
   340     QSettings("HKEY_LOCAL_MACHINE\\Software\\bat", QSettings::NativeFormat).clear();
       
   341     QSettings("HKEY_LOCAL_MACHINE\\Software\\baz", QSettings::NativeFormat).clear();
       
   342     if (QDir(settingsPath()).exists()) {
       
   343 #if defined(Q_OS_WINCE)
       
   344         removePath(settingsPath());
       
   345 #else
       
   346         if (QSysInfo::windowsVersion() & QSysInfo::WV_NT_based)
       
   347 	    system(QString("rmdir /Q /S %1").arg(settingsPath()).toLatin1());
       
   348 	else
       
   349 	    system(QString("deltree /Y %1").arg(settingsPath()).toLatin1());
       
   350 #endif
       
   351     }
       
   352 #elif defined(Q_OS_DARWIN)
       
   353     QSettings(QSettings::UserScope, "software.org", "KillerAPP").clear();
       
   354     QSettings(QSettings::SystemScope, "software.org", "KillerAPP").clear();
       
   355     QSettings(QSettings::UserScope, "other.software.org", "KillerAPP").clear();
       
   356     QSettings(QSettings::SystemScope, "other.software.org", "KillerAPP").clear();
       
   357     QSettings(QSettings::UserScope, "software.org").clear();
       
   358     QSettings(QSettings::SystemScope, "software.org").clear();
       
   359     QSettings(QSettings::UserScope, "other.software.org").clear();
       
   360     QSettings(QSettings::SystemScope, "other.software.org").clear();
       
   361 #elif defined(Q_OS_SYMBIAN)
       
   362     removePath(settingsPath());
       
   363 #endif
       
   364 
       
   365 #if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
       
   366     system(QString("chmod -R u+rw %1 2> /dev/null").arg(settingsPath()).toLatin1());
       
   367     system(QString("rm -fr %1 2> /dev/null").arg(settingsPath()).toLatin1());
       
   368 #endif
       
   369 
       
   370     QFile::remove("foo");
       
   371 }
       
   372 
       
   373 void tst_QSettings::cleanup()
       
   374 {
       
   375     init();
       
   376 }
       
   377 
       
   378 /*
       
   379     Test the constructors and the assignment operator.
       
   380 */
       
   381 
       
   382 void tst_QSettings::ctor_data()
       
   383 {
       
   384     populateWithFormats();
       
   385 }
       
   386 
       
   387 void tst_QSettings::ctor()
       
   388 {
       
   389     QFETCH(QSettings::Format, format);
       
   390 
       
   391     {
       
   392         QSettings settings1(format, QSettings::UserScope, "software.org", "KillerAPP");
       
   393         QSettings settings2(format, QSettings::UserScope, "software.org");
       
   394         QSettings settings3(format, QSettings::SystemScope, "software.org", "KillerAPP");
       
   395         QSettings settings4(format, QSettings::SystemScope, "software.org");
       
   396 
       
   397         QSettings settings5(format, QSettings::UserScope, "software.org", "KillerAPP");
       
   398         QSettings settings6(format, QSettings::UserScope, "software.org");
       
   399         QSettings settings7(format, QSettings::SystemScope, "software.org", "KillerAPP");
       
   400         QSettings settings8(format, QSettings::SystemScope, "software.org");
       
   401 
       
   402         // test QSettings::format() while we're at it
       
   403         QVERIFY(settings1.format() == format);
       
   404         QVERIFY(settings2.format() == format);
       
   405         QVERIFY(settings3.format() == format);
       
   406         QVERIFY(settings4.format() == format);
       
   407 
       
   408         // test QSettings::scope() while we're at it
       
   409         QVERIFY(settings1.scope() == QSettings::UserScope);
       
   410         QVERIFY(settings2.scope() == QSettings::UserScope);
       
   411         QVERIFY(settings3.scope() == QSettings::SystemScope);
       
   412         QVERIFY(settings4.scope() == QSettings::SystemScope);
       
   413 
       
   414         // test QSettings::organizationName() while we're at it
       
   415         QVERIFY(settings1.organizationName() == "software.org");
       
   416         QVERIFY(settings2.organizationName() == "software.org");
       
   417         QVERIFY(settings3.organizationName() == "software.org");
       
   418         QVERIFY(settings4.organizationName() == "software.org");
       
   419 
       
   420         // test QSettings::applicationName() while we're at it
       
   421         QCOMPARE(settings1.applicationName(), QString("KillerAPP"));
       
   422         QVERIFY(settings2.applicationName().isEmpty());
       
   423         QVERIFY(settings3.applicationName() == "KillerAPP");
       
   424         QVERIFY(settings4.applicationName().isEmpty());
       
   425 
       
   426         /*
       
   427             Go forwards.
       
   428         */
       
   429         settings4.setValue("key 1", QString("doodah"));
       
   430 
       
   431         QCOMPARE(settings1.value("key 1").toString(), QString("doodah"));
       
   432         QCOMPARE(settings2.value("key 1").toString(), QString("doodah"));
       
   433         QCOMPARE(settings3.value("key 1").toString(), QString("doodah"));
       
   434         QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
       
   435 
       
   436         settings3.setValue("key 1", QString("blah"));
       
   437         QCOMPARE(settings1.value("key 1").toString(), QString("blah"));
       
   438         QCOMPARE(settings2.value("key 1").toString(), QString("doodah"));
       
   439         QCOMPARE(settings3.value("key 1").toString(), QString("blah"));
       
   440         QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
       
   441 
       
   442         settings2.setValue("key 1", QString("whoa"));
       
   443         QCOMPARE(settings1.value("key 1").toString(), QString("whoa"));
       
   444         QCOMPARE(settings2.value("key 1").toString(), QString("whoa"));
       
   445         QCOMPARE(settings3.value("key 1").toString(), QString("blah"));
       
   446         QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
       
   447 
       
   448         settings1.setValue("key 1", QString("gurgle"));
       
   449         QCOMPARE(settings1.value("key 1").toString(), QString("gurgle"));
       
   450         QCOMPARE(settings2.value("key 1").toString(), QString("whoa"));
       
   451         QCOMPARE(settings3.value("key 1").toString(), QString("blah"));
       
   452         QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
       
   453 
       
   454         /*
       
   455             Test the copies.
       
   456         */
       
   457         QCOMPARE(settings5.value("key 1").toString(), settings1.value("key 1").toString());
       
   458         QCOMPARE(settings6.value("key 1").toString(), settings2.value("key 1").toString());
       
   459         QCOMPARE(settings7.value("key 1").toString(), settings3.value("key 1").toString());
       
   460         QCOMPARE(settings8.value("key 1").toString(), settings4.value("key 1").toString());
       
   461 
       
   462         /*
       
   463             Go backwards.
       
   464         */
       
   465 
       
   466         settings2.setValue("key 1", QString("bilboh"));
       
   467         QCOMPARE(settings1.value("key 1").toString(), QString("gurgle"));
       
   468         QCOMPARE(settings2.value("key 1").toString(), QString("bilboh"));
       
   469         QCOMPARE(settings3.value("key 1").toString(), QString("blah"));
       
   470         QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
       
   471 
       
   472         settings3.setValue("key 1", QString("catha"));
       
   473         QCOMPARE(settings1.value("key 1").toString(), QString("gurgle"));
       
   474         QCOMPARE(settings2.value("key 1").toString(), QString("bilboh"));
       
   475         QCOMPARE(settings3.value("key 1").toString(), QString("catha"));
       
   476         QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
       
   477 
       
   478         settings4.setValue("key 1", QString("quirko"));
       
   479         QCOMPARE(settings1.value("key 1").toString(), QString("gurgle"));
       
   480         QCOMPARE(settings2.value("key 1").toString(), QString("bilboh"));
       
   481         QCOMPARE(settings3.value("key 1").toString(), QString("catha"));
       
   482         QCOMPARE(settings4.value("key 1").toString(), QString("quirko"));
       
   483 
       
   484         /*
       
   485             Test the copies again.
       
   486         */
       
   487         QCOMPARE(settings5.value("key 1").toString(), settings1.value("key 1").toString());
       
   488         QCOMPARE(settings6.value("key 1").toString(), settings2.value("key 1").toString());
       
   489         QCOMPARE(settings7.value("key 1").toString(), settings3.value("key 1").toString());
       
   490         QCOMPARE(settings8.value("key 1").toString(), settings4.value("key 1").toString());
       
   491 
       
   492         /*
       
   493             "General" is a problem key for .ini files.
       
   494         */
       
   495         settings1.setValue("General", 1);
       
   496         settings1.setValue("%General", 2);
       
   497         settings1.setValue("alpha", 3);
       
   498         settings1.setValue("General/alpha", 4);
       
   499         settings1.setValue("%General/alpha", 5);
       
   500         settings1.setValue("alpha/General", 6);
       
   501         settings1.setValue("alpha/%General", 7);
       
   502         settings1.setValue("General/General", 8);
       
   503         settings1.setValue("General/%General", 9);
       
   504         settings1.setValue("%General/General", 10);
       
   505         settings1.setValue("%General/%General", 11);
       
   506     }
       
   507 
       
   508     {
       
   509         /*
       
   510             Test that the data was stored on disk after all instances
       
   511             of QSettings are destroyed.
       
   512         */
       
   513 
       
   514         QSettings settings1(format, QSettings::UserScope, "software.org", "KillerAPP");
       
   515         QSettings settings2(format, QSettings::UserScope, "software.org");
       
   516         QSettings settings3(format, QSettings::SystemScope, "software.org", "KillerAPP");
       
   517         QSettings settings4(format, QSettings::SystemScope, "software.org");
       
   518 
       
   519         QCOMPARE(settings1.value("key 1").toString(), QString("gurgle"));
       
   520         QCOMPARE(settings2.value("key 1").toString(), QString("bilboh"));
       
   521         QCOMPARE(settings3.value("key 1").toString(), QString("catha"));
       
   522         QCOMPARE(settings4.value("key 1").toString(), QString("quirko"));
       
   523 
       
   524         /*
       
   525             Test problem keys.
       
   526         */
       
   527 
       
   528         QCOMPARE(settings1.value("General").toInt(), 1);
       
   529         QCOMPARE(settings1.value("%General").toInt(), 2);
       
   530         QCOMPARE(settings1.value("alpha").toInt(), 3);
       
   531         QCOMPARE(settings1.value("General/alpha").toInt(), 4);
       
   532         QCOMPARE(settings1.value("%General/alpha").toInt(), 5);
       
   533         QCOMPARE(settings1.value("alpha/General").toInt(), 6);
       
   534         QCOMPARE(settings1.value("alpha/%General").toInt(), 7);
       
   535         QCOMPARE(settings1.value("General/General").toInt(), 8);
       
   536         QCOMPARE(settings1.value("General/%General").toInt(), 9);
       
   537         QCOMPARE(settings1.value("%General/General").toInt(), 10);
       
   538         QCOMPARE(settings1.value("%General/%General").toInt(), 11);
       
   539 
       
   540         /*
       
   541             Test that the organization and product parameters is
       
   542             case-insensitive on Windows and Mac, case-sensitive on
       
   543             Unix.
       
   544         */
       
   545         QSettings settings5(format, QSettings::UserScope, "SoftWare.ORG", "killerApp");
       
   546         if (format == QSettings::NativeFormat) {
       
   547 #if defined(Q_OS_WIN) || defined(Q_OS_DARWIN) || defined(Q_OS_SYMBIAN)
       
   548             QCOMPARE(settings5.value("key 1").toString(), QString("gurgle"));
       
   549 #else
       
   550             QVERIFY(!settings5.contains("key 1"));
       
   551 #endif
       
   552         } else {
       
   553 #if defined(Q_OS_WIN) || defined(Q_OS_DARWIN) || defined(Q_OS_SYMBIAN)
       
   554             QCOMPARE(settings5.value("key 1").toString(), QString("gurgle"));
       
   555 #else
       
   556             QVERIFY(!settings5.contains("key 1"));
       
   557 #endif
       
   558         }
       
   559     }
       
   560 
       
   561     {
       
   562         QSettings settings1(settingsPath("custom/custom.conf"), QSettings::IniFormat);
       
   563         settings1.beginGroup("alpha/beta");
       
   564         settings1.setValue("geometry", -7);
       
   565         settings1.setValue("geometry/x", 1);
       
   566         settings1.setValue("geometry/y", 2);
       
   567         QSettings settings2(settingsPath("custom/custom.conf"), QSettings::IniFormat);
       
   568         settings1.setValue("geometry/width", 3);
       
   569         settings2.setValue("alpha/beta/geometry/height", 4);
       
   570         settings2.setValue("alpha/gamma/splitter", 5);
       
   571         settings1.endGroup();
       
   572 
       
   573         // test QSettings::scope() while we're at it
       
   574         QVERIFY(settings1.scope() == QSettings::UserScope);
       
   575 
       
   576         // test QSettings::organizationName() while we're at it
       
   577         QVERIFY(settings1.organizationName().isEmpty());
       
   578 
       
   579         // test QSettings::applicationName() while we're at it
       
   580         QVERIFY(settings1.organizationName().isEmpty());
       
   581 
       
   582         QSettings settings3(settingsPath("custom/custom2.conf"), QSettings::IniFormat);
       
   583         settings3.beginGroup("doodley/beta");
       
   584         settings3.setValue("geometry", -7);
       
   585         settings3.setValue("geometry/x", 1);
       
   586         settings3.setValue("geometry/y", 2);
       
   587         settings3.setValue("geometry/width", 3);
       
   588         settings3.setValue("geometry/height", 4);
       
   589         settings3.endGroup();
       
   590         settings3.setValue("alpha/gamma/splitter", 5);
       
   591 
       
   592         QCOMPARE(settings1.value("alpha/beta/geometry").toInt(), -7);
       
   593         QCOMPARE(settings1.value("alpha/beta/geometry/x").toInt(), 1);
       
   594         QCOMPARE(settings1.value("alpha/beta/geometry/y").toInt(), 2);
       
   595         QCOMPARE(settings1.value("alpha/beta/geometry/width").toInt(), 3);
       
   596         QCOMPARE(settings1.value("alpha/beta/geometry/height").toInt(), 4);
       
   597         QCOMPARE(settings1.value("alpha/gamma/splitter").toInt(), 5);
       
   598         QCOMPARE(settings1.allKeys().count(), 6);
       
   599 
       
   600         QCOMPARE(settings2.value("alpha/beta/geometry").toInt(), -7);
       
   601         QCOMPARE(settings2.value("alpha/beta/geometry/x").toInt(), 1);
       
   602         QCOMPARE(settings2.value("alpha/beta/geometry/y").toInt(), 2);
       
   603         QCOMPARE(settings2.value("alpha/beta/geometry/width").toInt(), 3);
       
   604         QCOMPARE(settings2.value("alpha/beta/geometry/height").toInt(), 4);
       
   605         QCOMPARE(settings2.value("alpha/gamma/splitter").toInt(), 5);
       
   606         QCOMPARE(settings2.allKeys().count(), 6);
       
   607     }
       
   608 
       
   609     {
       
   610         QSettings settings1(settingsPath("custom/custom.conf"), QSettings::IniFormat);
       
   611         QCOMPARE(settings1.value("alpha/beta/geometry").toInt(), -7);
       
   612         QCOMPARE(settings1.value("alpha/beta/geometry/x").toInt(), 1);
       
   613         QCOMPARE(settings1.value("alpha/beta/geometry/y").toInt(), 2);
       
   614         QCOMPARE(settings1.value("alpha/beta/geometry/width").toInt(), 3);
       
   615         QCOMPARE(settings1.value("alpha/beta/geometry/height").toInt(), 4);
       
   616         QCOMPARE(settings1.value("alpha/gamma/splitter").toInt(), 5);
       
   617         QCOMPARE(settings1.allKeys().count(), 6);
       
   618     }
       
   619 
       
   620     {
       
   621         // QSettings's default constructor is native by default
       
   622         if (format == QSettings::NativeFormat) {
       
   623             QCoreApplication::instance()->setOrganizationName("");
       
   624             QCoreApplication::instance()->setApplicationName("");
       
   625             QSettings settings;
       
   626             QCOMPARE(settings.status(), QSettings::AccessError);
       
   627             QCoreApplication::instance()->setOrganizationName("software.org");
       
   628             QCoreApplication::instance()->setApplicationName("KillerAPP");
       
   629             QSettings settings2;
       
   630             QCOMPARE(settings2.status(), QSettings::NoError);
       
   631             QSettings settings3("software.org", "KillerAPP");
       
   632             QCOMPARE(settings2.fileName(), settings3.fileName());
       
   633             QCoreApplication::instance()->setOrganizationName("");
       
   634             QCoreApplication::instance()->setApplicationName("");
       
   635         }
       
   636 
       
   637         QSettings settings(format, QSettings::UserScope, "", "");
       
   638         QCOMPARE(settings.status(), QSettings::AccessError);
       
   639         QSettings settings2(format, QSettings::UserScope, "software.org", "KillerAPP");
       
   640         QCOMPARE(settings2.status(), QSettings::NoError);
       
   641 
       
   642         // test QSettings::format() while we're at it
       
   643         QVERIFY(settings.format() == format);
       
   644         QVERIFY(settings2.format() == format);
       
   645 
       
   646         // test QSettings::scope() while we're at it
       
   647         QVERIFY(settings.scope() == QSettings::UserScope);
       
   648         QVERIFY(settings2.scope() == QSettings::UserScope);
       
   649 
       
   650         // test QSettings::organizationName() while we're at it
       
   651         QVERIFY(settings.organizationName().isEmpty());
       
   652         QVERIFY(settings2.organizationName() == "software.org");
       
   653 
       
   654         // test QSettings::applicationName() while we're at it
       
   655         QVERIFY(settings.applicationName().isEmpty());
       
   656         QVERIFY(settings2.applicationName() == "KillerAPP");
       
   657     }
       
   658 }
       
   659 
       
   660 void tst_QSettings::testByteArray_data()
       
   661 {
       
   662     QTest::addColumn<QByteArray>("data");
       
   663 
       
   664     QByteArray bytes("Hello world!");
       
   665 
       
   666     QTest::newRow("latin1") << bytes;
       
   667 #ifndef QT_NO_COMPRESS
       
   668     QTest::newRow("compressed") << qCompress(bytes);
       
   669 #endif
       
   670     QTest::newRow("with \\0") << bytes + '\0' + bytes;
       
   671 }
       
   672 
       
   673 void tst_QSettings::testByteArray()
       
   674 {
       
   675     QFETCH(QByteArray, data);
       
   676 
       
   677     // write
       
   678     {
       
   679         QSettings settings("Trolltech", "tst_qsettings");
       
   680         settings.setValue("byteArray", data);
       
   681     }
       
   682     // read
       
   683     {
       
   684         QSettings settings("Trolltech", "tst_qsettings");
       
   685         QByteArray ret = settings.value("byteArray", data).toByteArray();
       
   686         QCOMPARE(ret, data);
       
   687     }
       
   688 }
       
   689 
       
   690 void tst_QSettings::testErrorHandling_data()
       
   691 {
       
   692     QTest::addColumn<int>("filePerms"); // -1 means file should not exist
       
   693     QTest::addColumn<int>("dirPerms");
       
   694     QTest::addColumn<int>("statusAfterCtor");
       
   695     QTest::addColumn<bool>("shouldBeEmpty");
       
   696     QTest::addColumn<int>("statusAfterGet");
       
   697     QTest::addColumn<int>("statusAfterSetAndSync");
       
   698 
       
   699     //                         file    dir     afterCtor                      empty     afterGet                      afterSetAndSync
       
   700     QTest::newRow("0600 0700") << 0600 << 0700 << (int)QSettings::NoError     << false << (int)QSettings::NoError     << (int)QSettings::NoError;
       
   701 
       
   702     QTest::newRow("0400 0700") << 0400 << 0700 << (int)QSettings::NoError
       
   703         << false << (int)QSettings::NoError     << (int)QSettings::AccessError;
       
   704     QTest::newRow("0200 0700") << 0200 << 0700 << (int)QSettings::AccessError
       
   705         << true  << (int)QSettings::AccessError << (int)QSettings::AccessError;
       
   706 
       
   707     QTest::newRow("  -1 0700") <<   -1 << 0700 << (int)QSettings::NoError     << true  << (int)QSettings::NoError     << (int)QSettings::NoError;
       
   708 
       
   709     QTest::newRow("  -1 0000") <<   -1 << 0000 << (int)QSettings::NoError     << true  << (int)QSettings::NoError     << (int)QSettings::AccessError;
       
   710     QTest::newRow("  -1 0100") <<   -1 << 0100 << (int)QSettings::NoError     << true  << (int)QSettings::NoError     << (int)QSettings::AccessError;
       
   711     QTest::newRow("0600 0100") << 0600 << 0100 << (int)QSettings::NoError     << false << (int)QSettings::NoError     << (int)QSettings::NoError;
       
   712     QTest::newRow("  -1 0300") <<   -1 << 0300 << (int)QSettings::NoError     << true  << (int)QSettings::NoError     << (int)QSettings::NoError;
       
   713     QTest::newRow("0600 0300") << 0600 << 0300 << (int)QSettings::NoError     << false << (int)QSettings::NoError     << (int)QSettings::NoError;
       
   714     QTest::newRow("  -1 0500") <<   -1 << 0500 << (int)QSettings::NoError     << true  << (int)QSettings::NoError     << (int)QSettings::AccessError;
       
   715     QTest::newRow("0600 0500") << 0600 << 0500 << (int)QSettings::NoError     << false << (int)QSettings::NoError     << (int)QSettings::NoError;
       
   716 }
       
   717 
       
   718 void tst_QSettings::testErrorHandling()
       
   719 {
       
   720 #ifdef QT_BUILD_INTERNAL
       
   721 #ifdef Q_OS_WIN
       
   722     QSKIP("Windows doesn't support most file modes, including read-only directories, so this test is moot.", SkipAll);
       
   723 #elif defined(Q_OS_SYMBIAN)
       
   724     QSKIP("Symbian/Open C doesn't support execute or write only file modes, or directory permissions, so this test is mostly moot.", SkipAll);
       
   725 #elif defined(Q_OS_UNIX)
       
   726     if (::getuid() == 0)
       
   727         QSKIP("Running this test as root doesn't work, since file perms do not bother him", SkipAll);
       
   728 #else
       
   729     QFETCH(int, filePerms);
       
   730     QFETCH(int, dirPerms);
       
   731     QFETCH(int, statusAfterCtor);
       
   732     QFETCH(bool, shouldBeEmpty);
       
   733     QFETCH(int, statusAfterGet);
       
   734     QFETCH(int, statusAfterSetAndSync);
       
   735 
       
   736     system(QString("chmod 700 %1 2>/dev/null").arg(settingsPath("someDir")).toLatin1());
       
   737     system(QString("chmod -R u+rwx %1 2>/dev/null").arg(settingsPath("someDir")).toLatin1());
       
   738     system(QString("rm -fr %1").arg(settingsPath("someDir")).toLatin1());
       
   739 
       
   740     // prepare a file with some settings
       
   741     if (filePerms != -1) {
       
   742         QSettings settings(settingsPath("someDir/someSettings.ini"), QSettings::IniFormat);
       
   743         QCOMPARE((int) settings.status(), (int) QSettings::NoError);
       
   744 
       
   745         settings.beginGroup("alpha/beta");
       
   746         settings.setValue("geometry", -7);
       
   747         settings.setValue("geometry/x", 1);
       
   748         settings.setValue("geometry/y", 2);
       
   749         settings.setValue("geometry/width", 3);
       
   750         settings.setValue("geometry/height", 4);
       
   751         settings.endGroup();
       
   752         settings.setValue("alpha/gamma/splitter", 5);
       
   753     } else {
       
   754         system(QString("mkdir -p %1").arg(settingsPath("someDir")).toLatin1());
       
   755     }
       
   756 
       
   757     if (filePerms != -1) {
       
   758         system(QString("chmod %1 %2")
       
   759                     .arg(QString::number(filePerms, 8))
       
   760                     .arg(settingsPath("someDir/someSettings.ini"))
       
   761                     .toLatin1());
       
   762     }
       
   763     system(QString("chmod %1 %2")
       
   764                 .arg(QString::number(dirPerms, 8))
       
   765                 .arg(settingsPath("someDir"))
       
   766                 .toLatin1());
       
   767 
       
   768     // the test
       
   769     {
       
   770         QConfFile::clearCache();
       
   771         QSettings settings(settingsPath("someDir/someSettings.ini"), QSettings::IniFormat);
       
   772         QCOMPARE((int)settings.status(), statusAfterCtor);
       
   773         if (shouldBeEmpty) {
       
   774             QCOMPARE(settings.allKeys().count(), 0);
       
   775         } else {
       
   776             QVERIFY(settings.allKeys().count() > 0);
       
   777         }
       
   778         settings.value("alpha/beta/geometry");
       
   779         QCOMPARE((int)settings.status(), statusAfterGet);
       
   780         settings.setValue("alpha/beta/geometry", 100);
       
   781         QCOMPARE((int)settings.status(), statusAfterGet);
       
   782         QCOMPARE(settings.value("alpha/beta/geometry").toInt(), 100);
       
   783         settings.sync();
       
   784         QCOMPARE(settings.value("alpha/beta/geometry").toInt(), 100);
       
   785         QCOMPARE((int)settings.status(), statusAfterSetAndSync);
       
   786     }
       
   787 #endif // !Q_OS_WIN
       
   788 #endif
       
   789 }
       
   790 
       
   791 Q_DECLARE_METATYPE(QVariant)
       
   792 Q_DECLARE_METATYPE(QSettings::Status)
       
   793 
       
   794 void tst_QSettings::testIniParsing_data()
       
   795 {
       
   796     QTest::addColumn<QByteArray>("inicontent");
       
   797     QTest::addColumn<QString>("key");
       
   798     QTest::addColumn<QVariant>("expect");
       
   799     QTest::addColumn<QSettings::Status>("status");
       
   800 
       
   801     // Test "forgiving" parsing of entries not terminated with newline or unterminated strings
       
   802     QTest::newRow("good1")    << QByteArray("v=1\n")          << "v" << QVariant(1) << QSettings::NoError;
       
   803     QTest::newRow("good2")    << QByteArray("v=1\\\n2")       << "v" << QVariant(12) << QSettings::NoError;
       
   804     QTest::newRow("good3")    << QByteArray("v=1\\\r2")       << "v" << QVariant(12) << QSettings::NoError;
       
   805     QTest::newRow("good4")    << QByteArray("v=1\\\n\r2")     << "v" << QVariant(12) << QSettings::NoError;
       
   806     QTest::newRow("good5")    << QByteArray("v=1\\\r\n2")     << "v" << QVariant(12) << QSettings::NoError;
       
   807     QTest::newRow("good6")    << QByteArray("v  \t = \t 1\\\r\n2")     << "v" << QVariant(12) << QSettings::NoError;
       
   808     QTest::newRow("garbage1") << QByteArray("v")              << "v" << QVariant() << QSettings::FormatError;
       
   809     QTest::newRow("nonterm1") << QByteArray("v=str")          << "v" << QVariant("str") << QSettings::NoError;
       
   810     QTest::newRow("nonterm2") << QByteArray("v=\"str\"")      << "v" << QVariant("str") << QSettings::NoError;
       
   811     QTest::newRow("nonterm3") << QByteArray("v=\"str")        << "v" << QVariant("str") << QSettings::NoError;
       
   812     QTest::newRow("nonterm4") << QByteArray("v=\\")           << "v" << QVariant("") << QSettings::NoError;
       
   813     QTest::newRow("nonterm5") << QByteArray("u=s\nv=\"str")   << "v" << QVariant("str") << QSettings::NoError;
       
   814     QTest::newRow("nonterm6") << QByteArray("v=\"str\nw=ok")  << "v" << QVariant("str\nw=ok") << QSettings::NoError;
       
   815     QTest::newRow("nonterm7") << QByteArray("v=")             << "v" << QVariant("") << QSettings::NoError;
       
   816     QTest::newRow("nonterm8") << QByteArray("v=\"str\njnk")   << "v" << QVariant("str\njnk") << QSettings::NoError;
       
   817     QTest::newRow("nonterm9") << QByteArray("v=1\\")          << "v" << QVariant(1) << QSettings::NoError;
       
   818     QTest::newRow("nonterm10") << QByteArray("v=1\\\n")       << "v" << QVariant(1) << QSettings::NoError;
       
   819     QTest::newRow("nonterm11") << QByteArray("v=1\\\r")       << "v" << QVariant(1) << QSettings::NoError;
       
   820     QTest::newRow("nonterm12") << QByteArray("v=1\\\n\r")     << "v" << QVariant(1) << QSettings::NoError;
       
   821     QTest::newRow("nonterm13") << QByteArray("v=1\\\r\n")     << "v" << QVariant(1) << QSettings::NoError;
       
   822     QTest::newRow("nonterm14") << QByteArray("v=1\\\n\nx=2")  << "v" << QVariant(1) << QSettings::NoError;
       
   823     QTest::newRow("nonterm15") << QByteArray("v=1\\\r\rx=2")  << "v" << QVariant(1) << QSettings::NoError;
       
   824     QTest::newRow("nonterm16") << QByteArray("v=1\\\n\n\nx=2") << "v" << QVariant(1) << QSettings::NoError;
       
   825     QTest::newRow("nonterm17") << QByteArray("; foo\nv=1") << "v" << QVariant(1) << QSettings::NoError;
       
   826     QTest::newRow("nonterm18") << QByteArray("; foo\n\nv=1") << "v" << QVariant(1) << QSettings::NoError;
       
   827     QTest::newRow("nonterm19") << QByteArray("\nv=1;foo") << "v" << QVariant(1) << QSettings::NoError;
       
   828     QTest::newRow("nonterm20") << QByteArray("v=x ") << "v" << QVariant("x") << QSettings::NoError;
       
   829     QTest::newRow("nonterm21") << QByteArray("v=x ;") << "v" << QVariant("x") << QSettings::NoError;
       
   830 }
       
   831 
       
   832 void tst_QSettings::testIniParsing()
       
   833 {
       
   834 #ifdef QT_BUILD_INTERNAL
       
   835     qRegisterMetaType<QVariant>("QVariant");
       
   836     qRegisterMetaType<QSettings::Status>("QSettings::Status");
       
   837 
       
   838     QDir dir(settingsPath());
       
   839     QVERIFY(dir.mkpath("someDir"));
       
   840     QFile f(dir.path()+"/someDir/someSettings.ini");
       
   841 
       
   842     QFETCH(QByteArray, inicontent);
       
   843     QFETCH(QString, key);
       
   844     QFETCH(QVariant, expect);
       
   845     QFETCH(QSettings::Status, status);
       
   846 
       
   847     QVERIFY(f.open(QFile::WriteOnly));
       
   848     f.write(inicontent);
       
   849     f.close();
       
   850 
       
   851     QConfFile::clearCache();
       
   852     QSettings settings(settingsPath("someDir/someSettings.ini"), QSettings::IniFormat);
       
   853 
       
   854     if ( settings.status() == QSettings::NoError ) { // else no point proceeding
       
   855 	QVariant v = settings.value(key);
       
   856 	QVERIFY(v.canConvert(expect.type()));
       
   857 	// check some types so as to give prettier error messages
       
   858 	if ( v.type() == QVariant::String ) {
       
   859 	    QCOMPARE(v.toString(), expect.toString());
       
   860 	} else if ( v.type() == QVariant::Int ) {
       
   861 	    QCOMPARE(v.toInt(), expect.toInt());
       
   862 	} else {
       
   863 	    QCOMPARE(v, expect);
       
   864 	}
       
   865     }
       
   866 
       
   867     QCOMPARE(settings.status(), status);
       
   868 #endif
       
   869 }
       
   870 
       
   871 /*
       
   872     Tests beginGroup(), endGroup(), and group().
       
   873 */
       
   874 void tst_QSettings::beginGroup()
       
   875 {
       
   876     QSettings settings1(QSettings::UserScope, "software.org", "KillerAPP");
       
   877     QSettings settings2(QSettings::UserScope, "software.org", "KillerAPP");
       
   878 
       
   879     /*
       
   880       Let's start with some back and forthing.
       
   881     */
       
   882 
       
   883     settings1.beginGroup("alpha");
       
   884     QCOMPARE(settings1.group(), QString("alpha"));
       
   885     settings1.endGroup();
       
   886     QCOMPARE(settings1.group(), QString());
       
   887     settings1.beginGroup("/beta");
       
   888     QCOMPARE(settings1.group(), QString("beta"));
       
   889     settings1.endGroup();
       
   890     QCOMPARE(settings1.group(), QString());
       
   891 
       
   892     settings1.beginGroup("///gamma//");
       
   893     QCOMPARE(settings1.group(), QString("gamma"));
       
   894     settings1.endGroup();
       
   895     QCOMPARE(settings1.group(), QString());
       
   896 
       
   897     settings1.setValue("geometry", 5);
       
   898     QCOMPARE(settings1.value("geometry").toInt(), 5);
       
   899     QCOMPARE(settings1.value("/geometry///").toInt(), 5);
       
   900     QCOMPARE(settings2.value("geometry").toInt(), 5);
       
   901     QCOMPARE(settings2.value("/geometry///").toInt(), 5);
       
   902 
       
   903     /*
       
   904       OK, now start for real.
       
   905     */
       
   906 
       
   907     settings1.beginGroup("alpha");
       
   908     QCOMPARE(settings1.group(), QString("alpha"));
       
   909     settings1.setValue("geometry", 66);
       
   910     QCOMPARE(settings1.value("geometry").toInt(), 66);
       
   911     QCOMPARE(settings2.value("geometry").toInt(), 5);
       
   912     QCOMPARE(settings2.value("alpha/geometry").toInt(), 66);
       
   913 
       
   914     QSettings settings3(QSettings::UserScope, "software.org", "KillerAPP");
       
   915     settings3.beginGroup("alpha");
       
   916     QCOMPARE(settings3.value("geometry").toInt(), 66);
       
   917 
       
   918     settings1.beginGroup("/beta///");
       
   919     QCOMPARE(settings1.group(), QString("alpha/beta"));
       
   920     settings1.setValue("geometry", 777);
       
   921     QCOMPARE(settings1.value("geometry").toInt(), 777);
       
   922     QCOMPARE(settings2.value("geometry").toInt(), 5);
       
   923     QCOMPARE(settings2.value("alpha/geometry").toInt(), 66);
       
   924     QCOMPARE(settings2.value("alpha/beta/geometry").toInt(), 777);
       
   925     QCOMPARE(settings3.value("geometry").toInt(), 66);
       
   926     QCOMPARE(settings3.value("beta/geometry").toInt(), 777);
       
   927 
       
   928     settings3.beginGroup("gamma");
       
   929     settings3.setValue("geometry", 8888);
       
   930     QCOMPARE(settings3.value("geometry").toInt(), 8888);
       
   931     QCOMPARE(settings2.value("geometry").toInt(), 5);
       
   932     QCOMPARE(settings2.value("alpha/geometry").toInt(), 66);
       
   933     QCOMPARE(settings2.value("alpha/beta/geometry").toInt(), 777);
       
   934     QCOMPARE(settings2.value("alpha/gamma/geometry").toInt(), 8888);
       
   935     QCOMPARE(settings1.value("geometry").toInt(), 777);
       
   936 
       
   937     // endGroup() should do nothing if group() is empty
       
   938     for (int i = 0; i < 10; ++i)
       
   939         settings2.endGroup();
       
   940     QCOMPARE(settings2.value("geometry").toInt(), 5);
       
   941     QCOMPARE(settings2.value("alpha/geometry").toInt(), 66);
       
   942     QCOMPARE(settings2.value("alpha/beta/geometry").toInt(), 777);
       
   943     QCOMPARE(settings2.value("alpha/gamma/geometry").toInt(), 8888);
       
   944 
       
   945     QCOMPARE(settings1.group(), QString("alpha/beta"));
       
   946     settings1.endGroup();
       
   947     QCOMPARE(settings1.group(), QString("alpha"));
       
   948     settings1.endGroup();
       
   949     QCOMPARE(settings1.group(), QString());
       
   950     QCOMPARE(settings1.value("geometry").toInt(), 5);
       
   951     QCOMPARE(settings1.value("alpha/geometry").toInt(), 66);
       
   952     QCOMPARE(settings1.value("alpha/beta/geometry").toInt(), 777);
       
   953     QCOMPARE(settings1.value("alpha/gamma/geometry").toInt(), 8888);
       
   954 
       
   955     settings1.beginGroup("delta");
       
   956     QCOMPARE(settings1.group(), QString("delta"));
       
   957     settings1.beginGroup("");
       
   958     QCOMPARE(settings1.group(), QString("delta"));
       
   959     settings1.beginGroup("/");
       
   960     QCOMPARE(settings1.group(), QString("delta"));
       
   961     settings1.beginGroup("////");
       
   962     QCOMPARE(settings1.group(), QString("delta"));
       
   963     settings1.beginGroup("////omega///epsilon zeta eta  theta/ / /");
       
   964     QCOMPARE(settings1.group(), QString("delta/omega/epsilon zeta eta  theta/ / "));
       
   965     settings1.endGroup();
       
   966     QCOMPARE(settings1.group(), QString("delta"));
       
   967     settings1.endGroup();
       
   968     QCOMPARE(settings1.group(), QString("delta"));
       
   969     settings1.endGroup();
       
   970     QCOMPARE(settings1.group(), QString("delta"));
       
   971     settings1.endGroup();
       
   972     QCOMPARE(settings1.group(), QString("delta"));
       
   973     settings1.endGroup();
       
   974     QCOMPARE(settings1.group(), QString());
       
   975 }
       
   976 
       
   977 /*
       
   978     Tests setValue() and getXxx().
       
   979 */
       
   980 void tst_QSettings::setValue()
       
   981 {
       
   982     QSettings settings(QSettings::UserScope, "software.org", "KillerAPP");
       
   983 
       
   984     settings.setValue("key 2", (int)0x7fffffff);
       
   985     QCOMPARE(settings.value("key 2").toInt(), (int)0x7fffffff);
       
   986     QCOMPARE(settings.value("key 2").toString(), QString::number((int)0x7fffffff));
       
   987     settings.setValue("key 2", -1);
       
   988     QCOMPARE(settings.value("key 2").toInt(), -1);
       
   989     QCOMPARE(settings.value("key 2").toString(), QString("-1"));
       
   990     settings.setValue("key 2", (int)0x80000000);
       
   991     QCOMPARE(settings.value("key 2").toInt(), (int)0x80000000);
       
   992     settings.setValue("key 2", (int)0);
       
   993     QCOMPARE(settings.value("key 2", 123).toInt(), (int)0);
       
   994     settings.setValue("key 2", (int)12345);
       
   995     QCOMPARE(settings.value("key 2").toInt(), (int)12345);
       
   996     QCOMPARE(settings.value("no such key", 1234).toInt(), (int)1234);
       
   997     QCOMPARE(settings.value("no such key").toInt(), (int)0);
       
   998 
       
   999     settings.setValue("key 2", true);
       
  1000     QCOMPARE(settings.value("key 2").toBool(), true);
       
  1001     settings.setValue("key 2", false);
       
  1002     QCOMPARE(settings.value("key 2", true).toBool(), false);
       
  1003     settings.setValue("key 2", (int)1);
       
  1004     QCOMPARE(settings.value("key 2").toBool(), true);
       
  1005     settings.setValue("key 2", (int)-1);
       
  1006     QCOMPARE(settings.value("key 2").toBool(), true);
       
  1007     settings.setValue("key 2", (int)0);
       
  1008     QCOMPARE(settings.value("key 2", true).toBool(), false);
       
  1009     settings.setValue("key 2", QString("true"));
       
  1010     QCOMPARE(settings.value("key 2").toBool(), true);
       
  1011     settings.setValue("key 2", QString("false"));
       
  1012     QCOMPARE(settings.value("key 2", true).toBool(), false);
       
  1013 /*
       
  1014     settings.setValue("key 2", "true");
       
  1015     QCOMPARE(settings.value("key 2").toBool(), true);
       
  1016     settings.setValue("key 2", "false");
       
  1017     QCOMPARE(settings.value("key 2", true).toBool(), false);
       
  1018     settings.setValue("key 2", "");
       
  1019     QCOMPARE(settings.value("key 2", true).toBool(), true);
       
  1020     settings.setValue("key 2", "");
       
  1021     QCOMPARE(settings.value("key 2", false).toBool(), false);
       
  1022     settings.setValue("key 2", "0.000e-00"); // cannot convert double to a bool
       
  1023     QCOMPARE(settings.value("key 2", true).toBool(), true);
       
  1024     settings.setValue("key 2", "0.000e-00");
       
  1025     QCOMPARE(settings.value("key 2", false).toBool(), false);
       
  1026 
       
  1027 */
       
  1028     settings.setValue("key 2", QStringList());
       
  1029     QCOMPARE(settings.value("key 2").toStringList(), QStringList());
       
  1030     settings.setValue("key 2", QStringList(""));
       
  1031     QCOMPARE(settings.value("key 2").toStringList(), QStringList(""));
       
  1032     settings.setValue("key 2", QStringList() << "" << "");
       
  1033     QCOMPARE(settings.value("key 2").toStringList(), QStringList() << "" << "");
       
  1034     settings.setValue("key 2", QStringList() << "" << "a" << "" << "bc" << "");
       
  1035     QCOMPARE(settings.value("key 2").toStringList(), QStringList() << "" << "a" << "" << "bc" << "");
       
  1036 
       
  1037     settings.setValue("key 3", QList<QVariant>());
       
  1038     QCOMPARE(settings.value("key 3").toList(), QList<QVariant>());
       
  1039     settings.setValue("key 3", QList<QVariant>() << 1 << QString("a"));
       
  1040     QCOMPARE(settings.value("key 3").toList(), QList<QVariant>() << 1 << QString("a"));
       
  1041 
       
  1042     QList<QVariant> outerList;
       
  1043     outerList << 1 << QString("b");
       
  1044     QList<QVariant> innerList = outerList;
       
  1045     outerList.append(QVariant(innerList));
       
  1046     outerList.append(QVariant(innerList));
       
  1047     outerList << 2 << QString("c");
       
  1048     innerList = outerList;
       
  1049     outerList.append(QVariant(innerList));
       
  1050     // outerList: [1, "b", [1, "b"], [1, "b"], 2, "c", [1, "b", [1, "b"], [1, "b"], 2, "c"]]
       
  1051 
       
  1052     settings.setValue("key 3", outerList);
       
  1053     QCOMPARE(settings.value("key 3").toList(), outerList);
       
  1054     QCOMPARE(settings.value("key 3").toList().size(), 7);
       
  1055 
       
  1056     QMap<QString, QVariant> map;
       
  1057     map.insert("1", "one");
       
  1058     map.insert("2", "two");
       
  1059     map.insert("3", outerList);
       
  1060     map.insert("5", "cinco");
       
  1061     map.insert("10", "zehn");
       
  1062     settings.setValue("key 4", map);
       
  1063     QCOMPARE(settings.value("key 4").toMap(), map);
       
  1064 }
       
  1065 
       
  1066 void tst_QSettings::testVariantTypes_data()
       
  1067 {
       
  1068     populateWithFormats();
       
  1069 }
       
  1070 
       
  1071 void tst_QSettings::testVariantTypes()
       
  1072 {
       
  1073 #ifdef QT_BUILD_INTERNAL
       
  1074 #define testVal(key, val, tp, rtype) \
       
  1075     { \
       
  1076         QSettings settings1(format, QSettings::UserScope, "software.org", "KillerAPP"); \
       
  1077         settings1.setValue(key, qVariantFromValue(val)); \
       
  1078     } \
       
  1079     QConfFile::clearCache(); \
       
  1080     { \
       
  1081         QSettings settings2(format, QSettings::UserScope, "software.org", "KillerAPP"); \
       
  1082         QVariant v = settings2.value(key); \
       
  1083         QVERIFY(qvariant_cast<tp >(v) == val); \
       
  1084         QVERIFY(v.type() == QVariant::rtype); \
       
  1085     }
       
  1086 
       
  1087     typedef QMap<QString, QVariant> TestVariantMap;
       
  1088 
       
  1089     QFETCH(QSettings::Format, format);
       
  1090 
       
  1091     TestVariantMap m2;
       
  1092     m2.insert("ene", "due");
       
  1093     m2.insert("rike", "fake");
       
  1094     m2.insert("borba", "dorba");
       
  1095     testVal("key2", m2, TestVariantMap, Map);
       
  1096 
       
  1097     QStringList l2;
       
  1098 
       
  1099     l2 << "ene" << "due" << "@Point(1 2)" << "@fake";
       
  1100     testVal("key3", l2, QStringList, StringList);
       
  1101 
       
  1102     l2.clear();
       
  1103     l2 << "ene" << "due" << "rike" << "fake";
       
  1104     testVal("key3", l2, QStringList, StringList);
       
  1105 
       
  1106     QList<QVariant> l3;
       
  1107     QDate date = QDate::currentDate();
       
  1108     QTime time = QTime::currentTime();
       
  1109     l3 << QString("ene") << 10 << qVariantFromValue(QColor(1, 2, 3)) << QVariant(QRect(1, 2, 3, 4))
       
  1110         << QVariant(QSize(4, 56)) << QVariant(QPoint(4, 2)) << true << false << date << time;
       
  1111     testVal("key3", l3, QVariantList, List);
       
  1112 
       
  1113     testVal("key4", QString("hello"), QString, String);
       
  1114     testVal("key5", QColor(1, 2, 3), QColor, Color);
       
  1115     testVal("key6", QRect(1, 2, 3, 4), QRect, Rect);
       
  1116     testVal("key7", QSize(4, 56), QSize, Size);
       
  1117     testVal("key8", QPoint(4, 2), QPoint, Point);
       
  1118     testVal("key10", date, QDate, Date);
       
  1119     testVal("key11", time, QTime, Time);
       
  1120     testVal("key12", QByteArray("foo bar"), QByteArray, ByteArray);
       
  1121 
       
  1122     {
       
  1123         QSettings settings(format, QSettings::UserScope, "software.org", "KillerAPP");
       
  1124         QVERIFY(!settings.contains("key99"));
       
  1125         QCOMPARE(settings.value("key99"), QVariant());
       
  1126 
       
  1127         settings.setValue("key99", QVariant());
       
  1128         QVERIFY(settings.contains("key99"));
       
  1129         QCOMPARE(settings.value("key99"), QVariant());
       
  1130 
       
  1131         settings.setValue("key99", QVariant(1));
       
  1132         QVERIFY(settings.contains("key99"));
       
  1133         QCOMPARE(settings.value("key99"), QVariant(1));
       
  1134 
       
  1135         settings.setValue("key99", QVariant());
       
  1136         QVERIFY(settings.contains("key99"));
       
  1137         QCOMPARE(settings.value("key99"), QVariant());
       
  1138 
       
  1139         settings.remove("key99");
       
  1140         QVERIFY(!settings.contains("key99"));
       
  1141         QCOMPARE(settings.value("key99"), QVariant());
       
  1142     }
       
  1143 
       
  1144     QList<QVariant> l4;
       
  1145     l4 << QVariant(m2) << QVariant(l2) << QVariant(l3);
       
  1146     testVal("key13", l4, QVariantList, List);
       
  1147 
       
  1148     // We store key sequences as strings instead of binary variant blob, for improved
       
  1149     // readability in the resulting format.
       
  1150     if (format >= QSettings::InvalidFormat) {
       
  1151         testVal("keysequence", QKeySequence(Qt::ControlModifier + Qt::Key_F1), QKeySequence, KeySequence);
       
  1152     } else {
       
  1153         testVal("keysequence", QKeySequence(Qt::ControlModifier + Qt::Key_F1), QString, String);
       
  1154     }
       
  1155 
       
  1156 #undef testVal
       
  1157 #endif
       
  1158 }
       
  1159 
       
  1160 void tst_QSettings::remove()
       
  1161 {
       
  1162     QSettings settings0(QSettings::UserScope, "software.org", "KillerAPP");
       
  1163     int initialNumKeys = settings0.allKeys().size();
       
  1164     QCOMPARE(settings0.value("key 1", "123").toString(), QString("123"));
       
  1165     settings0.remove("key 1");
       
  1166     QCOMPARE(settings0.value("key 1", "456").toString(), QString("456"));
       
  1167 
       
  1168     settings0.setValue("key 1", "bubloo");
       
  1169     QCOMPARE(settings0.value("key 1").toString(), QString("bubloo"));
       
  1170     settings0.remove("key 2");
       
  1171     QCOMPARE(settings0.value("key 1").toString(), QString("bubloo"));
       
  1172     settings0.remove("key 1");
       
  1173     QCOMPARE(settings0.value("key 1", "789").toString(), QString("789"));
       
  1174 
       
  1175     /*
       
  1176       Make sure that removing a key removes all the subkeys.
       
  1177     */
       
  1178     settings0.setValue("alpha/beta/geometry", -7);
       
  1179     settings0.setValue("alpha/beta/geometry/x", 1);
       
  1180     settings0.setValue("alpha/beta/geometry/y", 2);
       
  1181     settings0.setValue("alpha/beta/geometry/width", 3);
       
  1182     settings0.setValue("alpha/beta/geometry/height", 4);
       
  1183     settings0.setValue("alpha/gamma/splitter", 5);
       
  1184 
       
  1185     settings0.remove("alpha/beta/geometry/x");
       
  1186     QCOMPARE(settings0.value("alpha/beta/geometry").toInt(), -7);
       
  1187     QCOMPARE(settings0.value("alpha/beta/geometry/x", 999).toInt(), 999);
       
  1188     QCOMPARE(settings0.value("alpha/beta/geometry/y").toInt(), 2);
       
  1189     QCOMPARE(settings0.value("alpha/beta/geometry/width").toInt(), 3);
       
  1190     QCOMPARE(settings0.value("alpha/beta/geometry/height").toInt(), 4);
       
  1191     QCOMPARE(settings0.value("alpha/gamma/splitter").toInt(), 5);
       
  1192 
       
  1193     settings0.remove("alpha/beta/geometry");
       
  1194     QCOMPARE(settings0.value("alpha/beta/geometry", 777).toInt(), 777);
       
  1195     QCOMPARE(settings0.value("alpha/beta/geometry/x", 111).toInt(), 111);
       
  1196     QCOMPARE(settings0.value("alpha/beta/geometry/y", 222).toInt(), 222);
       
  1197     QCOMPARE(settings0.value("alpha/beta/geometry/width", 333).toInt(), 333);
       
  1198     QCOMPARE(settings0.value("alpha/beta/geometry/height", 444).toInt(), 444);
       
  1199     QCOMPARE(settings0.value("alpha/gamma/splitter").toInt(), 5);
       
  1200 
       
  1201     settings0.setValue("alpha/beta/geometry", -7);
       
  1202     settings0.setValue("alpha/beta/geometry/x", 1);
       
  1203     settings0.setValue("alpha/beta/geometry/y", 2);
       
  1204     settings0.setValue("alpha/beta/geometry/width", 3);
       
  1205     settings0.setValue("alpha/beta/geometry/height", 4);
       
  1206     settings0.setValue("alpha/gamma/splitter", 5);
       
  1207     QCOMPARE(settings0.allKeys().size(), initialNumKeys + 6);
       
  1208 
       
  1209     settings0.beginGroup("alpha/beta/geometry");
       
  1210     settings0.remove("");
       
  1211     settings0.endGroup();
       
  1212     QVERIFY(!settings0.contains("alpha/beta/geometry"));
       
  1213     QVERIFY(!settings0.contains("alpha/beta/geometry/x"));
       
  1214     QVERIFY(!settings0.contains("alpha/beta/geometry/y"));
       
  1215     QVERIFY(!settings0.contains("alpha/beta/geometry/width"));
       
  1216     QVERIFY(!settings0.contains("alpha/beta/geometry/height"));
       
  1217     QVERIFY(settings0.contains("alpha/gamma/splitter"));
       
  1218     QCOMPARE(settings0.allKeys().size(), initialNumKeys + 1);
       
  1219 
       
  1220     settings0.beginGroup("alpha/beta");
       
  1221     settings0.remove("");
       
  1222     settings0.endGroup();
       
  1223     QVERIFY(!settings0.contains("alpha/beta/geometry"));
       
  1224     QVERIFY(!settings0.contains("alpha/beta/geometry/x"));
       
  1225     QVERIFY(!settings0.contains("alpha/beta/geometry/y"));
       
  1226     QVERIFY(!settings0.contains("alpha/beta/geometry/width"));
       
  1227     QVERIFY(!settings0.contains("alpha/beta/geometry/height"));
       
  1228     QVERIFY(settings0.contains("alpha/gamma/splitter"));
       
  1229     QCOMPARE(settings0.allKeys().size(), initialNumKeys + 1);
       
  1230 
       
  1231     settings0.remove("");
       
  1232     QVERIFY(!settings0.contains("alpha/gamma/splitter"));
       
  1233     QCOMPARE(settings0.allKeys().size(), initialNumKeys);
       
  1234 
       
  1235     /*
       
  1236       Do it again, but this time let's use setGroup().
       
  1237     */
       
  1238 
       
  1239     settings0.setValue("alpha/beta/geometry", -7);
       
  1240     settings0.setValue("alpha/beta/geometry/x", 1);
       
  1241     settings0.setValue("alpha/beta/geometry/y", 2);
       
  1242     settings0.setValue("alpha/beta/geometry/width", 3);
       
  1243     settings0.setValue("alpha/beta/geometry/height", 4);
       
  1244     settings0.setValue("alpha/gamma/splitter", 5);
       
  1245 
       
  1246     settings0.beginGroup("foo/bar/baz/doesn't");
       
  1247     settings0.remove("exist");
       
  1248     settings0.endGroup();
       
  1249     QCOMPARE(settings0.value("alpha/beta/geometry").toInt(), -7);
       
  1250     QCOMPARE(settings0.value("alpha/beta/geometry/x").toInt(), 1);
       
  1251     QCOMPARE(settings0.value("alpha/beta/geometry/y").toInt(), 2);
       
  1252     QCOMPARE(settings0.value("alpha/beta/geometry/width").toInt(), 3);
       
  1253     QCOMPARE(settings0.value("alpha/beta/geometry/height").toInt(), 4);
       
  1254     QCOMPARE(settings0.value("alpha/gamma/splitter").toInt(), 5);
       
  1255 
       
  1256     settings0.beginGroup("alpha/beta/geometry");
       
  1257     settings0.remove("x");
       
  1258     settings0.endGroup();
       
  1259     QCOMPARE(settings0.value("alpha/beta/geometry").toInt(), -7);
       
  1260     QCOMPARE(settings0.value("alpha/beta/geometry/x", 999).toInt(), 999);
       
  1261     QCOMPARE(settings0.value("alpha/beta/geometry/y").toInt(), 2);
       
  1262     QCOMPARE(settings0.value("alpha/beta/geometry/width").toInt(), 3);
       
  1263     QCOMPARE(settings0.value("alpha/beta/geometry/height").toInt(), 4);
       
  1264     QCOMPARE(settings0.value("alpha/gamma/splitter").toInt(), 5);
       
  1265 
       
  1266     settings0.remove("alpha/beta");
       
  1267     QCOMPARE(settings0.value("alpha/beta/geometry", 777).toInt(), 777);
       
  1268     QCOMPARE(settings0.value("alpha/beta/geometry/x", 111).toInt(), 111);
       
  1269     QCOMPARE(settings0.value("alpha/beta/geometry/y", 222).toInt(), 222);
       
  1270     QCOMPARE(settings0.value("alpha/beta/geometry/width", 333).toInt(), 333);
       
  1271     QCOMPARE(settings0.value("alpha/beta/geometry/height", 444).toInt(), 444);
       
  1272     QCOMPARE(settings0.value("alpha/gamma/splitter").toInt(), 5);
       
  1273 
       
  1274     settings0.clear();
       
  1275     QCOMPARE(settings0.value("alpha/gamma/splitter", 888).toInt(), 888);
       
  1276 
       
  1277     /*
       
  1278       OK, now let's check what happens if settings are spread across
       
  1279       multiple files (user vs. global, product-specific vs.
       
  1280       company-wide).
       
  1281     */
       
  1282 
       
  1283     QSettings settings1(QSettings::UserScope, "software.org", "KillerAPP");
       
  1284     QSettings settings2(QSettings::UserScope, "software.org");
       
  1285     QSettings settings3(QSettings::SystemScope, "software.org", "KillerAPP");
       
  1286     QSettings settings4(QSettings::SystemScope, "software.org");
       
  1287 
       
  1288     settings4.setValue("key 1", "doodah");
       
  1289     settings3.setValue("key 1", "blah");
       
  1290     settings2.setValue("key 1", "whoa");
       
  1291     settings1.setValue("key 1", "gurgle");
       
  1292     QCOMPARE(settings1.value("key 1").toString(), QString("gurgle"));
       
  1293     QCOMPARE(settings2.value("key 1").toString(), QString("whoa"));
       
  1294     QCOMPARE(settings3.value("key 1").toString(), QString("blah"));
       
  1295     QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
       
  1296 
       
  1297     settings1.remove("key 1");
       
  1298     QCOMPARE(settings1.value("key 1").toString(), QString("whoa"));
       
  1299     QCOMPARE(settings2.value("key 1").toString(), QString("whoa"));
       
  1300     QCOMPARE(settings3.value("key 1").toString(), QString("blah"));
       
  1301     QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
       
  1302 
       
  1303     settings2.remove("key 1");
       
  1304     QCOMPARE(settings1.value("key 1").toString(), QString("blah"));
       
  1305     QCOMPARE(settings2.value("key 1").toString(), QString("doodah"));
       
  1306     QCOMPARE(settings3.value("key 1").toString(), QString("blah"));
       
  1307     QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
       
  1308 
       
  1309     settings3.remove("key 1");
       
  1310     QCOMPARE(settings1.value("key 1").toString(), QString("doodah"));
       
  1311     QCOMPARE(settings2.value("key 1").toString(), QString("doodah"));
       
  1312     QCOMPARE(settings3.value("key 1").toString(), QString("doodah"));
       
  1313     QCOMPARE(settings4.value("key 1").toString(), QString("doodah"));
       
  1314 
       
  1315     settings4.remove("key 1");
       
  1316     QVERIFY(!settings1.contains("key 1"));
       
  1317     QVERIFY(!settings2.contains("key 1"));
       
  1318     QVERIFY(!settings3.contains("key 1"));
       
  1319     QVERIFY(!settings4.contains("key 1"));
       
  1320 
       
  1321     /*
       
  1322       Get ready for the next part of the test.
       
  1323     */
       
  1324 
       
  1325     settings1.clear();
       
  1326     settings2.clear();
       
  1327     settings3.clear();
       
  1328     settings4.clear();
       
  1329 
       
  1330     settings1.sync();
       
  1331     settings2.sync();
       
  1332     settings3.sync();
       
  1333     settings4.sync();
       
  1334 
       
  1335     /*
       
  1336       Check that recursive removes work correctly when some of the
       
  1337       keys are loaded from the file and others have been modified in
       
  1338       memory (corresponds to originalKeys vs. addedKeys in the
       
  1339       QSettingsFile code).
       
  1340     */
       
  1341 
       
  1342     settings1.setValue("alpha/beta/geometry", -7);
       
  1343     settings1.setValue("alpha/beta/geometry/x", 1);
       
  1344     settings1.setValue("alpha/beta/geometry/y", 2);
       
  1345     settings1.setValue("alpha/gamma/splitter", 5);
       
  1346     settings1.sync();
       
  1347 
       
  1348     settings1.setValue("alpha/beta/geometry/width", 3);
       
  1349     settings1.setValue("alpha/beta/geometry/height", 4);
       
  1350 
       
  1351     settings1.remove("alpha/beta/geometry/y");
       
  1352     QVERIFY(settings1.contains("alpha/beta/geometry"));
       
  1353     QVERIFY(settings1.contains("alpha/beta/geometry/x"));
       
  1354     QVERIFY(!settings1.contains("alpha/beta/geometry/y"));
       
  1355     QVERIFY(settings1.contains("alpha/beta/geometry/width"));
       
  1356     QVERIFY(settings1.contains("alpha/beta/geometry/height"));
       
  1357     QCOMPARE(settings1.allKeys().size(), initialNumKeys + 5);
       
  1358 
       
  1359     settings1.remove("alpha/beta/geometry/y");
       
  1360     QCOMPARE(settings1.allKeys().size(), initialNumKeys + 5);
       
  1361 
       
  1362     settings1.remove("alpha/beta/geometry/height");
       
  1363     QVERIFY(settings1.contains("alpha/beta/geometry"));
       
  1364     QVERIFY(settings1.contains("alpha/beta/geometry/x"));
       
  1365     QVERIFY(!settings1.contains("alpha/beta/geometry/y"));
       
  1366     QVERIFY(settings1.contains("alpha/beta/geometry/width"));
       
  1367     QVERIFY(!settings1.contains("alpha/beta/geometry/height"));
       
  1368     QCOMPARE(settings1.allKeys().size(), initialNumKeys + 4);
       
  1369 
       
  1370     settings1.remove("alpha/beta/geometry");
       
  1371     QVERIFY(!settings1.contains("alpha/beta/geometry"));
       
  1372     QVERIFY(!settings1.contains("alpha/beta/geometry/x"));
       
  1373     QVERIFY(!settings1.contains("alpha/beta/geometry/y"));
       
  1374     QVERIFY(!settings1.contains("alpha/beta/geometry/width"));
       
  1375     QVERIFY(!settings1.contains("alpha/beta/geometry/height"));
       
  1376     QVERIFY(settings1.contains("alpha/gamma/splitter"));
       
  1377     QCOMPARE(settings1.allKeys().size(), initialNumKeys + 1);
       
  1378 
       
  1379     settings1.sync();
       
  1380     QVERIFY(!settings1.contains("alpha/beta/geometry"));
       
  1381     QVERIFY(!settings1.contains("alpha/beta/geometry/x"));
       
  1382     QVERIFY(!settings1.contains("alpha/beta/geometry/y"));
       
  1383     QVERIFY(!settings1.contains("alpha/beta/geometry/width"));
       
  1384     QVERIFY(!settings1.contains("alpha/beta/geometry/height"));
       
  1385     QVERIFY(settings1.contains("alpha/gamma/splitter"));
       
  1386     QCOMPARE(settings1.allKeys().size(), initialNumKeys + 1);
       
  1387 }
       
  1388 
       
  1389 /*
       
  1390     Tests contains() and keys().
       
  1391 */
       
  1392 void tst_QSettings::contains()
       
  1393 {
       
  1394     QSettings settings1(QSettings::UserScope, "software.org", "KillerAPP");
       
  1395     int initialNumKeys = settings1.allKeys().size(); // 0 on all platforms but Mac OS X.
       
  1396     settings1.setValue("alpha/beta/geometry", -7);
       
  1397     settings1.setValue("alpha/beta/geometry/x", 1);
       
  1398     settings1.setValue("alpha/beta/geometry/y", 2);
       
  1399     settings1.setValue("alpha/beta/geometry/width", 3);
       
  1400     settings1.setValue("alpha/beta/geometry/height", 4);
       
  1401     settings1.setValue("alpha/gamma/splitter", 5);
       
  1402     settings1.setValue("alpha/gamma/splitter/ /", 5);
       
  1403 
       
  1404     QVERIFY(!settings1.contains("alpha"));
       
  1405     QVERIFY(!settings1.contains("alpha/beta"));
       
  1406     QVERIFY(!settings1.contains("///alpha///beta///"));
       
  1407     QVERIFY(settings1.contains("alpha/beta/geometry"));
       
  1408     QVERIFY(settings1.contains("///alpha///beta//geometry//"));
       
  1409     QVERIFY(settings1.contains("alpha/beta/geometry/x"));
       
  1410     QVERIFY(settings1.contains("alpha/beta/geometry/y"));
       
  1411     QVERIFY(settings1.contains("alpha/beta/geometry/width"));
       
  1412     QVERIFY(settings1.contains("alpha/beta/geometry/height"));
       
  1413     QVERIFY(!settings1.contains("alpha/beta/geometry/height/foo/bar/doesn't/exist"));
       
  1414     QVERIFY(!settings1.contains("alpha/gamma"));
       
  1415     QVERIFY(settings1.contains("alpha/gamma/splitter"));
       
  1416     QVERIFY(settings1.contains("alpha/gamma/splitter/ "));
       
  1417     QVERIFY(settings1.contains("////alpha/gamma/splitter// ////"));
       
  1418 
       
  1419     settings1.beginGroup("alpha");
       
  1420     QVERIFY(!settings1.contains("beta"));
       
  1421     QVERIFY(!settings1.contains("/////beta///"));
       
  1422     QVERIFY(settings1.contains("beta/geometry"));
       
  1423     QVERIFY(settings1.contains("/////beta//geometry//"));
       
  1424     QVERIFY(settings1.contains("beta/geometry/x"));
       
  1425     QVERIFY(settings1.contains("beta/geometry/y"));
       
  1426     QVERIFY(settings1.contains("beta/geometry/width"));
       
  1427     QVERIFY(settings1.contains("beta/geometry/height"));
       
  1428     QVERIFY(!settings1.contains("beta/geometry/height/foo/bar/doesn't/exist"));
       
  1429     QVERIFY(!settings1.contains("gamma"));
       
  1430     QVERIFY(settings1.contains("gamma/splitter"));
       
  1431     QVERIFY(settings1.contains("gamma/splitter/ "));
       
  1432     QVERIFY(settings1.contains("////gamma/splitter// ////"));
       
  1433 
       
  1434     settings1.beginGroup("beta/geometry");
       
  1435     QVERIFY(settings1.contains("x"));
       
  1436     QVERIFY(settings1.contains("y"));
       
  1437     QVERIFY(settings1.contains("width"));
       
  1438     QVERIFY(settings1.contains("height"));
       
  1439     QVERIFY(!settings1.contains("height/foo/bar/doesn't/exist"));
       
  1440 
       
  1441     QStringList keys = settings1.allKeys();
       
  1442     QStringList expectedResult = QStringList() << "x" << "y" << "width" << "height";
       
  1443     keys.sort();
       
  1444     expectedResult.sort();
       
  1445     int i;
       
  1446     QCOMPARE(keys, expectedResult);
       
  1447     for (i = 0; i < keys.size(); ++i) {
       
  1448         QVERIFY(settings1.contains(keys.at(i)));
       
  1449     }
       
  1450 
       
  1451     settings1.endGroup();
       
  1452     QVERIFY(settings1.group() == "alpha");
       
  1453     keys = settings1.allKeys();
       
  1454     QCOMPARE(keys.size(), expectedResult.size() + 3);
       
  1455     for (i = 0; i < keys.size(); ++i) {
       
  1456         QVERIFY(settings1.contains(keys.at(i)));
       
  1457     }
       
  1458 
       
  1459     settings1.endGroup();
       
  1460     QVERIFY(settings1.group().isEmpty());
       
  1461     keys = settings1.allKeys();
       
  1462 
       
  1463     QCOMPARE(keys.size(), initialNumKeys + 7);
       
  1464     for (i = 0; i < keys.size(); ++i) {
       
  1465         QVERIFY(settings1.contains(keys.at(i)));
       
  1466     }
       
  1467 }
       
  1468 
       
  1469 void tst_QSettings::sync()
       
  1470 {
       
  1471     /*
       
  1472         What we're trying to test here is the case where two
       
  1473         instances of the same application access the same preference
       
  1474         files. We want to make sure that the results are 'merged',
       
  1475         rather than having the last application overwrite settings
       
  1476         set by the first application (like in Qt 3).
       
  1477 
       
  1478         This is only applicable to the INI format. The Windows
       
  1479         registry and Mac's CFPreferences API should take care of this
       
  1480         by themselves.
       
  1481     */
       
  1482 
       
  1483     QSettings settings1(QSettings::IniFormat, QSettings::UserScope, "software.org");
       
  1484     settings1.setValue("alpha/beta/geometry", -7);
       
  1485     settings1.setValue("alpha/beta/geometry/x", 1);
       
  1486     settings1.setValue("alpha/beta/geometry/y", 2);
       
  1487     settings1.setValue("alpha/beta/geometry/width", 3);
       
  1488     settings1.setValue("alpha/beta/geometry/height", 4);
       
  1489     settings1.setValue("alpha/gamma/splitter", 5);
       
  1490     settings1.sync(); // and it all goes into the file
       
  1491 
       
  1492     QSettings settings2(QSettings::IniFormat, QSettings::UserScope, "other.software.org");
       
  1493     settings2.setValue("alpha/beta/geometry/x", 8);
       
  1494     settings2.sync();
       
  1495 
       
  1496     settings2.setValue("moo/beta/geometry", -7);
       
  1497     settings2.setValue("moo/beta/geometry/x", 1);
       
  1498     settings2.setValue("moo/beta/geometry/y", 2);
       
  1499     settings2.setValue("moo/beta/geometry/width", 3);
       
  1500     settings2.setValue("moo/beta/geometry/height", 4);
       
  1501     settings2.setValue("moo/gamma/splitter", 5);
       
  1502     settings2.setValue("alpha/gamma/splitter", 15);
       
  1503     settings2.remove("alpha/beta/geometry/x");
       
  1504     settings2.remove("alpha/beta/geometry/y"); // should do nothing
       
  1505 
       
  1506     // Now "some other app" will change other.software.org.ini
       
  1507     QString userConfDir = settingsPath("__user__") + QDir::separator();
       
  1508 #if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
       
  1509     unlink((userConfDir + "other.software.org.ini").toLatin1());
       
  1510     rename((userConfDir + "software.org.ini").toLatin1(),
       
  1511            (userConfDir + "other.software.org.ini").toLatin1());
       
  1512 #else
       
  1513     QFile::remove(userConfDir + "other.software.org.ini");
       
  1514     QFile::rename(userConfDir + "software.org.ini" , userConfDir + "other.software.org.ini");
       
  1515 #endif
       
  1516 
       
  1517     settings2.sync();
       
  1518 
       
  1519     // And voila, we should be merged
       
  1520 
       
  1521     QCOMPARE(settings2.value("alpha/beta/geometry").toInt(), -7);
       
  1522     QVERIFY(!settings2.contains("alpha/beta/geometry/x")); // <----- removed by settings2
       
  1523     QCOMPARE(settings2.value("alpha/beta/geometry/y").toInt(), 2);
       
  1524     QCOMPARE(settings2.value("alpha/beta/geometry/width").toInt(), 3);
       
  1525     QCOMPARE(settings2.value("alpha/beta/geometry/height").toInt(), 4);
       
  1526     QCOMPARE(settings2.value("alpha/gamma/splitter").toInt(), 15); // <---- set by settings2
       
  1527     QCOMPARE(settings2.value("moo/beta/geometry").toInt(), -7);
       
  1528     QCOMPARE(settings2.value("moo/beta/geometry/x").toInt(), 1);
       
  1529     QCOMPARE(settings2.value("moo/beta/geometry/y").toInt(), 2);
       
  1530     QCOMPARE(settings2.value("moo/beta/geometry/width").toInt(), 3);
       
  1531     QCOMPARE(settings2.value("moo/beta/geometry/height").toInt(), 4);
       
  1532     QCOMPARE(settings2.value("moo/gamma/splitter").toInt(), 5);
       
  1533     QCOMPARE(settings2.allKeys().count(), 11);
       
  1534 
       
  1535     // Now, software.org.ini no longer exists, this is same as another app
       
  1536     // clearing all settings.
       
  1537     settings1.sync();
       
  1538     QCOMPARE(settings1.allKeys().count(), 0);
       
  1539 
       
  1540 /*
       
  1541     // Now "some other app" will change software.org.conf
       
  1542     unlink((userConfDir + "software.org.ini").toLatin1());
       
  1543     rename((userConfDir + "other.software.org.ini").toLatin1(),
       
  1544             (userConfDir + "software.org.ini").toLatin1());
       
  1545 
       
  1546     settings1.sync();
       
  1547     QCOMPARE(settings1.value("alpha/beta/geometry").toInt(), -7);
       
  1548     QCOMPARE(settings1.value("alpha/beta/geometry/y").toInt(), 2);
       
  1549     QCOMPARE(settings1.value("alpha/beta/geometry/width").toInt(), 3);
       
  1550     QCOMPARE(settings1.value("alpha/beta/geometry/height").toInt(), 4);
       
  1551     QCOMPARE(settings1.value("alpha/gamma/splitter").toInt(), 15);
       
  1552     QCOMPARE(settings1.value("moo/beta/geometry").toInt(), -7);
       
  1553     QCOMPARE(settings1.value("moo/beta/geometry/x").toInt(), 1);
       
  1554     QCOMPARE(settings1.value("moo/beta/geometry/y").toInt(), 2);
       
  1555     QCOMPARE(settings1.value("moo/beta/geometry/width").toInt(), 3);
       
  1556     QCOMPARE(settings1.value("moo/beta/geometry/height").toInt(), 4);
       
  1557     QCOMPARE(settings1.value("moo/gamma/splitter").toInt(), 5);
       
  1558     QCOMPARE(settings1.allKeys().count(), 11);
       
  1559 */
       
  1560 }
       
  1561 
       
  1562 void tst_QSettings::setFallbacksEnabled_data()
       
  1563 {
       
  1564     populateWithFormats();
       
  1565 }
       
  1566 
       
  1567 void tst_QSettings::setFallbacksEnabled()
       
  1568 {
       
  1569     QFETCH(QSettings::Format, format);
       
  1570 
       
  1571     QSettings settings1(format, QSettings::UserScope, "software.org", "KillerAPP");
       
  1572     QSettings settings2(format, QSettings::UserScope, "software.org");
       
  1573     QSettings settings3(format, QSettings::SystemScope, "software.org", "KillerAPP");
       
  1574     QSettings settings4(format, QSettings::SystemScope, "software.org");
       
  1575 
       
  1576     settings1.setValue("key 1", "alpha");
       
  1577     settings2.setValue("key 1", "beta");
       
  1578     settings3.setValue("key 1", "gamma");
       
  1579     settings4.setValue("key 1", "delta");
       
  1580 
       
  1581     settings1.setValue("key 2", "alpha");
       
  1582     settings2.setValue("key 2", "beta");
       
  1583     settings3.setValue("key 2", "gamma");
       
  1584 
       
  1585     settings1.setValue("key 3", "alpha");
       
  1586     settings3.setValue("key 3", "gamma");
       
  1587     settings4.setValue("key 3", "delta");
       
  1588 
       
  1589     settings1.setValue("key 4", "alpha");
       
  1590     settings2.setValue("key 4", "beta");
       
  1591     settings4.setValue("key 4", "delta");
       
  1592 
       
  1593     settings2.setValue("key 5", "beta");
       
  1594     settings3.setValue("key 5", "gamma");
       
  1595     settings4.setValue("key 5", "delta");
       
  1596 
       
  1597     QVERIFY(settings1.fallbacksEnabled());
       
  1598     QVERIFY(settings2.fallbacksEnabled());
       
  1599     QVERIFY(settings3.fallbacksEnabled());
       
  1600     QVERIFY(settings4.fallbacksEnabled());
       
  1601 
       
  1602     settings1.setFallbacksEnabled(false);
       
  1603     settings2.setFallbacksEnabled(false);
       
  1604     settings3.setFallbacksEnabled(false);
       
  1605     settings4.setFallbacksEnabled(false);
       
  1606 
       
  1607     QVERIFY(!settings1.fallbacksEnabled());
       
  1608     QVERIFY(!settings2.fallbacksEnabled());
       
  1609     QVERIFY(!settings3.fallbacksEnabled());
       
  1610     QVERIFY(!settings4.fallbacksEnabled());
       
  1611 
       
  1612     /*
       
  1613         Make sure that the QSettings objects can still access their
       
  1614         main associated file when fallbacks are turned off.
       
  1615     */
       
  1616 
       
  1617     QCOMPARE(settings1.value("key 1").toString(), QString("alpha"));
       
  1618     QCOMPARE(settings2.value("key 1").toString(), QString("beta"));
       
  1619     QCOMPARE(settings3.value("key 1").toString(), QString("gamma"));
       
  1620     QCOMPARE(settings4.value("key 1").toString(), QString("delta"));
       
  1621 
       
  1622     QCOMPARE(settings1.value("key 2").toString(), QString("alpha"));
       
  1623     QCOMPARE(settings2.value("key 2").toString(), QString("beta"));
       
  1624     QCOMPARE(settings3.value("key 2").toString(), QString("gamma"));
       
  1625     QVERIFY(!settings4.contains("key 2"));
       
  1626 
       
  1627     QCOMPARE(settings1.value("key 3").toString(), QString("alpha"));
       
  1628     QCOMPARE(settings3.value("key 3").toString(), QString("gamma"));
       
  1629     QCOMPARE(settings4.value("key 3").toString(), QString("delta"));
       
  1630     QVERIFY(!settings2.contains("key 3"));
       
  1631 
       
  1632     QCOMPARE(settings1.value("key 4").toString(), QString("alpha"));
       
  1633     QCOMPARE(settings2.value("key 4").toString(), QString("beta"));
       
  1634     QCOMPARE(settings4.value("key 4").toString(), QString("delta"));
       
  1635     QVERIFY(!settings3.contains("key 4"));
       
  1636 
       
  1637     QCOMPARE(settings2.value("key 5").toString(), QString("beta"));
       
  1638     QCOMPARE(settings3.value("key 5").toString(), QString("gamma"));
       
  1639     QCOMPARE(settings4.value("key 5").toString(), QString("delta"));
       
  1640     QVERIFY(!settings1.contains("key 5"));
       
  1641 
       
  1642     QCOMPARE(settings1.value("key 1").toString(), QString("alpha"));
       
  1643     QCOMPARE(settings1.value("key 5").toString(), QString(""));
       
  1644     QVERIFY(settings1.contains("key 1"));
       
  1645     QVERIFY(!settings1.contains("key 5"));
       
  1646 }
       
  1647 
       
  1648 void tst_QSettings::testChildKeysAndGroups_data()
       
  1649 {
       
  1650     populateWithFormats();
       
  1651 }
       
  1652 
       
  1653 void tst_QSettings::testChildKeysAndGroups()
       
  1654 {
       
  1655     QFETCH(QSettings::Format, format);
       
  1656 
       
  1657     QSettings settings1(format, QSettings::UserScope, "software.org");
       
  1658     settings1.setFallbacksEnabled(false);
       
  1659     settings1.setValue("alpha/beta/geometry", -7);
       
  1660     settings1.setValue("alpha/beta/geometry/x", 1);
       
  1661     settings1.setValue("alpha/beta/geometry/y", 2);
       
  1662     settings1.setValue("alpha/beta/geometry/width", 3);
       
  1663     settings1.setValue("alpha/beta/geometry/height", 4);
       
  1664     settings1.setValue("alpha/gamma/splitter", 5);
       
  1665 
       
  1666     QCOMPARE(settings1.childKeys(), QStringList());
       
  1667     QCOMPARE(settings1.childGroups(), QStringList() << "alpha");
       
  1668 
       
  1669     settings1.beginGroup("/alpha");
       
  1670     QCOMPARE(settings1.childKeys(), QStringList());
       
  1671     QCOMPARE(settings1.childGroups(), QStringList() << "beta" << "gamma");
       
  1672 
       
  1673     settings1.beginGroup("/beta");
       
  1674     QCOMPARE(settings1.childKeys(), QStringList() << "geometry");
       
  1675     QCOMPARE(settings1.childGroups(), QStringList() << "geometry");
       
  1676 
       
  1677     settings1.beginGroup("/geometry");
       
  1678     QCOMPARE(settings1.childKeys(), QStringList()  << "height" << "width" << "x" << "y");
       
  1679     QCOMPARE(settings1.childGroups(), QStringList());
       
  1680 
       
  1681     settings1.beginGroup("/width");
       
  1682     QCOMPARE(settings1.childKeys(), QStringList());
       
  1683     QCOMPARE(settings1.childGroups(), QStringList());
       
  1684 
       
  1685     settings1.endGroup();
       
  1686     settings1.endGroup();
       
  1687     settings1.endGroup();
       
  1688     settings1.endGroup();
       
  1689 
       
  1690     { // task 53792
       
  1691         QSettings settings2("other.software.org");
       
  1692         settings2.setValue("viewbar/foo/test1", "1");
       
  1693         settings2.setValue("viewbar/foo/test2", "2");
       
  1694         settings2.setValue("viewbar/foo/test3", "3");
       
  1695         settings2.setValue("viewbar/foo/test4", "4");
       
  1696         settings2.setValue("viewbar/foo/test5", "5");
       
  1697         settings2.setValue("viewbar/bar/test1", "1");
       
  1698         settings2.setValue("viewbar/bar/test2", "2");
       
  1699         settings2.setValue("viewbar/bar/test3", "3");
       
  1700         settings2.setValue("viewbar/bar/test4", "4");
       
  1701         settings2.setValue("viewbar/bar/test5", "5");
       
  1702 
       
  1703         settings2.beginGroup("viewbar");
       
  1704         QStringList l = settings2.childGroups();
       
  1705         settings2.endGroup();
       
  1706         l.sort();
       
  1707         QCOMPARE(l, QStringList() << "bar" << "foo");
       
  1708     }
       
  1709 }
       
  1710 
       
  1711 void tst_QSettings::testUpdateRequestEvent()
       
  1712 {
       
  1713     QFile::remove("foo");
       
  1714     QVERIFY(!QFile::exists("foo"));
       
  1715 
       
  1716     QSettings settings1("foo", QSettings::IniFormat);
       
  1717     QVERIFY(!QFile::exists("foo"));
       
  1718     QVERIFY(QFileInfo("foo").size() == 0);
       
  1719     settings1.setValue("key1", 1);
       
  1720     QVERIFY(QFileInfo("foo").size() == 0);
       
  1721 
       
  1722     qApp->processEvents();
       
  1723     QVERIFY(QFileInfo("foo").size() > 0);
       
  1724 
       
  1725     settings1.remove("key1");
       
  1726     QVERIFY(QFileInfo("foo").size() > 0);
       
  1727 
       
  1728     qApp->processEvents();
       
  1729     QVERIFY(QFileInfo("foo").size() == 0);
       
  1730 
       
  1731     settings1.setValue("key2", 2);
       
  1732     QVERIFY(QFileInfo("foo").size() == 0);
       
  1733 
       
  1734     qApp->processEvents();
       
  1735     QVERIFY(QFileInfo("foo").size() > 0);
       
  1736 
       
  1737     settings1.clear();
       
  1738     QVERIFY(QFileInfo("foo").size() > 0);
       
  1739 
       
  1740     qApp->processEvents();
       
  1741     QVERIFY(QFileInfo("foo").size() == 0);
       
  1742 }
       
  1743 
       
  1744 const int NumIterations = 5;
       
  1745 const int NumThreads = 4;
       
  1746 
       
  1747 class SettingsThread : public QThread
       
  1748 {
       
  1749 public:
       
  1750     void run();
       
  1751     void start(int n) { param = n; QThread::start(); }
       
  1752 
       
  1753 private:
       
  1754     int param;
       
  1755 };
       
  1756 
       
  1757 void SettingsThread::run()
       
  1758 {
       
  1759     for (int i = 0; i < NumIterations; ++i) {
       
  1760         QSettings settings("software.org", "KillerAPP");
       
  1761         settings.setValue(QString::number((param * NumIterations) + i), param);
       
  1762         settings.sync();
       
  1763         QCOMPARE((int)settings.status(), (int)QSettings::NoError);
       
  1764     }
       
  1765 }
       
  1766 
       
  1767 void tst_QSettings::testThreadSafety()
       
  1768 {
       
  1769     SettingsThread threads[NumThreads];
       
  1770     int i, j;
       
  1771 
       
  1772     for (i = 0; i < NumThreads; ++i)
       
  1773         threads[i].start(i + 1);
       
  1774     for (i = 0; i < NumThreads; ++i)
       
  1775         threads[i].wait();
       
  1776 
       
  1777     QSettings settings("software.org", "KillerAPP");
       
  1778     for (i = 0; i < NumThreads; ++i) {
       
  1779         int param = i + 1;
       
  1780         for (j = 0; j < NumIterations; ++j) {
       
  1781             QCOMPARE(settings.value(QString::number((param * NumIterations) + j)).toInt(), param);
       
  1782         }
       
  1783     }
       
  1784 }
       
  1785 
       
  1786 void tst_QSettings::testNormalizedKey_data()
       
  1787 {
       
  1788     QTest::addColumn<QString>("inKey");
       
  1789     QTest::addColumn<QString>("outKey");
       
  1790 
       
  1791     QTest::newRow("empty1") << "" << "";
       
  1792     QTest::newRow("empty2") << "/" << "";
       
  1793     QTest::newRow("empty3") << "//" << "";
       
  1794     QTest::newRow("empty4") << "///" << "";
       
  1795 
       
  1796     QTest::newRow("a1") << "a" << "a";
       
  1797     QTest::newRow("a2") << "/a" << "a";
       
  1798     QTest::newRow("a3") << "a/" << "a";
       
  1799     QTest::newRow("a4") << "//a" << "a";
       
  1800     QTest::newRow("a5") << "a//" << "a";
       
  1801     QTest::newRow("a6") << "///a" << "a";
       
  1802     QTest::newRow("a7") << "a///" << "a";
       
  1803     QTest::newRow("a8") << "///a/" << "a";
       
  1804     QTest::newRow("a9") << "/a///" << "a";
       
  1805 
       
  1806     QTest::newRow("ab1") << "aaa/bbb" << "aaa/bbb";
       
  1807     QTest::newRow("ab2") << "/aaa/bbb" << "aaa/bbb";
       
  1808     QTest::newRow("ab3") << "aaa/bbb/" << "aaa/bbb";
       
  1809     QTest::newRow("ab4") << "/aaa/bbb/" << "aaa/bbb";
       
  1810     QTest::newRow("ab5") << "aaa///bbb" << "aaa/bbb";
       
  1811     QTest::newRow("ab6") << "aaa///bbb/" << "aaa/bbb";
       
  1812     QTest::newRow("ab7") << "/aaa///bbb/" << "aaa/bbb";
       
  1813     QTest::newRow("ab8") << "////aaa///bbb////" << "aaa/bbb";
       
  1814 }
       
  1815 
       
  1816 void tst_QSettings::testNormalizedKey()
       
  1817 {
       
  1818 #ifdef QT_BUILD_INTERNAL
       
  1819     QFETCH(QString, inKey);
       
  1820     QFETCH(QString, outKey);
       
  1821 
       
  1822     inKey.detach();
       
  1823 
       
  1824     QString result = QSettingsPrivate::normalizedKey(inKey);
       
  1825     QCOMPARE(result, outKey);
       
  1826 
       
  1827     /*
       
  1828         If the key is already normalized, we verify that outKey is
       
  1829         just a shallow copy of the input string. This is an important
       
  1830         optimization that shouldn't be removed accidentally.
       
  1831     */
       
  1832     if (inKey == outKey) {
       
  1833         QVERIFY(!result.isDetached());
       
  1834     } else {
       
  1835         if (!result.isEmpty()) {
       
  1836             QVERIFY(result.isDetached());
       
  1837         }
       
  1838     }
       
  1839 #endif
       
  1840 }
       
  1841 
       
  1842 void tst_QSettings::testEmptyData()
       
  1843 {
       
  1844     QString filename(QDir::tempPath() + "/empty.ini");
       
  1845     QFile::remove(filename);
       
  1846     QVERIFY(!QFile::exists(filename));
       
  1847 
       
  1848     QString nullString;
       
  1849     QString emptyString("");
       
  1850     QStringList emptyList;
       
  1851     QStringList list;
       
  1852     QStringList list2;
       
  1853 
       
  1854     QVariantList emptyVList;
       
  1855     QVariantList vList, vList2, vList3;
       
  1856 
       
  1857     list << emptyString << nullString;
       
  1858     list2 << emptyString;
       
  1859     vList << emptyString;
       
  1860     vList2 << emptyString << nullString;
       
  1861     vList3 << QString("foo");
       
  1862 
       
  1863     {
       
  1864         QSettings settings(filename, QSettings::IniFormat);
       
  1865         settings.setValue("nullString", nullString);
       
  1866         settings.setValue("emptyString", emptyString);
       
  1867         settings.setValue("emptyList", emptyList);
       
  1868         settings.setValue("list", list);
       
  1869         settings.setValue("list2", list2);
       
  1870         settings.setValue("emptyVList", emptyVList);
       
  1871         settings.setValue("vList", vList);
       
  1872         settings.setValue("vList2", vList2);
       
  1873         settings.setValue("vList3", vList3);
       
  1874         QVERIFY(settings.status() == QSettings::NoError);
       
  1875     }
       
  1876     {
       
  1877         QSettings settings(filename, QSettings::IniFormat);
       
  1878         QCOMPARE(settings.value("nullString").toString(), nullString);
       
  1879         QCOMPARE(settings.value("emptyString").toString(), emptyString);
       
  1880         QCOMPARE(settings.value("emptyList").toStringList(), emptyList);
       
  1881         QCOMPARE(settings.value("list").toStringList(), list);
       
  1882         QCOMPARE(settings.value("list2").toStringList(), list2);
       
  1883         QCOMPARE(settings.value("emptyVList").toList(), emptyVList);
       
  1884         QCOMPARE(settings.value("vList").toList(), vList);
       
  1885         QCOMPARE(settings.value("vList2").toList(), vList2);
       
  1886         QCOMPARE(settings.value("vList3").toList(), vList3);
       
  1887         QVERIFY(settings.status() == QSettings::NoError);
       
  1888     }
       
  1889 
       
  1890     {
       
  1891         QSettings settings("Trolltech", "tst_qsettings");
       
  1892         settings.setValue("nullString", nullString);
       
  1893         settings.setValue("emptyString", emptyString);
       
  1894         settings.setValue("emptyList", emptyList);
       
  1895         settings.setValue("list", list);
       
  1896         settings.setValue("list2", list2);
       
  1897         settings.setValue("emptyVList", emptyVList);
       
  1898         settings.setValue("vList", vList);
       
  1899         settings.setValue("vList2", vList2);
       
  1900         settings.setValue("vList3", vList3);
       
  1901         QVERIFY(settings.status() == QSettings::NoError);
       
  1902     }
       
  1903     {
       
  1904         QSettings settings("Trolltech", "tst_qsettings");
       
  1905         QCOMPARE(settings.value("nullString").toString(), nullString);
       
  1906         QCOMPARE(settings.value("emptyString").toString(), emptyString);
       
  1907         QCOMPARE(settings.value("emptyList").toStringList(), emptyList);
       
  1908         QCOMPARE(settings.value("list").toStringList(), list);
       
  1909         QCOMPARE(settings.value("list2").toStringList(), list2);
       
  1910         QCOMPARE(settings.value("emptyVList").toList(), emptyVList);
       
  1911         QCOMPARE(settings.value("vList").toList(), vList);
       
  1912         QCOMPARE(settings.value("vList2").toList(), vList2);
       
  1913         QCOMPARE(settings.value("vList3").toList(), vList3);
       
  1914         QVERIFY(settings.status() == QSettings::NoError);
       
  1915     }
       
  1916     QFile::remove(filename);
       
  1917 }
       
  1918 
       
  1919 void tst_QSettings::testResourceFiles()
       
  1920 {
       
  1921     QSettings settings(":/resourcefile.ini", QSettings::IniFormat);
       
  1922     QVERIFY(settings.status() == QSettings::NoError);
       
  1923     QVERIFY(!settings.isWritable());
       
  1924     QCOMPARE(settings.value("Field 1/Bottom").toInt(), 89);
       
  1925     settings.setValue("Field 1/Bottom", 90);
       
  1926 
       
  1927     // the next two lines check the statu quo; another behavior would be possible
       
  1928     QVERIFY(settings.status() == QSettings::NoError);
       
  1929     QCOMPARE(settings.value("Field 1/Bottom").toInt(), 90);
       
  1930 
       
  1931     settings.sync();
       
  1932     QVERIFY(settings.status() == QSettings::AccessError);
       
  1933     QCOMPARE(settings.value("Field 1/Bottom").toInt(), 90);
       
  1934 }
       
  1935 
       
  1936 void tst_QSettings::fromFile_data()
       
  1937 {
       
  1938     populateWithFormats();
       
  1939 }
       
  1940 
       
  1941 void tst_QSettings::fromFile()
       
  1942 {
       
  1943     QFETCH(QSettings::Format, format);
       
  1944 
       
  1945     QFile::remove("foo");
       
  1946     QVERIFY(!QFile::exists("foo"));
       
  1947 
       
  1948     QString path = "foo";
       
  1949 
       
  1950 #ifdef Q_OS_WIN
       
  1951     if (format == QSettings::NativeFormat)
       
  1952         path = "\\HKEY_CURRENT_USER\\Software\\foo";
       
  1953 #endif
       
  1954 
       
  1955     QStringList strList = QStringList() << "hope" << "destiny" << "chastity";
       
  1956 
       
  1957     {
       
  1958         QSettings settings1(path, format);
       
  1959         QVERIFY(settings1.allKeys().isEmpty());
       
  1960 
       
  1961         settings1.setValue("alpha", 1);
       
  1962         settings1.setValue("alpha", 2);
       
  1963         settings1.setValue("beta", strList);
       
  1964 
       
  1965         QSettings settings2(path, format);
       
  1966         QCOMPARE(settings2.value("alpha").toInt(), 2);
       
  1967 
       
  1968         settings1.sync();
       
  1969 #ifndef Q_OS_WIN
       
  1970         QVERIFY(QFile::exists("foo"));
       
  1971 #endif
       
  1972         QCOMPARE(settings1.value("alpha").toInt(), 2);
       
  1973         QCOMPARE(settings2.value("alpha").toInt(), 2);
       
  1974 
       
  1975         settings2.setValue("alpha", 3);
       
  1976         settings2.setValue("gamma/foo.bar", 4);
       
  1977         QCOMPARE(settings1.value("alpha").toInt(), 3);
       
  1978         QCOMPARE(settings2.value("alpha").toInt(), 3);
       
  1979         QCOMPARE(settings1.value("beta").toStringList(), strList);
       
  1980         QCOMPARE(settings2.value("beta").toStringList(), strList);
       
  1981         QCOMPARE(settings1.value("gamma/foo.bar").toInt(), 4);
       
  1982         QCOMPARE(settings2.value("gamma/foo.bar").toInt(), 4);
       
  1983     }
       
  1984 
       
  1985     {
       
  1986         QSettings settings1(path, format);
       
  1987         QCOMPARE(settings1.value("alpha").toInt(), 3);
       
  1988         QCOMPARE(settings1.value("beta").toStringList(), strList);
       
  1989         QCOMPARE(settings1.value("gamma/foo.bar").toInt(), 4);
       
  1990         QCOMPARE(settings1.allKeys().size(), 3);
       
  1991     }
       
  1992 }
       
  1993 
       
  1994 void tst_QSettings::setIniCodec()
       
  1995 {
       
  1996 #ifdef QT_BUILD_INTERNAL
       
  1997     QByteArray expeContents4, expeContents5;
       
  1998     QByteArray actualContents4, actualContents5;
       
  1999 
       
  2000     {
       
  2001     QFile inFile(":/resourcefile4.ini");
       
  2002     inFile.open(QIODevice::ReadOnly);
       
  2003     expeContents4 = inFile.readAll();
       
  2004     inFile.close();
       
  2005     }
       
  2006 
       
  2007     {
       
  2008     QFile inFile(":/resourcefile5.ini");
       
  2009     inFile.open(QIODevice::ReadOnly);
       
  2010     expeContents5 = inFile.readAll();
       
  2011     inFile.close();
       
  2012     }
       
  2013 
       
  2014     {
       
  2015     QSettings settings4(QSettings::IniFormat, QSettings::UserScope, "software.org", "KillerAPP");
       
  2016     settings4.setIniCodec("UTF-8");
       
  2017     settings4.setValue(QLatin1String("Fa\xe7" "ade/QU\xc9" "BEC"), QLatin1String("Fa\xe7" "ade/QU\xc9" "BEC"));
       
  2018     settings4.sync();
       
  2019 
       
  2020     QSettings settings5(QSettings::IniFormat, QSettings::UserScope, "other.software.org", "KillerAPP");
       
  2021     settings5.setIniCodec("ISO 8859-1");
       
  2022     settings5.setValue(QLatin1String("Fa\xe7" "ade/QU\xc9" "BEC"), QLatin1String("Fa\xe7" "ade/QU\xc9" "BEC"));
       
  2023     settings5.sync();
       
  2024 
       
  2025     {
       
  2026     QFile inFile(settings4.fileName());
       
  2027     inFile.open(QIODevice::ReadOnly);
       
  2028     actualContents4 = inFile.readAll();
       
  2029     inFile.close();
       
  2030     }
       
  2031 
       
  2032     {
       
  2033     QFile inFile(settings5.fileName());
       
  2034     inFile.open(QIODevice::ReadOnly);
       
  2035     actualContents5 = inFile.readAll();
       
  2036     inFile.close();
       
  2037     }
       
  2038     }
       
  2039 
       
  2040     QConfFile::clearCache();
       
  2041 
       
  2042     QCOMPARE(actualContents4, expeContents4);
       
  2043     QCOMPARE(actualContents5, expeContents5);
       
  2044 
       
  2045     QSettings settings4(QSettings::IniFormat, QSettings::UserScope, "software.org", "KillerAPP");
       
  2046     settings4.setIniCodec("UTF-8");
       
  2047     QSettings settings5(QSettings::IniFormat, QSettings::UserScope, "other.software.org", "KillerAPP");
       
  2048     settings5.setIniCodec("Latin-1");
       
  2049 
       
  2050     QCOMPARE(settings4.allKeys().count(), 1);
       
  2051     QCOMPARE(settings5.allKeys().count(), 1);
       
  2052 
       
  2053     QCOMPARE(settings4.allKeys().first(), settings5.allKeys().first());
       
  2054     QCOMPARE(settings4.value(settings4.allKeys().first()).toString(),
       
  2055              settings5.value(settings5.allKeys().first()).toString());
       
  2056 #endif
       
  2057 }
       
  2058 
       
  2059 static bool containsSubList(QStringList mom, QStringList son)
       
  2060 {
       
  2061     for (int i = 0; i < son.size(); ++i) {
       
  2062         if (!mom.contains(son.at(i)))
       
  2063             return false;
       
  2064     }
       
  2065     return true;
       
  2066 }
       
  2067 
       
  2068 void tst_QSettings::testArrays_data()
       
  2069 {
       
  2070     populateWithFormats();
       
  2071 }
       
  2072 
       
  2073 /*
       
  2074     Tests beginReadArray(), beginWriteArray(), endArray(), and
       
  2075     setArrayIndex().
       
  2076 */
       
  2077 void tst_QSettings::testArrays()
       
  2078 {
       
  2079     QFETCH(QSettings::Format, format);
       
  2080 
       
  2081     {
       
  2082         QSettings settings1(format, QSettings::UserScope, "software.org", "KillerAPP");
       
  2083 
       
  2084         settings1.beginWriteArray("foo/bar", 3);
       
  2085         settings1.setValue("bip", 1);
       
  2086         settings1.setArrayIndex(0);
       
  2087         settings1.setValue("ene", 2);
       
  2088         settings1.setValue("due", 3);
       
  2089         settings1.setValue("rike", 4);
       
  2090         settings1.setArrayIndex(1);
       
  2091         settings1.setValue("ene", 5);
       
  2092         settings1.setValue("due", 6);
       
  2093         settings1.setValue("rike", 7);
       
  2094         settings1.setArrayIndex(2);
       
  2095         settings1.setValue("ene", 8);
       
  2096         settings1.setValue("due", 9);
       
  2097         settings1.setValue("rike", 10);
       
  2098         settings1.endArray();
       
  2099 
       
  2100         QStringList expectedList;
       
  2101         expectedList
       
  2102             << "foo/bar/bip"
       
  2103             << "foo/bar/size"
       
  2104             << "foo/bar/1/ene"
       
  2105             << "foo/bar/1/due"
       
  2106             << "foo/bar/1/rike"
       
  2107             << "foo/bar/2/ene"
       
  2108             << "foo/bar/2/due"
       
  2109             << "foo/bar/2/rike"
       
  2110             << "foo/bar/3/ene"
       
  2111             << "foo/bar/3/due"
       
  2112             << "foo/bar/3/rike";
       
  2113         expectedList.sort();
       
  2114 
       
  2115         QStringList actualList = settings1.allKeys();
       
  2116         actualList.sort();
       
  2117         QVERIFY(containsSubList(actualList, expectedList));
       
  2118 
       
  2119         QCOMPARE(settings1.value("/foo/bar/bip").toInt(), 1);
       
  2120         QCOMPARE(settings1.value("/foo/bar/1/ene").toInt(), 2);
       
  2121         QCOMPARE(settings1.value("/foo/bar/1/due").toInt(), 3);
       
  2122         QCOMPARE(settings1.value("/foo/bar/1/rike").toInt(), 4);
       
  2123         QCOMPARE(settings1.value("/foo/bar/2/ene").toInt(), 5);
       
  2124         QCOMPARE(settings1.value("/foo/bar/2/due").toInt(), 6);
       
  2125         QCOMPARE(settings1.value("/foo/bar/2/rike").toInt(), 7);
       
  2126         QCOMPARE(settings1.value("/foo/bar/3/ene").toInt(), 8);
       
  2127         QCOMPARE(settings1.value("/foo/bar/3/due").toInt(), 9);
       
  2128         QCOMPARE(settings1.value("/foo/bar/3/rike").toInt(), 10);
       
  2129 
       
  2130         settings1.beginGroup("/foo");
       
  2131         int count = settings1.beginReadArray("bar");
       
  2132         QCOMPARE(count, 3);
       
  2133         QCOMPARE(settings1.value("bip").toInt(), 1);
       
  2134         settings1.setArrayIndex(0);
       
  2135         QCOMPARE(settings1.value("ene").toInt(), 2);
       
  2136         QCOMPARE(settings1.value("due").toInt(), 3);
       
  2137         QCOMPARE(settings1.value("rike").toInt(), 4);
       
  2138         QCOMPARE(settings1.allKeys().count(), 3);
       
  2139         settings1.setArrayIndex(1);
       
  2140         QCOMPARE(settings1.value("ene").toInt(), 5);
       
  2141         QCOMPARE(settings1.value("due").toInt(), 6);
       
  2142         QCOMPARE(settings1.value("rike").toInt(), 7);
       
  2143         QCOMPARE(settings1.allKeys().count(), 3);
       
  2144         settings1.setArrayIndex(2);
       
  2145         QCOMPARE(settings1.value("ene").toInt(), 8);
       
  2146         QCOMPARE(settings1.value("due").toInt(), 9);
       
  2147         QCOMPARE(settings1.value("rike").toInt(), 10);
       
  2148         QCOMPARE(settings1.allKeys().count(), 3);
       
  2149 
       
  2150         settings1.endArray();
       
  2151         settings1.endGroup();
       
  2152     }
       
  2153     /*
       
  2154         Check that we get the arrays right when we load them again
       
  2155     */
       
  2156 
       
  2157     {
       
  2158         QSettings settings1(format, QSettings::UserScope, "software.org", "KillerAPP");
       
  2159 
       
  2160         QStringList expectedList;
       
  2161         expectedList
       
  2162             << "foo/bar/bip"
       
  2163             << "foo/bar/size"
       
  2164             << "foo/bar/1/ene"
       
  2165             << "foo/bar/1/due"
       
  2166             << "foo/bar/1/rike"
       
  2167             << "foo/bar/2/ene"
       
  2168             << "foo/bar/2/due"
       
  2169             << "foo/bar/2/rike"
       
  2170             << "foo/bar/3/ene"
       
  2171             << "foo/bar/3/due"
       
  2172             << "foo/bar/3/rike";
       
  2173         expectedList.sort();
       
  2174 
       
  2175         QStringList actualList = settings1.allKeys();
       
  2176         actualList.sort();
       
  2177         QVERIFY(containsSubList(actualList, expectedList));
       
  2178 
       
  2179         QCOMPARE(settings1.value("/foo/bar/bip").toInt(), 1);
       
  2180         QCOMPARE(settings1.value("/foo/bar/1/ene").toInt(), 2);
       
  2181         QCOMPARE(settings1.value("/foo/bar/1/due").toInt(), 3);
       
  2182         QCOMPARE(settings1.value("/foo/bar/1/rike").toInt(), 4);
       
  2183         QCOMPARE(settings1.value("/foo/bar/2/ene").toInt(), 5);
       
  2184         QCOMPARE(settings1.value("/foo/bar/2/due").toInt(), 6);
       
  2185         QCOMPARE(settings1.value("/foo/bar/2/rike").toInt(), 7);
       
  2186         QCOMPARE(settings1.value("/foo/bar/3/ene").toInt(), 8);
       
  2187         QCOMPARE(settings1.value("/foo/bar/3/due").toInt(), 9);
       
  2188         QCOMPARE(settings1.value("/foo/bar/3/rike").toInt(), 10);
       
  2189 
       
  2190         settings1.beginGroup("/foo");
       
  2191         int count = settings1.beginReadArray("bar");
       
  2192         QCOMPARE(count, 3);
       
  2193         QCOMPARE(settings1.value("bip").toInt(), 1);
       
  2194         settings1.setArrayIndex(0);
       
  2195         QCOMPARE(settings1.value("ene").toInt(), 2);
       
  2196         QCOMPARE(settings1.value("due").toInt(), 3);
       
  2197         QCOMPARE(settings1.value("rike").toInt(), 4);
       
  2198         QCOMPARE(settings1.allKeys().count(), 3);
       
  2199         settings1.setArrayIndex(1);
       
  2200         QCOMPARE(settings1.value("ene").toInt(), 5);
       
  2201         QCOMPARE(settings1.value("due").toInt(), 6);
       
  2202         QCOMPARE(settings1.value("rike").toInt(), 7);
       
  2203         QCOMPARE(settings1.allKeys().count(), 3);
       
  2204         settings1.setArrayIndex(2);
       
  2205         QCOMPARE(settings1.value("ene").toInt(), 8);
       
  2206         QCOMPARE(settings1.value("due").toInt(), 9);
       
  2207         QCOMPARE(settings1.value("rike").toInt(), 10);
       
  2208         QCOMPARE(settings1.allKeys().count(), 3);
       
  2209 
       
  2210         settings1.endArray();
       
  2211         settings1.endGroup();
       
  2212     }
       
  2213     /*
       
  2214         This code generates lots of warnings, but that's on purpose.
       
  2215         Basically, we check that endGroup() can be used instead of
       
  2216         endArray() and vice versa. This is not documented, but this
       
  2217         is the behavior that we have chosen.
       
  2218     */
       
  2219     QSettings settings1(format, QSettings::UserScope, "software.org", "KillerAPP");
       
  2220     settings1.clear();
       
  2221     settings1.beginGroup("/alpha");
       
  2222     QCOMPARE(settings1.group(), QString("alpha"));
       
  2223     settings1.setArrayIndex(0);
       
  2224     QCOMPARE(settings1.group(), QString("alpha"));
       
  2225     settings1.setArrayIndex(1);
       
  2226     QCOMPARE(settings1.group(), QString("alpha"));
       
  2227     settings1.setArrayIndex(2);
       
  2228     QCOMPARE(settings1.group(), QString("alpha"));
       
  2229     settings1.beginGroup("/beta");
       
  2230     QCOMPARE(settings1.group(), QString("alpha/beta"));
       
  2231     settings1.beginGroup("");
       
  2232     QCOMPARE(settings1.group(), QString("alpha/beta"));
       
  2233     settings1.beginWriteArray("DO", 4);
       
  2234     QCOMPARE(settings1.value("size").toInt(), 4);
       
  2235     QCOMPARE(settings1.group(), QString("alpha/beta/DO"));
       
  2236     settings1.setArrayIndex(0);
       
  2237     QCOMPARE(settings1.group(), QString("alpha/beta/DO/1"));
       
  2238     settings1.setArrayIndex(1);
       
  2239     QCOMPARE(settings1.group(), QString("alpha/beta/DO/2"));
       
  2240     settings1.beginGroup("1");
       
  2241     QCOMPARE(settings1.group(), QString("alpha/beta/DO/2/1"));
       
  2242     settings1.setArrayIndex(3);
       
  2243     QCOMPARE(settings1.group(), QString("alpha/beta/DO/2/1"));
       
  2244     settings1.setArrayIndex(4);
       
  2245     QCOMPARE(settings1.group(), QString("alpha/beta/DO/2/1"));
       
  2246     settings1.beginWriteArray("RE");
       
  2247     QVERIFY(!settings1.contains("size"));
       
  2248     QCOMPARE(settings1.group(), QString("alpha/beta/DO/2/1/RE"));
       
  2249     settings1.setArrayIndex(0);
       
  2250     QCOMPARE(settings1.group(), QString("alpha/beta/DO/2/1/RE/1"));
       
  2251     settings1.setArrayIndex(1);
       
  2252     QCOMPARE(settings1.group(), QString("alpha/beta/DO/2/1/RE/2"));
       
  2253     settings1.endArray();
       
  2254     QCOMPARE(settings1.group(), QString("alpha/beta/DO/2/1"));
       
  2255     settings1.endArray();
       
  2256     QCOMPARE(settings1.group(), QString("alpha/beta/DO/2"));
       
  2257     settings1.setArrayIndex(2);
       
  2258     QCOMPARE(settings1.group(), QString("alpha/beta/DO/3"));
       
  2259     settings1.endGroup();
       
  2260     QCOMPARE(settings1.group(), QString("alpha/beta"));
       
  2261     settings1.endGroup();
       
  2262     QCOMPARE(settings1.group(), QString("alpha/beta"));
       
  2263     settings1.endGroup();
       
  2264     QCOMPARE(settings1.group(), QString("alpha"));
       
  2265     settings1.endArray();
       
  2266     QCOMPARE(settings1.group(), QString());
       
  2267     settings1.endGroup();
       
  2268     QCOMPARE(settings1.group(), QString());
       
  2269 
       
  2270     /*
       
  2271         Now, let's make sure that things work well if an array
       
  2272         is spread across multiple files.
       
  2273     */
       
  2274     int i;
       
  2275 
       
  2276     settings1.clear();
       
  2277     QSettings settings2(format, QSettings::UserScope, "software.org");
       
  2278 
       
  2279     QStringList threeStrings;
       
  2280     threeStrings << "Uno" << "Dos" << "Tres";
       
  2281 
       
  2282     QStringList fiveStrings;
       
  2283     fiveStrings << "alpha" << "beta" << "gamma" << "delta" << "epsilon";
       
  2284 
       
  2285     settings1.beginWriteArray("strings");
       
  2286     for (i = threeStrings.size() - 1; i >= 0; --i) {
       
  2287         settings1.setArrayIndex(i);
       
  2288         settings1.setValue("fileName", threeStrings.at(i));
       
  2289     }
       
  2290     settings1.endArray();
       
  2291 
       
  2292     settings2.beginWriteArray("strings");
       
  2293     for (i = fiveStrings.size() - 1; i >= 0; --i) {
       
  2294         settings2.setArrayIndex(i);
       
  2295         settings2.setValue("fileName", fiveStrings.at(i));
       
  2296     }
       
  2297     settings2.endArray();
       
  2298 
       
  2299     int size1 = settings1.beginReadArray("strings");
       
  2300     QCOMPARE(size1, 3);
       
  2301     QCOMPARE(settings1.value("size").toInt(), 3);
       
  2302 
       
  2303     for (i = 0; i < size1; ++i) {
       
  2304         settings1.setArrayIndex(i);
       
  2305         QString str = settings1.value("fileName").toString();
       
  2306         QCOMPARE(str, threeStrings.at(i));
       
  2307     }
       
  2308     settings1.endArray();
       
  2309 
       
  2310     int size2 = settings2.beginReadArray("strings");
       
  2311     QCOMPARE(size2, 5);
       
  2312     QCOMPARE(settings2.value("size").toInt(), 5);
       
  2313 
       
  2314     for (i = 0; i < size2; ++i) {
       
  2315         settings2.setArrayIndex(i);
       
  2316         QString str = settings2.value("fileName").toString();
       
  2317         QCOMPARE(str, fiveStrings.at(i));
       
  2318     }
       
  2319     settings2.endArray();
       
  2320 
       
  2321     size1 = settings1.beginReadArray("strings");
       
  2322     QCOMPARE(size1, 3);
       
  2323 
       
  2324     // accessing entries beyond the end of settings1 goes to settings2
       
  2325     for (i = size1; i < size2; ++i) {
       
  2326         settings1.setArrayIndex(i);
       
  2327         QString str = settings1.value("fileName").toString();
       
  2328         QCOMPARE(str, fiveStrings.at(i));
       
  2329     }
       
  2330     settings1.endArray();
       
  2331 }
       
  2332 
       
  2333 #ifdef QT_BUILD_INTERNAL
       
  2334 static QByteArray iniEscapedKey(const QString &str)
       
  2335 {
       
  2336     QByteArray result;
       
  2337     QSettingsPrivate::iniEscapedKey(str, result);
       
  2338     return result;
       
  2339 }
       
  2340 
       
  2341 static QString iniUnescapedKey(const QByteArray &ba)
       
  2342 {
       
  2343     QString result;
       
  2344     QSettingsPrivate::iniUnescapedKey(ba, 0, ba.size(), result);
       
  2345     return result;
       
  2346 }
       
  2347 
       
  2348 static QByteArray iniEscapedStringList(const QStringList &strList)
       
  2349 {
       
  2350     QByteArray result;
       
  2351     QSettingsPrivate::iniEscapedStringList(strList, result, 0);
       
  2352     return result;
       
  2353 }
       
  2354 
       
  2355 static QStringList iniUnescapedStringList(const QByteArray &ba)
       
  2356 {
       
  2357     QStringList result;
       
  2358     QString str;
       
  2359 #if QSETTINGS_P_H_VERSION >= 2
       
  2360     bool isStringList = QSettingsPrivate::iniUnescapedStringList(ba, 0, ba.size(), str, result
       
  2361 #if QSETTINGS_P_H_VERSION >= 3
       
  2362                                                                  , 0
       
  2363 #endif
       
  2364                                                                     );
       
  2365     if (!isStringList)
       
  2366         result = QStringList(str);
       
  2367 #else
       
  2368     QStringList *strList = QSettingsPrivate::iniUnescapedStringList(ba, 0, ba.size(), str);
       
  2369     if (strList) {
       
  2370         result = *strList;
       
  2371         delete strList;
       
  2372     } else {
       
  2373         result = QStringList(str);
       
  2374     }
       
  2375 #endif
       
  2376     return result;
       
  2377 }
       
  2378 #endif
       
  2379 
       
  2380 QString escapeWeirdChars(const QString &s)
       
  2381 {
       
  2382     QString result;
       
  2383     bool escapeNextDigit = false;
       
  2384 
       
  2385     for (int i = 0; i < s.length(); ++i) {
       
  2386         QChar c = s.at(i);
       
  2387         if (c.unicode() < ' ' || c.unicode() > '~'
       
  2388             || (escapeNextDigit && c.unicode() >= '0' && c.unicode() <= 'f')) {
       
  2389             result += QString("\\x%1").arg(c.unicode(), 0, 16);
       
  2390             escapeNextDigit = true;
       
  2391         } else {
       
  2392             result += c;
       
  2393             escapeNextDigit = false;
       
  2394         }
       
  2395     }
       
  2396 
       
  2397     return result;
       
  2398 }
       
  2399 
       
  2400 void tst_QSettings::testEscapes()
       
  2401 {
       
  2402 #ifdef QT_BUILD_INTERNAL
       
  2403     QSettings settings(QSettings::UserScope, "software.org", "KillerAPP");
       
  2404 
       
  2405 #define testEscapedKey(plainKey, escKey) \
       
  2406     QCOMPARE(iniEscapedKey(plainKey), QByteArray(escKey)); \
       
  2407     QCOMPARE(iniUnescapedKey(escKey), QString(plainKey));
       
  2408 
       
  2409 #define testUnescapedKey(escKey, plainKey, reescKey) \
       
  2410     QCOMPARE(iniUnescapedKey(escKey), QString(plainKey)); \
       
  2411     QCOMPARE(iniEscapedKey(plainKey), QByteArray(reescKey)); \
       
  2412     QCOMPARE(iniUnescapedKey(reescKey), QString(plainKey));
       
  2413 
       
  2414 #define testEscapedStringList(plainStrList, escStrList) \
       
  2415     { \
       
  2416         QStringList plainList(plainStrList); \
       
  2417         QByteArray escList(escStrList); \
       
  2418         QCOMPARE(iniEscapedStringList(plainList), escList); \
       
  2419         QCOMPARE(iniUnescapedStringList(escList), plainList); \
       
  2420     } \
       
  2421 
       
  2422 
       
  2423 #define testUnescapedStringList(escStrList, plainStrList, reescStrList) \
       
  2424     { \
       
  2425         QStringList plainList(plainStrList); \
       
  2426         QByteArray escList(escStrList); \
       
  2427         QByteArray reescList(reescStrList); \
       
  2428         QCOMPARE(iniUnescapedStringList(escList), plainList); \
       
  2429         QCOMPARE(iniEscapedStringList(plainList), reescList); \
       
  2430         QCOMPARE(iniUnescapedStringList(reescList), plainList); \
       
  2431     } \
       
  2432 
       
  2433 
       
  2434 #define testVariant(val, escStr, func) \
       
  2435     { \
       
  2436         QVariant v(val); \
       
  2437         QString s = QSettingsPrivate::variantToString(v); \
       
  2438         /*qDebug() << QString("testVariant(): reference=\"%1\" result=\"%2\"").arg(escStr).arg(s); */\
       
  2439         QCOMPARE(s, escStr); \
       
  2440         QCOMPARE(QVariant(QSettingsPrivate::stringToVariant(escStr)), v); \
       
  2441         QVERIFY(val == v.func()); \
       
  2442     }
       
  2443 
       
  2444 #define testBadEscape(escStr, vStr) \
       
  2445     { \
       
  2446         QVariant v = QSettingsPrivate::stringToVariant(QString(escStr)); \
       
  2447         QCOMPARE(v.toString(), QString(vStr)); \
       
  2448     }
       
  2449 
       
  2450     testEscapedKey("", "");
       
  2451     testEscapedKey(" ", "%20");
       
  2452     testEscapedKey(" 0123 abcd ", "%200123%20abcd%20");
       
  2453     testEscapedKey("~!@#$%^&*()_+.-/\\=", "%7E%21%40%23%24%25%5E%26%2A%28%29_%2B.-\\%5C%3D");
       
  2454     testEscapedKey(QString() + QChar(0xabcd) + QChar(0x1234) + QChar(0x0081), "%UABCD%U1234%81");
       
  2455     testEscapedKey(QString() + QChar(0xFE) + QChar(0xFF) + QChar(0x100) + QChar(0x101), "%FE%FF%U0100%U0101");
       
  2456 
       
  2457     testUnescapedKey("", "", "");
       
  2458     testUnescapedKey("%20", " ", "%20");
       
  2459     testUnescapedKey("/alpha/beta", "/alpha/beta", "\\alpha\\beta");
       
  2460     testUnescapedKey("\\alpha\\beta", "/alpha/beta", "\\alpha\\beta");
       
  2461     testUnescapedKey("%5Calpha%5Cbeta", "\\alpha\\beta", "%5Calpha%5Cbeta");
       
  2462     testUnescapedKey("%", "%", "%25");
       
  2463     testUnescapedKey("%f%!%%%%1x%x1%U%Uz%U123%U1234%1234%", QString("%f%!%%%%1x%x1%U%Uz%U123") + QChar(0x1234) + "\x12" + "34%",
       
  2464                      "%25f%25%21%25%25%25%251x%25x1%25U%25Uz%25U123%U1234%1234%25");
       
  2465 
       
  2466     testEscapedStringList("", "");
       
  2467     testEscapedStringList(" ", "\" \"");
       
  2468     testEscapedStringList(";", "\";\"");
       
  2469     testEscapedStringList(",", "\",\"");
       
  2470     testEscapedStringList("=", "\"=\"");
       
  2471     testEscapedStringList("abc-def", "abc-def");
       
  2472     testEscapedStringList(QChar(0) + QString("0"), "\\0\\x30");
       
  2473     testEscapedStringList("~!@#$%^&*()_+.-/\\=", "\"~!@#$%^&*()_+.-/\\\\=\"");
       
  2474     testEscapedStringList("~!@#$%^&*()_+.-/\\", "~!@#$%^&*()_+.-/\\\\");
       
  2475     testEscapedStringList(QString("\x7F") + "12aFz", "\\x7f\\x31\\x32\\x61\\x46z");
       
  2476     testEscapedStringList(QString("   \t\n\\n") + QChar(0x123) + QChar(0x4567), "\"   \\t\\n\\\\n\\x123\\x4567\"");
       
  2477     testEscapedStringList(QString("\a\b\f\n\r\t\v'\"?\001\002\x03\x04"), "\\a\\b\\f\\n\\r\\t\\v'\\\"?\\x1\\x2\\x3\\x4");
       
  2478     testEscapedStringList(QStringList() << "," << ";" << "a" << "ab,  \tc, d ", "\",\", \";\", a, \"ab,  \\tc, d \"");
       
  2479 
       
  2480     /*
       
  2481       Test .ini syntax that cannot be generated by QSettings (but can be entered by users).
       
  2482     */
       
  2483     testUnescapedStringList("", "", "");
       
  2484     testUnescapedStringList("\"\"", "", "");
       
  2485     testUnescapedStringList("\"abcdef\"", "abcdef", "abcdef");
       
  2486     testUnescapedStringList("\"\\?\\'\\\"\"", "?'\"", "?'\\\"");
       
  2487     testUnescapedStringList("\\0\\00\\000\\0000000\\1\\111\\11111\\x\\x0\\xABCDEFGH\\x0123456\\",
       
  2488                             QString() + QChar(0) + QChar(0) + QChar(0) + QChar(0) + QChar(1)
       
  2489                             + QChar(0111) + QChar(011111) + QChar(0) + QChar(0xCDEF) + "GH"
       
  2490                             + QChar(0x3456),
       
  2491                             "\\0\\0\\0\\0\\x1I\\x1249\\0\\xcdefGH\\x3456");
       
  2492     testUnescapedStringList(QByteArray("\\c\\d\\e\\f\\g\\$\\*\\\0", 16), "\f", "\\f");
       
  2493     testUnescapedStringList("\"a\",  \t\"bc \", \"  d\" , \"ef  \" ,,g,   hi  i,,, ,",
       
  2494                             QStringList() << "a" << "bc " << "  d" << "ef  " << "" << "g" << "hi  i"
       
  2495                                           << "" << "" << "" << "",
       
  2496                             "a, \"bc \", \"  d\", \"ef  \", , g, hi  i, , , , ");
       
  2497     testUnescapedStringList("a ,  b   ,   c   d   , efg   ",
       
  2498                             QStringList() << "a" << "b" << "c   d" << "efg",
       
  2499                             "a, b, c   d, efg");
       
  2500 
       
  2501     // streaming qvariant into a string
       
  2502     testVariant(QString("Hello World!"), QString("Hello World!"), toString);
       
  2503     testVariant(QString("Hello, World!"), QString("Hello, World!"), toString);
       
  2504     testVariant(QString("@Hello World!"), QString("@@Hello World!"), toString);
       
  2505     testVariant(QString("@@Hello World!"), QString("@@@Hello World!"), toString);
       
  2506     testVariant(QByteArray("Hello World!"), QString("@ByteArray(Hello World!)"), toString);
       
  2507     testVariant(QByteArray("@Hello World!"), QString("@ByteArray(@Hello World!)"), toString);
       
  2508     testVariant(QVariant(100), QString("100"), toString);
       
  2509     testVariant(QStringList() << "ene" << "due" << "rike", QString::fromLatin1("@Variant(\x0\x0\x0\xb\x0\x0\x0\x3\x0\x0\x0\x6\x0\x65\x0n\x0\x65\x0\x0\x0\x6\x0\x64\x0u\x0\x65\x0\x0\x0\x8\x0r\x0i\x0k\x0\x65)", 50), toStringList);
       
  2510     testVariant(QRect(1, 2, 3, 4), QString("@Rect(1 2 3 4)"), toRect);
       
  2511     testVariant(QSize(5, 6), QString("@Size(5 6)"), toSize);
       
  2512     testVariant(QPoint(7, 8), QString("@Point(7 8)"), toPoint);
       
  2513 
       
  2514     testBadEscape("", "");
       
  2515     testBadEscape("@", "@");
       
  2516     testBadEscape("@@", "@");
       
  2517     testBadEscape("@@@", "@@");
       
  2518     testBadEscape(" ", " ");
       
  2519     testBadEscape("@Rect", "@Rect");
       
  2520     testBadEscape("@Rect(", "@Rect(");
       
  2521     testBadEscape("@Rect()", "@Rect()");
       
  2522     testBadEscape("@Rect)", "@Rect)");
       
  2523     testBadEscape("@Rect(1 2 3)", "@Rect(1 2 3)");
       
  2524     testBadEscape("@@Rect(1 2 3)", "@Rect(1 2 3)");
       
  2525 #endif
       
  2526 }
       
  2527 
       
  2528 void tst_QSettings::testCompatFunctions()
       
  2529 {
       
  2530 #ifdef QT3_SUPPORT
       
  2531     QSettings settings1("software.org", "KillerAPP");
       
  2532 
       
  2533     bool ok;
       
  2534     ok = settings1.writeEntry("/root/bool", true);
       
  2535     QVERIFY(ok);
       
  2536     ok = settings1.writeEntry("/root/double", 1.4);
       
  2537     QVERIFY(ok);
       
  2538     ok = settings1.writeEntry("/root/int", 66666);
       
  2539     QVERIFY(ok);
       
  2540     ok = settings1.writeEntry("/root/const char */1", "Hello");
       
  2541     QVERIFY(ok);
       
  2542     ok = settings1.writeEntry("/root/const char */2", "");
       
  2543     QVERIFY(ok);
       
  2544     ok = settings1.writeEntry("/root/const char */3", (const char *)0);
       
  2545     QVERIFY(ok);
       
  2546     ok = settings1.writeEntry("/root/QString/1", QString("Hello"));
       
  2547     QVERIFY(ok);
       
  2548     ok = settings1.writeEntry("/root/QString/2", QString(""));
       
  2549     QVERIFY(ok);
       
  2550     ok = settings1.writeEntry("/root/QString/3", QString());
       
  2551     QVERIFY(ok);
       
  2552     ok = settings1.writeEntry("/root/QStringList/1", QStringList());
       
  2553     QVERIFY(ok);
       
  2554     ok = settings1.writeEntry("/root/QStringList/2", QStringList() << "");
       
  2555     QVERIFY(ok);
       
  2556     ok = settings1.writeEntry("/root/QStringList/3", QStringList() << "a" << "" << "b");
       
  2557     QVERIFY(ok);
       
  2558     ok = settings1.writeEntry("/root/QStringList/4", QStringList() << "a" << "" << "b", ':');
       
  2559     QVERIFY(ok);
       
  2560 
       
  2561     QCOMPARE(settings1.readBoolEntry("/root/bool"), true);
       
  2562     QCOMPARE(settings1.readDoubleEntry("/root/double"), 1.4);
       
  2563     QCOMPARE(settings1.readNumEntry("/root/int"), 66666);
       
  2564     QCOMPARE(settings1.readEntry("/root/const char */1"), QString("Hello"));
       
  2565     QCOMPARE(settings1.readEntry("/root/const char */2"), QString(""));
       
  2566     QCOMPARE(settings1.readEntry("/root/const char */3"), QString());
       
  2567     QCOMPARE(settings1.readEntry("/root/QString/1"), QString("Hello"));
       
  2568     QCOMPARE(settings1.readEntry("/root/QString/2"), QString(""));
       
  2569     QCOMPARE(settings1.readEntry("/root/QString/3"), QString());
       
  2570     QCOMPARE(settings1.readListEntry("/root/QStringList/1"), QStringList());
       
  2571     QCOMPARE(settings1.readListEntry("/root/QStringList/2"), QStringList() << "");
       
  2572     QCOMPARE(settings1.readListEntry("/root/QStringList/3"), QStringList() << "a" << "" << "b");
       
  2573     QCOMPARE(settings1.readListEntry("/root/QStringList/4", ':'), QStringList() << "a" << "" << "b");
       
  2574     QCOMPARE(settings1.readEntry("/root/QStringList/4"), QString("a::b"));
       
  2575 
       
  2576     QStringList actual, expectedSubKey, expectedEntry;
       
  2577 
       
  2578     settings1.clear();
       
  2579     QStringList initialKeys = settings1.allKeys();
       
  2580     settings1.setValue("/alpha/beta", 5);
       
  2581     settings1.setValue("/alpha/beta/gamma", 5);
       
  2582     settings1.setValue("/alpha/beta/delta", 5);
       
  2583     settings1.setValue("/alpha/epsilon/zeta/eta", 5);
       
  2584     settings1.setValue("/alpha/theta", 5);
       
  2585 
       
  2586     settings1.beginGroup("/alpha");
       
  2587     QCOMPARE(settings1.group(), QString("alpha"));
       
  2588 
       
  2589     actual = settings1.entryList("");
       
  2590     actual.sort();
       
  2591     expectedEntry = QStringList() << "beta" << "theta";
       
  2592     QCOMPARE(actual, expectedEntry);
       
  2593 
       
  2594     actual = settings1.subkeyList("");
       
  2595     actual.sort();
       
  2596     expectedSubKey = QStringList() << "beta" << "epsilon";
       
  2597     QCOMPARE(actual, expectedSubKey);
       
  2598 
       
  2599     settings1.endGroup();
       
  2600 
       
  2601     actual = settings1.entryList("alpha");
       
  2602     actual.sort();
       
  2603     QCOMPARE(actual, expectedEntry);
       
  2604 
       
  2605     actual = settings1.subkeyList("alpha");
       
  2606     actual.sort();
       
  2607     QCOMPARE(actual, expectedSubKey);
       
  2608 
       
  2609     actual = settings1.entryList("");
       
  2610     QVERIFY(containsSubList(initialKeys, actual));
       
  2611 
       
  2612     actual = settings1.subkeyList("");
       
  2613     QVERIFY(actual.contains("alpha"));
       
  2614 
       
  2615     actual = settings1.subkeyList("foo/bar/baz");
       
  2616     QVERIFY(actual.isEmpty());
       
  2617 
       
  2618     actual = settings1.subkeyList("alpha/epsilon");
       
  2619     expectedSubKey = QStringList() << "zeta";
       
  2620     QCOMPARE(actual, expectedSubKey);
       
  2621 #else
       
  2622     QSKIP("Compiled without Qt3Support", SkipAll);
       
  2623 #endif
       
  2624 }
       
  2625 
       
  2626 void tst_QSettings::testCaseSensitivity_data()
       
  2627 {
       
  2628     populateWithFormats();
       
  2629 }
       
  2630 
       
  2631 void tst_QSettings::testCaseSensitivity()
       
  2632 {
       
  2633     QFETCH(QSettings::Format, format);
       
  2634 
       
  2635     for (int pass = 0; pass < 2; ++pass) {
       
  2636         QSettings settings(format, QSettings::UserScope, "software.org", "KillerAPP");
       
  2637         settings.beginGroup("caseSensitivity");
       
  2638 
       
  2639         bool cs = true;
       
  2640 #ifndef QT_QSETTINGS_ALWAYS_CASE_SENSITIVE_AND_FORGET_ORIGINAL_KEY_ORDER
       
  2641         switch (format) {
       
  2642         case QSettings::NativeFormat:
       
  2643 #ifdef Q_OS_DARWIN
       
  2644             cs = true;
       
  2645 #else
       
  2646             cs = false;
       
  2647 #endif
       
  2648             break;
       
  2649         case QSettings::IniFormat:
       
  2650             cs = false;
       
  2651             break;
       
  2652         case QSettings::CustomFormat1:
       
  2653             cs = true;
       
  2654             break;
       
  2655         case QSettings::CustomFormat2:
       
  2656             cs = false;
       
  2657             break;
       
  2658         default:
       
  2659             ;
       
  2660         }
       
  2661 #endif
       
  2662 
       
  2663         if (pass == 0) {
       
  2664             settings.setValue("key 1", 1);
       
  2665             settings.setValue("KEY 1", 2);
       
  2666             settings.setValue("key 2", 3);
       
  2667         }
       
  2668 
       
  2669         for (int i = 0; i < 2; ++i) {
       
  2670             QVERIFY(settings.contains("key 1"));
       
  2671             QVERIFY(settings.contains("KEY 1"));
       
  2672             QCOMPARE(settings.value("KEY 1").toInt(), 2);
       
  2673 /*            QVERIFY(settings.allKeys().contains("/KEY 1"));
       
  2674             QVERIFY(settings.allKeys().contains("/key 2")); */
       
  2675 
       
  2676             if (cs) {
       
  2677                 QVERIFY(!settings.contains("kEy 1"));
       
  2678                 QCOMPARE(settings.value("key 1").toInt(), 1);
       
  2679                 QCOMPARE(settings.allKeys().size(), 3);
       
  2680                 QVERIFY(settings.allKeys().contains("key 1"));
       
  2681             } else {
       
  2682                 QVERIFY(settings.contains("kEy 1"));
       
  2683                 QCOMPARE(settings.value("kEy 1").toInt(), 2);
       
  2684                 QCOMPARE(settings.value("key 1").toInt(), 2);
       
  2685                 QCOMPARE(settings.allKeys().size(), 2);
       
  2686             }
       
  2687 
       
  2688             settings.sync();
       
  2689         }
       
  2690 
       
  2691         settings.remove("KeY 1");
       
  2692 
       
  2693         if (cs) {
       
  2694             QVERIFY(!settings.contains("KeY 1"));
       
  2695             QVERIFY(settings.contains("key 1"));
       
  2696             QVERIFY(settings.contains("KEY 1"));
       
  2697             QCOMPARE(settings.value("key 1").toInt(), 1);
       
  2698             QCOMPARE(settings.value("KEY 1").toInt(), 2);
       
  2699             QCOMPARE(settings.allKeys().size(), 3);
       
  2700         } else {
       
  2701             QVERIFY(!settings.contains("KeY 1"));
       
  2702             QVERIFY(!settings.contains("key 1"));
       
  2703             QVERIFY(!settings.contains("KEY 1"));
       
  2704             QCOMPARE(settings.allKeys().size(), 1);
       
  2705         }
       
  2706         settings.setValue("KEY 1", 2);
       
  2707     }
       
  2708 }
       
  2709 
       
  2710 #ifdef QT3_SUPPORT
       
  2711 void tst_QSettings::oldEntryList_data()
       
  2712 {
       
  2713     oldWriteEntry_data();
       
  2714 }
       
  2715 
       
  2716 void tst_QSettings::oldReadEntryIni_data()
       
  2717 {
       
  2718     oldWriteEntry_data();
       
  2719 }
       
  2720 
       
  2721 void tst_QSettings::oldWriteEntryIni_data()
       
  2722 {
       
  2723     oldWriteEntry_data();
       
  2724 }
       
  2725 
       
  2726 void tst_QSettings::oldReadEntry_data()
       
  2727 {
       
  2728     oldWriteEntry_data();
       
  2729 }
       
  2730 
       
  2731 void tst_QSettings::oldWriteEntry_data()
       
  2732 {
       
  2733     // define the test elements we're going to use
       
  2734     QTest::addColumn<QString>("string");
       
  2735     QTest::addColumn<QString>("empty");
       
  2736     QTest::addColumn<QString>("unicode");
       
  2737     QTest::addColumn<int>("integer");
       
  2738     QTest::addColumn<bool>("boolean");
       
  2739     QTest::addColumn<double>("floating");
       
  2740     QTest::addColumn<QStringList>("list");
       
  2741 
       
  2742     QStringList list0;
       
  2743     list0 << "elem1";
       
  2744     list0 << "elem2";
       
  2745     list0 << "elem3";
       
  2746     list0 << "elem4";
       
  2747 
       
  2748     QTest::newRow( "data0") << QString("blah") << QString("") << QString( QChar(0x0E12) ) << 99 << TRUE << 3.1415 << list0;
       
  2749 
       
  2750     QStringList list1;
       
  2751     list1 << " elem1";
       
  2752     list1 << "elem2 ";
       
  2753     list1 << QString();
       
  2754     list1 << "";
       
  2755     list1 << "elem3";
       
  2756     QTest::newRow( "data1") << QString("foo") << QString("") << QString( QChar(0xFEFC) ) << -150 << FALSE << 0.0 << list1;
       
  2757 }
       
  2758 
       
  2759 void tst_QSettings::oldWriteEntryHelper( QSettings &settings )
       
  2760 {
       
  2761     QFETCH( QString, string );
       
  2762     QFETCH( QString, empty );
       
  2763     QFETCH( QString, unicode );
       
  2764     QFETCH( int, integer );
       
  2765     QFETCH( bool, boolean );
       
  2766     QFETCH( double, floating );
       
  2767     QFETCH( QStringList, list );
       
  2768 
       
  2769     QVERIFY( settings.writeEntry( "/Trolltech/QSettingsTesting", string ) );
       
  2770     QVERIFY( settings.writeEntry( "/Trolltech/QSettingsTesting/String", string ) );
       
  2771     QVERIFY( settings.writeEntry( "/Trolltech/QSettingsTesting/Empty", empty ) );
       
  2772     QVERIFY( settings.writeEntry( "/Trolltech/QSettingsTesting/Unicode", unicode ) );
       
  2773     QVERIFY( settings.writeEntry( "/Trolltech/QSettingsTesting/Integer", integer ) );
       
  2774     QVERIFY( settings.writeEntry( "/Trolltech/QSettingsTesting/Boolean", boolean ) );
       
  2775     QVERIFY( settings.writeEntry( "/Trolltech/QSettingsTesting/Floating", floating ) );
       
  2776     QVERIFY( settings.writeEntry( "/Trolltech/QSettingsTesting/List", list ) );
       
  2777 }
       
  2778 
       
  2779 void tst_QSettings::oldReadEntryHelper( QSettings &settings )
       
  2780 {
       
  2781     bool ok;
       
  2782 
       
  2783     QFETCH( QString, string );
       
  2784     QFETCH( QString, empty );
       
  2785     QFETCH( QString, unicode );
       
  2786     QFETCH( int, integer );
       
  2787     QFETCH( bool, boolean );
       
  2788     QFETCH( double, floating );
       
  2789     QFETCH( QStringList, list );
       
  2790 
       
  2791     QCOMPARE( settings.readEntry( "/Trolltech/QSettingsTesting", QString::null, &ok ), string );
       
  2792     QVERIFY( ok );
       
  2793     QCOMPARE( settings.readEntry( "/Trolltech/QSettingsTesting/String", QString::null, &ok ), string );
       
  2794     QVERIFY( ok );
       
  2795     QCOMPARE( settings.readEntry( "/Trolltech/QSettingsTesting/Empty", QString::null, &ok ), empty );
       
  2796     QVERIFY( ok );
       
  2797     QCOMPARE( settings.readEntry( "/Trolltech/QSettingsTesting/Unicode", QString::null, &ok ), unicode );
       
  2798     QVERIFY( ok );
       
  2799     QCOMPARE( settings.readNumEntry( "/Trolltech/QSettingsTesting/Integer", 0, &ok ), integer );
       
  2800     QVERIFY( ok );
       
  2801     QCOMPARE( settings.readBoolEntry( "/Trolltech/QSettingsTesting/Boolean", 0, &ok ), boolean );
       
  2802     QVERIFY( ok );
       
  2803     QCOMPARE( settings.readDoubleEntry( "/Trolltech/QSettingsTesting/Floating", 0, &ok ), floating );
       
  2804     QVERIFY( ok );
       
  2805     QCOMPARE( settings.readListEntry( "/Trolltech/QSettingsTesting/List", &ok ), list );
       
  2806     QVERIFY( ok );
       
  2807 
       
  2808     settings.readListEntry( "/Trolltech/QSettingsTesting/NonExistingValue", &ok );
       
  2809     QVERIFY( !ok );
       
  2810 }
       
  2811 
       
  2812 void tst_QSettings::oldWriteEntryIni()
       
  2813 {
       
  2814     QSettings settings(QSettings::IniFormat, QSettings::UserScope, "software.org", "KillerAPP");
       
  2815     oldWriteEntryHelper(settings);
       
  2816 }
       
  2817 
       
  2818 void tst_QSettings::oldReadEntryIni()
       
  2819 {
       
  2820     {
       
  2821 	QSettings writeSettings(QSettings::IniFormat, QSettings::UserScope, "software.org", "KillerAPP");
       
  2822 	oldWriteEntryHelper( writeSettings );
       
  2823     }
       
  2824     {
       
  2825 	QSettings readSettings(QSettings::IniFormat, QSettings::UserScope, "software.org", "KillerAPP");
       
  2826 	oldReadEntryHelper( readSettings );
       
  2827     }
       
  2828 }
       
  2829 
       
  2830 
       
  2831 void tst_QSettings::oldEndGroup_data()
       
  2832 {
       
  2833     oldBeginGroup_data();
       
  2834 }
       
  2835 
       
  2836 void tst_QSettings::oldResetGroup_data()
       
  2837 {
       
  2838     oldBeginGroup_data();
       
  2839 }
       
  2840 
       
  2841 void tst_QSettings::oldBeginGroup_data()
       
  2842 {
       
  2843     // define the test elements we're going to use
       
  2844     QTest::addColumn<QString>("group");
       
  2845     QTest::addColumn<QString>("value");
       
  2846 
       
  2847     QTest::newRow( "data0") << QString("blah") << "value";
       
  2848     QTest::newRow( "data1") << QString("") << "first/value";
       
  2849     QTest::newRow( "data2") << QString("first/second") << "value";
       
  2850     QTest::newRow( "data3") << QString("first/second/third") << "value";
       
  2851     QTest::newRow( "data4") << QString("first/second/third") << "value";
       
  2852 }
       
  2853 
       
  2854 void tst_QSettings::oldBeginGroup()
       
  2855 {
       
  2856     bool ok;
       
  2857 
       
  2858     QFETCH( QString, group );
       
  2859     QFETCH( QString, value );
       
  2860 
       
  2861     QSettings settings("software.org", "KillerAPP");
       
  2862 
       
  2863     QCOMPARE(settings.group(), QString());
       
  2864     settings.beginGroup( group );
       
  2865     QCOMPARE(settings.group(), group);
       
  2866 
       
  2867     QVERIFY( settings.writeEntry( "/" + value, value ) );
       
  2868     QCOMPARE( settings.readEntry( "/" + value ), value );
       
  2869     settings.endGroup();
       
  2870     QCOMPARE( settings.readEntry( group + "/" + value, QString::null, &ok ), value );
       
  2871     QVERIFY( ok );
       
  2872 }
       
  2873 
       
  2874 void tst_QSettings::oldEndGroup()
       
  2875 {
       
  2876     QFETCH( QString, group );
       
  2877 
       
  2878     QSettings settings("software.org", "KillerAPP");
       
  2879     QCOMPARE( settings.group(), QString() );
       
  2880 
       
  2881     settings.beginGroup( group );
       
  2882     settings.endGroup();
       
  2883     QCOMPARE( settings.group(), QString() );
       
  2884 
       
  2885     settings.beginGroup( group );
       
  2886     settings.beginGroup( group );
       
  2887     settings.endGroup();
       
  2888     QCOMPARE( settings.group(), group );
       
  2889     settings.endGroup();
       
  2890     QCOMPARE( settings.group(), QString() );
       
  2891 
       
  2892     QTest::ignoreMessage(QtWarningMsg, "QSettings::endGroup: No matching beginGroup()");
       
  2893     settings.endGroup();
       
  2894     QCOMPARE( settings.group(), QString() );
       
  2895 }
       
  2896 
       
  2897 void tst_QSettings::oldResetGroup()
       
  2898 {
       
  2899     QFETCH( QString, group );
       
  2900 
       
  2901     QSettings settings("software.org", "KillerAPP");
       
  2902     settings.beginGroup( group );
       
  2903 
       
  2904     settings.resetGroup();
       
  2905     QCOMPARE( settings.group(), QString() );
       
  2906 }
       
  2907 
       
  2908 void tst_QSettings::oldEntryList()
       
  2909 {
       
  2910     {
       
  2911 	QSettings writeSettings("software.org", "KillerAPP");
       
  2912 	oldWriteEntryHelper( writeSettings );
       
  2913     }
       
  2914 
       
  2915     QStringList entryKeys;
       
  2916     entryKeys << "String" << "Empty" << "Unicode" << "Integer" << "Boolean" << "Floating" << "List";
       
  2917 
       
  2918     QSettings readSettings("software.org", "KillerAPP");
       
  2919     QStringList entryList = readSettings.entryList( "/Trolltech/QSettingsTesting/" );
       
  2920     entryKeys.sort();
       
  2921     entryList.sort();
       
  2922     QCOMPARE( entryKeys, entryList );
       
  2923 }
       
  2924 
       
  2925 void tst_QSettings::oldWriteEntry_QString_bool_data()
       
  2926 {
       
  2927     QTest::addColumn<bool>("b");
       
  2928     QTest::newRow( "false" ) << bool(FALSE);
       
  2929     QTest::newRow( "true" ) << bool(TRUE);
       
  2930 }
       
  2931 
       
  2932 void tst_QSettings::oldWriteEntry_QString_bool()
       
  2933 {
       
  2934     {
       
  2935 	QSettings writeSettings("software.org", "KillerAPP");
       
  2936 	QFETCH( bool, b );
       
  2937 	QVERIFY( writeSettings.writeEntry( "/Trolltech/QSettingsTesting/Boolean", b ) );
       
  2938     }
       
  2939 
       
  2940     {
       
  2941 	QSettings readSettings("software.org", "KillerAPP");
       
  2942 	QFETCH( bool, b );
       
  2943 	bool ok = FALSE;
       
  2944 	QCOMPARE( readSettings.readBoolEntry( "/Trolltech/QSettingsTesting/Boolean", 0, &ok ), b );
       
  2945 	QVERIFY( ok );
       
  2946     }
       
  2947 }
       
  2948 
       
  2949 void tst_QSettings::oldWriteEntry_QString_double_data()
       
  2950 {
       
  2951     QTest::addColumn<double>("f");
       
  2952     QTest::newRow( "data0" ) << 3.1415;
       
  2953     QTest::newRow( "data1" ) << 0.0;
       
  2954     QTest::newRow( "data2" ) << 0.0000000000000000000000000001;
       
  2955 }
       
  2956 
       
  2957 void tst_QSettings::oldWriteEntry_QString_double()
       
  2958 {
       
  2959     {
       
  2960 	QSettings writeSettings("software.org", "KillerAPP");
       
  2961 	QFETCH( double, f );
       
  2962 	QVERIFY( writeSettings.writeEntry( "/Trolltech/QSettingsTesting/Floating", f ) );
       
  2963     }
       
  2964     {
       
  2965 	QSettings readSettings("software.org", "KillerAPP");
       
  2966 	QFETCH( double, f );
       
  2967 	bool ok = FALSE;
       
  2968 	QCOMPARE( readSettings.readDoubleEntry( "/Trolltech/QSettingsTesting/Floating", 0, &ok ), f );
       
  2969 	QVERIFY( ok );
       
  2970     }
       
  2971 }
       
  2972 
       
  2973 void tst_QSettings::oldWriteEntry_QString_int_data()
       
  2974 {
       
  2975     QTest::addColumn<int>("i");
       
  2976     QTest::newRow( "data0" ) << int(0);
       
  2977     QTest::newRow( "data1" ) << int(1);
       
  2978     QTest::newRow( "data2" ) << int(11);
       
  2979     QTest::newRow( "data3" ) << int(111);
       
  2980     QTest::newRow( "data4" ) << int(1111);
       
  2981     QTest::newRow( "data5" ) << int(11111);
       
  2982     QTest::newRow( "data6" ) << int(-1);
       
  2983     QTest::newRow( "data7" ) << int(-11);
       
  2984     QTest::newRow( "data8" ) << int(-111);
       
  2985     QTest::newRow( "data9" ) << int(-1111);
       
  2986     QTest::newRow( "data10" ) << int(-11111);
       
  2987 }
       
  2988 
       
  2989 void tst_QSettings::oldWriteEntry_QString_int()
       
  2990 {
       
  2991     {
       
  2992 	QSettings writeSettings("software.org", "KillerAPP");
       
  2993 	QFETCH( int, i );
       
  2994 	QVERIFY( writeSettings.writeEntry( "/Trolltech/QSettingsTesting/Integer", i ) );
       
  2995     }
       
  2996     {
       
  2997 	QSettings readSettings("software.org", "KillerAPP");
       
  2998 	QFETCH( int, i );
       
  2999 	bool ok = FALSE;
       
  3000 	QCOMPARE( readSettings.readNumEntry( "/Trolltech/QSettingsTesting/Integer", 0, &ok ), i );
       
  3001 	QVERIFY( ok );
       
  3002     }
       
  3003 }
       
  3004 
       
  3005 void tst_QSettings::oldWriteEntry_QString_QString_data()
       
  3006 {
       
  3007     QTest::addColumn<QString>("s");
       
  3008     QTest::newRow( "data0" ) << QString( "blah" );
       
  3009     QTest::newRow( "data1" ) << QString( "" );
       
  3010     QTest::newRow( "data2" ) << QString( QChar(0x0E12) ); // unicode
       
  3011     QTest::newRow( "data3" ) << QString("foo");
       
  3012 //    QTest::newRow( "data4" ) << QString::null;	       // nul string (not supported on Windows!)
       
  3013     QTest::newRow( "data5" ) << QString( QChar(0xFEFC) ); // more unicode
       
  3014     QTest::newRow( "data6" ) << QString( "This is s short string" );
       
  3015     QTest::newRow( "data7" ) << QString( "This is a string with a cr\nand some text on the second line" );
       
  3016     QTest::newRow( "data8" ) << QString( "\n" );
       
  3017     QTest::newRow( "data9" ) << QString( "01234567890, abcdefghijklmnopqrestuvxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ~`!@#$%^&*()_+=-[{]}\\|'\":;/?.>,<" );
       
  3018 }
       
  3019 
       
  3020 void tst_QSettings::oldWriteEntry_QString_QString()
       
  3021 {
       
  3022     {
       
  3023 	QSettings writeSettings("software.org", "KillerAPP");
       
  3024 	QFETCH( QString, s );
       
  3025 	QVERIFY( writeSettings.writeEntry( "/Trolltech/QSettingsTesting/String", s ) );
       
  3026     }
       
  3027     {
       
  3028 	QSettings readSettings("software.org", "KillerAPP");
       
  3029 	QFETCH( QString, s );
       
  3030 	bool ok = FALSE;
       
  3031 	QCOMPARE( readSettings.readEntry( "/Trolltech/QSettingsTesting/String", QString::null, &ok ), s );
       
  3032 	QVERIFY( ok );
       
  3033     }
       
  3034 }
       
  3035 
       
  3036 void tst_QSettings::oldWriteEntry_QString_QStringList_data()
       
  3037 {
       
  3038     QTest::addColumn<QStringList>("l");
       
  3039     QStringList list0;
       
  3040     list0 << "elem1";
       
  3041     list0 << "elem2";
       
  3042     list0 << "elem3";
       
  3043     list0 << "elem4";
       
  3044 
       
  3045     QTest::newRow( "data0") << list0;
       
  3046 
       
  3047     QStringList list1;
       
  3048     list1 << " elem1";
       
  3049     list1 << "elem2 ";
       
  3050     list1 << QString();
       
  3051     list1 << "";
       
  3052     list1 << "elem3";
       
  3053     QTest::newRow( "data1") << list1;
       
  3054 
       
  3055     QStringList list2;
       
  3056     list2 << " elem1";
       
  3057     list2 << "elem2 bla bla bla, yada yada, 01234567890, abcdefghijklmnopqrestuvxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ~`!@#$%^&*()_+=-[{]}\\|'\":;/?.>,<";
       
  3058     list1 << QString();
       
  3059     list2 << "\n";
       
  3060     list2 << "elem3\nand another line";
       
  3061     QTest::newRow( "data2") << list2;
       
  3062 }
       
  3063 
       
  3064 void tst_QSettings::oldWriteEntry_QString_QStringList()
       
  3065 {
       
  3066     {
       
  3067 	QSettings writeSettings("software.org", "KillerAPP");
       
  3068 	QFETCH( QStringList, l );
       
  3069 	QVERIFY( writeSettings.writeEntry( "/Trolltech/QSettingsTesting/List", l ) );
       
  3070     }
       
  3071     {
       
  3072 	QSettings readSettings("software.org", "KillerAPP");
       
  3073 	QFETCH( QStringList, l );
       
  3074 	bool ok = FALSE;
       
  3075 	QCOMPARE( readSettings.readListEntry( "/Trolltech/QSettingsTesting/List", &ok ), l );
       
  3076 	QVERIFY( ok );
       
  3077     }
       
  3078 }
       
  3079 
       
  3080 void tst_QSettings::oldWriteEntry_QString_QStringList_QChar_data()
       
  3081 {
       
  3082     QTest::addColumn<QStringList>("l");
       
  3083     QTest::addColumn<QString>("sep");
       
  3084 
       
  3085     QStringList list0;
       
  3086     list0 << "elem1";
       
  3087     list0 << "elem2";
       
  3088     list0 << "elem3";
       
  3089     list0 << "elem4";
       
  3090 
       
  3091     QTest::newRow( "data00") << list0 << "\\";
       
  3092     QTest::newRow( "data01") << list0 << "/";
       
  3093     QTest::newRow( "data02") << list0 << " ";
       
  3094 
       
  3095     QStringList list1;
       
  3096     list1 << " elem1";
       
  3097     list1 << "elem2 ";
       
  3098     list1 << "elem3";
       
  3099     QTest::newRow( "data10") << list1 << "\\";
       
  3100     QTest::newRow( "data11") << list1 << "/";
       
  3101     QTest::newRow( "data12") << list1 << "&";
       
  3102 
       
  3103     QStringList list2;
       
  3104     list2 << " elem1";
       
  3105     list2 << "elem2 bla bla bla, yada yada, 01234567890, abcdefghijklmnopqrestuvxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ~`!@#$%^*()_+=-[{]}\\|/'\":;?.>,<";
       
  3106     list2 << "\n";
       
  3107     list2 << "elem3\nand another line";
       
  3108     QTest::newRow( "data20") << list2 << "&";
       
  3109 
       
  3110     // an empty stringlist should be stored as an empty string (and return an empty stringlist?)
       
  3111     QStringList list3;
       
  3112     QTest::newRow( "data30") << list3 << "/";
       
  3113 }
       
  3114 
       
  3115 void tst_QSettings::oldWriteEntry_QString_QStringList_QChar()
       
  3116 {
       
  3117     // edba:
       
  3118     // data10, data11, data12, data20, data21 and data22 currently fail.
       
  3119     // This is because the list DOES contain the separator which is a fail IMO, so i
       
  3120     // expect the writeEntry to return FALSE (but it doesn't).
       
  3121     // If my interpretation of the doc is wrong, then the separators should be deleted from
       
  3122     // data10 .. data22.
       
  3123     {
       
  3124 	QSettings writeSettings("software.org", "KillerAPP");
       
  3125 	QFETCH( QStringList, l );
       
  3126 	QFETCH( QString, sep );
       
  3127 	QVERIFY( writeSettings.writeEntry( "/Trolltech/QSettingsTesting/List", l, QChar(sep[0]) ) );
       
  3128     }
       
  3129     {
       
  3130 	QSettings readSettings("software.org", "KillerAPP");
       
  3131 	QFETCH( QStringList, l );
       
  3132 	QFETCH( QString, sep );
       
  3133 	bool ok = FALSE;
       
  3134 	QStringList actual;
       
  3135 	actual = readSettings.readListEntry( "/Trolltech/QSettingsTesting/List", QChar(sep[0]), &ok );
       
  3136 	QVERIFY2( ok, "Read the stringlist from the settings" );
       
  3137 	QCOMPARE( actual, l );
       
  3138     }
       
  3139 }
       
  3140 
       
  3141 void tst_QSettings::oldReadListEntry_QString()
       
  3142 {
       
  3143     DEPENDS_ON( "writeEntry_QString_QStringList" );
       
  3144 }
       
  3145 
       
  3146 void tst_QSettings::oldReadListEntry_QString_QChar()
       
  3147 {
       
  3148     DEPENDS_ON( "writeEntry_QString_QStringList_QChar" );
       
  3149 }
       
  3150 
       
  3151 void tst_QSettings::oldReadEntry()
       
  3152 {
       
  3153     DEPENDS_ON( "writeEntry_QString_QString" );
       
  3154 }
       
  3155 
       
  3156 void tst_QSettings::oldReadNumEntry()
       
  3157 {
       
  3158     DEPENDS_ON( "writeEntry_QString_int" );
       
  3159 }
       
  3160 
       
  3161 void tst_QSettings::oldReadDoubleEntry()
       
  3162 {
       
  3163     DEPENDS_ON( "writeEntry_QString_double" );
       
  3164 }
       
  3165 
       
  3166 void tst_QSettings::oldReadBoolEntry()
       
  3167 {
       
  3168     DEPENDS_ON( "writeEntry_QString_bool" );
       
  3169 }
       
  3170 
       
  3171 void tst_QSettings::oldRemoveEntry()
       
  3172 {
       
  3173     // we'll use this one later
       
  3174     QSettings firstSettings("software.org", "KillerAPP");
       
  3175 
       
  3176     // first write a key
       
  3177     {
       
  3178 	QSettings writeSettings("software.org", "KillerAPP");
       
  3179 	writeSettings.writeEntry( "/Trolltech/QSettingsTesting/removeEntry", "foobar" );
       
  3180     }
       
  3181 
       
  3182     // check that the key exists
       
  3183     {
       
  3184 	QSettings readSettings("software.org", "KillerAPP");
       
  3185 	bool ok = FALSE;
       
  3186 	QString foo = readSettings.readEntry( "/Trolltech/QSettingsTesting/removeEntry", QString::null, &ok  );
       
  3187 	QVERIFY( ok );
       
  3188 	QVERIFY( foo == "foobar" );
       
  3189 
       
  3190 	// and remove it
       
  3191 	QVERIFY( readSettings.removeEntry( "/Trolltech/QSettingsTesting/removeEntry") );
       
  3192 
       
  3193 	// check that it is gone
       
  3194 	QString foo2 = readSettings.readEntry( "/Trolltech/QSettingsTesting/removeEntry", QString::null, &ok  );
       
  3195 	QVERIFY( ok == FALSE );
       
  3196 	QVERIFY( foo2 == "" );
       
  3197     }
       
  3198 
       
  3199     // Take another chance with a fresh instance
       
  3200     {
       
  3201 	QSettings readSettings("software.org", "KillerAPP");
       
  3202 	bool ok = FALSE;
       
  3203 	QString foo = readSettings.readEntry( "/Trolltech/QSettingsTesting/removeEntry", QString::null, &ok  );
       
  3204 	QVERIFY( ok == FALSE );
       
  3205 	QVERIFY( foo == "" );
       
  3206     }
       
  3207 
       
  3208     // and another chance with an instance that existed already
       
  3209     {
       
  3210 	bool ok = FALSE;
       
  3211 	QString foo = firstSettings.readEntry( "/Trolltech/QSettingsTesting/removeEntry", QString::null, &ok  );
       
  3212 	QVERIFY( ok == FALSE );
       
  3213 	QVERIFY( foo == "" );
       
  3214     }
       
  3215 }
       
  3216 
       
  3217 void tst_QSettings::oldGlobalVersusLocal()
       
  3218 {
       
  3219     { //write global
       
  3220         QSettings settings("foo");
       
  3221         settings.setPath("software.org", "KillerAPP", QSettings::Global);
       
  3222         settings.writeEntry("/vs/just_global/", "from Global");
       
  3223         settings.writeEntry("/vs/local_and_global/", "from Global");
       
  3224     }
       
  3225     { //write local
       
  3226         QSettings settings("bar");
       
  3227         settings.setPath("software.org", "KillerAPP", QSettings::User);
       
  3228         settings.writeEntry("/vs/local_and_global/", "from User");
       
  3229     }
       
  3230     bool ok;
       
  3231     {
       
  3232         QSettings settings("baz");
       
  3233         settings.setPath("software.org", "KillerAPP", QSettings::User);
       
  3234         QString just_global = settings.readEntry("/vs/just_global/", "not_available", &ok);
       
  3235 	    QVERIFY(ok);
       
  3236         QCOMPARE(just_global, QString("from Global"));
       
  3237         QString local_and_global = settings.readEntry("/vs/local_and_global/", "not_available", &ok);
       
  3238 	    QVERIFY(ok);
       
  3239         QCOMPARE(local_and_global, QString("from User"));
       
  3240     }
       
  3241     {
       
  3242         QSettings settings("bat");
       
  3243         settings.setPath("software.org", "KillerAPP", QSettings::Global);
       
  3244         QString just_global = settings.readEntry("/vs/just_global/", "not_available", &ok);
       
  3245         QVERIFY(ok);
       
  3246         QCOMPARE(just_global, QString("from Global"));
       
  3247         QString local_and_global = settings.readEntry("/vs/local_and_global/", "not_available", &ok);
       
  3248         QVERIFY(ok);
       
  3249         QCOMPARE(local_and_global, QString("from Global"));
       
  3250     }
       
  3251 }
       
  3252 #endif // QT3_SUPPORT
       
  3253 
       
  3254 void tst_QSettings::fileName()
       
  3255 {
       
  3256 #ifdef Q_OS_MAC
       
  3257     QSettings s1(QSettings::UserScope, "Apple", "Console");
       
  3258     QSettings s2(QSettings::UserScope, "Apple");
       
  3259     QSettings s3(QSettings::SystemScope, "Apple", "Console");
       
  3260     QSettings s4(QSettings::SystemScope, "Apple");
       
  3261 
       
  3262     QCOMPARE(s1.fileName(), QDir::homePath() + "/Library/Preferences/com.apple.Console.plist");
       
  3263     QCOMPARE(s2.fileName(), QDir::homePath() + "/Library/Preferences/com.apple.plist");
       
  3264     QCOMPARE(s3.fileName(), QString("/Library/Preferences/com.apple.Console.plist"));
       
  3265     QCOMPARE(s4.fileName(), QString("/Library/Preferences/com.apple.plist"));
       
  3266 
       
  3267     QSettings s5(QSettings::SystemScope, "Apple.com", "Console");
       
  3268     QCOMPARE(s5.fileName(), QString("/Library/Preferences/com.apple.Console.plist"));
       
  3269 
       
  3270     QSettings s6(QSettings::SystemScope, "apple.com", "Console");
       
  3271     QCOMPARE(s6.fileName(), QString("/Library/Preferences/com.apple.Console.plist"));
       
  3272 
       
  3273     QSettings s7(QSettings::SystemScope, "apple.Com", "Console");
       
  3274     QCOMPARE(s7.fileName(), QString("/Library/Preferences/com.apple.Console.plist"));
       
  3275 
       
  3276     QSettings s8(QSettings::SystemScope, "apple.fr", "Console");
       
  3277     QCOMPARE(s8.fileName(), QString("/Library/Preferences/fr.apple.Console.plist"));
       
  3278 
       
  3279     QSettings s9(QSettings::SystemScope, "apple.co.jp", "Console");
       
  3280     QCOMPARE(s9.fileName(), QString("/Library/Preferences/jp.co.apple.Console.plist"));
       
  3281 
       
  3282     QSettings s10(QSettings::SystemScope, "apple.org", "Console");
       
  3283     QCOMPARE(s10.fileName(), QString("/Library/Preferences/org.apple.Console.plist"));
       
  3284 
       
  3285     QSettings s11(QSettings::SystemScope, "apple.net", "Console");
       
  3286     QCOMPARE(s11.fileName(), QString("/Library/Preferences/net.apple.Console.plist"));
       
  3287 
       
  3288     QSettings s12(QSettings::SystemScope, "apple.museum", "Console");
       
  3289     QCOMPARE(s12.fileName(), QString("/Library/Preferences/museum.apple.Console.plist"));
       
  3290 
       
  3291     QSettings s13(QSettings::SystemScope, "apple.FR", "Console");
       
  3292     QCOMPARE(s13.fileName(), QString("/Library/Preferences/fr.apple.Console.plist"));
       
  3293 
       
  3294     QSettings s14(QSettings::SystemScope, "apple.mUseum", "Console");
       
  3295     QCOMPARE(s14.fileName(), QString("/Library/Preferences/museum.apple.Console.plist"));
       
  3296 
       
  3297     QSettings s15(QSettings::SystemScope, "apple.zz", "Console");
       
  3298     QCOMPARE(s15.fileName(), QString("/Library/Preferences/zz.apple.Console.plist"));
       
  3299 
       
  3300     QSettings s15_prime(QSettings::SystemScope, "apple.foo", "Console");
       
  3301     QCOMPARE(s15_prime.fileName(), QString("/Library/Preferences/com.apple-foo.Console.plist"));
       
  3302 
       
  3303     QSettings s16(QSettings::SystemScope, "apple.f", "Console");
       
  3304     QCOMPARE(s16.fileName(), QString("/Library/Preferences/com.apple-f.Console.plist"));
       
  3305 
       
  3306     QSettings s17(QSettings::SystemScope, "apple.", "Console");
       
  3307     QCOMPARE(s17.fileName(), QString("/Library/Preferences/com.apple.Console.plist"));
       
  3308 
       
  3309     QSettings s18(QSettings::SystemScope, "Foo, Inc.", "Console");
       
  3310     QCOMPARE(s18.fileName(), QString("/Library/Preferences/com.foo-inc.Console.plist"));
       
  3311 
       
  3312     QSettings s19(QSettings::SystemScope, "Foo, Inc.com", "Console");
       
  3313     QCOMPARE(s19.fileName(), QString("/Library/Preferences/com.foo, inc.Console.plist"));
       
  3314 
       
  3315     QSettings s20(QSettings::SystemScope, QLatin1String("   ") + QChar(0xbd) + QLatin1String("Foo//:/Barxxx  Baz!()#@.com"), "Console");
       
  3316     QCOMPARE(s20.fileName(), QLatin1String("/Library/Preferences/com.   ") + QChar(0xbd) + QLatin1String("foo  : barxxx  baz!()#@.Console.plist"));
       
  3317 
       
  3318     QSettings s21(QSettings::SystemScope, QLatin1String("   ") + QChar(0xbd) + QLatin1String("Foo//:/Bar,,,  Baz!()#"), "Console");
       
  3319     QCOMPARE(s21.fileName(), QString("/Library/Preferences/com.foo-bar-baz.Console.plist"));
       
  3320 #else
       
  3321     QSKIP("Please write a fileName() test for the other platforms", SkipAll);
       
  3322 #endif
       
  3323 }
       
  3324 
       
  3325 void tst_QSettings::isWritable_data()
       
  3326 {
       
  3327     populateWithFormats();
       
  3328 }
       
  3329 
       
  3330 void tst_QSettings::isWritable()
       
  3331 {
       
  3332     QFETCH(QSettings::Format, format);
       
  3333 
       
  3334     {
       
  3335         QSettings s1(format, QSettings::UserScope, "software.org", "KillerAPP");
       
  3336         s1.setValue("foo", 1);
       
  3337         s1.sync();
       
  3338         // that should create the file
       
  3339     }
       
  3340 
       
  3341     {
       
  3342         QSettings s1(format, QSettings::UserScope, "software.org", "KillerAPP");
       
  3343         QVERIFY(s1.isWritable());
       
  3344     }
       
  3345 
       
  3346     {
       
  3347         QSettings s1(format, QSettings::SystemScope, "software.org", "KillerAPP");
       
  3348         s1.setValue("foo", 1);
       
  3349         s1.sync();
       
  3350         // that should create the file, *if* we have the permissions
       
  3351     }
       
  3352 
       
  3353     {
       
  3354         QSettings s1(format, QSettings::SystemScope, "software.org", "KillerAPP");
       
  3355         QSettings s2(format, QSettings::SystemScope, "software.org", "Something Different");
       
  3356         QSettings s3(format, QSettings::SystemScope, "foo.org", "Something Different");
       
  3357         if (s1.contains("foo")) {
       
  3358             QVERIFY(s1.isWritable());
       
  3359             QVERIFY(s2.isWritable());
       
  3360             QVERIFY(s3.isWritable());
       
  3361         } else {
       
  3362             QVERIFY(!s1.isWritable());
       
  3363             QVERIFY(!s2.isWritable());
       
  3364             QVERIFY(!s3.isWritable());
       
  3365         }
       
  3366     }
       
  3367 }
       
  3368 
       
  3369 void tst_QSettings::childGroups_data()
       
  3370 {
       
  3371     populateWithFormats();
       
  3372 }
       
  3373 
       
  3374 void tst_QSettings::childGroups()
       
  3375 {
       
  3376 #ifdef QT_BUILD_INTERNAL
       
  3377     QFETCH(QSettings::Format, format);
       
  3378 
       
  3379     {
       
  3380         QSettings settings(format, QSettings::SystemScope, "software.org");
       
  3381         settings.setValue("alpha", "1");
       
  3382         settings.setValue("alpha/a", "2");
       
  3383         settings.setValue("alpha/b", "3");
       
  3384         settings.setValue("alpha/c", "4");
       
  3385         settings.setValue("beta", "5");
       
  3386         settings.setValue("gamma", "6");
       
  3387         settings.setValue("gamma/d", "7");
       
  3388         settings.setValue("gamma/d/e", "8");
       
  3389         settings.setValue("gamma/f/g", "9");
       
  3390         settings.setValue("omicron/h/i/j/x", "10");
       
  3391         settings.setValue("omicron/h/i/k/y", "11");
       
  3392         settings.setValue("zeta/z", "12");
       
  3393     }
       
  3394 
       
  3395     for (int pass = 0; pass < 3; ++pass) {
       
  3396         QConfFile::clearCache();
       
  3397         QSettings settings(format, QSettings::SystemScope, "software.org");
       
  3398         settings.setFallbacksEnabled(false);
       
  3399         if (pass == 1) {
       
  3400             settings.value("gamma/d");
       
  3401         } else if (pass == 2) {
       
  3402             settings.value("gamma");
       
  3403         }
       
  3404 
       
  3405         settings.beginGroup("gamma");
       
  3406         QCOMPARE(settings.childGroups(), QStringList() << "d" << "f");
       
  3407         settings.beginGroup("d");
       
  3408         QCOMPARE(settings.childGroups(), QStringList());
       
  3409         settings.endGroup();
       
  3410         settings.endGroup();
       
  3411 
       
  3412         settings.beginGroup("alpha");
       
  3413         QCOMPARE(settings.childGroups(), QStringList());
       
  3414         settings.endGroup();
       
  3415 
       
  3416         settings.beginGroup("d");
       
  3417         QCOMPARE(settings.childGroups(), QStringList());
       
  3418         settings.endGroup();
       
  3419 
       
  3420         settings.beginGroup("/omicron///h/i///");
       
  3421         QCOMPARE(settings.childGroups(), QStringList() << "j" << "k");
       
  3422         settings.endGroup();
       
  3423 
       
  3424         settings.beginGroup("////");
       
  3425         QCOMPARE(settings.childGroups(), QStringList() << "alpha" << "gamma" << "omicron" << "zeta");
       
  3426         settings.endGroup();
       
  3427 
       
  3428         QCOMPARE(settings.childGroups(), QStringList() << "alpha" << "gamma" << "omicron" << "zeta");
       
  3429     }
       
  3430 #endif
       
  3431 }
       
  3432 
       
  3433 void tst_QSettings::childKeys_data()
       
  3434 {
       
  3435     populateWithFormats();
       
  3436 }
       
  3437 
       
  3438 void tst_QSettings::childKeys()
       
  3439 {
       
  3440 #ifdef QT_BUILD_INTERNAL
       
  3441     QFETCH(QSettings::Format, format);
       
  3442 
       
  3443     {
       
  3444         QSettings settings(format, QSettings::SystemScope, "software.org");
       
  3445         settings.setValue("alpha", "1");
       
  3446         settings.setValue("alpha/a", "2");
       
  3447         settings.setValue("alpha/b", "3");
       
  3448         settings.setValue("alpha/c", "4");
       
  3449         settings.setValue("beta", "5");
       
  3450         settings.setValue("gamma", "6");
       
  3451         settings.setValue("gamma/d", "7");
       
  3452         settings.setValue("gamma/d/e", "8");
       
  3453         settings.setValue("gamma/f/g", "9");
       
  3454         settings.setValue("omicron/h/i/j/x", "10");
       
  3455         settings.setValue("omicron/h/i/k/y", "11");
       
  3456         settings.setValue("zeta/z", "12");
       
  3457     }
       
  3458 
       
  3459     for (int pass = 0; pass < 3; ++pass) {
       
  3460         QConfFile::clearCache();
       
  3461         QSettings settings(format, QSettings::SystemScope, "software.org");
       
  3462         settings.setFallbacksEnabled(false);
       
  3463         if (pass == 1) {
       
  3464             settings.value("gamma/d");
       
  3465         } else if (pass == 2) {
       
  3466             settings.value("gamma");
       
  3467         }
       
  3468 
       
  3469         settings.beginGroup("gamma");
       
  3470         QCOMPARE(settings.childKeys(), QStringList() << "d");
       
  3471         settings.beginGroup("d");
       
  3472         QCOMPARE(settings.childKeys(), QStringList() << "e");
       
  3473         settings.endGroup();
       
  3474         settings.endGroup();
       
  3475 
       
  3476         settings.beginGroup("alpha");
       
  3477         QCOMPARE(settings.childKeys(), QStringList() << "a" << "b" << "c");
       
  3478         settings.endGroup();
       
  3479 
       
  3480         settings.beginGroup("d");
       
  3481         QCOMPARE(settings.childKeys(), QStringList());
       
  3482         settings.endGroup();
       
  3483 
       
  3484         settings.beginGroup("/omicron///h/i///");
       
  3485         QCOMPARE(settings.childKeys(), QStringList());
       
  3486         settings.endGroup();
       
  3487 
       
  3488         settings.beginGroup("////");
       
  3489         QCOMPARE(settings.childKeys(), QStringList() << "alpha" << "beta" << "gamma");
       
  3490         settings.endGroup();
       
  3491 
       
  3492         QCOMPARE(settings.childKeys(), QStringList() << "alpha" << "beta" << "gamma");
       
  3493     }
       
  3494 #endif
       
  3495 }
       
  3496 
       
  3497 void tst_QSettings::allKeys_data()
       
  3498 {
       
  3499     populateWithFormats();
       
  3500 }
       
  3501 
       
  3502 void tst_QSettings::allKeys()
       
  3503 {
       
  3504 #ifdef QT_BUILD_INTERNAL
       
  3505     QFETCH(QSettings::Format, format);
       
  3506 
       
  3507     QStringList allKeys;
       
  3508     allKeys << "alpha" << "alpha/a" << "alpha/b" << "alpha/c" << "beta" << "gamma" << "gamma/d"
       
  3509             << "gamma/d/e" << "gamma/f/g" << "omicron/h/i/j/x" << "omicron/h/i/k/y" << "zeta/z";
       
  3510 
       
  3511     {
       
  3512         QSettings settings(format, QSettings::SystemScope, "software.org");
       
  3513         for (int i = 0; i < allKeys.size(); ++i)
       
  3514             settings.setValue(allKeys.at(i), QString::number(i + 1));
       
  3515     }
       
  3516 
       
  3517     for (int pass = 0; pass < 3; ++pass) {
       
  3518         QConfFile::clearCache();
       
  3519         QSettings settings(format, QSettings::SystemScope, "software.org");
       
  3520         settings.setFallbacksEnabled(false);
       
  3521 
       
  3522         if (pass == 1) {
       
  3523             settings.value("gamma/d");
       
  3524         } else if (pass == 2) {
       
  3525             settings.value("gamma");
       
  3526         }
       
  3527 
       
  3528         settings.beginGroup("gamma");
       
  3529         QCOMPARE(settings.allKeys(), QStringList() << "d" << "d/e" << "f/g");
       
  3530         settings.beginGroup("d");
       
  3531         QCOMPARE(settings.allKeys(), QStringList() << "e");
       
  3532         settings.endGroup();
       
  3533         settings.endGroup();
       
  3534 
       
  3535         settings.beginGroup("alpha");
       
  3536         QCOMPARE(settings.allKeys(), QStringList() << "a" << "b" << "c");
       
  3537         settings.endGroup();
       
  3538 
       
  3539         settings.beginGroup("d");
       
  3540         QCOMPARE(settings.allKeys(), QStringList());
       
  3541         settings.endGroup();
       
  3542 
       
  3543         settings.beginGroup("/omicron///h/i///");
       
  3544         QCOMPARE(settings.allKeys(), QStringList() << "j/x" << "k/y");
       
  3545         settings.endGroup();
       
  3546 
       
  3547         settings.beginGroup("////");
       
  3548         QCOMPARE(settings.allKeys(), allKeys);
       
  3549         settings.endGroup();
       
  3550 
       
  3551         QCOMPARE(settings.allKeys(), allKeys);
       
  3552     }
       
  3553 #endif
       
  3554 }
       
  3555 
       
  3556 void tst_QSettings::registerFormat()
       
  3557 {
       
  3558     QSettings settings1(QSettings::IniFormat, QSettings::UserScope, "software.org", "KillerAPP");
       
  3559     QSettings settings2(QSettings::CustomFormat1, QSettings::UserScope, "software.org", "KillerAPP");
       
  3560 
       
  3561     QString fileName = settings1.fileName();
       
  3562     fileName.chop(3); // "ini";
       
  3563     fileName.append("custom1");
       
  3564     QCOMPARE(settings2.fileName(), fileName);
       
  3565 
       
  3566     // OK, let's see if it can read a generated file of a custom type
       
  3567     // Beware: readCustom3File() and writeCustom3File() have unintuitive behavior
       
  3568     // so we can test error handling
       
  3569 
       
  3570     QSettings::Format custom3 = QSettings::registerFormat("custom3", readCustom3File, writeCustom3File);
       
  3571     QVERIFY(custom3 == QSettings::CustomFormat3);
       
  3572 
       
  3573     QDir dir(settingsPath());
       
  3574     QVERIFY(dir.mkpath("someDir"));
       
  3575     QFile f(dir.path()+"/someDir/someSettings.custom3");
       
  3576 
       
  3577     QVERIFY(f.open(QFile::WriteOnly));
       
  3578     f.write("OK");
       
  3579     f.close();
       
  3580 
       
  3581     {
       
  3582     QSettings settings(settingsPath("someDir/someSettings.custom3"), QSettings::CustomFormat3);
       
  3583     QCOMPARE(settings.status(), QSettings::NoError);
       
  3584     QCOMPARE(settings.value("retval").toString(), QString("OK"));
       
  3585     QVERIFY(settings.isWritable());
       
  3586     }
       
  3587 
       
  3588     QVERIFY(f.open(QFile::WriteOnly));
       
  3589     f.write("NotOK");
       
  3590     f.close();
       
  3591 
       
  3592     {
       
  3593     QSettings settings(settingsPath("someDir/someSettings.custom3"), QSettings::CustomFormat3);
       
  3594     QCOMPARE(settings.status(), QSettings::FormatError);
       
  3595     QCOMPARE(settings.value("retval").toString(), QString());
       
  3596     QVERIFY(settings.isWritable());
       
  3597     }
       
  3598 
       
  3599     QVERIFY(f.open(QFile::WriteOnly));
       
  3600     f.write("OK");
       
  3601     f.close();
       
  3602 
       
  3603     {
       
  3604     QSettings settings(settingsPath("someDir/someSettings.custom3"), QSettings::CustomFormat3);
       
  3605     QCOMPARE(settings.status(), QSettings::NoError);
       
  3606     settings.setValue("zzz", "bar");
       
  3607     settings.sync();
       
  3608     QCOMPARE(settings.status(), QSettings::NoError);
       
  3609 
       
  3610     settings.setValue("retval", "NotOK");
       
  3611     settings.sync();
       
  3612     QCOMPARE(settings.status(), QSettings::AccessError);
       
  3613 
       
  3614     QCOMPARE(settings.value("retval").toString(), QString("NotOK"));
       
  3615     QVERIFY(settings.isWritable());
       
  3616     }
       
  3617 
       
  3618     {
       
  3619     QSettings settings(settingsPath("someDir/someSettings.custom3"), QSettings::CustomFormat4);
       
  3620     QCOMPARE(settings.status(), QSettings::AccessError);
       
  3621     QVERIFY(!settings.isWritable());
       
  3622     }
       
  3623 }
       
  3624 
       
  3625 void tst_QSettings::setPath()
       
  3626 {
       
  3627 #define TEST_PATH(doSet, ext, format, scope, path) \
       
  3628     { \
       
  3629     if (doSet) \
       
  3630         QSettings::setPath(QSettings::format, QSettings::scope, settingsPath(path)); \
       
  3631     QSettings settings1(QSettings::format, QSettings::scope, "software.org", "KillerAPP"); \
       
  3632     QCOMPARE(QDir(settings1.fileName()), QDir(settingsPath(path) + QDir::separator() + "software.org" \
       
  3633                                   + QDir::separator() + "KillerAPP." + ext)); \
       
  3634     }
       
  3635 
       
  3636     /*
       
  3637         The first pass checks that setPath() works; the second
       
  3638         path checks that it has no bad side effects.
       
  3639     */
       
  3640     for (int i = 0; i < 2; ++i) {
       
  3641 #if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
       
  3642         TEST_PATH(i == 0, "conf", NativeFormat, UserScope, "alpha")
       
  3643         TEST_PATH(i == 0, "conf", NativeFormat, SystemScope, "beta")
       
  3644 #endif
       
  3645         TEST_PATH(i == 0, "ini", IniFormat, UserScope, "gamma")
       
  3646         TEST_PATH(i == 0, "ini", IniFormat, SystemScope, "omicron")
       
  3647         TEST_PATH(i == 0, "custom1", CustomFormat1, UserScope, "epsilon")
       
  3648         TEST_PATH(i == 0, "custom1", CustomFormat1, SystemScope, "zeta")
       
  3649         TEST_PATH(i == 0, "custom2", CustomFormat2, UserScope, "eta")
       
  3650         TEST_PATH(i == 0, "custom2", CustomFormat2, SystemScope, "iota")
       
  3651     }
       
  3652 }
       
  3653 
       
  3654 void tst_QSettings::setDefaultFormat()
       
  3655 {
       
  3656     QVERIFY(QSettings::defaultFormat() == QSettings::NativeFormat);
       
  3657 
       
  3658     QSettings::setDefaultFormat(QSettings::CustomFormat1);
       
  3659     QSettings settings1("org", "app");
       
  3660     QSettings settings2(QSettings::SystemScope, "org", "app");
       
  3661     QSettings settings3;
       
  3662 
       
  3663     QVERIFY(settings1.format() == QSettings::NativeFormat);
       
  3664     QVERIFY(settings2.format() == QSettings::NativeFormat);
       
  3665     QVERIFY(settings3.format() == QSettings::CustomFormat1);
       
  3666 
       
  3667     QSettings::setDefaultFormat(QSettings::NativeFormat);
       
  3668     QVERIFY(QSettings::defaultFormat() == QSettings::NativeFormat);
       
  3669 
       
  3670     QVERIFY(settings1.format() == QSettings::NativeFormat);
       
  3671     QVERIFY(settings2.format() == QSettings::NativeFormat);
       
  3672     QVERIFY(settings3.format() == QSettings::CustomFormat1);
       
  3673 }
       
  3674 
       
  3675 void tst_QSettings::dontCreateNeedlessPaths()
       
  3676 {
       
  3677     QString path;
       
  3678     {
       
  3679         QSettings settings(QSettings::IniFormat, QSettings::UserScope, "Hello", "Test");
       
  3680         QVariant val = settings.value("foo", "bar");
       
  3681         path = settings.fileName();
       
  3682     }
       
  3683 
       
  3684     QFileInfo fileInfo(path);
       
  3685     QVERIFY(!fileInfo.dir().exists());
       
  3686 }
       
  3687 
       
  3688 #if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
       
  3689 void tst_QSettings::dontReorderIniKeysNeedlessly()
       
  3690 {
       
  3691 #ifdef  QT_QSETTINGS_ALWAYS_CASE_SENSITIVE_AND_FORGET_ORIGINAL_KEY_ORDER
       
  3692     QSKIP("This Qt build does not preserve ordering, as a code size optimization.", SkipAll);
       
  3693 #endif
       
  3694 
       
  3695     /*
       
  3696         This is a very strong test. It asserts that modifying
       
  3697         resourcefile2.ini will lead to the exact contents of
       
  3698         resourcefile3.ini. Right now it's run only on Unix
       
  3699         systems, but that should be enough since the INI
       
  3700         code (unlike this test) is platform-agnostic.
       
  3701 
       
  3702         Things that are tested:
       
  3703 
       
  3704             * keys are written in the same order that they were
       
  3705               read in
       
  3706 
       
  3707             * new keys are put at the end of their respective
       
  3708               sections
       
  3709     */
       
  3710 
       
  3711     QFile inFile(":/resourcefile2.ini");
       
  3712     inFile.open(QIODevice::ReadOnly);
       
  3713     QByteArray contentsBefore = inFile.readAll();
       
  3714     inFile.close();
       
  3715 
       
  3716     QByteArray expectedContentsAfter;
       
  3717 
       
  3718     {
       
  3719         QFile inFile(":/resourcefile3.ini");
       
  3720         inFile.open(QIODevice::ReadOnly);
       
  3721         expectedContentsAfter = inFile.readAll();
       
  3722         inFile.close();
       
  3723     }
       
  3724 
       
  3725     QString outFileName;
       
  3726     QString outFileName2;
       
  3727 
       
  3728     QTemporaryFile outFile;
       
  3729     outFile.open();
       
  3730     outFile.write(contentsBefore);
       
  3731     outFileName = outFile.fileName();
       
  3732     outFile.close();
       
  3733 
       
  3734     QSettings settings(outFileName, QSettings::IniFormat);
       
  3735     QVERIFY(settings.status() == QSettings::NoError);
       
  3736     QVERIFY(settings.isWritable());
       
  3737 
       
  3738     settings.setValue("Field 1/Bottom", 90);
       
  3739     settings.setValue("Field 1/x", 1);
       
  3740     settings.setValue("Field 1/y", 1);
       
  3741     settings.setValue("Field 1/width", 1);
       
  3742     settings.setValue("Field 1/height", 1);
       
  3743     settings.sync();
       
  3744 
       
  3745     QFile outFile2(outFileName);
       
  3746     QVERIFY(outFile2.open(QIODevice::ReadOnly));
       
  3747     QCOMPARE(outFile2.readAll(), expectedContentsAfter);
       
  3748     outFile2.close();
       
  3749 }
       
  3750 #endif
       
  3751 
       
  3752 void tst_QSettings::rainersSyncBugOnMac_data()
       
  3753 {
       
  3754     ctor_data();
       
  3755 }
       
  3756 
       
  3757 void tst_QSettings::rainersSyncBugOnMac()
       
  3758 {
       
  3759     QFETCH(QSettings::Format, format);
       
  3760 
       
  3761     QString fileName;
       
  3762 
       
  3763     {
       
  3764         QSettings s1(format, QSettings::UserScope, "software.org", "KillerAPP");
       
  3765         QCOMPARE(s1.value("key1", 5).toInt(), 5);
       
  3766         fileName = s1.fileName();
       
  3767     }
       
  3768 
       
  3769     {
       
  3770         QSettings s2(fileName, format);
       
  3771         s2.setValue("key1", 25);
       
  3772     }
       
  3773 
       
  3774     {
       
  3775         QSettings s3(format, QSettings::UserScope, "software.org", "KillerAPP");
       
  3776         QCOMPARE(s3.value("key1", 30).toInt(), 25);
       
  3777     }
       
  3778 }
       
  3779 
       
  3780 void tst_QSettings::recursionBug()
       
  3781 {
       
  3782     QPixmap pix(10,10);
       
  3783     pix.fill("blue");
       
  3784 
       
  3785     {
       
  3786         QSettings settings(settingsPath("starrunner.ini"), QSettings::IniFormat);
       
  3787         settings.setValue("General/Pixmap", pix );
       
  3788     }
       
  3789 }
       
  3790 
       
  3791 #ifdef QT3_SUPPORT
       
  3792 void tst_QSettings::setPathBug()
       
  3793 {
       
  3794     QSettings settings("software.org", "KillerAPP", this);
       
  3795     settings.setPath("foo.org", "Bar", QSettings::User);
       
  3796     QVERIFY(settings.parent() == this);
       
  3797     settings.setValue("blah", "BAZ");
       
  3798     settings.setPath("bar.org", "Baz", QSettings::User);
       
  3799     settings.setValue("blah", "BAZ");
       
  3800     QVERIFY(settings.parent() == this);
       
  3801 }
       
  3802 #endif
       
  3803 
       
  3804 /*
       
  3805 // Not tested at the moment.
       
  3806 void tst_QSettings::oldSubkeyList()
       
  3807 {
       
  3808     QVERIFY( TRUE );
       
  3809 }
       
  3810 */
       
  3811 
       
  3812 QTEST_MAIN(tst_QSettings)
       
  3813 #include "tst_qsettings.moc"
       
  3814 
       
  3815 
       
  3816 // foo