summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/installer/binaryformat/tst_binaryformat.cpp8
-rw-r--r--tests/auto/installer/clientserver/tst_clientserver.cpp11
-rw-r--r--tests/auto/installer/componentmodel/data/updates.xml48
-rw-r--r--tests/auto/installer/componentmodel/tst_componentmodel.cpp135
-rw-r--r--tests/auto/installer/consumeoutputoperationtest/tst_consumeoutputoperationtest.cpp10
-rw-r--r--tests/auto/installer/copyoperationtest/tst_copyoperationtest.cpp21
-rw-r--r--tests/auto/installer/extractarchiveoperationtest/tst_extractarchiveoperationtest.cpp12
-rw-r--r--tests/auto/installer/factory/factory.pro5
-rw-r--r--tests/auto/installer/factory/tst_factory.cpp228
-rw-r--r--tests/auto/installer/fakestopprocessforupdateoperation/tst_fakestopprocessforupdateoperation.cpp16
-rw-r--r--tests/auto/installer/installer.pro9
-rw-r--r--tests/auto/installer/lib7zfacade/tst_lib7zfacade.cpp114
-rw-r--r--tests/auto/installer/messageboxhandler/tst_messageboxhandler.cpp17
-rw-r--r--tests/auto/installer/mkdiroperationtest/tst_mkdiroperationtest.cpp7
-rw-r--r--tests/auto/installer/packagemanagercore/tst_packagemanagercore.cpp27
-rw-r--r--tests/auto/installer/registerfiletypeoperation/registerfiletypeoperation.pro6
-rw-r--r--tests/auto/installer/registerfiletypeoperation/tst_registerfiletypeoperation.cpp126
-rw-r--r--tests/auto/installer/scriptengine/data/addOperation.qs52
-rw-r--r--tests/auto/installer/scriptengine/scriptengine.pro2
-rw-r--r--tests/auto/installer/scriptengine/scriptengine.qrc1
-rw-r--r--tests/auto/installer/scriptengine/tst_scriptengine.cpp166
-rw-r--r--tests/auto/installer/settings/data/full_config.xml3
-rw-r--r--tests/auto/installer/settings/data/length_units_invalid.xml7
-rw-r--r--tests/auto/installer/settings/data/length_units_valid_em.xml7
-rw-r--r--tests/auto/installer/settings/data/length_units_valid_ex.xml7
-rw-r--r--tests/auto/installer/settings/data/length_units_valid_px.xml7
-rw-r--r--tests/auto/installer/settings/settings.qrc4
-rw-r--r--tests/auto/installer/settings/tst_settings.cpp60
-rw-r--r--tests/auto/installer/settingsoperation/tst_settingsoperation.cpp34
-rw-r--r--tests/auto/installer/unicodeexecutable/main.c54
-rw-r--r--tests/auto/installer/unicodeexecutable/stringdata.h41
-rw-r--r--tests/auto/installer/unicodeexecutable/unicodeexecutable.pro8
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 =