diff options
Diffstat (limited to 'tests/auto')
32 files changed, 1027 insertions, 226 deletions
diff --git a/tests/auto/installer/binaryformat/tst_binaryformat.cpp b/tests/auto/installer/binaryformat/tst_binaryformat.cpp index 0098ba34e..57f2a37e3 100644 --- a/tests/auto/installer/binaryformat/tst_binaryformat.cpp +++ b/tests/auto/installer/binaryformat/tst_binaryformat.cpp @@ -30,7 +30,7 @@ #include <binaryformat.h> #include <errors.h> #include <fileio.h> -#include <kdupdaterupdateoperation.h> +#include <updateoperation.h> #include <QTest> #include <QTemporaryFile> @@ -51,7 +51,9 @@ struct Layout : public QInstaller::BinaryLayout class TestOperation : public KDUpdater::UpdateOperation { public: - TestOperation(const QString &name) { setName(name); } + TestOperation(const QString &name) + : KDUpdater::UpdateOperation(0) + { setName(name); } virtual void backup() {} virtual bool performOperation() { return true; } @@ -117,8 +119,6 @@ private slots: void findMagicCookieWithError() { - QTest::ignoreMessage(QtDebugMsg, "create Error-Exception: \"No marker found, stopped after 71.00 KiB.\" "); - QTemporaryFile file; file.open(); diff --git a/tests/auto/installer/clientserver/tst_clientserver.cpp b/tests/auto/installer/clientserver/tst_clientserver.cpp index 9bb4d65a2..b3e220c9f 100644 --- a/tests/auto/installer/clientserver/tst_clientserver.cpp +++ b/tests/auto/installer/clientserver/tst_clientserver.cpp @@ -207,7 +207,7 @@ private slots: QLocalSocket socket; socket.connectToServer(socketName); - QVERIFY2(socket.waitForConnected(), "Could not connect to server."); + QVERIFY2(socket.waitForConnected(), "Cannot connect to server."); QCOMPARE(socket.state() == QLocalSocket::ConnectedState, true); sendCommand(&socket, Protocol::Authorize, QString(Protocol::DefaultAuthorizationKey)); @@ -240,7 +240,7 @@ private slots: QLocalSocket socket; socket.connectToServer(socketName); - QVERIFY2(socket.waitForConnected(), "Could not connect to server."); + QVERIFY2(socket.waitForConnected(), "Cannot connect to server."); QCOMPARE(socket.state() == QLocalSocket::ConnectedState, true); sendCommand(&socket, Protocol::Authorize, QString::fromLatin1("SomeKey")); @@ -454,8 +454,7 @@ private slots: } QSignalSpy spy(&wrapper, SIGNAL(started())); - QSignalSpy spy2(&wrapper, SIGNAL(finished(int))); - QSignalSpy spy3(&wrapper, SIGNAL(finished(int, QProcess::ExitStatus))); + QSignalSpy spy2(&wrapper, SIGNAL(finished(int, QProcess::ExitStatus))); #ifdef Q_OS_WIN wrapper.start(fileName); @@ -474,10 +473,6 @@ private slots: QCOMPARE(spy2.count(), 1); QList<QVariant> arguments = spy2.takeFirst(); QCOMPARE(arguments.first().toInt(), 0); - - QCOMPARE(spy3.count(), 1); - arguments = spy3.takeFirst(); - QCOMPARE(arguments.first().toInt(), 0); QCOMPARE(arguments.last().toInt(), int(QProcessWrapper::NormalExit)); QFile::remove(fileName); diff --git a/tests/auto/installer/componentmodel/data/updates.xml b/tests/auto/installer/componentmodel/data/updates.xml index e1f72de10..2341866ee 100644 --- a/tests/auto/installer/componentmodel/data/updates.xml +++ b/tests/auto/installer/componentmodel/data/updates.xml @@ -5,6 +5,8 @@ <PackageUpdate> <Name>com.vendor.product</Name> <DisplayName>The root component</DisplayName> + <DisplayName xml:lang="ru_RU">Корневая компонента</DisplayName> + <DisplayName xml:lang="de_DE">Wurzel Komponente</DisplayName> <Description>Install this example.</Description> <Version>0.1.0-1</Version> <ReleaseDate>2010-09-21</ReleaseDate> @@ -129,4 +131,50 @@ file="license.txt"/> </Licenses> </PackageUpdate> + <PackageUpdate> + <Name>com.vendor.fourth.product.checkable</Name> + <DisplayName>A checkable root component</DisplayName> + <Description>Install this example.</Description> + <Version>0.1.0-1</Version> + <ReleaseDate>2010-09-21</ReleaseDate> + <Checkable>true</Checkable> + <Default>false</Default> + <Script>installscript.qs</Script> + <UpdateFile UncompressedSize="61" + CompressedSize="61"/> + <Licenses> + <License name="Beer Public License Agreement" + file="license.txt"/> + </Licenses> + </PackageUpdate> + <PackageUpdate> + <Name>com.vendor.fifth.product.noncheckable</Name> + <DisplayName>A non-checkable root component</DisplayName> + <Description>Install this example.</Description> + <Version>0.1.0-1</Version> + <ReleaseDate>2010-09-21</ReleaseDate> + <Script>installscript.qs</Script> + <Checkable>false</Checkable> + <UpdateFile UncompressedSize="61" + CompressedSize="61"/> + <Licenses> + <License name="Beer Public License Agreement" + file="license.txt"/> + </Licenses> + </PackageUpdate> + <PackageUpdate> + <Name>com.vendor.fifth.product.noncheckable.sub</Name> + <DisplayName>A sub component for non-checkable root component</DisplayName> + <Description>Install this example.</Description> + <Version>0.1.0-1</Version> + <ReleaseDate>2010-09-21</ReleaseDate> + <Script>installscript.qs</Script> + <SortingPriority>0</SortingPriority> + <UpdateFile UncompressedSize="61" + CompressedSize="61"/> + <Licenses> + <License name="Beer Public License Agreement" + file="license.txt"/> + </Licenses> + </PackageUpdate> </Updates> diff --git a/tests/auto/installer/componentmodel/tst_componentmodel.cpp b/tests/auto/installer/componentmodel/tst_componentmodel.cpp index 290f0d733..5d86103a9 100644 --- a/tests/auto/installer/componentmodel/tst_componentmodel.cpp +++ b/tests/auto/installer/componentmodel/tst_componentmodel.cpp @@ -1,18 +1,16 @@ #include "component.h" #include "componentmodel.h" - -#include "kdupdaterupdatesinfo_p.h" -#include "kdupdaterupdatesourcesinfo.h" - +#include "updatesinfo_p.h" #include "packagemanagercore.h" #include <QTest> +#include <QtCore/QLocale> using namespace KDUpdater; using namespace QInstaller; -#define EXPECTED_COUNT_VIRTUALS_VISIBLE 8 -#define EXPECTED_COUNT_VIRTUALS_INVISIBLE 7 +#define EXPECTED_COUNT_VIRTUALS_VISIBLE 11 +#define EXPECTED_COUNT_VIRTUALS_INVISIBLE 10 static const char vendorProduct[] = "com.vendor.product"; static const char vendorSecondProduct[] = "com.vendor.second.product"; @@ -22,6 +20,15 @@ static const char vendorSecondProductVirtual[] = "com.vendor.second.product.virt static const char vendorSecondProductSubnode[] = "com.vendor.second.product.subnode"; static const char vendorSecondProductSubnodeSub[] = "com.vendor.second.product.subnode.sub"; static const char vendorThirdProductVirtual[] = "com.vendor.third.product.virtual"; +static const char vendorFourthProductCheckable[] = "com.vendor.fourth.product.checkable"; +static const char vendorFifthProductNonCheckable[] = "com.vendor.fifth.product.noncheckable"; +static const char vendorFifthProductSub[] = "com.vendor.fifth.product.noncheckable.sub"; + +static const QMap<QString, QString> rootComponentDisplayNames = { + {"", QLatin1String("The root component")}, + {"ru_ru", QString::fromUtf8("Корневая компонента")}, + {"de_de", QString::fromUtf8("Wurzel Komponente")} +}; class tst_ComponentModel : public QObject { @@ -41,7 +48,9 @@ private slots: m_defaultChecked << vendorProduct << vendorSecondProductSub; m_defaultPartially << vendorSecondProduct; m_defaultUnchecked << vendorSecondProductSub1 << vendorSecondProductSubnode - << vendorSecondProductSubnodeSub; + << vendorSecondProductSubnodeSub << vendorFourthProductCheckable + << vendorFifthProductSub; + m_uncheckable << vendorFifthProductNonCheckable; } void testNameToIndexAndIndexToName() @@ -57,7 +66,7 @@ private slots: // all names should be resolvable, virtual components are not indexed if they are not visible QStringList all; - all << m_defaultChecked << m_defaultPartially << m_defaultUnchecked; + all << m_defaultChecked << m_defaultPartially << m_defaultUnchecked << m_uncheckable; foreach (const QString &name, all) { QVERIFY(model.indexFromComponentName(name).isValid()); QVERIFY(model.componentFromIndex(model.indexFromComponentName(name)) != 0); @@ -81,8 +90,8 @@ private slots: // all names should be resolvable, including virtual components QStringList all; - all << m_defaultChecked << m_defaultPartially << m_defaultUnchecked << vendorSecondProductVirtual - << vendorThirdProductVirtual; + all << m_defaultChecked << m_defaultPartially << m_defaultUnchecked << m_uncheckable + << vendorSecondProductVirtual << vendorThirdProductVirtual; foreach (const QString &name, all) { QVERIFY(model.indexFromComponentName(name).isValid()); QVERIFY(model.componentFromIndex(model.indexFromComponentName(name)) != 0); @@ -107,7 +116,8 @@ private slots: QCOMPARE(model.core(), &m_core); QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked); - testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked); + testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked + + m_uncheckable); foreach (Component *const component, rootComponents) delete component; @@ -126,9 +136,10 @@ private slots: testDefaultInheritedModelBehavior(&model, 1); QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked); - // the virtual components are not checked - testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked - + QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual); + // the virtual and non-checkable components are not checked + testModelState(&model, m_defaultChecked, m_defaultPartially, + m_defaultUnchecked + m_uncheckable + + QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual); foreach (Component *const component, rootComponents) delete component; @@ -147,7 +158,8 @@ private slots: testDefaultInheritedModelBehavior(&model, 1); QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked); - testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked); + testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked + + m_uncheckable); foreach (Component *const component, rootComponents) delete component; @@ -167,7 +179,8 @@ private slots: QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked); // the virtual components are not checked - testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked + testModelState(&model, m_defaultChecked, m_defaultPartially, + m_defaultUnchecked + m_uncheckable + QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual); foreach (Component *const component, rootComponents) @@ -186,23 +199,24 @@ private slots: model.setRootComponents(rootComponents); testDefaultInheritedModelBehavior(&model, 1); - // select all possible components + // select all possible components. As one is uncheckable should result in partial check. model.setCheckedState(ComponentModel::AllChecked); - QCOMPARE(model.checkedState(), ComponentModel::AllChecked); - testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked, QStringList() - , QStringList()); + QCOMPARE(model.checkedState(), ComponentModel::PartiallyChecked); + testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked, + QStringList(), m_uncheckable); // deselect all possible components // as the first root is a forced install, should result in partially checked state model.setCheckedState(ComponentModel::AllUnchecked); QCOMPARE(model.checkedState(), ComponentModel::PartiallyChecked); testModelState(&model, QStringList() << vendorProduct, QStringList(), m_defaultPartially - + m_defaultUnchecked + QStringList(vendorSecondProductSub)); + + m_defaultUnchecked + QStringList(vendorSecondProductSub) + m_uncheckable); // reset all possible components model.setCheckedState(ComponentModel::DefaultChecked); QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked); - testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked); + testModelState(&model, m_defaultChecked, m_defaultPartially, + m_defaultUnchecked + m_uncheckable); foreach (Component *const component, rootComponents) delete component; @@ -220,25 +234,26 @@ private slots: model.setRootComponents(rootComponents); testDefaultInheritedModelBehavior(&model, 1); - // select all possible components + // select all possible components. As one is uncheckable should result to partially check model.setCheckedState(ComponentModel::AllChecked); - QCOMPARE(model.checkedState(), ComponentModel::AllChecked); + QCOMPARE(model.checkedState(), ComponentModel::PartiallyChecked); testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked + QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual, QStringList(), - QStringList()); + m_uncheckable); // deselect all possible components // as the first root is a forced install, should result in partially checked state model.setCheckedState(ComponentModel::AllUnchecked); QCOMPARE(model.checkedState(), ComponentModel::PartiallyChecked); testModelState(&model, QStringList() << vendorProduct, QStringList(), m_defaultPartially - + m_defaultUnchecked + QStringList(vendorSecondProductSub) << vendorSecondProductVirtual - << vendorThirdProductVirtual); + + m_defaultUnchecked + m_uncheckable + QStringList(vendorSecondProductSub) + << vendorSecondProductVirtual << vendorThirdProductVirtual); // reset all possible components model.setCheckedState(ComponentModel::DefaultChecked); QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked); - testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked + testModelState(&model, m_defaultChecked, m_defaultPartially, + m_defaultUnchecked + m_uncheckable + QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual); foreach (Component *const component, rootComponents) @@ -257,22 +272,24 @@ private slots: model.setRootComponents(rootComponents); testDefaultInheritedModelBehavior(&model, 1); - // select all possible components + // select all possible components. As one is uncheckable should result to partially check model.setCheckedState(ComponentModel::AllChecked); - QCOMPARE(model.checkedState(), ComponentModel::AllChecked); - testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked, QStringList() - , QStringList()); + QCOMPARE(model.checkedState(), ComponentModel::PartiallyChecked); + testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked, + QStringList(), m_uncheckable); // deselect all possible components model.setCheckedState(ComponentModel::AllUnchecked); QCOMPARE(model.checkedState(), ComponentModel::AllUnchecked); - testModelState(&model, QStringList(), QStringList(), m_defaultPartially + m_defaultUnchecked + testModelState(&model, QStringList(), QStringList(), m_defaultPartially + + m_defaultUnchecked + m_uncheckable + QStringList(vendorSecondProductSub) << vendorProduct); // reset all possible components model.setCheckedState(ComponentModel::DefaultChecked); QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked); - testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked); + testModelState(&model, m_defaultChecked, m_defaultPartially, + m_defaultUnchecked + m_uncheckable); foreach (Component *const component, rootComponents) delete component; @@ -290,30 +307,56 @@ private slots: model.setRootComponents(rootComponents); testDefaultInheritedModelBehavior(&model, 1); - // select all possible components + // select all possible components. As one is uncheckable should result to partially check model.setCheckedState(ComponentModel::AllChecked); - QCOMPARE(model.checkedState(), ComponentModel::AllChecked); + QCOMPARE(model.checkedState(), ComponentModel::PartiallyChecked); testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked + QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual, QStringList(), - QStringList()); + m_uncheckable); // deselect all possible components model.setCheckedState(ComponentModel::AllUnchecked); QCOMPARE(model.checkedState(), ComponentModel::AllUnchecked); - testModelState(&model, QStringList(), QStringList(), m_defaultPartially + m_defaultUnchecked - + QStringList(vendorSecondProductSub) << vendorSecondProductVirtual << vendorProduct - << vendorThirdProductVirtual); + testModelState(&model, QStringList(), QStringList(), m_defaultPartially + + m_defaultUnchecked + m_uncheckable + QStringList(vendorSecondProductSub) + << vendorSecondProductVirtual << vendorProduct << vendorThirdProductVirtual); // reset all possible components model.setCheckedState(ComponentModel::DefaultChecked); QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked); testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked - + QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual); + + m_uncheckable + QStringList(vendorSecondProductVirtual) + << vendorThirdProductVirtual); foreach (Component *const component, rootComponents) delete component; } + void testComponentsLocalization() + { + QStringList localesToTest = { "en_US", "ru_RU", "de_DE", "fr_FR" }; + foreach (const QString &localeToTest, localesToTest) { + QLocale::setDefault(localeToTest); + QString expectedName = rootComponentDisplayNames.contains(localeToTest.toLower()) + ? rootComponentDisplayNames[localeToTest.toLower()] + : rootComponentDisplayNames[QString()]; + + setPackageManagerOptions(NoFlags); + + QList<Component*> rootComponents = loadComponents(); + testComponentsLoaded(rootComponents); + + // setup the model with 1 column + ComponentModel model(1, &m_core); + model.setRootComponents(rootComponents); + + const QModelIndex root = model.indexFromComponentName(vendorProduct); + QCOMPARE(model.data(root, Qt::DisplayRole).toString(), expectedName); + + qDeleteAll(rootComponents); + } + } + private: void setPackageManagerOptions(Options flags) const { @@ -323,8 +366,8 @@ private: void testComponentsLoaded(const QList<Component *> &rootComponents) const { - // we need to have three root components - QCOMPARE(rootComponents.count(), 3); + // we need to have five root components + QCOMPARE(rootComponents.count(), 5); QList<Component*> components = rootComponents; foreach (Component *const component, rootComponents) @@ -339,9 +382,9 @@ private: { // row count with invalid model index should return: if (m_core.virtualComponentsVisible()) - QCOMPARE(model->rowCount(), 3); // 3 (2 non virtual and 1 virtual root component) + QCOMPARE(model->rowCount(), 5); // 5 (4 non virtual and 1 virtual root component) else - QCOMPARE(model->rowCount(), 2); // 2 (the 2 non virtual root components) + QCOMPARE(model->rowCount(), 4); // 4 (the 4 non virtual root components) QCOMPARE(model->columnCount(), columnCount); const QModelIndex firstParent = model->indexFromComponentName(vendorProduct); @@ -431,6 +474,7 @@ private: component->setValue("Default", info.data.value("Default").toString()); component->setValue("Virtual", info.data.value("Virtual").toString()); component->setValue("DisplayName", info.data.value("DisplayName").toString()); + component->setValue("Checkable", info.data.value("Checkable").toString()); QString forced = info.data.value("ForcedInstallation", scFalse).toString().toLower(); if (m_core.noForceInstallation()) @@ -470,6 +514,7 @@ private: QStringList m_defaultChecked; QStringList m_defaultPartially; QStringList m_defaultUnchecked; + QStringList m_uncheckable; }; Q_DECLARE_OPERATORS_FOR_FLAGS(tst_ComponentModel::Options) diff --git a/tests/auto/installer/consumeoutputoperationtest/tst_consumeoutputoperationtest.cpp b/tests/auto/installer/consumeoutputoperationtest/tst_consumeoutputoperationtest.cpp index 9d670542b..885aca81a 100644 --- a/tests/auto/installer/consumeoutputoperationtest/tst_consumeoutputoperationtest.cpp +++ b/tests/auto/installer/consumeoutputoperationtest/tst_consumeoutputoperationtest.cpp @@ -62,7 +62,7 @@ private slots: void testMissingArguments() { - ConsumeOutputOperation operation; + ConsumeOutputOperation operation(0); QVERIFY(operation.testOperation()); QVERIFY(!operation.performOperation()); @@ -73,7 +73,8 @@ private slots: QCOMPARE(UpdateOperation::Error(operation.error()), UpdateOperation::InvalidArguments); //qDebug() << operation.errorString(); QString compareString("Invalid arguments in ConsumeOutput: 0 arguments given, at least 2 " - "expected(<to be saved installer key name>, <executable>, [argument1], [argument2], ...)."); + "arguments expected in the form: <to be saved installer key name> " + "<executable> [argument1] [argument2] [...]."); //qDebug() << compareString; QCOMPARE(operation.errorString(), compareString); } @@ -82,8 +83,7 @@ private slots: { QString testOutput = getOutputFrom(QUOTE(QMAKE_BINARY), QStringList("-query")); - ConsumeOutputOperation operation; - operation.setValue(QLatin1String("installer"), QVariant::fromValue(&m_core)); + ConsumeOutputOperation operation(&m_core); operation.setArguments(QStringList() << "testConsumeOutputKey" << QUOTE(QMAKE_BINARY) << "-query"); QVERIFY2(operation.performOperation(), qPrintable(operation.errorString())); @@ -107,7 +107,7 @@ private: QEventLoop loop; QProcess process; - QObject::connect(&process, SIGNAL(finished(int, QProcess::ExitStatus)), &loop, SLOT(quit())); + QObject::connect(&process, SIGNAL(finished(int,QProcess::ExitStatus)), &loop, SLOT(quit())); process.start(binary, arguments, QIODevice::ReadOnly); if (process.state() != QProcess::NotRunning) diff --git a/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp b/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp index feae79d18..e55fc89f4 100644 --- a/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp +++ b/tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp @@ -27,7 +27,7 @@ **************************************************************************/ #include <init.h> -#include <kdupdaterupdateoperations.h> +#include <updateoperations.h> #include <utils.h> #include <QDir> @@ -63,7 +63,8 @@ private slots: QVERIFY(!op.performOperation()); QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); - QCOMPARE(op.errorString(), QString("Invalid arguments: 0 arguments given, 2 expected.")); + QCOMPARE(op.errorString(), QString("Invalid arguments in Copy: " + "0 arguments given, exactly 2 arguments expected.")); } @@ -82,17 +83,17 @@ private slots: QFETCH(QString, source); QFETCH(QString, destination); - QVERIFY2(QFileInfo(source).exists(), QString("Source '%1' does not exist.").arg(source).toLatin1()); + 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(m_testDestinationFilePath).exists(), QString("Copying from '%1' to '%2' was " + QVERIFY2(QFileInfo(m_testDestinationFilePath).exists(), 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(!QFileInfo(m_testDestinationFilePath).exists(), QString("Undo of copying from \"%1\" to " + "\"%2\" was not working.").toLatin1()); } void testCopyIfDestinationExist_data() @@ -114,7 +115,7 @@ private slots: QByteArray testFileHash = QInstaller::calculateHash(m_testDestinationFilePath, QCryptographicHash::Sha1); - QVERIFY2(QFileInfo(source).exists(), QString("Source '%1' does not exist.").arg(source).toLatin1()); + QVERIFY2(QFileInfo(source).exists(), QString("Source file \"%1\" does not exist.").arg(source).toLatin1()); CopyOperation op; op.setArguments(QStringList() << source << destination); op.backup(); @@ -125,8 +126,8 @@ private slots: QByteArray currentFileHash = QInstaller::calculateHash(m_testDestinationFilePath, QCryptographicHash::Sha1); QVERIFY(testFileHash != currentFileHash); - QVERIFY2(QFileInfo(m_testDestinationFilePath).exists(), QString("Copying from '%1' to '%2' was " - "not working: '%3' does not exist").arg(source, destination, m_testDestinationFilePath).toLatin1()); + QVERIFY2(QFileInfo(m_testDestinationFilePath).exists(), QString("Copying from \"%1\" to \"%2\" was " + "not working: \"%3\" does not exist").arg(source, destination, m_testDestinationFilePath).toLatin1()); // undo should replace the new one with the old backuped one QVERIFY2(op.undoOperation(), op.errorString().toLatin1()); @@ -135,7 +136,7 @@ private slots: } void init() { - QVERIFY2(!QFileInfo(m_testDestinationFilePath).exists(), QString("Destination '%1' should not exist " + QVERIFY2(!QFileInfo(m_testDestinationFilePath).exists(), QString("Destination \"%1\" should not exist " "to test the copy operation.").arg(m_testDestinationFilePath).toLatin1()); QDir().mkpath(m_testDestinationPath); } diff --git a/tests/auto/installer/extractarchiveoperationtest/tst_extractarchiveoperationtest.cpp b/tests/auto/installer/extractarchiveoperationtest/tst_extractarchiveoperationtest.cpp index 14e34a2d7..40af0d497 100644 --- a/tests/auto/installer/extractarchiveoperationtest/tst_extractarchiveoperationtest.cpp +++ b/tests/auto/installer/extractarchiveoperationtest/tst_extractarchiveoperationtest.cpp @@ -48,20 +48,21 @@ private slots: void testMissingArguments() { - ExtractArchiveOperation op; + ExtractArchiveOperation op(0); QVERIFY(op.testOperation()); QVERIFY(!op.performOperation()); //QVERIFY(!op.undoOperation()); Can't test for failure as we run into Q_ASSERT QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); - QCOMPARE(op.errorString(), QString("Invalid arguments in Extract: 0 arguments given, exactly 2 expected.")); + QCOMPARE(op.errorString(), QString("Invalid arguments in Extract: " + "0 arguments given, exactly 2 arguments expected.")); } void testExtractOperationValidFile() { - ExtractArchiveOperation op; + ExtractArchiveOperation op(0); op.setArguments(QStringList() << ":///data/valid.7z" << QDir::tempPath()); QVERIFY(op.testOperation()); @@ -71,7 +72,7 @@ private slots: void testExtractOperationInvalidFile() { - ExtractArchiveOperation op; + ExtractArchiveOperation op(0); op.setArguments(QStringList() << ":///data/invalid.7z" << QDir::tempPath()); QVERIFY(op.testOperation()); @@ -79,7 +80,8 @@ private slots: QVERIFY(op.undoOperation()); QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::UserDefinedError); - QCOMPARE(op.errorString(), QString("Error while extracting ':///data/invalid.7z': Could not open archive")); + QCOMPARE(op.errorString(), QString("Error while extracting archive \":///data/invalid.7z\": " + "Cannot open archive \":///data/invalid.7z\".")); } }; diff --git a/tests/auto/installer/factory/factory.pro b/tests/auto/installer/factory/factory.pro new file mode 100644 index 000000000..b87f23bab --- /dev/null +++ b/tests/auto/installer/factory/factory.pro @@ -0,0 +1,5 @@ +include(../../qttest.pri) + +QT -= gui + +SOURCES += tst_factory.cpp diff --git a/tests/auto/installer/factory/tst_factory.cpp b/tests/auto/installer/factory/tst_factory.cpp new file mode 100644 index 000000000..a693a2ce6 --- /dev/null +++ b/tests/auto/installer/factory/tst_factory.cpp @@ -0,0 +1,228 @@ +/************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** 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 The Qt Company. For licensing terms +** and conditions see http://qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include <genericfactory.h> + +#include <QDebug> +#include <QTest> + +#include <functional> + +class Food { +public: + explicit Food(int amount) + : m_amount(amount) + {} + virtual ~Food() {} + + int available() const { + return m_amount; + } + virtual QDate expireDate() const = 0; + + template <typename T, typename... Args> + static Food *create(Args... args) { + qDebug().nospace().noquote() << "Create function."; + return new T(std::forward<Args>(args)...); + } + +private: + int m_amount; +}; + +class EggStore : public GenericFactory<Food, QString, int> +{ +public: + static EggStore &instance() { + static EggStore factory; + return factory; + } +}; + +class Bread : public Food +{ +public: + Bread(int amount, const QDate &expireDate) + : Food(amount) + , m_expireDate(expireDate) + { qDebug().nospace().noquote() << "Constructor."; } + QDate expireDate() const { + return m_expireDate; + } +private: + QDate m_expireDate; +}; + +class Butter : public Food +{ +public: + QDate expireDate() const { + return m_expireDate; + } + static Food *create(int amount, const QDate expireDate) { + qDebug().nospace().noquote() << "Create function."; + return new Butter(amount, expireDate); + } + +private: + Butter(int amount, const QDate &expireDate) + : Food(amount) + , m_expireDate(expireDate) + { qDebug().nospace().noquote() << "Constructor."; } + +private: + QDate m_expireDate; +}; + +class ColdCuts : public Food +{ +public: + ColdCuts(int amount, const QDate &expireDate) + : Food(amount) + , m_expireDate(expireDate) + { qDebug().nospace().noquote() << "Constructor."; } + QDate expireDate() const { + return m_expireDate; + } + +private: + QDate m_expireDate; +}; + +class FoodStore : public GenericFactory<Food, QString, int, QDate> +{ +public: + static FoodStore &instance() { + static FoodStore factory; + return factory; + } +}; + +class tst_Factory : public QObject +{ + Q_OBJECT + +private slots: + void testSingleArg() + { + class Egg : public Food + { + public: + explicit Egg(int amount) + : Food(amount) + { qDebug().nospace().noquote() << "Constructor."; } + QDate expireDate() const { + return QDate::currentDate().addDays(1); + } + private: + QDate m_expireDate; + }; + class EggStore : public GenericFactory<Food, QString, int> + { + public: + static EggStore &instance() { + static EggStore factory; + return factory; + } + }; + + EggStore::instance().registerProduct<Egg>("Egg"); + QCOMPARE(EggStore::instance().containsProduct("Egg"), true); + // EggStore::instance().registerProduct<Bread>("Bread"); // Does not compile. + + QTest::ignoreMessage(QtDebugMsg, "Constructor."); + auto food = EggStore::instance().create("Egg", 100); + QCOMPARE(food->available(), 100); + QCOMPARE(food->expireDate(), QDate::currentDate().addDays(1)); + + QTest::ignoreMessage(QtDebugMsg, "Create function."); + QTest::ignoreMessage(QtDebugMsg, "Constructor."); + EggStore::instance().registerProduct("Egg", &Egg::create<Egg, int>); + food = EggStore::instance().create("Egg", 10); + QCOMPARE(food->available(), 10); + QCOMPARE(food->expireDate(), QDate::currentDate().addDays(1)); + + auto lambda = [](int amount) -> Food* { return new Egg(amount); }; + EggStore::instance().registerProduct("Egg", lambda); + + QTest::ignoreMessage(QtDebugMsg, "Constructor."); + food = EggStore::instance().create("Egg", 20); + QCOMPARE(food->available(), 20); + QCOMPARE(food->expireDate(), QDate::currentDate().addDays(1)); + } + + void testMultiArg() + { + FoodStore::instance().registerProduct<Bread>("Bread"); + FoodStore::instance().registerProduct("Butter", &Butter::create); + FoodStore::instance().registerProduct<ColdCuts>("ColdCuts"); + // FoodStore::instance().registerProduct<Eggs>("Eggs"); // Does not compile. + + QCOMPARE(FoodStore::instance().containsProduct("Bread"), true); + QCOMPARE(FoodStore::instance().containsProduct("Butter"), true); + QCOMPARE(FoodStore::instance().containsProduct("ColdCuts"), true); + QCOMPARE(FoodStore::instance().containsProduct("Sandwich"), false); + + QTest::ignoreMessage(QtDebugMsg, "Constructor."); + auto food = FoodStore::instance().create("Bread", 10, QDate::currentDate().addDays(7)); + QCOMPARE(food->available(), 10); + QCOMPARE(food->expireDate(), QDate::currentDate().addDays(7)); + + QTest::ignoreMessage(QtDebugMsg, "Create function."); + QTest::ignoreMessage(QtDebugMsg, "Constructor."); + food = FoodStore::instance().create("Butter", 2, QDate::currentDate().addDays(3)); + QCOMPARE(food->available(), 2); + QCOMPARE(food->expireDate(), QDate::currentDate().addDays(3)); + + QTest::ignoreMessage(QtDebugMsg, "Constructor."); + food = FoodStore::instance().create("ColdCuts", 50, QDate::currentDate().addDays(5)); + QCOMPARE(food->available(), 50); + QCOMPARE(food->expireDate(), QDate::currentDate().addDays(5)); + + food = FoodStore::instance().create("Sandwich", 50, QDate::currentDate()); + QCOMPARE(food == Q_NULLPTR, true); + + // overwrites the existing registration + FoodStore::instance().registerProduct("ColdCuts", &ColdCuts::create<ColdCuts, int, QDate>); + QTest::ignoreMessage(QtDebugMsg, "Create function."); + QTest::ignoreMessage(QtDebugMsg, "Constructor."); + food = FoodStore::instance().create("ColdCuts", 100, QDate::currentDate().addDays(4)); + QCOMPARE(food->available(), 100); + QCOMPARE(food->expireDate(), QDate::currentDate().addDays(4)); + } +}; + +QTEST_MAIN(tst_Factory) + +#include "tst_factory.moc" diff --git a/tests/auto/installer/fakestopprocessforupdateoperation/tst_fakestopprocessforupdateoperation.cpp b/tests/auto/installer/fakestopprocessforupdateoperation/tst_fakestopprocessforupdateoperation.cpp index c8b314657..583bb26f0 100644 --- a/tests/auto/installer/fakestopprocessforupdateoperation/tst_fakestopprocessforupdateoperation.cpp +++ b/tests/auto/installer/fakestopprocessforupdateoperation/tst_fakestopprocessforupdateoperation.cpp @@ -15,20 +15,20 @@ class tst_FakeStopProcessForUpdateOperation : public QObject private slots: void testMissingArgument() { - FakeStopProcessForUpdateOperation op; - op.setValue(QLatin1String("installer"), QVariant::fromValue(&m_core)); + FakeStopProcessForUpdateOperation op(&m_core); QVERIFY(op.testOperation()); QVERIFY(op.performOperation()); QVERIFY(!op.undoOperation()); QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); - QCOMPARE(op.errorString(), QString("Number of arguments does not match: one is required")); + QCOMPARE(op.errorString(), QString("Invalid arguments in FakeStopProcessForUpdate: " + "0 arguments given, exactly 1 arguments expected.")); } void testMissingPackageManagerCore() { - FakeStopProcessForUpdateOperation op; + FakeStopProcessForUpdateOperation op(0); op.setArguments(QStringList() << QFileInfo(QCoreApplication::applicationFilePath()).fileName()); QVERIFY(op.testOperation()); @@ -36,16 +36,15 @@ private slots: QVERIFY(!op.undoOperation()); QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::UserDefinedError); - QCOMPARE(op.errorString(), QString("Could not get package manager core.")); + QCOMPARE(op.errorString(), QString("Cannot get package manager core.")); } void testRunningApplication() { const QString app = QFileInfo(QCoreApplication::applicationFilePath()).fileName(); - FakeStopProcessForUpdateOperation op; + FakeStopProcessForUpdateOperation op(&m_core); op.setArguments(QStringList() << app); - op.setValue(QLatin1String("installer"), QVariant::fromValue(&m_core)); QVERIFY(op.testOperation()); QVERIFY(op.performOperation()); @@ -58,9 +57,8 @@ private slots: void testRunningNonApplication() { - FakeStopProcessForUpdateOperation op; + FakeStopProcessForUpdateOperation op(&m_core); op.setArguments(QStringList() << "dummy.exe"); - op.setValue(QLatin1String("installer"), QVariant::fromValue(&m_core)); QVERIFY(op.testOperation()); QVERIFY(op.performOperation()); diff --git a/tests/auto/installer/installer.pro b/tests/auto/installer/installer.pro index 0bd5e8690..ba2dd0244 100644 --- a/tests/auto/installer/installer.pro +++ b/tests/auto/installer/installer.pro @@ -8,6 +8,7 @@ SUBDIRS += \ messageboxhandler \ extractarchiveoperationtest \ lib7zfacade \ + unicodeexecutable \ scriptengine \ consumeoutputoperationtest \ mkdiroperationtest \ @@ -17,4 +18,10 @@ SUBDIRS += \ packagemanagercore \ settingsoperation \ task \ - clientserver + clientserver \ + factory + +win32 { + SUBDIRS += registerfiletypeoperation +} +scriptengine.depends += unicodeexecutable diff --git a/tests/auto/installer/lib7zfacade/tst_lib7zfacade.cpp b/tests/auto/installer/lib7zfacade/tst_lib7zfacade.cpp index 75b7bf148..ffc5b330a 100644 --- a/tests/auto/installer/lib7zfacade/tst_lib7zfacade.cpp +++ b/tests/auto/installer/lib7zfacade/tst_lib7zfacade.cpp @@ -26,8 +26,10 @@ ** **************************************************************************/ -#include "init.h" -#include "lib7z_facade.h" +#include <lib7z_create.h> +#include <lib7z_extract.h> +#include <lib7z_facade.h> +#include <lib7z_list.h> #include <QDir> #include <QObject> @@ -41,7 +43,7 @@ class tst_lib7zfacade : public QObject private slots: void initTestCase() { - QInstaller::init(); + Lib7z::initSevenZ(); m_file.path = "valid"; m_file.permissions = 0; @@ -49,7 +51,7 @@ private slots: m_file.uncompressedSize = 5242880; m_file.isDirectory = false; m_file.archiveIndex = QPoint(0, 0); - m_file.mtime = QDateTime(QDate::fromJulianDay(2456413), QTime(12, 50, 42)); + m_file.utcTime = QDateTime(QDate::fromJulianDay(2456413), QTime(10, 50, 42), Qt::UTC); } void testIsSupportedArchive() @@ -57,109 +59,111 @@ private slots: QCOMPARE(Lib7z::isSupportedArchive(":///data/valid.7z"), true); QCOMPARE(Lib7z::isSupportedArchive(":///data/invalid.7z"), false); - { + try { QFile file(":///data/valid.7z"); QVERIFY(file.open(QIODevice::ReadOnly)); QCOMPARE(Lib7z::isSupportedArchive(&file), true); + } catch (...) { + QFAIL("Unexpected error during Lib7z::isSupportedArchive."); } - { + try { QFile file(":///data/invalid.7z"); QVERIFY(file.open(QIODevice::ReadOnly)); QCOMPARE(Lib7z::isSupportedArchive(&file), false); + } catch (...) { + QFAIL("Unexpected error during Lib7z::isSupportedArchive."); } } void testListArchive() { - // TODO: this should work without scope, there's a bug in Lib7z::OpenArchiveInfo - // caused by the fact that we keep a pointer to the device, not the devices target - { + try { QFile file(":///data/valid.7z"); QVERIFY(file.open(QIODevice::ReadOnly)); QVector<Lib7z::File> files = Lib7z::listArchive(&file); QCOMPARE(files.count(), 1); -#ifdef Q_OS_UNIX - QSKIP("This test requires the time handling to be repaired first."); -#endif QCOMPARE(files.first(), m_file); + } catch (...) { + QFAIL("Unexpected error during list archive."); } - { - try { - QFile file(":///data/invalid.7z"); - QVERIFY(file.open(QIODevice::ReadOnly)); - QVector<Lib7z::File> files = Lib7z::listArchive(&file); - } catch (const Lib7z::SevenZipException& e) { - QCOMPARE(e.message(), QString("Could not open archive")); - } catch (...) { - QFAIL("Unexpected error during list archive!"); - } + try { + QFile file(":///data/invalid.7z"); + QVERIFY(file.open(QIODevice::ReadOnly)); + QVector<Lib7z::File> files = Lib7z::listArchive(&file); + } catch (const Lib7z::SevenZipException& e) { + QCOMPARE(e.message(), QString("Cannot open archive \":///data/invalid.7z\".")); + } catch (...) { + QFAIL("Unexpected error during list archive."); } } void testCreateArchive() { - QTemporaryFile target; - QVERIFY(target.open()); - try { - // TODO: we do not get any information about success - Lib7z::createArchive(&target, QStringList() << ":///data/invalid.7z"); + const QString path = tempSourceFile("Source File 1."); + const QString path2 = tempSourceFile("Source File 2."); + + QTemporaryFile target; + QVERIFY(target.open()); + Lib7z::createArchive(&target, QStringList() << path << path2); + QCOMPARE(Lib7z::listArchive(&target).count(), 2); } catch (const Lib7z::SevenZipException& e) { QFAIL(e.message().toUtf8()); } catch (...) { - QFAIL("Unexpected error during create archive!"); + QFAIL("Unexpected error during create archive."); } - } - - void testExtractArchive() - { - QFile source(":///data/valid.7z"); - QVERIFY(source.open(QIODevice::ReadOnly)); try { - // TODO: we do not get any information about success - Lib7z::extractArchive(&source, QDir::tempPath()); + const QString path1 = tempSourceFile( + "Source File 1.", + QDir::tempPath() + "/temp file with spaces.XXXXXX" + ); + const QString path2 = tempSourceFile( + "Source File 2.", + QDir::tempPath() + "/temp file with spaces.XXXXXX" + ); + + QTemporaryFile target(QDir::tempPath() + "/target file with spaces.XXXXXX"); + QVERIFY(target.open()); + Lib7z::createArchive(&target, QStringList() << path1 << path2); + QCOMPARE(Lib7z::listArchive(&target).count(), 2); } catch (const Lib7z::SevenZipException& e) { QFAIL(e.message().toUtf8()); } catch (...) { - QFAIL("Unexpected error during extract archive!"); + QFAIL("Unexpected error during create archive."); } + } - void testExtractFileFromArchive() + void testExtractArchive() { QFile source(":///data/valid.7z"); QVERIFY(source.open(QIODevice::ReadOnly)); - QTemporaryFile target; - QVERIFY(target.open()); - try { - // TODO: we do not get any information about success - Lib7z::extractFileFromArchive(&source, m_file, &target); + Lib7z::extractArchive(&source, QDir::tempPath()); + QCOMPARE(QFile::exists(QDir::tempPath() + QString("/valid")), true); } catch (const Lib7z::SevenZipException& e) { QFAIL(e.message().toUtf8()); } catch (...) { - QFAIL("Unexpected error during extract file from archive!"); + QFAIL("Unexpected error during extract archive."); } } - void testExtractFileFromArchive2() +private: + QString tempSourceFile(const QByteArray &data, const QString &templateName = QString()) { - QFile source(":///data/valid.7z"); - QVERIFY(source.open(QIODevice::ReadOnly)); - - try { - // TODO: we do not get any information about success - Lib7z::extractFileFromArchive(&source, m_file, QDir::tempPath()); - } catch (const Lib7z::SevenZipException& e) { - QFAIL(e.message().toUtf8()); - } catch (...) { - QFAIL("Unexpected error during extract file from archive!"); + QTemporaryFile source; + if (!templateName.isEmpty()) { + source.setFileTemplate(templateName); } + source.open(); + source.write(data); + source.setAutoRemove(false); + return source.fileName(); } private: diff --git a/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp b/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp index d032b973f..dd127f626 100644 --- a/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp +++ b/tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp @@ -12,6 +12,17 @@ using namespace QInstaller; +QT_BEGIN_NAMESPACE +namespace QTest { + template<> + char *toString(const QMessageBox::StandardButton &button) + { + QString buttonAsString(QString::number(button)); + return qstrdup(buttonAsString.toLatin1().data()); + } +} +QT_END_NAMESPACE + class tst_MessageBoxHandler : public QObject { Q_OBJECT @@ -56,8 +67,8 @@ private slots: void testDefaultAction() { - const char ignoreMessage[] = "\"created critical message box TestError: 'A test error', " - "This is a test error message.\" "; + const char ignoreMessage[] = "Created critical message box \"TestError\": \"A test error\", " + "\"This is a test error message.\""; srand(time(0)); /* initialize random seed: */ int standardButtons = QMessageBox::NoButton; @@ -85,7 +96,7 @@ private slots: wantedButton = button; } - QVERIFY2(wantedButton != QMessageBox::NoButton, "Could not find a wantedButton."); + QVERIFY2(wantedButton != QMessageBox::NoButton, "Cannot find a wantedButton."); QCOMPARE(static_cast<QMessageBox::StandardButton>(returnButton), wantedButton); } while (standardButtons < m_maxStandardButtons); } diff --git a/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp b/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp index b18cae3a0..f52c27d0f 100644 --- a/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp +++ b/tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp @@ -27,7 +27,7 @@ **************************************************************************/ #include "init.h" -#include "kdupdaterupdateoperations.h" +#include "updateoperations.h" #include <QDir> #include <QObject> @@ -60,7 +60,8 @@ private slots: QVERIFY(!op.performOperation()); QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); - QCOMPARE(op.errorString(), QString("Invalid arguments: 0 arguments given, 1 expected.")); + QCOMPARE(op.errorString(), QString("Invalid arguments in Mkdir: " + "0 arguments given, exactly 1 arguments expected.")); } @@ -116,7 +117,7 @@ private slots: file.close(); QVERIFY2(!op.undoOperation(), op.errorString().toLatin1()); QVERIFY2(file.exists(), filepath.toLatin1()); - QVERIFY2(QDir(filepath).remove(filepath), "Could not remove file"); + QVERIFY2(QDir(filepath).remove(filepath), "Cannot remove file"); QVERIFY2(!file.exists(), filepath.toLatin1()); QVERIFY2(op.undoOperation(), op.errorString().toLatin1()); QVERIFY2(!QDir(path).exists(), path.toLatin1()); diff --git a/tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp b/tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp index 42be8038e..47fb41bf1 100644 --- a/tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp +++ b/tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp @@ -84,26 +84,19 @@ class tst_PackageManagerCore : public QObject private: void setIgnoreMessage(const QString &testDirectory) { -#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) - const QString message = "\"\t- arguments: %1\" "; -#else - const QString message = "\"\\t- arguments: %1\" "; -#endif + const QString message = "\t- arguments: %1"; QTest::ignoreMessage(QtDebugMsg, "Operations sanity check succeeded."); - QTest::ignoreMessage(QtDebugMsg, "\"backup operation: Mkdir\" "); + QTest::ignoreMessage(QtDebugMsg, "backup operation: Mkdir"); QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(testDirectory))); QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(testDirectory))); QTest::ignoreMessage(QtDebugMsg, qPrintable(message.arg(testDirectory))); - QTest::ignoreMessage(QtDebugMsg, "\"perform operation: Mkdir\" "); - QTest::ignoreMessage(QtDebugMsg, "Install size: 1 components "); - QTest::ignoreMessage(QtDebugMsg, "create Error-Exception: \"Force crash to test rollback!\" "); - QTest::ignoreMessage(QtDebugMsg, "\"created critical message box installationError: 'Error" - "', Force crash to test rollback!\" "); - QTest::ignoreMessage(QtDebugMsg, "ROLLING BACK operations= 1 "); - QTest::ignoreMessage(QtDebugMsg, "\"undo operation: Mkdir\" "); - QTest::ignoreMessage(QtDebugMsg, "Done "); - QTest::ignoreMessage(QtDebugMsg, "Done "); - QTest::ignoreMessage(QtDebugMsg, "Done "); + QTest::ignoreMessage(QtDebugMsg, "perform operation: Mkdir"); + QTest::ignoreMessage(QtDebugMsg, "Install size: 1 components"); + QTest::ignoreMessage(QtDebugMsg, "ROLLING BACK operations= 1"); + QTest::ignoreMessage(QtDebugMsg, "undo operation: Mkdir"); + QTest::ignoreMessage(QtDebugMsg, "Done"); + QTest::ignoreMessage(QtDebugMsg, "Done"); + QTest::ignoreMessage(QtDebugMsg, "Done"); } private slots: @@ -202,8 +195,6 @@ private slots: Component *root = new NamedComponent(&core, QLatin1String("root1")); try { - QTest::ignoreMessage(QtDebugMsg, "create Error-Exception: \"Components cannot " - "have children in updater mode.\" "); root->appendComponent(new NamedComponent(&core, QLatin1String("root1.foo"))); QFAIL("Components cannot have children in updater mode."); } catch (const QInstaller::Error &error) { diff --git a/tests/auto/installer/registerfiletypeoperation/registerfiletypeoperation.pro b/tests/auto/installer/registerfiletypeoperation/registerfiletypeoperation.pro new file mode 100644 index 000000000..0e541ceed --- /dev/null +++ b/tests/auto/installer/registerfiletypeoperation/registerfiletypeoperation.pro @@ -0,0 +1,6 @@ +include(../../qttest.pri) + +QT -= gui +QT += testlib network + +SOURCES = tst_registerfiletypeoperation.cpp diff --git a/tests/auto/installer/registerfiletypeoperation/tst_registerfiletypeoperation.cpp b/tests/auto/installer/registerfiletypeoperation/tst_registerfiletypeoperation.cpp new file mode 100644 index 000000000..7afc372b4 --- /dev/null +++ b/tests/auto/installer/registerfiletypeoperation/tst_registerfiletypeoperation.cpp @@ -0,0 +1,126 @@ +/************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "init.h" +#include "registerfiletypeoperation.h" +#include "packagemanagercore.h" + +#include <QDir> +#include <QObject> +#include <QTest> +#include <QFile> +#include <QTextStream> +#include <QSettings> +#include "qsettingswrapper.h" + +using namespace KDUpdater; +using namespace QInstaller; + +class tst_registerfiletypeoperation : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase() + { + QInstaller::init(); + QString randomString = ""; + const QString possible = "abcdefghijklmnopqrstuvwxyz0123456789"; + qsrand(QTime::currentTime().msec()); + for (int i = 0; i < 5; i++) { + int index = qrand() % possible.length(); + QChar nextChar = possible.at(index); + randomString.append(nextChar); + + } + m_fileType = randomString; + + m_command = m_core.environmentVariable("SystemRoot") + "\\notepad.exe"; + m_progId = "QtProject.QtInstallerFramework." + m_fileType; + + } + + void testMissingArguments() + { + RegisterFileTypeOperation op(&m_core); + + QVERIFY(op.testOperation()); + QVERIFY(!op.performOperation()); + + QCOMPARE(UpdateOperation::Error(op.error()), UpdateOperation::InvalidArguments); + QCOMPARE(op.errorString(), QString("Invalid arguments in RegisterFileType: 0 arguments given, " + "2 to 5 arguments expected in the form: <extension> <command> [description [contentType [icon]]].")); + + } + void testRegisterFileType() + { + RegisterFileTypeOperation op(&m_core); + op.setArguments(QStringList() << m_fileType << m_command << "test filetype" << + "text/plain" << 0 << "ProgId="+m_progId); + + const QString settingsPath = QString::fromLatin1("HKEY_CURRENT_USER\\Software\\Classes\\"); + QSettings settings(settingsPath, QSettings::NativeFormat); + + + QVERIFY(op.testOperation()); + QVERIFY(op.performOperation()); + + QString defaultKey = "."+m_fileType+ "/Default"; + QString openWithProgIdkey = "." + m_fileType + "/OpenWithProgIds/" +m_progId; + QString shellKey = m_progId + "/shell/Open/Command/Default/"; + QString shellAppkey = "/Applications/" + m_progId + "/shell/Open/Command/Default/"; + + QCOMPARE(settings.value(defaultKey).toString(), m_progId); + QCOMPARE(settings.value(openWithProgIdkey).toString(), QString()); + QCOMPARE(settings.value(shellKey).toString(), m_command); + QCOMPARE(settings.value(shellAppkey).toString(), m_command); + + QVERIFY(op.undoOperation()); + + //Test that values have been removed after undo operation + QCOMPARE(settings.value(defaultKey).toString(), QString()); + QCOMPARE(settings.value(openWithProgIdkey).toString(), QString()); + QCOMPARE(settings.value(shellKey).toString(), QString()); + QCOMPARE(settings.value(shellAppkey).toString(), QString()); + } + +private: + QString m_fileType; + QString m_command; + QString m_progId; + PackageManagerCore m_core; +}; + +QTEST_MAIN(tst_registerfiletypeoperation) + +#include "tst_registerfiletypeoperation.moc" diff --git a/tests/auto/installer/scriptengine/data/addOperation.qs b/tests/auto/installer/scriptengine/data/addOperation.qs new file mode 100644 index 000000000..d7d505a6b --- /dev/null +++ b/tests/auto/installer/scriptengine/data/addOperation.qs @@ -0,0 +1,52 @@ +/************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +function Component() +{ +} + +Component.prototype.createOperations = function () +{ + console.log("Component::createOperations()"); + component.createOperations(); + + component.addOperation("EmptyArg", "Arg", "Arg2", ""); + component.addOperation("EmptyArg", "Arg", "", "Arg3"); + component.addOperation("EmptyArg", "", "Arg2", "Arg3"); + component.addOperation("EmptyArg", ["Arg", "Arg2", ""]); + + component.addElevatedOperation("EmptyArg", "eArg", "eArg2", ""); + component.addElevatedOperation("EmptyArg", "eArg", "", "eArg3"); + component.addElevatedOperation("EmptyArg", "", "eArg2", "eArg3"); + component.addElevatedOperation("EmptyArg", ["eArg", "eArg2", ""]); +} diff --git a/tests/auto/installer/scriptengine/scriptengine.pro b/tests/auto/installer/scriptengine/scriptengine.pro index 71d8196a1..50aa859a3 100644 --- a/tests/auto/installer/scriptengine/scriptengine.pro +++ b/tests/auto/installer/scriptengine/scriptengine.pro @@ -4,5 +4,7 @@ QT += qml widgets SOURCES += tst_scriptengine.cpp +DEFINES += "BUILDDIR=\\\"$$OUT_PWD\\\"" + RESOURCES += \ scriptengine.qrc diff --git a/tests/auto/installer/scriptengine/scriptengine.qrc b/tests/auto/installer/scriptengine/scriptengine.qrc index d630f3196..9c72e686f 100644 --- a/tests/auto/installer/scriptengine/scriptengine.qrc +++ b/tests/auto/installer/scriptengine/scriptengine.qrc @@ -8,5 +8,6 @@ <file>data/enteringpage.qs</file> <file>data/form.ui</file> <file>data/userinterface.qs</file> + <file>data/addOperation.qs</file> </qresource> </RCC> diff --git a/tests/auto/installer/scriptengine/tst_scriptengine.cpp b/tests/auto/installer/scriptengine/tst_scriptengine.cpp index 5b7404557..186e341c7 100644 --- a/tests/auto/installer/scriptengine/tst_scriptengine.cpp +++ b/tests/auto/installer/scriptengine/tst_scriptengine.cpp @@ -28,10 +28,14 @@ #include <component.h> #include <errors.h> +#include <updateoperation.h> +#include <updateoperationfactory.h> #include <packagemanagercore.h> #include <packagemanagergui.h> #include <scriptengine.h> +#include <../unicodeexecutable/stringdata.h> + #include <QTest> #include <QSet> #include <QFile> @@ -151,6 +155,29 @@ signals: void emitted(); }; +class EmptyArgOperation : public KDUpdater::UpdateOperation +{ +public: + explicit EmptyArgOperation(QInstaller::PackageManagerCore *core) + : KDUpdater::UpdateOperation(core) + { + setName("EmptyArg"); + } + + void backup() {} + bool performOperation() { + return true; + } + bool undoOperation() { + return true; + } + bool testOperation() { + return true; + } +}; + + +// -- tst_ScriptEngine class tst_ScriptEngine : public QObject { @@ -166,6 +193,9 @@ private slots: m_component->setValue("Default", "Script"); m_component->setValue(scName, "component.test.name"); + Component *component = new Component(&m_core); + component->setValue(scName, "component.test.addOperation"); + m_core.appendRootComponent(component); m_scriptEngine = m_core.componentScriptEngine(); } @@ -245,9 +275,9 @@ private slots: QCOMPARE(context.isError(), false); // ignore Output from script - setExpectedScriptOutput("\"function receive()\""); + setExpectedScriptOutput("function receive()"); - QTest::ignoreMessage(QtWarningMsg, ":10: ReferenceError: foo is not defined"); + QTest::ignoreMessage(QtWarningMsg, ":43: ReferenceError: foo is not defined"); emiter.produceSignal(); const QJSValue value = m_scriptEngine->evaluate(""); @@ -256,7 +286,7 @@ private slots: void testScriptPrint() { - setExpectedScriptOutput("\"test\""); + setExpectedScriptOutput("test"); const QJSValue value = m_scriptEngine->evaluate("print(\"test\");"); if (value.isError()) { QFAIL(qPrintable(QString::fromLatin1("ScriptEngine error:\n %1").arg( @@ -266,7 +296,7 @@ private slots: void testExistingInstallerObject() { - setExpectedScriptOutput("\"object\""); + setExpectedScriptOutput("object"); const QJSValue value = m_scriptEngine->evaluate("print(typeof installer)"); if (value.isError()) { QFAIL(qPrintable(QString::fromLatin1("ScriptEngine error:\n %1").arg( @@ -280,7 +310,7 @@ private slots: "\n" "print(component.name);").arg(m_component->name()); - setExpectedScriptOutput("\"component.test.name\""); + setExpectedScriptOutput("component.test.name"); const QJSValue value = m_scriptEngine->evaluate(script); if (value.isError()) { QFAIL(qPrintable(QString::fromLatin1("ScriptEngine error:\n %1").arg( @@ -304,7 +334,7 @@ private slots: "\n" "print(components[0].name);"); - setExpectedScriptOutput("\"component.test.name\""); + setExpectedScriptOutput("component.test.name"); const QJSValue value = m_scriptEngine->evaluate(script); if (value.isError()) { QFAIL(qPrintable(QString::fromLatin1("ScriptEngine error:\n %1").arg( @@ -316,28 +346,28 @@ private slots: { try { // ignore retranslateUi which is called by loadComponentScript - setExpectedScriptOutput("\"Component constructor - OK\""); - setExpectedScriptOutput("\"retranslateUi - OK\""); + setExpectedScriptOutput("Component constructor - OK"); + setExpectedScriptOutput("retranslateUi - OK"); m_component->loadComponentScript(":///data/component1.qs"); - setExpectedScriptOutput("\"retranslateUi - OK\""); + setExpectedScriptOutput("retranslateUi - OK"); m_component->languageChanged(); - setExpectedScriptOutput("\"createOperationsForPath - OK\""); + setExpectedScriptOutput("createOperationsForPath - OK"); m_component->createOperationsForPath(":///data/"); - setExpectedScriptOutput("\"createOperationsForArchive - OK\""); + setExpectedScriptOutput("createOperationsForArchive - OK"); // ignore createOperationsForPath which is called by createOperationsForArchive - setExpectedScriptOutput("\"createOperationsForPath - OK\""); + setExpectedScriptOutput("createOperationsForPath - OK"); m_component->createOperationsForArchive("test.7z"); - setExpectedScriptOutput("\"beginInstallation - OK\""); + setExpectedScriptOutput("beginInstallation - OK"); m_component->beginInstallation(); - setExpectedScriptOutput("\"createOperations - OK\""); + setExpectedScriptOutput("createOperations - OK"); m_component->createOperations(); - setExpectedScriptOutput("\"isDefault - OK\""); + setExpectedScriptOutput("isDefault - OK"); bool returnIsDefault = m_component->isDefault(); QCOMPARE(returnIsDefault, false); @@ -354,23 +384,22 @@ private slots: // m_core becomes the owner of testComponent, it will delete it in the destructor m_core.appendRootComponent(testComponent); - const QString debugMesssage( - "create Error-Exception: \"Exception while loading the component script '" - ":///data/component2.qs'. (ReferenceError: broken is not defined)\""); try { // ignore Output from script - setExpectedScriptOutput("\"script function: Component\""); - setExpectedScriptOutput(qPrintable(debugMesssage)); + setExpectedScriptOutput("script function: Component"); testComponent->loadComponentScript(":///data/component2.qs"); } catch (const Error &error) { - QVERIFY2(debugMesssage.contains(error.message()), "(ReferenceError: broken is not defined)"); + const QString debugMessage( + QString("create Error-Exception: \"Exception while loading the component script \"%1\": " + "ReferenceError: broken is not defined\"").arg(QDir::toNativeSeparators(":///data/component2.qs"))); + QVERIFY2(debugMessage.contains(error.message()), "(ReferenceError: broken is not defined)"); } } void loadComponentUserInterfaces() { try { - setExpectedScriptOutput("\"checked: false\""); + setExpectedScriptOutput("checked: false"); m_component->loadUserInterfaces(QDir(":///data"), QStringList() << QLatin1String("form.ui")); m_component->loadComponentScript(":///data/userinterface.qs"); } catch (const Error &error) { @@ -392,7 +421,7 @@ private slots: QTest::ignoreMessage(QtWarningMsg, "Button with type: \"unknown button\" not found! "); testGui.callProtectedDelayedExecuteControlScript(PackageManagerCore::ComponentSelection); - setExpectedScriptOutput("\"FinishedPageCallback - OK\""); + setExpectedScriptOutput("FinishedPageCallback - OK"); testGui.callProtectedDelayedExecuteControlScript(PackageManagerCore::InstallationFinished); } catch (const Error &error) { QFAIL(qPrintable(error.message())); @@ -439,6 +468,56 @@ private slots: QCOMPARE(gui.widget()->property("complete").toString(), QString("true")); } + void testInstallerExecuteEncodings_data() + { + QTest::addColumn<QString>("argumentsToInstallerExecute"); + QTest::addColumn<QString>("expectedOutput"); + QTest::addColumn<int>("expectedExitCode"); + + QTest::newRow("default_encoding_ascii_output_exit_code_0") + << QString::fromLatin1("['ascii', '0']") << QString::fromLatin1(asciiText) << 0; + QTest::newRow("default_encoding_ascii_output_exit_code_52") + << QString::fromLatin1("['ascii', '52']") << QString::fromLatin1(asciiText) << 52; + + QTest::newRow("latin1_encoding_ascii_output") + << QString::fromLatin1("['ascii', '0'], '', 'latin1', 'latin1'") << QString::fromLatin1(asciiText) << 0; + QTest::newRow("latin1_encoding_utf8_output") + << QString::fromLatin1("['utf8', '0'], '', 'latin1', 'latin1'") << QString::fromLatin1(utf8Text) << 0; + + QTest::newRow("utf8_encoding_ascii_output") + << QString::fromLatin1("['ascii', '0'], '', 'utf8', 'utf8'") << QString::fromUtf8(asciiText) << 0; + QTest::newRow("utf8_encoding_utf8_output") + << QString::fromLatin1("['utf8', '0'], '', 'utf8', 'utf8'") << QString::fromUtf8(utf8Text) << 0; + } + + void testInstallerExecuteEncodings() + { + QString unicodeExecutableName = QLatin1String(BUILDDIR "/../unicodeexecutable/unicodeexecutable"); +#if defined(Q_OS_WIN) + unicodeExecutableName += QLatin1String(".exe"); +#endif + + QFileInfo unicodeExecutable(unicodeExecutableName); + if (!unicodeExecutable.isExecutable()) { + QFAIL(qPrintable(QString::fromLatin1("ScriptEngine error: test program %1 is not executable") + .arg(unicodeExecutable.absoluteFilePath()))); + return; + } + + const QString testProgramPath = unicodeExecutable.absoluteFilePath(); + + QFETCH(QString, argumentsToInstallerExecute); + QFETCH(QString, expectedOutput); + QFETCH(int, expectedExitCode); + + QJSValue result = m_scriptEngine->evaluate(QString::fromLatin1("installer.execute('%1', %2);") + .arg(testProgramPath) + .arg(argumentsToInstallerExecute)); + QCOMPARE(result.isArray(), true); + QCOMPARE(result.property(0).toString(), expectedOutput); + QCOMPARE(result.property(1).toString(), QString::number(expectedExitCode)); + } + void checkEnteringCalledBeforePageCallback() { EnteringGui gui(&m_core); @@ -454,6 +533,47 @@ private slots: QCOMPARE(enteringPage->invocationOrder(), expectedOrder); } + void testAddOperation_AddElevatedOperation() + { +#if QT_VERSION < 0x50600 + QSKIP("Behavior changed from 5.6.0 onwards."); +#endif + using namespace KDUpdater; + UpdateOperationFactory &factory = UpdateOperationFactory::instance(); + factory.registerUpdateOperation<EmptyArgOperation>(QLatin1String("EmptyArg")); + + try { + m_core.setPackageManager(); + Component *component = m_core.componentByName("component.test.addOperation"); + component->loadComponentScript(":///data/addOperation.qs"); + + setExpectedScriptOutput("Component::createOperations()"); + component->createOperations(); + + const OperationList operations = component->operations(); + QCOMPARE(operations.count(), 8); + + struct { + const char* args[3]; + const char* operator[](int i) const { + return args[i]; + } + } expectedArgs[] = { + { "Arg", "Arg2", "" }, { "Arg", "", "Arg3" }, { "", "Arg2", "Arg3" }, { "Arg", "Arg2", "" }, + { "eArg", "eArg2", "" }, { "eArg", "", "eArg3" }, { "", "eArg2", "eArg3" }, { "eArg", "eArg2", "" } + }; + + for (int i = 0; i < operations.count(); ++i) { + const QStringList arguments = operations[i]->arguments(); + QCOMPARE(arguments.count(), 3); + for (int j = 0; j < 3; ++j) + QCOMPARE(arguments[j], QString(expectedArgs[i][j])); + } + } catch (const QInstaller::Error &error) { + QFAIL(qPrintable(error.message())); + } + } + private: void setExpectedScriptOutput(const char *message) { diff --git a/tests/auto/installer/settings/data/full_config.xml b/tests/auto/installer/settings/data/full_config.xml index 5479fa353..272a1b0d7 100644 --- a/tests/auto/installer/settings/data/full_config.xml +++ b/tests/auto/installer/settings/data/full_config.xml @@ -37,6 +37,7 @@ File should contain all elements we allow in a config.xml <DependsOnLocalInstallerBinary>true</DependsOnLocalInstallerBinary> <AllowSpaceInPath>true</AllowSpaceInPath> <AllowNonAsciiCharacters>true</AllowNonAsciiCharacters> + <DisableAuthorizationFallback>true</DisableAuthorizationFallback> <RepositorySettingsPageVisible>false</RepositorySettingsPageVisible> <CreateLocalRepository>false</CreateLocalRepository> <TargetConfigurationFile>components.xml</TargetConfigurationFile> @@ -56,4 +57,6 @@ File should contain all elements we allow in a config.xml </Translations> <ControlScript>controlscript.js</ControlScript> + + <SupportsModify>true</SupportsModify> </Installer> diff --git a/tests/auto/installer/settings/data/length_units_invalid.xml b/tests/auto/installer/settings/data/length_units_invalid.xml new file mode 100644 index 000000000..b1dc5aa62 --- /dev/null +++ b/tests/auto/installer/settings/data/length_units_invalid.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Installer> + <Name>Your application</Name> + <Version>1.2.3</Version> + <WizardDefaultWidth>800pt</WizardDefaultWidth> + <WizardDefaultHeight>600pt</WizardDefaultHeight> +</Installer> diff --git a/tests/auto/installer/settings/data/length_units_valid_em.xml b/tests/auto/installer/settings/data/length_units_valid_em.xml new file mode 100644 index 000000000..af087fdfe --- /dev/null +++ b/tests/auto/installer/settings/data/length_units_valid_em.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Installer> + <Name>Your application</Name> + <Version>1.2.3</Version> + <WizardDefaultWidth>800em</WizardDefaultWidth> + <WizardDefaultHeight>600em</WizardDefaultHeight> +</Installer> diff --git a/tests/auto/installer/settings/data/length_units_valid_ex.xml b/tests/auto/installer/settings/data/length_units_valid_ex.xml new file mode 100644 index 000000000..3b39cf7a7 --- /dev/null +++ b/tests/auto/installer/settings/data/length_units_valid_ex.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Installer> + <Name>Your application</Name> + <Version>1.2.3</Version> + <WizardDefaultWidth>800ex</WizardDefaultWidth> + <WizardDefaultHeight>600ex</WizardDefaultHeight> +</Installer> diff --git a/tests/auto/installer/settings/data/length_units_valid_px.xml b/tests/auto/installer/settings/data/length_units_valid_px.xml new file mode 100644 index 000000000..3553dd7d8 --- /dev/null +++ b/tests/auto/installer/settings/data/length_units_valid_px.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Installer> + <Name>Your application</Name> + <Version>1.2.3</Version> + <WizardDefaultWidth>800px</WizardDefaultWidth> + <WizardDefaultHeight>600px</WizardDefaultHeight> +</Installer> diff --git a/tests/auto/installer/settings/settings.qrc b/tests/auto/installer/settings/settings.qrc index c86847993..092805980 100644 --- a/tests/auto/installer/settings/settings.qrc +++ b/tests/auto/installer/settings/settings.qrc @@ -9,5 +9,9 @@ <file>data/minimal_config_tag_defaults.xml</file> <file>data/unexpectedtag_config.xml</file> <file>data/unexpectedattribute_config.xml</file> + <file>data/length_units_valid_px.xml</file> + <file>data/length_units_valid_em.xml</file> + <file>data/length_units_valid_ex.xml</file> + <file>data/length_units_invalid.xml</file> </qresource> </RCC> diff --git a/tests/auto/installer/settings/tst_settings.cpp b/tests/auto/installer/settings/tst_settings.cpp index bf45f4856..fc49f4ed8 100644 --- a/tests/auto/installer/settings/tst_settings.cpp +++ b/tests/auto/installer/settings/tst_settings.cpp @@ -23,6 +23,8 @@ private slots: void loadMinimalConfigTagDefaults(); void loadUnexpectedAttributeConfig(); void loadUnexpectedTagConfig(); + void loadConfigWithValidLengthUnits(); + void loadConfigWithInvalidLengthUnits(); }; void tst_Settings::loadTutorialConfig() @@ -72,7 +74,9 @@ void tst_Settings::loadTutorialConfig() QCOMPARE(settings.repositorySettingsPageVisible(), true); QCOMPARE(settings.allowSpaceInPath(), true); QCOMPARE(settings.allowNonAsciiCharacters(), false); + QCOMPARE(settings.disableAuthorizationFallback(), false); QCOMPARE(settings.createLocalRepository(), false); + QCOMPARE(settings.installActionColumnVisible(), false); QCOMPARE(settings.hasReplacementRepos(), false); QCOMPARE(settings.repositories(), QSet<Repository>()); @@ -86,6 +90,8 @@ void tst_Settings::loadTutorialConfig() QCOMPARE(settings.translations(), QStringList()); QCOMPARE(settings.controlScript(), QString()); + + QCOMPARE(settings.supportsModify(), true); } void tst_Settings::loadFullConfig() @@ -95,8 +101,6 @@ void tst_Settings::loadFullConfig() void tst_Settings::loadEmptyConfig() { - QTest::ignoreMessage(QtDebugMsg, "create Error-Exception: \"Missing or empty <Name> tag in " - ":/data/empty_config.xml.\" "); try { Settings::fromFileAndPrefix(":/data/empty_config.xml", ":/data"); } catch (const Error &error) { @@ -115,13 +119,13 @@ void tst_Settings::loadNotExistingConfig() if (!file.open(QIODevice::ReadOnly)) { errorString = file.errorString(); } - QTest::ignoreMessage(QtDebugMsg, QString::fromLatin1("create Error-Exception: \"Could not open" + QTest::ignoreMessage(QtDebugMsg, QString::fromLatin1("create Error-Exception: \"Cannot open" " settings file %1 for reading: %2\"") .arg(configFile).arg(errorString).toLatin1()); try { Settings::fromFileAndPrefix(configFile, ":/data"); } catch (const Error &error) { - QCOMPARE(error.message(), QString::fromLatin1("Could not open settings file " + QCOMPARE(error.message(), QString::fromLatin1("Cannot open settings file " "%1 for reading: %2").arg(configFile).arg(errorString)); return; } @@ -130,8 +134,6 @@ void tst_Settings::loadNotExistingConfig() void tst_Settings::loadMalformedConfig() { - QTest::ignoreMessage(QtDebugMsg, "create Error-Exception: \"Error in :/data/malformed_config.xml, " - "line 9, column 0: Premature end of document.\" "); try { Settings::fromFileAndPrefix(":/data/malformed_config.xml", ":/data"); } catch (const Error &error) { @@ -144,13 +146,11 @@ void tst_Settings::loadMalformedConfig() void tst_Settings::loadUnknownElementConfigInStrictParseMode() { - QTest::ignoreMessage(QtDebugMsg, "create Error-Exception: \"Error in :/data/unknown_element_config.xml, " - "line 5, column 13: Unexpected element 'unknown'.\" "); try { Settings::fromFileAndPrefix(":/data/unknown_element_config.xml", ":/data"); } catch (const Error &error) { QCOMPARE(error.message(), QLatin1String("Error in :/data/unknown_element_config.xml, line 5, " - "column 13: Unexpected element 'unknown'.")); + "column 13: Unexpected element \"unknown\".")); return; } QFAIL("No exception thrown"); @@ -158,8 +158,8 @@ void tst_Settings::loadUnknownElementConfigInStrictParseMode() void tst_Settings::loadUnknownElementConfigInRelaxedParseMode() { - QTest::ignoreMessage(QtWarningMsg, "\"Ignoring following settings reader error in " - ":/data/unknown_element_config.xml, line 5, column 13: Unexpected element 'unknown'.\" "); + QTest::ignoreMessage(QtWarningMsg, "Ignoring following settings reader error in " + ":/data/unknown_element_config.xml, line 5, column 13: Unexpected element \"unknown\"."); try { Settings settings = Settings::fromFileAndPrefix(":/data/unknown_element_config.xml", ":/data", Settings::RelaxedParseMode); @@ -183,15 +183,11 @@ void tst_Settings::loadMinimalConfigTagDefaults() void tst_Settings::loadUnexpectedAttributeConfig() { - QTest::ignoreMessage(QtDebugMsg, "create Error-Exception: \"Error in " - ":///data/unexpectedattribute_config.xml, line 6, column 27: Unexpected attribute " - "for element 'Argument'.\" "); - try { Settings::fromFileAndPrefix(":///data/unexpectedattribute_config.xml", ":///data"); } catch (const Error &error) { QCOMPARE(error.message(), QLatin1String("Error in :///data/unexpectedattribute_config.xml," - " line 6, column 27: Unexpected attribute for element 'Argument'.")); + " line 6, column 27: Unexpected attribute for element \"Argument\".")); return; } QFAIL("No exception thrown"); @@ -201,14 +197,11 @@ void tst_Settings::loadUnexpectedAttributeConfig() void tst_Settings::loadUnexpectedTagConfig() { - QTest::ignoreMessage(QtDebugMsg, "create Error-Exception: \"Error in " - ":///data/unexpectedtag_config.xml, line 6, column 12: Unexpected element 'Foo'.\" "); - try { Settings::fromFileAndPrefix(":///data/unexpectedtag_config.xml", ":///data"); } catch (const Error &error) { QCOMPARE(error.message(), QLatin1String("Error in :///data/unexpectedtag_config.xml," - " line 6, column 12: Unexpected element 'Foo'.")); + " line 6, column 12: Unexpected element \"Foo\".")); return; } QFAIL("No exception thrown"); @@ -216,6 +209,33 @@ void tst_Settings::loadUnexpectedTagConfig() return; } +void tst_Settings::loadConfigWithValidLengthUnits() +{ + try { + Settings settings = Settings::fromFileAndPrefix(":///data/length_units_valid_px.xml", ":///data"); + QCOMPARE(settings.wizardDefaultWidth(), 800); + QCOMPARE(settings.wizardDefaultHeight(), 600); + + // Cannot test the parsed values for these units portably since the + // pixel value depends on the font metrics. Let's just check for parse + // errors. + (void)Settings::fromFileAndPrefix(":///data/length_units_valid_em.xml", ":///data"); + (void)Settings::fromFileAndPrefix(":///data/length_units_valid_ex.xml", ":///data"); + } catch (const Error &error) { + QFAIL(qPrintable(QString::fromLatin1("Exception caught: %1").arg(error.message()))); + } +} + +void tst_Settings::loadConfigWithInvalidLengthUnits() +{ + try { + Settings settings = Settings::fromFileAndPrefix(":///data/length_units_invalid.xml", ":///data"); + QCOMPARE(settings.wizardDefaultWidth(), 0); + QCOMPARE(settings.wizardDefaultHeight(), 0); + } catch (const Error &error) { + QFAIL(qPrintable(QString::fromLatin1("Exception caught: %1").arg(error.message()))); + } +} QTEST_MAIN(tst_Settings) diff --git a/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp b/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp index 93d8cd99a..7530910b6 100644 --- a/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp +++ b/tests/auto/installer/settingsoperation/tst_settingsoperation.cpp @@ -60,7 +60,7 @@ private slots: void testWrongArguments() { - SettingsOperation noArgumentsOperation; + SettingsOperation noArgumentsOperation(0); QVERIFY(noArgumentsOperation.testOperation()); @@ -69,14 +69,14 @@ private slots: QCOMPARE(UpdateOperation::Error(noArgumentsOperation.error()), UpdateOperation::InvalidArguments); - QString compareString("Missing argument(s) 'path; method; key; value' calling 'Settings' " - "with arguments ''."); + 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; + SettingsOperation wrongMethodArgumentOperation(0); wrongMethodArgumentOperation.setArguments(QStringList() << "path=first" << "method=second" << "key=third" << "value=fourth"); @@ -87,8 +87,8 @@ private slots: 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, " + 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); @@ -109,14 +109,14 @@ private slots: testSettings.setValue(key, value); } - SettingsOperation settingsOperation; + SettingsOperation settingsOperation(0); 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") + QVERIFY2(compareFiles(verifyFilePath, testFilePath), QString("\"%1\" and \"%2\" are different.") .arg(verifyFilePath, testFilePath).toLatin1()); } @@ -127,7 +127,7 @@ private slots: const QString key = "key"; const QString value = "value"; - SettingsOperation settingsOperation; + SettingsOperation settingsOperation(0); settingsOperation.setArguments(QStringList() << QString("path=%1").arg(testFilePath) << "method=set" << QString("key=%1").arg(key) << QString("value=%1").arg(value)); settingsOperation.backup(); @@ -154,7 +154,7 @@ private slots: } QCOMPARE(testValueString.isEmpty(), false); - SettingsOperation settingsOperation; + SettingsOperation settingsOperation(0); settingsOperation.setArguments(QStringList() << QString("path=%1").arg(testFilePath) << "method=remove" << QString("key=%1").arg(key)); settingsOperation.backup(); @@ -189,10 +189,10 @@ private slots: 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; + testSettingsOperationMap["testcategory/categoryarrayvalue1"] = new SettingsOperation(0); + testSettingsOperationMap["testcategory/categoryarrayvalue2"] = new SettingsOperation(0); + testSettingsOperationMap["testcategory/categoryarrayvalue3"] = new SettingsOperation(0); + testSettingsOperationMap["testcategory/categoryarrayvalue4"] = new SettingsOperation(0); QMap<QString, SettingsOperation*>::iterator i = testSettingsOperationMap.begin(); while (i != testSettingsOperationMap.end()) { @@ -256,9 +256,9 @@ private slots: testFile.close(); QMap<QString, SettingsOperation*> testSettingsOperationMap; - testSettingsOperationMap["testcategory/categoryarrayvalue1"] = new SettingsOperation; - testSettingsOperationMap["testcategory/categoryarrayvalue2"] = new SettingsOperation; - testSettingsOperationMap["testcategory/categoryarrayvalue3"] = new SettingsOperation; + testSettingsOperationMap["testcategory/categoryarrayvalue1"] = new SettingsOperation(0); + testSettingsOperationMap["testcategory/categoryarrayvalue2"] = new SettingsOperation(0); + testSettingsOperationMap["testcategory/categoryarrayvalue3"] = new SettingsOperation(0); QMap<QString, SettingsOperation*>::iterator i = testSettingsOperationMap.begin(); while (i != testSettingsOperationMap.end()) { diff --git a/tests/auto/installer/unicodeexecutable/main.c b/tests/auto/installer/unicodeexecutable/main.c new file mode 100644 index 000000000..d82e0cb60 --- /dev/null +++ b/tests/auto/installer/unicodeexecutable/main.c @@ -0,0 +1,54 @@ +/************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** 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 The Qt Company. For licensing terms +** and conditions see http://qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "stringdata.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +int main(int argc, char **argv) +{ + assert(argc == 3 || !"incorrect number of arguments"); + + if (!strcmp(argv[1], "utf8")) { + printf("%s", utf8Text); + } else { + printf("%s", asciiText); + } + + return atoi(argv[2]); +} + diff --git a/tests/auto/installer/unicodeexecutable/stringdata.h b/tests/auto/installer/unicodeexecutable/stringdata.h new file mode 100644 index 000000000..901fac31a --- /dev/null +++ b/tests/auto/installer/unicodeexecutable/stringdata.h @@ -0,0 +1,41 @@ +/************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** 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 The Qt Company. For licensing terms +** and conditions see http://qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#ifndef STRINGDATA_H +#define STRINGDATA_H + +const char asciiText[] = "This is some ASCII text."; +const char utf8Text[] = "\x46\x6F\x6F\x20\xC2\xA9\x20\x62\x61\x72\x20\xF0\x9D\x8C\x86\x20\x62\x61\x7A\x20\xE2\x98\x83\x20\x71\x75\x78"; + +#endif // !defined(STRINGDATA_H) diff --git a/tests/auto/installer/unicodeexecutable/unicodeexecutable.pro b/tests/auto/installer/unicodeexecutable/unicodeexecutable.pro new file mode 100644 index 000000000..742a8b168 --- /dev/null +++ b/tests/auto/installer/unicodeexecutable/unicodeexecutable.pro @@ -0,0 +1,8 @@ +SOURCES = main.c + +CONFIG -= qt app_bundle +CONFIG += console + +win32: DESTDIR = $$OUT_PWD + +QT = |