summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKatja Marttila <katja.marttila@qt.io>2024-03-18 11:47:11 +0200
committerKatja Marttila <katja.marttila@qt.io>2024-04-05 11:21:50 +0000
commit235714e66d92676491e8febf06d695ee4874d92a (patch)
treecc840e23850c0bf7881a92c96c7f41f1fc369fe3
parent5f3ca7366889c6e4cd699df47a6479ce200d6523 (diff)
Allow overwriting undo in some operations
Added possibility to overwrite undo in copy, move, delete, mkdir, rmdir, appendfile and prependfile operations. Undo is performed when component is uninstalled or updated, by adding UNDOOPERATION to the end of argument list will skip the undo operation. Also added unit tests for rmdir and prependfile operations Task-number: QTIFW-3333 Task-number: QTIFW-393 Change-Id: I88dbb16d2ebabe42b4ff810e6196da0be8b4cc65 Reviewed-by: Arttu Tarkiainen <arttu.tarkiainen@qt.io>
-rw-r--r--doc/operations.qdoc23
-rw-r--r--src/libs/installer/copydirectoryoperation.cpp2
-rw-r--r--src/libs/installer/createlocalrepositoryoperation.cpp2
-rw-r--r--src/libs/installer/globalsettingsoperation.cpp2
-rw-r--r--src/libs/installer/registerfiletypeoperation.cpp2
-rw-r--r--src/libs/installer/simplemovefileoperation.cpp2
-rw-r--r--src/libs/kdtools/updateoperation.cpp17
-rw-r--r--src/libs/kdtools/updateoperation.h2
-rw-r--r--src/libs/kdtools/updateoperations.cpp65
-rw-r--r--src/libs/kdtools/updateoperations.h2
-rw-r--r--tests/auto/installer/appendfileoperation/tst_appendfileoperation.cpp35
-rw-r--r--tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp47
-rw-r--r--tests/auto/installer/deleteoperation/tst_deleteoperation.cpp49
-rw-r--r--tests/auto/installer/installer.pro2
-rw-r--r--tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp28
-rw-r--r--tests/auto/installer/moveoperation/tst_moveoperation.cpp4
-rw-r--r--tests/auto/installer/prependfileoperation/data/repository/B/1.0.2-1content.7zbin0 -> 129 bytes
-rw-r--r--tests/auto/installer/prependfileoperation/data/repository/B/1.0.2-1meta.7zbin0 -> 910 bytes
-rw-r--r--tests/auto/installer/prependfileoperation/data/repository/Updates.xml16
-rw-r--r--tests/auto/installer/prependfileoperation/data/xmloperationrepository/C/1.0.0content.7zbin0 -> 129 bytes
-rw-r--r--tests/auto/installer/prependfileoperation/data/xmloperationrepository/Updates.xml20
-rw-r--r--tests/auto/installer/prependfileoperation/prependfileoperation.pro10
-rw-r--r--tests/auto/installer/prependfileoperation/settings.qrc9
-rw-r--r--tests/auto/installer/prependfileoperation/tst_prependfileoperation.cpp180
-rw-r--r--tests/auto/installer/rmdiroperationtest/rmdiroperationtest.pro6
-rw-r--r--tests/auto/installer/rmdiroperationtest/tst_rmdiroperationtest.cpp111
26 files changed, 540 insertions, 96 deletions
diff --git a/doc/operations.qdoc b/doc/operations.qdoc
index deea534c4..e148d6fc1 100644
--- a/doc/operations.qdoc
+++ b/doc/operations.qdoc
@@ -69,10 +69,16 @@
\li Copy
\li "Copy" \c source \c target
\li Copies a file from \c source to \c target.
+ \note The file will be restored during unistallation. If you want
+ to skip the copying, you can overwrite the \e UNDO by passing
+ \e UNDOOPERATION and \e "", to the end of the argument list.
\row
\li Move
\li "Move" \c source \c target
\li Moves a file from \c source to \c target.
+ \note Files restored during uninstallation. If you want to move the
+ files persistently, you can overwrite the \e UNDO by passing \e
+ UNDOOPERATION and \e "", to the end of the argument list.
\row
\li SimpleMoveFile
\li "SimpleMoveFile" \c source \c target
@@ -85,14 +91,25 @@
\li Delete
\li "Delete" \c filename
\li Deletes the file specified by \c filename.
+ \note File will be restored during uninstallation. If you want to
+ delete the files persistently, you can overwrite the \e UNDO by
+ passing \e UNDOOPERATION and \e "", to the end of the argument list.
\row
\li Mkdir
\li "Mkdir" \c path
\li Creates the directory path \c path.
+ \note Directory will be deleted during uninstallation.
+ If you want to create the directory persistently, you can overwrite the \e UNDO
+ by passing \e UNDOOPERATION and \e "", to the end of the argument list. Note that
+ during full uninstall, directory will be deleted if it was created to target directory
+ and \c RemoveTargetDir is false.
\row
\li Rmdir
\li "Rmdir" \c path
\li Removes the directory path \c path.
+ \note Directory will be recreated during uninstallation.
+ If you want to remove the directory persistently, you can overwrite the \e UNDO
+ by passing \e UNDOOPERATION and \e "", to the end of the argument list.
\row
\li CopyDirectory
\li "CopyDirectory" \c sourcePath \c targetPath
@@ -105,11 +122,17 @@
\li "AppendFile" \c filename \c text
\li Appends \c text to the file specified by \c filename. \c text is
treated as ASCII text.
+ \note Text will be removed from file during unistallation. If you want to append the
+ text persistently, you can overwrite the \e UNDO by passing \e UNDOOPERATION
+ and \e "", to the end of the argument list.
\row
\li PrependFile
\li "PrependFile" \c filename \c text
\li Prepends \c text to the file specified by \c filename. \c text
is treated as ASCII text.
+ \note Text will be removed from file during unistallation. If you want to append the
+ text persistently, you can overwrite the \e UNDO by passing \e UNDOOPERATION
+ and \e "", to the end of the argument list.
\row
\li Replace
\li "Replace" \c file \c search \c replace \c mode
diff --git a/src/libs/installer/copydirectoryoperation.cpp b/src/libs/installer/copydirectoryoperation.cpp
index a2ef2cf5a..c0fec0649 100644
--- a/src/libs/installer/copydirectoryoperation.cpp
+++ b/src/libs/installer/copydirectoryoperation.cpp
@@ -153,7 +153,7 @@ bool CopyDirectoryOperation::performOperation()
bool CopyDirectoryOperation::undoOperation()
{
- if (parseUndoOperationArguments().count() > 0)
+ if (skipUndoOperation())
return true;
if (!checkArgumentCount(2))
diff --git a/src/libs/installer/createlocalrepositoryoperation.cpp b/src/libs/installer/createlocalrepositoryoperation.cpp
index 7090f9a8b..286cc9b5b 100644
--- a/src/libs/installer/createlocalrepositoryoperation.cpp
+++ b/src/libs/installer/createlocalrepositoryoperation.cpp
@@ -378,7 +378,7 @@ bool CreateLocalRepositoryOperation::performOperation()
bool CreateLocalRepositoryOperation::undoOperation()
{
- if (parseUndoOperationArguments().count() > 0)
+ if (skipUndoOperation())
return true;
if (!checkArgumentCount(2))
diff --git a/src/libs/installer/globalsettingsoperation.cpp b/src/libs/installer/globalsettingsoperation.cpp
index 9608bba66..6ca50f96f 100644
--- a/src/libs/installer/globalsettingsoperation.cpp
+++ b/src/libs/installer/globalsettingsoperation.cpp
@@ -77,7 +77,7 @@ bool GlobalSettingsOperation::performOperation()
bool GlobalSettingsOperation::undoOperation()
{
- if (parseUndoOperationArguments().count() > 0)
+ if (skipUndoOperation())
return true;
const QStringList args = parsePerformOperationArguments();
diff --git a/src/libs/installer/registerfiletypeoperation.cpp b/src/libs/installer/registerfiletypeoperation.cpp
index 1754b664d..852714dfb 100644
--- a/src/libs/installer/registerfiletypeoperation.cpp
+++ b/src/libs/installer/registerfiletypeoperation.cpp
@@ -153,7 +153,7 @@ bool RegisterFileTypeOperation::undoOperation()
{
#ifdef Q_OS_WIN
ensureOptionalArgumentsRead();
- if (parseUndoOperationArguments().count() > 0)
+ if (skipUndoOperation())
return true;
QStringList args = arguments();
diff --git a/src/libs/installer/simplemovefileoperation.cpp b/src/libs/installer/simplemovefileoperation.cpp
index 5f3000be0..5bbbdabb4 100644
--- a/src/libs/installer/simplemovefileoperation.cpp
+++ b/src/libs/installer/simplemovefileoperation.cpp
@@ -93,7 +93,7 @@ bool SimpleMoveFileOperation::performOperation()
bool SimpleMoveFileOperation::undoOperation()
{
- if (parseUndoOperationArguments().count() > 0)
+ if (skipUndoOperation())
return true;
const QString source = arguments().at(0);
const QString target = arguments().at(1);
diff --git a/src/libs/kdtools/updateoperation.cpp b/src/libs/kdtools/updateoperation.cpp
index e9e69fc13..af89382a8 100644
--- a/src/libs/kdtools/updateoperation.cpp
+++ b/src/libs/kdtools/updateoperation.cpp
@@ -292,23 +292,18 @@ QStringList UpdateOperation::parsePerformOperationArguments()
}
/*!
- Returns undo operation argument list. If the installation is
- cancelled or failed, returns an empty list so that full undo
- operation can be performed.
+ Returns \c true if operation undo should not be performed.
+ Returns \c false if the installation is cancelled or failed, or
+ \c UNDOOPERATION is not set in operation call.
*/
-QStringList UpdateOperation::parseUndoOperationArguments()
+bool UpdateOperation::skipUndoOperation()
{
//Install has failed, allow a normal undo
if (m_core && (m_core->status() == QInstaller::PackageManagerCore::Canceled
|| m_core->status() == QInstaller::PackageManagerCore::Failure)) {
- return QStringList();
- }
- int index = arguments().indexOf(QLatin1String("UNDOOPERATION"));
- QStringList args;
- if ((index != -1) && (arguments().length() > index + 1)) {
- args = arguments().mid(index + 1);
+ return false;
}
- return args;
+ return arguments().contains(QLatin1String("UNDOOPERATION"));
}
/*!
diff --git a/src/libs/kdtools/updateoperation.h b/src/libs/kdtools/updateoperation.h
index 4a431f107..e25846cd3 100644
--- a/src/libs/kdtools/updateoperation.h
+++ b/src/libs/kdtools/updateoperation.h
@@ -112,7 +112,7 @@ protected:
bool checkArgumentCount(int minArgCount, int maxArgCount, const QString &argDescription = QString());
bool checkArgumentCount(int argCount);
QStringList parsePerformOperationArguments();
- QStringList parseUndoOperationArguments();
+ bool skipUndoOperation();
void setRequiresUnreplacedVariables(bool isRequired);
bool variableReplacement(QString *variableValue);
diff --git a/src/libs/kdtools/updateoperations.cpp b/src/libs/kdtools/updateoperations.cpp
index 9301d4f13..5f6135103 100644
--- a/src/libs/kdtools/updateoperations.cpp
+++ b/src/libs/kdtools/updateoperations.cpp
@@ -127,7 +127,7 @@ QString CopyOperation::sourcePath()
QString CopyOperation::destinationPath()
{
- QString destination = arguments().last();
+ QString destination = arguments().at(1);
// if the target is a directory use the source filename to complete the destination path
if (QFileInfo(destination).isDir())
@@ -135,7 +135,6 @@ QString CopyOperation::destinationPath()
return destination;
}
-
void CopyOperation::backup()
{
QString destination = destinationPath();
@@ -156,8 +155,8 @@ void CopyOperation::backup()
bool CopyOperation::performOperation()
{
// We need two args to complete the copy operation. First arg provides the complete file name of source
- // Second arg provides the complete file name of dest
- if (!checkArgumentCount(2))
+ // Second arg provides the complete file name of dest. Optionally UNDOOPERATION can be added as well
+ if (!checkArgumentCount(2, 4, QLatin1String("<source filename> <destination filename> [UNDOOPERATION, \"\"]")))
return false;
QString source = sourcePath();
@@ -193,6 +192,8 @@ bool CopyOperation::performOperation()
bool CopyOperation::undoOperation()
{
+ if (skipUndoOperation())
+ return true;
QString source = sourcePath();
QString destination = destinationPath();
@@ -270,7 +271,7 @@ MoveOperation::~MoveOperation()
void MoveOperation::backup()
{
- const QString dest = arguments().last();
+ const QString dest = arguments().at(1);
if (!QFile::exists(dest)) {
clearValue(QLatin1String("backupOfExistingDestination"));
return;
@@ -286,9 +287,10 @@ void MoveOperation::backup()
bool MoveOperation::performOperation()
{
- // We need two args to complete the copy operation. // First arg provides the complete file name of
- // source, second arg provides the complete file name of dest
- if (!checkArgumentCount(2))
+ // We need two args to complete the copy operation. First arg provides the complete file name of
+ // source, second arg provides the complete file name of dest. Optionally UNDOOPERATION can be added as well
+ if (!checkArgumentCount(2, 4, QLatin1String("<complete source file name> <complete destination "
+ "file name> [UNDOOPERATION, \"\"]")))
return false;
const QStringList args = arguments();
@@ -318,8 +320,10 @@ bool MoveOperation::performOperation()
bool MoveOperation::undoOperation()
{
+ if (skipUndoOperation())
+ return true;
const QStringList args = arguments();
- const QString dest = args.last();
+ const QString dest = args.at(1);
// first: copy back the destination to source
QFile destF(dest);
if (!destF.copy(args.first())) {
@@ -391,7 +395,8 @@ void DeleteOperation::backup()
bool DeleteOperation::performOperation()
{
// Requires only one parameter. That is the name of the file to remove.
- if (!checkArgumentCount(1))
+ // Optionally UNDOOPERATION can be added as well
+ if (!checkArgumentCount(1, 3, QLatin1String("<file to remove> [UNDOOPERATION, \"\"]")))
return false;
return deleteFileNowOrLater(arguments().at(0));
@@ -399,7 +404,7 @@ bool DeleteOperation::performOperation()
bool DeleteOperation::undoOperation()
{
- if (!hasValue(QLatin1String("backupOfExistingFile")))
+ if (skipUndoOperation())
return true;
const QString fileName = arguments().first();
@@ -478,7 +483,8 @@ void MkdirOperation::backup()
bool MkdirOperation::performOperation()
{
// Requires only one parameter. That is the path which should be created
- if (!checkArgumentCount(1))
+ // Optionally UNDOOPERATION can be added as well
+ if (!checkArgumentCount(1, 3, QLatin1String("<file to remove> [UNDOOPERATION, \"\"]")))
return false;
const QString dirName = arguments().at(0);
@@ -493,7 +499,8 @@ bool MkdirOperation::performOperation()
bool MkdirOperation::undoOperation()
{
- Q_ASSERT(arguments().count() == 1);
+ if (skipUndoOperation())
+ return true;
QString createdDirValue = value(QLatin1String("createddir")).toString();
if (packageManager()) {
@@ -572,7 +579,8 @@ void RmdirOperation::backup()
bool RmdirOperation::performOperation()
{
// Requires only one parameter. That is the name of the file to remove.
- if (!checkArgumentCount(1))
+ // Optionally UNDOOPERATION can be added as well
+ if (!checkArgumentCount(1, 3, QLatin1String("<file to remove> [UNDOOPERATION, \"\"]")))
return false;
const QString firstArg = arguments().at(0);
@@ -597,7 +605,7 @@ bool RmdirOperation::performOperation()
bool RmdirOperation::undoOperation()
{
- if (!value(QLatin1String("removed")).toBool())
+ if (!value(QLatin1String("removed")).toBool() || skipUndoOperation())
return true;
errno = 0;
@@ -633,6 +641,12 @@ AppendFileOperation::AppendFileOperation(QInstaller::PackageManagerCore *core)
setName(QLatin1String("AppendFile"));
}
+AppendFileOperation::~AppendFileOperation()
+{
+ if (skipUndoOperation())
+ deleteFileNowOrLater(value(QLatin1String("backupOfFile")).toString());
+}
+
void AppendFileOperation::backup()
{
const QString filename = arguments().first();
@@ -653,10 +667,10 @@ bool AppendFileOperation::performOperation()
{
// This operation takes two arguments. First argument is the name of the file into which a text has to be
// appended. Second argument is the text to append.
- if (!checkArgumentCount(2))
+ if (!checkArgumentCount(2, 4, QLatin1String("<filename> <text to apply> [UNDOOPERATION, \"\"]")))
return false;
- const QStringList args = this->arguments();
+ const QStringList args = arguments();
const QString fName = args.at(0);
QFile file(fName);
if (!file.open(QFile::Append)) {
@@ -695,6 +709,9 @@ bool AppendFileOperation::performOperation()
bool AppendFileOperation::undoOperation()
{
+ if (skipUndoOperation())
+ return true;
+
// backupOfFile being empty -> file didn't exist before -> no error
const QString filename = arguments().first();
const QString backupOfFile = value(QLatin1String("backupOfFile")).toString();
@@ -746,6 +763,12 @@ PrependFileOperation::PrependFileOperation(QInstaller::PackageManagerCore *core)
setName(QLatin1String("PrependFile"));
}
+PrependFileOperation::~PrependFileOperation()
+{
+ if (skipUndoOperation())
+ deleteFileNowOrLater(value(QLatin1String("backupOfFile")).toString());
+}
+
void PrependFileOperation::backup()
{
const QString filename = arguments().first();
@@ -767,10 +790,10 @@ bool PrependFileOperation::performOperation()
// This operation takes two arguments. First argument is the name
// of the file into which a text has to be appended. Second argument
// is the text to append.
- if (!checkArgumentCount(2))
+ if (!checkArgumentCount(2, 4, QLatin1String("<filename> <text to prepend> [UNDOOPERATION, \"\"]")))
return false;
- const QStringList args = this->arguments();
+ const QStringList args = arguments();
const QString fName = args.at(0);
// Load the file first.
QFile file(fName);
@@ -810,7 +833,9 @@ bool PrependFileOperation::performOperation()
bool PrependFileOperation::undoOperation()
{
- // bockupOfFile being empty -> file didn't exist before -> no error
+ if (skipUndoOperation())
+ return true;
+
const QString filename = arguments().first();
const QString backupOfFile = value(QLatin1String("backupOfFile")).toString();
if (!backupOfFile.isEmpty() && !QFile::exists(backupOfFile)) {
diff --git a/src/libs/kdtools/updateoperations.h b/src/libs/kdtools/updateoperations.h
index c789975e2..adbfc7de1 100644
--- a/src/libs/kdtools/updateoperations.h
+++ b/src/libs/kdtools/updateoperations.h
@@ -109,6 +109,7 @@ class KDTOOLS_EXPORT AppendFileOperation : public UpdateOperation
Q_DECLARE_TR_FUNCTIONS(KDUpdater::AppendFileOperation)
public:
explicit AppendFileOperation(QInstaller::PackageManagerCore *core = 0);
+ ~AppendFileOperation();
void backup() override;
bool performOperation() override;
@@ -121,6 +122,7 @@ class KDTOOLS_EXPORT PrependFileOperation : public UpdateOperation
Q_DECLARE_TR_FUNCTIONS(KDUpdater::PrependFileOperation)
public:
explicit PrependFileOperation(QInstaller::PackageManagerCore *core = 0);
+ ~PrependFileOperation();
void backup() override;
bool performOperation() override;
diff --git a/tests/auto/installer/appendfileoperation/tst_appendfileoperation.cpp b/tests/auto/installer/appendfileoperation/tst_appendfileoperation.cpp
index 9eb1e2401..743e4c625 100644
--- a/tests/auto/installer/appendfileoperation/tst_appendfileoperation.cpp
+++ b/tests/auto/installer/appendfileoperation/tst_appendfileoperation.cpp
@@ -81,8 +81,7 @@ private slots:
QVERIFY(!op.performOperation());
QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments);
- QCOMPARE(op.errorString(), QString("Invalid arguments in AppendFile: "
- "0 arguments given, exactly 2 arguments expected."));
+ QCOMPARE(op.errorString(), QString("Invalid arguments in AppendFile: 0 arguments given, 2 to 4 arguments expected in the form: <filename> <text to apply> [UNDOOPERATION, \"\"]."));
op.setArguments(QStringList() << "" << "");
QTest::ignoreMessage(QtWarningMsg, "QFSFileEngine::open: No file name specified");
@@ -98,10 +97,14 @@ private slots:
QTest::addColumn<QString>("source");
QTest::addColumn<QString>("append");
QTest::addColumn<QString>("expected");
+ QTest::addColumn<bool>("overrideUndo");
QTest::newRow("newline") << "Line1\nLine2\nLine3\n" << "AppendedText"
- << "Line1\nLine2\nLine3\nAppendedText";
+ << "Line1\nLine2\nLine3\nAppendedText" << false;
QTest::newRow("no newline") << "Lorem ipsum " << "dolore sit amet"
- << "Lorem ipsum dolore sit amet";
+ << "Lorem ipsum dolore sit amet" << false;
+
+ QTest::newRow("no undo") << "Lorem ipsum " << "dolore sit amet"
+ << "Lorem ipsum dolore sit amet" << true;
}
void testAppendText()
@@ -109,6 +112,7 @@ private slots:
QFETCH(QString, source);
QFETCH(QString, append);
QFETCH(QString, expected);
+ QFETCH(bool, overrideUndo);
QFile file(m_testFilePath);
QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text));
@@ -117,20 +121,29 @@ private slots:
stream << source << Qt::flush;
file.close();
- AppendFileOperation op;
- op.setArguments(QStringList() << m_testFilePath << append);
+ AppendFileOperation *op = new AppendFileOperation();
+ op->setArguments(QStringList() << m_testFilePath << append);
+ if (overrideUndo)
+ op->setArguments(op->arguments() << QLatin1String("UNDOOPERATION"));
- op.backup();
- QVERIFY(QFileInfo(op.value("backupOfFile").toString()).exists());
+ op->backup();
+ QVERIFY(QFileInfo(op->value("backupOfFile").toString()).exists());
- QVERIFY2(op.performOperation(), op.errorString().toLatin1());
+ QVERIFY2(op->performOperation(), op->errorString().toLatin1());
QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
QCOMPARE(stream.readAll(), expected);
file.close();
- QVERIFY2(op.undoOperation(), op.errorString().toLatin1());
+ QVERIFY2(op->undoOperation(), op->errorString().toLatin1());
QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
- QCOMPARE(stream.readAll(), source);
+ if (overrideUndo)
+ QCOMPARE(stream.readAll(), expected);
+ else
+ QCOMPARE(stream.readAll(), source);
+ QString backupFileName = op->value("backupOfFile").toString();
+ delete op;
+ QVERIFY(!QFileInfo::exists(backupFileName));
+
file.close();
QVERIFY(file.remove());
diff --git a/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp b/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp
index d41853eee..692fd86d9 100644
--- a/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp
+++ b/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp
@@ -87,37 +87,48 @@ private slots:
QVERIFY(!op.performOperation());
QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments);
- QCOMPARE(op.errorString(), QString("Invalid arguments in Copy: "
- "0 arguments given, exactly 2 arguments expected."));
-
+ QCOMPARE(op.errorString(), QString("Invalid arguments in Copy: 0 arguments given, "
+ "2 to 4 arguments expected in the form: <source filename> <destination filename> [UNDOOPERATION, \"\"]."));
}
void testCopySomething_data()
{
- QTest::addColumn<QString>("source");
- QTest::addColumn<QString>("destination");
- QTest::newRow("full path syntax") << qApp->applicationFilePath() << m_testDestinationFilePath;
- QTest::newRow("short destination syntax") << qApp->applicationFilePath() << m_testDestinationPath;
- QTest::newRow("short destination syntax with ending separator") << qApp->applicationFilePath()
- << m_testDestinationPath + QDir::separator();
+ QTest::addColumn<QString>("source");
+ QTest::addColumn<QString>("destination");
+ QTest::addColumn<bool>("overrideUndo");
+ QTest::newRow("full path syntax") << qApp->applicationFilePath() << m_testDestinationFilePath << false;
+ QTest::newRow("short destination syntax") << qApp->applicationFilePath() << m_testDestinationPath << false;
+ QTest::newRow("short destination syntax with ending separator") << qApp->applicationFilePath()
+ << m_testDestinationPath + QDir::separator() << false;
+ QTest::newRow("override undo") << qApp->applicationFilePath() << m_testDestinationFilePath << true;
}
void testCopySomething()
{
QFETCH(QString, source);
QFETCH(QString, destination);
+ QFETCH(bool, overrideUndo);
- QVERIFY2(QFileInfo(source).exists(), QString("Source file \"%1\" does not exist.").arg(source).toLatin1());
- CopyOperation op;
- op.setArguments(QStringList() << source << destination);
- op.backup();
- QVERIFY2(op.performOperation(), op.errorString().toLatin1());
+ QVERIFY2(QFileInfo::exists(source), QString("Source file \"%1\" does not exist.").arg(source).toLatin1());
+ CopyOperation *op = new CopyOperation();
+ op->setArguments(QStringList() << source << destination);
+ if (overrideUndo)
+ op->setArguments(op->arguments() << QLatin1String("UNDOOPERATION"));
+ op->backup();
+ QVERIFY2(op->performOperation(), op->errorString().toLatin1());
- QVERIFY2(QFileInfo(m_testDestinationFilePath).exists(), QString("Copying from \"%1\" to \"%2\" was "
+ QVERIFY2(QFileInfo::exists(m_testDestinationFilePath), QString("Copying from \"%1\" to \"%2\" was "
"not working: '%3' does not exist").arg(source, destination, m_testDestinationFilePath).toLatin1());
- QVERIFY2(op.undoOperation(), op.errorString().toLatin1());
- QVERIFY2(!QFileInfo(m_testDestinationFilePath).exists(), QString("Undo of copying from \"%1\" to "
- "\"%2\" was not working.").toLatin1());
+ QVERIFY2(op->undoOperation(), op->errorString().toLatin1());
+ if (!overrideUndo) {
+ QVERIFY2(!QFileInfo::exists(m_testDestinationFilePath), QString("Undo of copying from \"%1\" to "
+ "\"%2\" was not working.").toLatin1());
+ } else {
+ QVERIFY(QFileInfo::exists(m_testDestinationFilePath));
+ }
+ QString backupFileName = op->value("backupOfExistingDestination").toString();
+ delete op;
+ QVERIFY(!QFileInfo::exists(backupFileName));
}
void testCopyIfDestinationExist_data()
diff --git a/tests/auto/installer/deleteoperation/tst_deleteoperation.cpp b/tests/auto/installer/deleteoperation/tst_deleteoperation.cpp
index 807d03498..43ea52407 100644
--- a/tests/auto/installer/deleteoperation/tst_deleteoperation.cpp
+++ b/tests/auto/installer/deleteoperation/tst_deleteoperation.cpp
@@ -75,8 +75,7 @@ private slots:
QVERIFY(!op.performOperation());
QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments);
- QCOMPARE(op.errorString(), QString("Invalid arguments in Delete: "
- "0 arguments given, exactly 1 arguments expected."));
+ QCOMPARE(op.errorString(), QString("Invalid arguments in Delete: 0 arguments given, 1 to 3 arguments expected in the form: <file to remove> [UNDOOPERATION, \"\"]."));
op.setArguments(QStringList() << "");
QTest::ignoreMessage(QtWarningMsg, "QFile::copy: Empty or null file name");
@@ -92,13 +91,16 @@ private slots:
void testDeleteRestore_data()
{
QTest::addColumn<QString>("path");
- QTest::newRow("relative") << "test";
- QTest::newRow("absolute") << qApp->applicationDirPath() + QDir::toNativeSeparators("/test");
+ QTest::addColumn<bool>("overrideUndo");
+ QTest::newRow("relative") << "test" << false;
+ QTest::newRow("absolute") << qApp->applicationDirPath() + QDir::toNativeSeparators("/test") << false;
+ QTest::newRow("no undo") << "test" << true;
}
void testDeleteRestore()
{
QFETCH(QString, path);
+ QFETCH(bool, overrideUndo);
QByteArray testString("Generated by QTest\n");
QFile testFile(path);
@@ -107,23 +109,32 @@ private slots:
out << testString;
testFile.close();
- QVERIFY(QFileInfo(path).exists());
+ QVERIFY(QFileInfo::exists(path));
QByteArray testFileHash = QInstaller::calculateHash(path, QCryptographicHash::Sha1);
- DeleteOperation op;
- op.setArguments(QStringList() << path);
-
- op.backup();
- QVERIFY(QFileInfo(op.value("backupOfExistingFile").toString()).exists());
-
- QVERIFY2(op.performOperation(), op.errorString().toLatin1());
- QVERIFY(!QFileInfo(path).exists());
-
- QVERIFY2(op.undoOperation(), op.errorString().toLatin1());
- QByteArray restoredFileHash = QInstaller::calculateHash(path, QCryptographicHash::Sha1);
- QVERIFY(testFileHash == restoredFileHash);
-
- QVERIFY(QFile(path).remove());
+ DeleteOperation *op = new DeleteOperation();
+ op->setArguments(QStringList() << path);
+ if (overrideUndo)
+ op->setArguments(op->arguments() << QLatin1String("UNDOOPERATION"));
+
+ op->backup();
+ QVERIFY(QFileInfo::exists(op->value("backupOfExistingFile").toString()));
+
+ QVERIFY2(op->performOperation(), op->errorString().toLatin1());
+ QVERIFY(!QFileInfo::exists(path));
+
+ QVERIFY2(op->undoOperation(), op->errorString().toLatin1());
+ if (!overrideUndo) {
+ QByteArray restoredFileHash = QInstaller::calculateHash(path, QCryptographicHash::Sha1);
+ QVERIFY(testFileHash == restoredFileHash);
+ } else {
+ QVERIFY(!QFileInfo::exists(path));
+ }
+
+ QString backupFileName = op->value("backupOfExistingFile").toString();
+ delete op;
+ QVERIFY(!QFileInfo::exists(backupFileName));
+ QCOMPARE(QFile(path).remove(), !overrideUndo);
}
void testDeleteFromScript()
diff --git a/tests/auto/installer/installer.pro b/tests/auto/installer/installer.pro
index a5f5b3a2e..b2eb57790 100644
--- a/tests/auto/installer/installer.pro
+++ b/tests/auto/installer/installer.pro
@@ -15,6 +15,7 @@ SUBDIRS += \
scriptengine \
consumeoutputoperationtest \
mkdiroperationtest \
+ rmdiroperationtest \
copyoperationtest \
solver \
binaryformat \
@@ -29,6 +30,7 @@ SUBDIRS += \
linereplaceoperation \
metadatajob \
appendfileoperation \
+ prependfileoperation \
simplemovefileoperation \
deleteoperation \
copydirectoryoperation \
diff --git a/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp b/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp
index f52c27d0f..e41ba8049 100644
--- a/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp
+++ b/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2024 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -60,32 +60,42 @@ private slots:
QVERIFY(!op.performOperation());
QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments);
- QCOMPARE(op.errorString(), QString("Invalid arguments in Mkdir: "
- "0 arguments given, exactly 1 arguments expected."));
-
+ QCOMPARE(op.errorString(), QString("Invalid arguments in Mkdir: 0 arguments given, 1 to 3 "
+ "arguments expected in the form: <file to remove> [UNDOOPERATION, \"\"]."));
}
void testCreateDirectory_data()
{
- QTest::addColumn<QString>("directory");
- QTest::newRow("/test") << "/test";
- QTest::newRow("/test/test") << "/test/test";
- QTest::newRow("/test/test/test") << "/test/test/test";
+ QTest::addColumn<QString>("directory");
+ QTest::addColumn<bool>("overrideUndo");
+ QTest::newRow("/test") << "/test" << false;
+ QTest::newRow("/test/test") << "/test/test" << false;
+ QTest::newRow("/test/test/test") << "/test/test/test" << false;
+ QTest::newRow("no undo") << "/test" << true;
}
void testCreateDirectory()
{
QFETCH(QString, directory);
+ QFETCH(bool, overrideUndo);
+
QString path = QDir::current().path() + QDir::toNativeSeparators(directory);
QVERIFY2(!QDir(path).exists(), path.toLatin1());
MkdirOperation op;
op.setArguments(QStringList() << path);
+ if (overrideUndo)
+ op.setArguments(op.arguments() << QLatin1String("UNDOOPERATION"));
op.backup();
QVERIFY2(op.performOperation(), op.errorString().toLatin1());
QVERIFY2(QDir(path).exists(), path.toLatin1());
QVERIFY2(op.undoOperation(), op.errorString().toLatin1());
- QVERIFY2(!QDir(path).exists(), path.toLatin1());
+ if (overrideUndo) {
+ QVERIFY2(QDir(path).exists(), path.toLatin1());
+ QVERIFY(QDir(path).removeRecursively());
+ } else {
+ QVERIFY2(!QDir(path).exists(), path.toLatin1());
+ }
}
void testCreateDirectory_customFile_data()
diff --git a/tests/auto/installer/moveoperation/tst_moveoperation.cpp b/tests/auto/installer/moveoperation/tst_moveoperation.cpp
index 136eb1e45..bb391efee 100644
--- a/tests/auto/installer/moveoperation/tst_moveoperation.cpp
+++ b/tests/auto/installer/moveoperation/tst_moveoperation.cpp
@@ -86,8 +86,8 @@ private slots:
QVERIFY(!op.performOperation());
QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments);
- QCOMPARE(op.errorString(), QString("Invalid arguments in Move: "
- "0 arguments given, exactly 2 arguments expected."));
+ QCOMPARE(op.errorString(), QString("Invalid arguments in Move: 0 arguments given, 2 to 4 arguments "
+ "expected in the form: <complete source file name> <complete destination file name> [UNDOOPERATION, \"\"]."));
}
void testMoveFile()
diff --git a/tests/auto/installer/prependfileoperation/data/repository/B/1.0.2-1content.7z b/tests/auto/installer/prependfileoperation/data/repository/B/1.0.2-1content.7z
new file mode 100644
index 000000000..543aab656
--- /dev/null
+++ b/tests/auto/installer/prependfileoperation/data/repository/B/1.0.2-1content.7z
Binary files differ
diff --git a/tests/auto/installer/prependfileoperation/data/repository/B/1.0.2-1meta.7z b/tests/auto/installer/prependfileoperation/data/repository/B/1.0.2-1meta.7z
new file mode 100644
index 000000000..a59f269e7
--- /dev/null
+++ b/tests/auto/installer/prependfileoperation/data/repository/B/1.0.2-1meta.7z
Binary files differ
diff --git a/tests/auto/installer/prependfileoperation/data/repository/Updates.xml b/tests/auto/installer/prependfileoperation/data/repository/Updates.xml
new file mode 100644
index 000000000..e61d2445f
--- /dev/null
+++ b/tests/auto/installer/prependfileoperation/data/repository/Updates.xml
@@ -0,0 +1,16 @@
+<Updates>
+ <ApplicationName>{AnyApplication}</ApplicationName>
+ <ApplicationVersion>1.0.0</ApplicationVersion>
+ <Checksum>false</Checksum>
+ <PackageUpdate>
+ <Name>B</Name>
+ <DisplayName>A</DisplayName>
+ <Description>Example component B</Description>
+ <Version>1.0.2-1</Version>
+ <ReleaseDate>2015-01-01</ReleaseDate>
+ <Default>true</Default>
+ <Script>script.qs</Script>
+ <SHA1>750eda14d867849aeb2f47d620f6e5f32134f375</SHA1>
+ <DownloadableArchives>content.7z</DownloadableArchives>
+ </PackageUpdate>
+</Updates>
diff --git a/tests/auto/installer/prependfileoperation/data/xmloperationrepository/C/1.0.0content.7z b/tests/auto/installer/prependfileoperation/data/xmloperationrepository/C/1.0.0content.7z
new file mode 100644
index 000000000..d936db354
--- /dev/null
+++ b/tests/auto/installer/prependfileoperation/data/xmloperationrepository/C/1.0.0content.7z
Binary files differ
diff --git a/tests/auto/installer/prependfileoperation/data/xmloperationrepository/Updates.xml b/tests/auto/installer/prependfileoperation/data/xmloperationrepository/Updates.xml
new file mode 100644
index 000000000..379fe865f
--- /dev/null
+++ b/tests/auto/installer/prependfileoperation/data/xmloperationrepository/Updates.xml
@@ -0,0 +1,20 @@
+<Updates>
+ <ApplicationName>{AnyApplication}</ApplicationName>
+ <ApplicationVersion>1.0.0</ApplicationVersion>
+ <PackageUpdate>
+ <Name>C</Name>
+ <DisplayName>C</DisplayName>
+ <Description>Example component C</Description>
+ <Version>1.0.0</Version>
+ <ReleaseDate>2020-01-01</ReleaseDate>
+ <Default>true</Default>
+ <UpdateFile CompressedSize="224" OS="Any" UncompressedSize="74"/>
+ <DownloadableArchives>content.7z</DownloadableArchives>
+ <Operations>
+ <Operation name="PrependFile">
+ <Argument>@TargetDir@/C.txt</Argument>
+ <Argument>Prepended text: </Argument>
+ </Operation>
+ </Operations>
+ </PackageUpdate>
+</Updates>
diff --git a/tests/auto/installer/prependfileoperation/prependfileoperation.pro b/tests/auto/installer/prependfileoperation/prependfileoperation.pro
new file mode 100644
index 000000000..5f68385fe
--- /dev/null
+++ b/tests/auto/installer/prependfileoperation/prependfileoperation.pro
@@ -0,0 +1,10 @@
+include(../../qttest.pri)
+
+QT -= gui
+QT += testlib
+
+SOURCES += tst_prependfileoperation.cpp
+
+RESOURCES += \
+ settings.qrc \
+ ../shared/config.qrc
diff --git a/tests/auto/installer/prependfileoperation/settings.qrc b/tests/auto/installer/prependfileoperation/settings.qrc
new file mode 100644
index 000000000..deaeb257f
--- /dev/null
+++ b/tests/auto/installer/prependfileoperation/settings.qrc
@@ -0,0 +1,9 @@
+<RCC>
+ <qresource prefix="/">
+ <file>data/repository/Updates.xml</file>
+ <file>data/repository/B/1.0.2-1content.7z</file>
+ <file>data/repository/B/1.0.2-1meta.7z</file>
+ <file>data/xmloperationrepository/Updates.xml</file>
+ <file>data/xmloperationrepository/C/1.0.0content.7z</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/installer/prependfileoperation/tst_prependfileoperation.cpp b/tests/auto/installer/prependfileoperation/tst_prependfileoperation.cpp
new file mode 100644
index 000000000..12f178cb4
--- /dev/null
+++ b/tests/auto/installer/prependfileoperation/tst_prependfileoperation.cpp
@@ -0,0 +1,180 @@
+/**************************************************************************
+**
+** Copyright (C) 2024 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+#include "../shared/packagemanager.h"
+
+#include <updateoperations.h>
+#include <packagemanagercore.h>
+
+#include <QFile>
+#include <QTest>
+
+using namespace KDUpdater;
+using namespace QInstaller;
+
+class tst_prependfileoperation : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase()
+ {
+ m_testFilePath = qApp->applicationDirPath() + QDir::toNativeSeparators("/test");
+ }
+
+ void testMissingArguments()
+ {
+ PrependFileOperation op;
+
+ QVERIFY(op.testOperation());
+ QVERIFY(!op.performOperation());
+
+ QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments);
+ QCOMPARE(op.errorString(), QString("Invalid arguments in PrependFile: 0 arguments given, 2 to 4 arguments expected in the form: <filename> <text to prepend> [UNDOOPERATION, \"\"]."));
+
+ op.setArguments(QStringList() << "" << "");
+ QTest::ignoreMessage(QtWarningMsg, "QFSFileEngine::open: No file name specified");
+ QVERIFY(!op.performOperation());
+
+ QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::UserDefinedError);
+ QCOMPARE(op.errorString(), QString("Cannot open file \"\" for reading: No file name specified"));
+ }
+
+ void testPrependText_data()
+ {
+ QTest::addColumn<QString>("source");
+ QTest::addColumn<QString>("prepend");
+ QTest::addColumn<QString>("expected");
+ QTest::addColumn<bool>("overrideUndo");
+ QTest::newRow("newline") << "Line1\nLine2\nLine3\n" << "PrependedText"
+ << "PrependedTextLine1\nLine2\nLine3\n" << false;
+ QTest::newRow("no newline") << "dolore sit amet" << "Lorem ipsum "
+ << "Lorem ipsum dolore sit amet" << false;
+
+ QTest::newRow("no undo")<< "dolore sit amet" << "Lorem ipsum "
+ << "Lorem ipsum dolore sit amet" << true;
+ }
+
+ void testPrependText()
+ {
+ QFETCH(QString, source);
+ QFETCH(QString, prepend);
+ QFETCH(QString, expected);
+ QFETCH(bool, overrideUndo);
+
+ QFile file(m_testFilePath);
+ QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text));
+
+ QTextStream stream(&file);
+ stream << source << Qt::flush;
+ file.close();
+
+ PrependFileOperation *op = new PrependFileOperation();
+ op->setArguments(QStringList() << m_testFilePath << prepend);
+ if (overrideUndo)
+ op->setArguments(op->arguments() << QLatin1String("UNDOOPERATION"));
+
+ op->backup();
+ QVERIFY(QFileInfo(op->value("backupOfFile").toString()).exists());
+
+ QVERIFY2(op->performOperation(), op->errorString().toLatin1());
+ QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
+ QCOMPARE(stream.readAll(), expected);
+ file.close();
+
+ QVERIFY2(op->undoOperation(), op->errorString().toLatin1());
+ QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
+ if (overrideUndo)
+ QCOMPARE(stream.readAll(), expected);
+ else
+ QCOMPARE(stream.readAll(), source);
+ file.close();
+
+ QVERIFY(file.remove());
+
+ QString backupFileName = op->value("backupOfFile").toString();
+ delete op;
+ QVERIFY(!QFileInfo::exists(backupFileName));
+ }
+
+ void testPrependFromCLI_data()
+ {
+ QTest::addColumn<QString>("repository");
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<QString>("componentName");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("operationFromScript")
+ << (":///data/repository")
+ << ("B.txt")
+ << ("B")
+ << ("Prepended text: lorem ipsum");
+
+ QTest::newRow("operationFromXML")
+ << (":///data/xmloperationrepository")
+ << ("C.txt")
+ << ("C")
+ << ("Prepended text: lorem ipsum");
+ }
+
+ void testPrependFromCLI()
+ {
+ QFETCH(QString, repository);
+ QFETCH(QString, fileName);
+ QFETCH(QString, componentName);
+ QFETCH(QString, expected);
+
+ QString installDir = QInstaller::generateTemporaryFileName();
+ QVERIFY(QDir().mkpath(installDir));
+ QScopedPointer<PackageManagerCore> core(PackageManager::getPackageManagerWithInit
+ (installDir, repository));
+ core->installSelectedComponentsSilently(QStringList() << componentName);
+
+ QFile file(installDir + QDir::separator() + fileName);
+ QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
+ QTextStream stream(&file);
+ QCOMPARE(stream.readAll(), expected);
+ file.close();
+
+ core->setPackageManager();
+ core->commitSessionOperations();
+ // We cannot check the file contents here as it will be deleted on
+ // undo Extract, but at least check that the uninstallation succeeds.
+ QCOMPARE(PackageManagerCore::Success, core->uninstallComponentsSilently
+ (QStringList()<< componentName));
+
+ QDir dir(installDir);
+ QVERIFY(dir.removeRecursively());
+ }
+
+private:
+ QString m_testFilePath;
+};
+
+QTEST_MAIN(tst_prependfileoperation)
+
+#include "tst_prependfileoperation.moc"
diff --git a/tests/auto/installer/rmdiroperationtest/rmdiroperationtest.pro b/tests/auto/installer/rmdiroperationtest/rmdiroperationtest.pro
new file mode 100644
index 000000000..72e61ad80
--- /dev/null
+++ b/tests/auto/installer/rmdiroperationtest/rmdiroperationtest.pro
@@ -0,0 +1,6 @@
+include(../../qttest.pri)
+
+QT -= gui
+QT += testlib
+
+SOURCES = tst_rmdiroperationtest.cpp
diff --git a/tests/auto/installer/rmdiroperationtest/tst_rmdiroperationtest.cpp b/tests/auto/installer/rmdiroperationtest/tst_rmdiroperationtest.cpp
new file mode 100644
index 000000000..bfdd5921e
--- /dev/null
+++ b/tests/auto/installer/rmdiroperationtest/tst_rmdiroperationtest.cpp
@@ -0,0 +1,111 @@
+/**************************************************************************
+**
+** Copyright (C) 2024 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#include "init.h"
+#include "updateoperations.h"
+
+#include <QDir>
+#include <QObject>
+#include <QTest>
+#include <QFile>
+#include <QTextStream>
+
+using namespace KDUpdater;
+using namespace QInstaller;
+
+class tst_rmdiroperationtest : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase()
+ {
+ QInstaller::init();
+ QString path = QDir::current().path() + QDir::toNativeSeparators("/test");
+ if (QDir(path).exists()) {
+ QFAIL("Remove test folder first!");
+ }
+ }
+
+ void testMissingArguments()
+ {
+ RmdirOperation op;
+
+ QVERIFY(op.testOperation());
+ QVERIFY(!op.performOperation());
+
+ QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments);
+ QCOMPARE(op.errorString(), QLatin1String("Invalid arguments in Rmdir: 0 arguments given, 1 to 3 "
+ "arguments expected in the form: <file to remove> [UNDOOPERATION, \"\"]."));
+ }
+
+ void testRemoveDirectory_data()
+ {
+ QTest::addColumn<QString>("directory");
+ QTest::addColumn<bool>("overrideUndo");
+ QTest::newRow("/test") << "/test" << false;
+ QTest::newRow("/test/test") << "/test/test" << false;
+ QTest::newRow("/test/test/test") << "/test/test/test" << false;
+ QTest::newRow("no undo") << "/test/test/test/test" << true;
+ }
+
+ void testRemoveDirectory()
+ {
+ QFETCH(QString, directory);
+ QFETCH(bool, overrideUndo);
+
+ QString path = QDir::current().path() + QDir::toNativeSeparators(directory);
+ //Create first the directories utilizing MkdirOperation
+ MkdirOperation op;
+ op.setArguments(QStringList() << path);
+ op.setArguments(op.arguments() << QLatin1String("UNDOOPERATION"));
+ op.backup();
+ QVERIFY2(op.performOperation(), op.errorString().toLatin1());
+ QVERIFY2(QDir(path).exists(), path.toLatin1());
+
+ RmdirOperation rmOp;
+ rmOp.setArguments(QStringList() << path);
+ if (overrideUndo)
+ rmOp.setArguments(op.arguments() << QLatin1String("UNDOOPERATION"));
+ rmOp.backup();
+ rmOp.performOperation();
+ QVERIFY2(!QDir(path).exists(), path.toLatin1());
+
+ QVERIFY2(rmOp.undoOperation(), rmOp.errorString().toLatin1());
+ if (overrideUndo) {
+ QVERIFY2(!QDir(path).exists(), path.toLatin1());
+ } else {
+ QVERIFY2(QDir(path).exists(), path.toLatin1());
+ QVERIFY(QDir(path).removeRecursively());
+ }
+ }
+};
+
+QTEST_MAIN(tst_rmdiroperationtest)
+
+#include "tst_rmdiroperationtest.moc"