summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Jenssen <tim.jenssen@digia.com>2013-11-14 16:47:27 +0100
committerTim Jenssen <tim.jenssen@digia.com>2013-11-14 17:17:59 +0100
commit8d6c1d091496950339748bec8099b4feddf0ea12 (patch)
tree7585dcead1ecb8186c33aaa91ca25c6ca4f8919c
parent54e4f19a86e64347f66dfd7345f9428c55123fe0 (diff)
add new settingsoperation
Change-Id: I3c05c51241a19304b43c0fc4f1306b36b6a84c86 Reviewed-by: Karsten Heimrich <karsten.heimrich@digia.com>
-rw-r--r--src/libs/installer/installer.pro6
-rw-r--r--src/libs/installer/settingsoperation.cpp216
-rw-r--r--src/libs/installer/settingsoperation.h66
-rw-r--r--src/libs/kdtools/kdupdaterupdateoperation.cpp34
-rw-r--r--src/libs/kdtools/kdupdaterupdateoperation.h1
-rw-r--r--tests/auto/installer/installer.pro4
-rw-r--r--tests/auto/installer/settingsoperation/settingsoperation.pro6
-rw-r--r--tests/auto/installer/settingsoperation/tst_settingsoperation.cpp328
8 files changed, 657 insertions, 4 deletions
diff --git a/src/libs/installer/installer.pro b/src/libs/installer/installer.pro
index a1631c4a3..1595773f2 100644
--- a/src/libs/installer/installer.pro
+++ b/src/libs/installer/installer.pro
@@ -101,7 +101,8 @@ HEADERS += packagemanagercore.h \
packagemanagercoredata.h \
applyproductkeyoperation.h \
globals.h \
- graph.h
+ graph.h \
+ settingsoperation.h
SOURCES += packagemanagercore.cpp \
packagemanagercore_p.cpp \
@@ -163,7 +164,8 @@ HEADERS += packagemanagercore.h \
createlinkoperation.cpp \
packagemanagercoredata.cpp \
applyproductkeyoperation.cpp \
- globals.cpp
+ globals.cpp \
+ settingsoperation.cpp
RESOURCES += resources/patch_file_lists.qrc \
resources/installer.qrc
diff --git a/src/libs/installer/settingsoperation.cpp b/src/libs/installer/settingsoperation.cpp
new file mode 100644
index 000000000..6fde21268
--- /dev/null
+++ b/src/libs/installer/settingsoperation.cpp
@@ -0,0 +1,216 @@
+/**************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+#include "settingsoperation.h"
+#include "packagemanagercore.h"
+#include "kdupdaterupdateoperations.h"
+
+#include <QSettings>
+#include <QDir>
+#include <QDebug>
+
+using namespace QInstaller;
+
+SettingsOperation::SettingsOperation()
+{
+ setName(QLatin1String("Settings"));
+}
+
+void SettingsOperation::backup()
+{
+}
+
+bool SettingsOperation::checkArguments()
+{
+ const QString path = argumentKeyValue(QLatin1String("path"));
+ const QString method = argumentKeyValue(QLatin1String("method"));
+ const QString key = argumentKeyValue(QLatin1String("key"));
+ const QString aValue = argumentKeyValue(QLatin1String("value"));
+
+ QStringList missingArguments;
+ if (path.isEmpty())
+ missingArguments << QLatin1String("path");
+ if (method.isEmpty())
+ missingArguments << QLatin1String("method");
+ if (key.isEmpty())
+ missingArguments << QLatin1String("key");
+ if (method != QLatin1String("remove") && aValue.isEmpty())
+ missingArguments << QLatin1String("value");
+
+ if (!missingArguments.isEmpty()) {
+ setError(InvalidArguments);
+ setErrorString(tr("Missing argument(s) '%1' calling '%2' with arguments '%3'.").arg(
+ missingArguments.join(QLatin1String("; ")), name(), arguments().join(QLatin1String("; "))));
+ return false;
+ }
+ QStringList possibleMethodValues;
+ possibleMethodValues << QLatin1String("set") << QLatin1String("remove") <<
+ QLatin1String("add_array_value") << QLatin1String("remove_array_value");
+
+ if (!possibleMethodValues.contains(method)) {
+ setError(InvalidArguments);
+ setErrorString(tr("Current method argument calling '%1' with arguments '%2' is not "
+ "supported. Please use set, remove, add_array_value or remove_array_value.").arg(name(),
+ arguments().join(QLatin1String("; "))));
+ return false;
+ }
+ return true;
+}
+
+
+bool SettingsOperation::performOperation()
+{
+ // Arguments:
+ // 1. path=settings file path or registry path
+ // 2. method=set|remove|add_array_value|remove_array_value
+ // 3. key=can be prepended by a category name separated by slash
+ // 4. value=just the value
+ // optional arguments are
+ // formate=native or ini TODO
+ // backup=true or false (default is true) TODO
+ // NOTE: remove and remove_array_value will do nothing at the undostep
+
+ if (!checkArguments())
+ return false;
+ const QString path = argumentKeyValue(QLatin1String("path"));
+ const QString method = argumentKeyValue(QLatin1String("method"));
+ const QString key = argumentKeyValue(QLatin1String("key"));
+ const QString aValue = argumentKeyValue(QLatin1String("value"));
+
+ // use MkdirOperation to get the path so it can remove it with MkdirOperation::undoOperation later
+ KDUpdater::MkdirOperation mkDirOperation;
+ mkDirOperation.setArguments(QStringList() << QFileInfo(path).absolutePath());
+ mkDirOperation.backup();
+ if (!mkDirOperation.performOperation()) {
+ setError(mkDirOperation.error());
+ setErrorString(mkDirOperation.errorString());
+ return false;
+ }
+ setValue(QLatin1String("createddir"), mkDirOperation.value(QLatin1String("createddir")));
+
+ QSettings settings(path, QSettings::IniFormat);
+ if (method == QLatin1String("set"))
+ settings.setValue(key, aValue);
+ else if (method == QLatin1String("remove"))
+ settings.remove(key);
+ else if (method == QLatin1String("add_array_value")) {
+ QVariant valueVariant = settings.value(key);
+ if (valueVariant.canConvert<QStringList>()) {
+ QStringList array = valueVariant.toStringList();
+ array.append(aValue);
+ settings.setValue(key, array);
+ } else {
+ settings.setValue(key, aValue);
+ }
+ } else if (method == QLatin1String("remove_array_value")) {
+ QVariant valueVariant = settings.value(key);
+ if (valueVariant.canConvert<QStringList>()) {
+ QStringList array = valueVariant.toStringList();
+ array.removeOne(aValue);
+ settings.setValue(key, array);
+ } else {
+ settings.remove(key);
+ }
+ }
+
+ return true;
+}
+
+bool SettingsOperation::undoOperation()
+{
+ if (!checkArguments())
+ return false;
+ const QString path = argumentKeyValue(QLatin1String("path"));
+ const QString method = argumentKeyValue(QLatin1String("method"));
+ const QString key = argumentKeyValue(QLatin1String("key"));
+ const QString aValue = argumentKeyValue(QLatin1String("value"));
+
+ if (method.startsWith(QLatin1String("remove")))
+ return true;
+
+ bool cleanUp = false;
+ { // kill the scope to kill settings object, else remove file will not work
+ QSettings settings(path, QSettings::IniFormat);
+ if (method == QLatin1String("set")) {
+ settings.remove(key);
+ } else if (method == QLatin1String("add_array_value")) {
+ QVariant valueVariant = settings.value(key);
+ if (valueVariant.canConvert<QStringList>()) {
+ QStringList array = valueVariant.toStringList();
+ array.removeOne(aValue);
+ if (array.isEmpty())
+ settings.remove(key);
+ else
+ settings.setValue(key, array);
+ } else {
+ settings.setValue(key, aValue);
+ }
+ }
+ settings.sync(); // be safe
+ cleanUp = settings.allKeys().isEmpty();
+ }
+
+ if (cleanUp) {
+ QFile settingsFile(path);
+ if (!settingsFile.remove())
+ qWarning() << settingsFile.errorString();
+ if (!value(QLatin1String("createddir")).toString().isEmpty()) {
+ KDUpdater::MkdirOperation mkDirOperation;
+ mkDirOperation.setArguments(QStringList() << QFileInfo(path).absolutePath());
+ mkDirOperation.setValue(QLatin1String("createddir"), value(QLatin1String("createddir")));
+
+ if (!mkDirOperation.undoOperation()) {
+ qWarning() << mkDirOperation.errorString();
+ }
+ }
+ }
+ return true;
+}
+
+bool SettingsOperation::testOperation()
+{
+ return true;
+}
+
+Operation *SettingsOperation::clone() const
+{
+ return new SettingsOperation();
+}
+
diff --git a/src/libs/installer/settingsoperation.h b/src/libs/installer/settingsoperation.h
new file mode 100644
index 000000000..248c9a0df
--- /dev/null
+++ b/src/libs/installer/settingsoperation.h
@@ -0,0 +1,66 @@
+/**************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#ifndef SETTINGSOPERATION_H
+#define SETTINGSOPERATION_H
+
+#include "qinstallerglobal.h"
+
+namespace QInstaller {
+
+class INSTALLER_EXPORT SettingsOperation : public Operation
+{
+public:
+ SettingsOperation();
+
+ void backup();
+ bool performOperation();
+ bool undoOperation();
+ bool testOperation();
+ Operation *clone() const;
+
+private:
+ bool checkArguments();
+};
+
+} // namespace QInstaller
+
+#endif // SETTINGSOPERATION_H
diff --git a/src/libs/kdtools/kdupdaterupdateoperation.cpp b/src/libs/kdtools/kdupdaterupdateoperation.cpp
index c1591f467..9ba165d4b 100644
--- a/src/libs/kdtools/kdupdaterupdateoperation.cpp
+++ b/src/libs/kdtools/kdupdaterupdateoperation.cpp
@@ -176,6 +176,40 @@ QStringList UpdateOperation::arguments() const
return m_arguments;
}
+struct StartsWith
+{
+ StartsWith(const QString &searchTerm)
+ : m_searchTerm(searchTerm) {}
+
+ bool operator()(const QString &searchString)
+ {
+ return searchString.startsWith(m_searchTerm);
+ }
+
+ QString m_searchTerm;
+};
+
+
+QString UpdateOperation::argumentKeyValue(const QString &key, const QString &defaultValue) const
+{
+ const QString keySeparater(key + QLatin1String("="));
+ const QStringList tArguments(arguments());
+ QStringList::const_iterator it = std::find_if(tArguments.begin(), tArguments.end(),
+ StartsWith(keySeparater));
+ if (it == tArguments.end())
+ return defaultValue;
+
+ const QString value = it->mid(keySeparater.size());
+
+ it = std::find_if(++it, tArguments.end(), StartsWith(keySeparater));
+ if (it != tArguments.end()) {
+ qWarning() << QString::fromLatin1("There are multiple keys in the arguments calling"
+ " '%1'. Only the first found '%2' is used: '%3'").arg(name(), key, arguments().join(
+ QLatin1String("; ")));
+ }
+ return value;
+}
+
/*!
Returns error details in case performOperation() failed.
*/
diff --git a/src/libs/kdtools/kdupdaterupdateoperation.h b/src/libs/kdtools/kdupdaterupdateoperation.h
index cac68d2f1..21b7b64a3 100644
--- a/src/libs/kdtools/kdupdaterupdateoperation.h
+++ b/src/libs/kdtools/kdupdaterupdateoperation.h
@@ -75,6 +75,7 @@ public:
void setArguments(const QStringList &args);
QStringList arguments() const;
+ QString argumentKeyValue(const QString & key, const QString &defaultValue = QString()) const;
void clear();
QString errorString() const;
int error() const;
diff --git a/tests/auto/installer/installer.pro b/tests/auto/installer/installer.pro
index c405cf087..f4c4bbaf4 100644
--- a/tests/auto/installer/installer.pro
+++ b/tests/auto/installer/installer.pro
@@ -14,5 +14,5 @@ SUBDIRS += \
copyoperationtest \
solver \
binaryformat \
- packagemanagercore
-
+ packagemanagercore \
+ settingsoperation
diff --git a/tests/auto/installer/settingsoperation/settingsoperation.pro b/tests/auto/installer/settingsoperation/settingsoperation.pro
new file mode 100644
index 000000000..60ddd329b
--- /dev/null
+++ b/tests/auto/installer/settingsoperation/settingsoperation.pro
@@ -0,0 +1,6 @@
+include(../../qttest.pri)
+
+QT -= gui
+QT += testlib
+
+SOURCES += tst_settingsoperation.cpp
diff --git a/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp b/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp
new file mode 100644
index 000000000..f663297ec
--- /dev/null
+++ b/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp
@@ -0,0 +1,328 @@
+/**************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+#include <utils.h>
+#include <settingsoperation.h>
+#include <qinstallerglobal.h>
+
+#include <QObject>
+#include <QTest>
+#include <QSettings>
+#include <QDir>
+
+using namespace KDUpdater;
+using namespace QInstaller;
+
+class tst_settingsoperation : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ // called before all tests
+ void initTestCase()
+ {
+ m_testSettingsDirPath = qApp->applicationDirPath();
+ m_testSettingsFilename = "test.ini";
+ QSettings testSettings(QDir(m_testSettingsDirPath).filePath(m_testSettingsFilename),
+ QSettings::IniFormat);
+ m_cleanupFilePathes << QDir(m_testSettingsDirPath).filePath(m_testSettingsFilename);
+ testSettings.setValue("testkey", "testvalue");
+ testSettings.setValue("testcategory/categorytestkey", "categorytestvalue");
+ testSettings.setValue("testcategory/categoryarrayvalue1", QStringList() << "value1" <<
+ "value2" << "value3");
+ testSettings.setValue("testcategory/categoryarrayvalue2", "value1,value2,value3");
+ testSettings.setValue("testcategory/categoryarrayvalue3", "value1 ,value2, value3");
+ }
+
+ void testWrongArguments()
+ {
+ SettingsOperation noArgumentsOperation;
+
+ QVERIFY(noArgumentsOperation.testOperation());
+
+ // operation should do nothing if there are no arguments
+ QCOMPARE(noArgumentsOperation.performOperation(), false);
+
+ QCOMPARE(UpdateOperation::Error(noArgumentsOperation.error()),
+ UpdateOperation::InvalidArguments);
+ QString compareString("Missing argument(s) 'path; method; key; value' calling 'Settings' "
+ "with arguments ''.");
+ QCOMPARE(noArgumentsOperation.errorString(), compareString);
+
+ // same for undo
+ QCOMPARE(noArgumentsOperation.undoOperation(), false);
+
+ SettingsOperation wrongMethodArgumentOperation;
+ wrongMethodArgumentOperation.setArguments(QStringList() << "path=first" << "method=second"
+ << "key=third" << "value=fourth");
+
+ QVERIFY(wrongMethodArgumentOperation.testOperation());
+
+ // operation should do nothing if there are no arguments
+ QCOMPARE(wrongMethodArgumentOperation.performOperation(), false);
+
+ QCOMPARE(UpdateOperation::Error(wrongMethodArgumentOperation.error()),
+ UpdateOperation::InvalidArguments);
+ compareString = "Current method argument calling 'Settings' with arguments 'path=first; "
+ "method=second; key=third; value=fourth' is not supported. Please use set, remove, "
+ "add_array_value or remove_array_value.";
+ QCOMPARE(wrongMethodArgumentOperation.errorString(), compareString);
+
+ // same for undo
+ QCOMPARE(wrongMethodArgumentOperation.undoOperation(), false);
+ }
+
+ void setSettingsValue()
+ {
+ const QString verifyFilePath = createFilePath(QTest::currentTestFunction());
+ const QString testFilePath = createFilePath(QString("_") + QTest::currentTestFunction());
+ m_cleanupFilePathes << verifyFilePath << testFilePath;
+
+ const QString key = "category/key";
+ const QString value = "value";
+ {
+ QSettings testSettings(verifyFilePath, QSettings::IniFormat);
+ testSettings.setValue(key, value);
+ }
+
+ SettingsOperation settingsOperation;
+ settingsOperation.setArguments(QStringList() << QString("path=%1").arg(testFilePath) <<
+ "method=set" << QString("key=%1").arg(key) << QString("value=%1").arg(value));
+ settingsOperation.backup();
+
+ QVERIFY2(settingsOperation.performOperation(), settingsOperation.errorString().toLatin1());
+
+ QVERIFY2(compareFiles(verifyFilePath, testFilePath), QString("'%1' and '%2' are different")
+ .arg(verifyFilePath, testFilePath).toLatin1());
+ }
+
+ void undoSettingsValueInCreatedSubDirectories()
+ {
+ const QString testFilePath = createFilePath(QString("sub/directory/") +
+ QTest::currentTestFunction());
+ const QString key = "key";
+ const QString value = "value";
+
+ SettingsOperation settingsOperation;
+ settingsOperation.setArguments(QStringList() << QString("path=%1").arg(testFilePath) <<
+ "method=set" << QString("key=%1").arg(key) << QString("value=%1").arg(value));
+ settingsOperation.backup();
+
+ QVERIFY2(settingsOperation.performOperation(), settingsOperation.errorString().toLatin1());
+ QCOMPARE(QFile(testFilePath).exists(), true);
+ QVERIFY2(settingsOperation.undoOperation(), settingsOperation.errorString().toLatin1());
+ QCOMPARE(QFile(testFilePath).exists(), false);
+ QCOMPARE(QDir(QFileInfo(testFilePath).absolutePath()).exists(), false);
+ }
+
+ void removeSettingsValue()
+ {
+ const QString testFilePath = createFilePath(QTest::currentTestFunction());
+ QFile testFile(QDir(m_testSettingsDirPath).filePath(m_testSettingsFilename));
+ QVERIFY2(testFile.copy(testFilePath), testFile.errorString().toLatin1());
+ m_cleanupFilePathes << testFilePath;
+
+ const QString key = "testkey";
+ QString testValueString;
+ {
+ QSettings testSettings(testFilePath, QSettings::IniFormat);
+ testValueString = testSettings.value(key).toString();
+ }
+ QCOMPARE(testValueString.isEmpty(), false);
+
+ SettingsOperation settingsOperation;
+ settingsOperation.setArguments(QStringList() << QString("path=%1").arg(testFilePath) <<
+ "method=remove" << QString("key=%1").arg(key));
+ settingsOperation.backup();
+ QVERIFY2(settingsOperation.performOperation(), settingsOperation.errorString().toLatin1());
+
+ QVariant testValueVariant;
+ {
+ QSettings testSettings(testFilePath, QSettings::IniFormat);
+ testValueVariant = testSettings.value(key);
+ }
+ QVERIFY(testValueVariant.isNull());
+ }
+
+ void addSettingsArrayValue()
+ {
+ const QString testFilePath = createFilePath(QTest::currentTestFunction());
+ QFile contentFile(QDir(m_testSettingsDirPath).filePath(m_testSettingsFilename));
+ QVERIFY2(contentFile.open(QIODevice::ReadOnly | QIODevice::Text), contentFile.errorString().toLatin1());
+
+ QFile testFile(testFilePath);
+ QVERIFY2(testFile.open(QIODevice::WriteOnly | QIODevice::Text), contentFile.errorString().toLatin1());
+
+ QTextStream out(&testFile);
+
+ QTextStream in(&contentFile);
+ QString line = in.readLine();
+ while (!line.isNull()) {
+ // remove the " to have some maybe invalid data
+ out << line.replace("\"", QLatin1String("")) << QLatin1String("\n");
+ line = in.readLine();
+ }
+ testFile.close();
+
+ QMap<QString, SettingsOperation*> testSettingsOperationMap;
+ testSettingsOperationMap["testcategory/categoryarrayvalue1"] = new SettingsOperation;
+ testSettingsOperationMap["testcategory/categoryarrayvalue2"] = new SettingsOperation;
+ testSettingsOperationMap["testcategory/categoryarrayvalue3"] = new SettingsOperation;
+ testSettingsOperationMap["testcategory/categoryarrayvalue4"] = new SettingsOperation;
+
+ QMap<QString, SettingsOperation*>::iterator i = testSettingsOperationMap.begin();
+ while (i != testSettingsOperationMap.end()) {
+ i.value()->setArguments(QStringList() << QString("path=%1").arg(testFilePath) <<
+ "method=add_array_value" << QString("key=%1").arg(i.key()) << "value=value4");
+ i.value()->backup();
+ QVERIFY2(i.value()->performOperation(), i.value()->errorString().toLatin1());
+ ++i;
+ }
+ QStringList testKeys(testSettingsOperationMap.keys());
+ {
+ QSettings verifySettings(testFilePath, QSettings::IniFormat);
+ QCOMPARE(verifySettings.value(testKeys.at(0)).isNull(), false);
+ QCOMPARE(verifySettings.value(testKeys.at(0)), verifySettings.value(testKeys.at(1)));
+ QCOMPARE(verifySettings.value(testKeys.at(1)), verifySettings.value(testKeys.at(2)));
+ QCOMPARE(verifySettings.value(testKeys.at(3)).toString(), QLatin1String("value4"));
+ }
+
+ i = testSettingsOperationMap.begin();
+ while (i != testSettingsOperationMap.end()) {
+ i.value()->setArguments(QStringList() << QString("path=%1").arg(testFilePath) <<
+ "method=add_array_value" << QString("key=%1").arg(i.key()) << "value=value4");
+ QVERIFY2(i.value()->undoOperation(), i.value()->errorString().toLatin1());
+ ++i;
+ }
+
+ {
+ QStringList verifyStringList;
+ verifyStringList << "value1" << "value2" << "value3";
+ QVariant verifyUndoValue = verifyStringList;
+ QSettings verifySettings(testFilePath, QSettings::IniFormat);
+ QCOMPARE(verifySettings.value(testKeys.at(0)), verifyUndoValue);
+ QCOMPARE(verifySettings.value(testKeys.at(1)), verifyUndoValue);
+ QCOMPARE(verifySettings.value(testKeys.at(2)), verifyUndoValue);
+ // checking the none array value is removed
+ QVERIFY(verifySettings.value(testKeys.at(3)).isNull());
+ }
+
+ }
+
+ void removeSettingsArrayValue()
+ {
+ const QString testFilePath = createFilePath(QTest::currentTestFunction());
+ QFile contentFile(QDir(m_testSettingsDirPath).filePath(m_testSettingsFilename));
+ QVERIFY2(contentFile.open(QIODevice::ReadOnly | QIODevice::Text), contentFile.errorString()
+ .toLatin1());
+
+ QFile testFile(testFilePath);
+ QVERIFY2(testFile.open(QIODevice::WriteOnly | QIODevice::Text), contentFile.errorString()
+ .toLatin1());
+
+ QTextStream out(&testFile);
+
+ QTextStream in(&contentFile);
+ QString line = in.readLine();
+ while (!line.isNull()) {
+ // remove the " to have some maybe invalid data
+ out << line.replace("\"", QLatin1String("")) << QLatin1String("\n");
+ line = in.readLine();
+ }
+ testFile.close();
+
+ QMap<QString, SettingsOperation*> testSettingsOperationMap;
+ testSettingsOperationMap["testcategory/categoryarrayvalue1"] = new SettingsOperation;
+ testSettingsOperationMap["testcategory/categoryarrayvalue2"] = new SettingsOperation;
+ testSettingsOperationMap["testcategory/categoryarrayvalue3"] = new SettingsOperation;
+
+ QMap<QString, SettingsOperation*>::iterator i = testSettingsOperationMap.begin();
+ while (i != testSettingsOperationMap.end()) {
+ i.value()->setArguments(QStringList() << QString("path=%1").arg(testFilePath) <<
+ "method=remove_array_value" << QString("key=%1").arg(i.key()) << "value=value3");
+ i.value()->backup();
+ QVERIFY2(i.value()->performOperation(), i.value()->errorString().toLatin1());
+ ++i;
+ }
+ QStringList testKeys(testSettingsOperationMap.keys());
+ {
+ QSettings verifySettings(testFilePath, QSettings::IniFormat);
+ QCOMPARE(verifySettings.value(testKeys.at(0)).isNull(), false);
+
+ QStringList verifyFirstValue = verifySettings.value(testKeys.at(0)).toStringList();
+#if QT_VERSION < 0x050000
+ QCOMPARE(verifyFirstValue.contains(QLatin1String("value3")), QBool(false));
+#else
+ QCOMPARE(verifyFirstValue.contains(QLatin1String("value3")), false);
+#endif
+ QCOMPARE(verifySettings.value(testKeys.at(0)), verifySettings.value(testKeys.at(1)));
+ QCOMPARE(verifySettings.value(testKeys.at(1)), verifySettings.value(testKeys.at(2)));
+ }
+ }
+
+ // called after all tests
+ void cleanupTestCase()
+ {
+ foreach (const QString &filePath, m_cleanupFilePathes)
+ QFile(filePath).remove();
+ }
+private:
+ QString createFilePath(const QString &fileNamePrependix)
+ {
+ return QDir(m_testSettingsDirPath).filePath(QString(fileNamePrependix) + m_testSettingsFilename);
+ }
+
+ bool compareFiles(const QString &filePath1, const QString &filePath2)
+ {
+ if (!QFile::exists(filePath1) || !QFile::exists(filePath2))
+ return false;
+ const QByteArray fileHash1 = QInstaller::calculateHash(filePath1, QCryptographicHash::Sha1);
+ const QByteArray fileHash2 = QInstaller::calculateHash(filePath2, QCryptographicHash::Sha1);
+ return fileHash1 == fileHash2;
+ }
+
+ QString m_testSettingsFilename;
+ QString m_testSettingsDirPath;
+ QStringList m_cleanupFilePathes;
+};
+
+QTEST_MAIN(tst_settingsoperation)
+
+#include "tst_settingsoperation.moc"