diff options
author | Tim Jenssen <tim.jenssen@digia.com> | 2013-11-14 16:47:27 +0100 |
---|---|---|
committer | Tim Jenssen <tim.jenssen@digia.com> | 2013-11-14 17:17:59 +0100 |
commit | 8d6c1d091496950339748bec8099b4feddf0ea12 (patch) | |
tree | 7585dcead1ecb8186c33aaa91ca25c6ca4f8919c | |
parent | 54e4f19a86e64347f66dfd7345f9428c55123fe0 (diff) |
add new settingsoperation
Change-Id: I3c05c51241a19304b43c0fc4f1306b36b6a84c86
Reviewed-by: Karsten Heimrich <karsten.heimrich@digia.com>
-rw-r--r-- | src/libs/installer/installer.pro | 6 | ||||
-rw-r--r-- | src/libs/installer/settingsoperation.cpp | 216 | ||||
-rw-r--r-- | src/libs/installer/settingsoperation.h | 66 | ||||
-rw-r--r-- | src/libs/kdtools/kdupdaterupdateoperation.cpp | 34 | ||||
-rw-r--r-- | src/libs/kdtools/kdupdaterupdateoperation.h | 1 | ||||
-rw-r--r-- | tests/auto/installer/installer.pro | 4 | ||||
-rw-r--r-- | tests/auto/installer/settingsoperation/settingsoperation.pro | 6 | ||||
-rw-r--r-- | tests/auto/installer/settingsoperation/tst_settingsoperation.cpp | 328 |
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" |