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