summaryrefslogtreecommitdiffstats
path: root/tests/auto/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/tools')
-rw-r--r--tests/auto/tools/moc/cxx-attributes.h103
-rw-r--r--tests/auto/tools/moc/moc.pro3
-rw-r--r--tests/auto/tools/moc/tst_moc.cpp50
-rw-r--r--tests/auto/tools/rcc/data/sizes/size-2-0-35-1_python.expected68
-rw-r--r--tests/auto/tools/rcc/tst_rcc.cpp230
5 files changed, 358 insertions, 96 deletions
diff --git a/tests/auto/tools/moc/cxx-attributes.h b/tests/auto/tools/moc/cxx-attributes.h
new file mode 100644
index 0000000000..eff6a3ec41
--- /dev/null
+++ b/tests/auto/tools/moc/cxx-attributes.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CXXATTRIBUTE_H
+#define CXXATTRIBUTE_H
+
+#include <QtCore/QObject>
+
+class CppAttribute : public QObject
+{
+ Q_OBJECT
+signals:
+ [[deprecated]] void deprecatedSignal();
+
+public slots:
+ [[deprecated]] void deprecatedSlot() {}
+ [[deprecated]] [[tst_moc::maybe_unused]] int deprecatedSlot2() { return 42; }
+ [[deprecated("reason")]] void deprecatedReason() {}
+ [[deprecated("reason[")]] void deprecatedReasonWithLBRACK() {}
+ [[deprecated("reason[[")]] void deprecatedReasonWith2LBRACK() {}
+ [[deprecated("reason]")]] void deprecatedReasonWithRBRACK() {}
+ [[deprecated("reason]]")]] void deprecatedReasonWith2RBRACK() {}
+ void slotWithArguments([[tst_moc::maybe_unused]] int) {}
+#if !defined(_MSC_VER) || _MSC_VER >= 1912
+ // On MSVC it causes:
+ // moc_cxx-attributes.cpp(133): fatal error C1001: An internal error has occurred in the compiler.
+ Q_INVOKABLE [[tst_moc::noreturn]] void noreturnSlot() { throw "unused"; }
+ [[tst_moc::noreturn]] Q_SCRIPTABLE void noreturnSlot2() { throw "unused"; }
+ [[deprecated]] int returnInt() { return 0; }
+ Q_SLOT [[tst_moc::noreturn]] [[deprecated]] void noreturnDeprecatedSlot() { throw "unused"; }
+ Q_INVOKABLE void noreturnSlot3() [[tst_moc::noreturn]] { throw "unused"; }
+#endif
+};
+
+#ifdef Q_MOC_RUN
+# define TEST_COMPILER_DEPRECATION [[deprecated]]
+# define TEST_COMPILER_DEPRECATION_X(x) [[deprecated(x)]]
+#else
+# define TEST_COMPILER_DEPRECATION Q_DECL_ENUMERATOR_DEPRECATED
+# define TEST_COMPILER_DEPRECATION_X(x) Q_DECL_ENUMERATOR_DEPRECATED_X(x)
+#endif
+
+namespace TestQNamespaceDeprecated {
+ Q_NAMESPACE
+ enum class TestEnum1 {
+ Key1 = 11,
+ Key2 TEST_COMPILER_DEPRECATION,
+ Key3 TEST_COMPILER_DEPRECATION_X("reason"),
+ Key4 TEST_COMPILER_DEPRECATION_X("reason["),
+ Key5 TEST_COMPILER_DEPRECATION_X("reason[["),
+ Key6 TEST_COMPILER_DEPRECATION_X("reason]"),
+ Key7 TEST_COMPILER_DEPRECATION_X("reason]]"),
+ };
+ Q_ENUM_NS(TestEnum1)
+
+ // try to dizzy moc by adding a struct in between
+ struct TestGadget {
+ Q_GADGET
+ public:
+ enum class TestGEnum1 {
+ Key1 = 13,
+ Key2 TEST_COMPILER_DEPRECATION,
+ Key3 TEST_COMPILER_DEPRECATION_X("reason")
+ };
+ Q_ENUM(TestGEnum1)
+ };
+
+ enum class TestFlag1 {
+ None = 0,
+ Flag1 = 1,
+ Flag2 TEST_COMPILER_DEPRECATION = 2,
+ Flag3 TEST_COMPILER_DEPRECATION_X("reason") = 3,
+ Any = Flag1 | Flag2 | Flag3
+ };
+ Q_FLAG_NS(TestFlag1)
+}
+
+#endif // CXXATTRIBUTE_H
diff --git a/tests/auto/tools/moc/moc.pro b/tests/auto/tools/moc/moc.pro
index 3cbc9ebb5e..ad8c093add 100644
--- a/tests/auto/tools/moc/moc.pro
+++ b/tests/auto/tools/moc/moc.pro
@@ -29,7 +29,8 @@ HEADERS += using-namespaces.h no-keywords.h task87883.h c-comments.h backslash-n
non-gadget-parent-class.h grand-parent-gadget-class.h \
related-metaobjects-in-gadget.h \
related-metaobjects-name-conflict.h \
- namespace.h cxx17-namespaces.h
+ namespace.h cxx17-namespaces.h \
+ cxx-attributes.h
if(*-g++*|*-icc*|*-clang*|*-llvm):!win32-*: HEADERS += os9-newlines.h win-newlines.h
diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp
index 74ddfd5620..f12df578f4 100644
--- a/tests/auto/tools/moc/tst_moc.cpp
+++ b/tests/auto/tools/moc/tst_moc.cpp
@@ -71,6 +71,7 @@
#include "grand-parent-gadget-class.h"
#include "namespace.h"
#include "cxx17-namespaces.h"
+#include "cxx-attributes.h"
#ifdef Q_MOC_RUN
// check that moc can parse these constructs, they are being used in Windows winsock2.h header
@@ -703,6 +704,7 @@ private slots:
void optionsFileError();
void testQNamespace();
void cxx17Namespaces();
+ void cxxAttributes();
signals:
void sigWithUnsignedArg(unsigned foo);
@@ -3847,6 +3849,14 @@ static void checkEnum(const QMetaEnum &enumerator, const QByteArray &name, const
}
}
+class EnumFromNamespaceClass : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(FooNamespace::Enum1 prop READ prop CONSTANT)
+public:
+ FooNamespace::Enum1 prop() { return FooNamespace::Enum1::Key2; }
+};
+
void tst_Moc::testQNamespace()
{
QCOMPARE(TestQNamespace::staticMetaObject.enumeratorCount(), 4);
@@ -3874,6 +3884,11 @@ void tst_Moc::testQNamespace()
QCOMPARE(FooNamespace::staticMetaObject.enumeratorCount(), 1);
QCOMPARE(FooNamespace::FooNestedNamespace::staticMetaObject.enumeratorCount(), 2);
QCOMPARE(FooNamespace::FooNestedNamespace::FooMoreNestedNamespace::staticMetaObject.enumeratorCount(), 1);
+
+ EnumFromNamespaceClass obj;
+ const QVariant prop = obj.property("prop");
+ QCOMPARE(prop.type(), QMetaType::Int);
+ QCOMPARE(prop.toInt(), int(FooNamespace::Enum1::Key2));
}
void tst_Moc::cxx17Namespaces()
@@ -3895,6 +3910,41 @@ void tst_Moc::cxx17Namespaces()
QCOMPARE(QMetaEnum::fromType<CXX17Namespace::A::B::C::D::ClassInNamespace::GadEn>().value(0), 3);
}
+void tst_Moc::cxxAttributes()
+{
+ auto so = CppAttribute::staticMetaObject;
+ QCOMPARE(so.className(), "CppAttribute");
+ QCOMPARE(so.enumeratorCount(), 0);
+ QVERIFY(so.indexOfSignal("deprecatedSignal") != 1);
+ for (auto a: {"deprecatedSlot", "deprecatedSlot2", "deprecatedReason", "deprecatedReasonWithLBRACK",
+ "deprecatedReasonWith2LBRACK", "deprecatedReasonWithRBRACK", "deprecatedReasonWith2RBRACK",
+ "slotWithArguments"
+#if !defined(_MSC_VER) || _MSC_VER >= 1912
+ , "noreturnSlot", "noreturnSlot2", "returnInt", "noreturnDeprecatedSlot",
+ "noreturnSlot3"
+#endif
+ }) {
+ QVERIFY(so.indexOfSlot(a) != 1);
+ }
+
+ QCOMPARE(TestQNamespaceDeprecated::staticMetaObject.enumeratorCount(), 2);
+ checkEnum(TestQNamespaceDeprecated::staticMetaObject.enumerator(0), "TestEnum1",
+ {{"Key1", 11}, {"Key2", 12}, {"Key3", 13}, {"Key4", 14}, {"Key5", 15}, {"Key6", 16},
+ {"Key7", 17}});
+ checkEnum(TestQNamespaceDeprecated::staticMetaObject.enumerator(1), "TestFlag1",
+ {{"None", 0}, {"Flag1", 1}, {"Flag2", 2}, {"Flag3", 3}, {"Any", 1 | 2 | 3}});
+
+ QCOMPARE(TestQNamespaceDeprecated::TestGadget::staticMetaObject.enumeratorCount(), 1);
+ checkEnum(TestQNamespaceDeprecated::TestGadget::staticMetaObject.enumerator(0), "TestGEnum1",
+ {{"Key1", 13}, {"Key2", 14}, {"Key3", 15}});
+
+ QMetaEnum meta = QMetaEnum::fromType<TestQNamespaceDeprecated::TestEnum1>();
+ QVERIFY(meta.isValid());
+ QCOMPARE(meta.name(), "TestEnum1");
+ QCOMPARE(meta.enclosingMetaObject(), &TestQNamespaceDeprecated::staticMetaObject);
+ QCOMPARE(meta.keyCount(), 7);
+}
+
QTEST_MAIN(tst_Moc)
// the generated code must compile with QT_NO_KEYWORDS
diff --git a/tests/auto/tools/rcc/data/sizes/size-2-0-35-1_python.expected b/tests/auto/tools/rcc/data/sizes/size-2-0-35-1_python.expected
new file mode 100644
index 0000000000..9dcd131af5
--- /dev/null
+++ b/tests/auto/tools/rcc/data/sizes/size-2-0-35-1_python.expected
@@ -0,0 +1,68 @@
+# Resource object code (Python 3)
+# Created by: object code
+# Created by: The Resource Compiler for Qt version 5.14.0
+# WARNING! All changes made in this file will be lost!
+
+from PySide2 import QtCore
+
+qt_resource_data = b"\
+\x00\x00\x00\x02\
+0\
+1\
+\x00\x00\x00#\
+0\
+123456789 012345\
+6789 0123456789 \
+12\
+\x00\x00\x00\x01\
+@\
+\
+\x00\x00\x00\x00\
+\
+"
+
+qt_resource_name = b"\
+\x00\x04\
+\x00\x06\xa8\xa1\
+\x00d\
+\x00a\x00t\x00a\
+\x00\x0a\
+\x04\x08\x0a\xb4\
+\x00d\
+\x00a\x00t\x00a\x00-\x002\x00.\x00t\x00x\x00t\
+\x00\x0b\
+\x00\xb5Ot\
+\x00d\
+\x00a\x00t\x00a\x00-\x003\x005\x00.\x00t\x00x\x00t\
+\x00\x0a\
+\x04\x11\x0a\xb4\
+\x00d\
+\x00a\x00t\x00a\x00-\x001\x00.\x00t\x00x\x00t\
+\x00\x0a\
+\x04\x0e\x0a\xb4\
+\x00d\
+\x00a\x00t\x00a\x00-\x000\x00.\x00t\x00x\x00t\
+"
+
+qt_resource_struct = b"\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x02\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00(\x00\x00\x00\x00\x00\x01\x00\x00\x00\x06\
+IGNORE: (time stamp)
+\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
+IGNORE: (time stamp)
+\x00\x00\x00^\x00\x00\x00\x00\x00\x01\x00\x00\x002\
+IGNORE: (time stamp)
+\x00\x00\x00D\x00\x00\x00\x00\x00\x01\x00\x00\x00-\
+IGNORE: (time stamp)
+"
+
+def qInitResources():
+ QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+def qCleanupResources():
+ QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+qInitResources()
diff --git a/tests/auto/tools/rcc/tst_rcc.cpp b/tests/auto/tools/rcc/tst_rcc.cpp
index c810c6e364..24fd79cf19 100644
--- a/tests/auto/tools/rcc/tst_rcc.cpp
+++ b/tests/auto/tools/rcc/tst_rcc.cpp
@@ -46,6 +46,33 @@
typedef QMap<QString, QString> QStringMap;
Q_DECLARE_METATYPE(QStringMap)
+static QByteArray msgProcessStartFailed(const QProcess &p)
+{
+ const QString result = QLatin1String("Could not start \"")
+ + QDir::toNativeSeparators(p.program()) + QLatin1String("\": ")
+ + p.errorString();
+ return result.toLocal8Bit();
+}
+
+static QByteArray msgProcessTimeout(const QProcess &p)
+{
+ return '"' + QDir::toNativeSeparators(p.program()).toLocal8Bit()
+ + "\" timed out.";
+}
+
+static QByteArray msgProcessCrashed(QProcess &p)
+{
+ return '"' + QDir::toNativeSeparators(p.program()).toLocal8Bit()
+ + "\" crashed.\n" + p.readAllStandardError();
+}
+
+static QByteArray msgProcessFailed(QProcess &p)
+{
+ return '"' + QDir::toNativeSeparators(p.program()).toLocal8Bit()
+ + "\" returned " + QByteArray::number(p.exitCode()) + ":\n"
+ + p.readAllStandardError();
+}
+
class tst_rcc : public QObject
{
Q_OBJECT
@@ -62,10 +89,13 @@ private slots:
void readback_data();
void readback();
+ void python();
+
void cleanupTestCase();
private:
QString m_rcc;
+ QString m_dataPath;
};
void tst_rcc::initTestCase()
@@ -74,20 +104,19 @@ void tst_rcc::initTestCase()
// we must force a certain hash order when testing or tst_rcc will fail, see QTBUG-25078
QVERIFY(qputenv("QT_RCC_TEST", "1"));
m_rcc = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QLatin1String("/rcc");
-}
-QString findExpectedFile(const QString &base)
-{
- QString expectedrccfile = base;
+ m_dataPath = QFINDTESTDATA("data");
+ QVERIFY(!m_dataPath.isEmpty());
+}
- // Must be updated with each minor release.
- if (QFileInfo(expectedrccfile + QLatin1String(".450")).exists())
- expectedrccfile += QLatin1String(".450");
- return expectedrccfile;
+static inline bool isPythonComment(const QString &line)
+{
+ return line.startsWith(QLatin1Char('#'));
}
-static QString doCompare(const QStringList &actual, const QStringList &expected)
+static QString doCompare(const QStringList &actual, const QStringList &expected,
+ const QString &timeStampPath)
{
if (actual.size() != expected.size()) {
return QString("Length count different: actual: %1, expected: %2")
@@ -95,13 +124,21 @@ static QString doCompare(const QStringList &actual, const QStringList &expected)
}
QByteArray ba;
+ const bool isPython = isPythonComment(expected.constFirst());
for (int i = 0, n = expected.size(); i != n; ++i) {
QString expectedLine = expected.at(i);
if (expectedLine.startsWith("IGNORE:"))
continue;
+ if (isPython && isPythonComment(expectedLine) && isPythonComment(actual.at(i)))
+ continue;
if (expectedLine.startsWith("TIMESTAMP:")) {
const QString relativePath = expectedLine.mid(strlen("TIMESTAMP:"));
- const quint64 timeStamp = QFileInfo(relativePath).lastModified().toMSecsSinceEpoch();
+ const QFileInfo fi(timeStampPath + QLatin1Char('/') + relativePath);
+ if (!fi.isFile()) {
+ ba.append("File " + fi.absoluteFilePath().toUtf8() + " does not exist!");
+ break;
+ }
+ const quint64 timeStamp = quint64(fi.lastModified().toMSecsSinceEpoch());
expectedLine.clear();
for (int shift = 56; shift >= 0; shift -= 8) {
expectedLine.append(QLatin1String("0x"));
@@ -110,7 +147,7 @@ static QString doCompare(const QStringList &actual, const QStringList &expected)
}
}
if (expectedLine != actual.at(i)) {
- qDebug() << "LINES" << i << "DIFFER";
+ qDebug() << "LINES" << (i + 1) << "DIFFER";
ba.append(
"\n<<<<<< actual\n" + actual.at(i) + "\n======\n" + expectedLine
+ "\n>>>>>> expected\n"
@@ -126,49 +163,53 @@ void tst_rcc::rcc_data()
QTest::addColumn<QString>("qrcfile");
QTest::addColumn<QString>("expected");
- QString dataPath = QFINDTESTDATA("data/images/");
- if (dataPath.isEmpty())
- QFAIL("data path not found");
- QTest::newRow("images") << dataPath << "images.qrc" << "images.expected";
+ const QString imagesPath = m_dataPath + QLatin1String("/images");
+ QTest::newRow("images") << imagesPath << "images.qrc" << "images.expected";
- QString sizesPath = QFINDTESTDATA("data/sizes/");
- if (sizesPath.isEmpty())
- QFAIL("data path not found");
+ const QString sizesPath = m_dataPath + QLatin1String("/sizes");
QTest::newRow("size-0") << sizesPath << "size-0.qrc" << "size-0.expected";
QTest::newRow("size-1") << sizesPath << "size-1.qrc" << "size-1.expected";
QTest::newRow("size-2-0-35-1") << sizesPath << "size-2-0-35-1.qrc" << "size-2-0-35-1.expected";
}
+static QStringList readLinesFromFile(const QString &fileName,
+ QString::SplitBehavior splitBehavior)
+{
+ QFile file(fileName);
+
+ bool ok = file.open(QIODevice::ReadOnly | QIODevice::Text);
+ if (!ok) {
+ QWARN(qPrintable(QString::fromLatin1("Could not open testdata file %1: %2")
+ .arg(fileName, file.errorString())));
+ }
+
+ return QString::fromUtf8(file.readAll()).split(QLatin1Char('\n'), splitBehavior);
+}
+
void tst_rcc::rcc()
{
QFETCH(QString, directory);
QFETCH(QString, qrcfile);
QFETCH(QString, expected);
- if (!QDir::setCurrent(directory)) {
- QString message = QString::fromLatin1("Unable to cd from '%1' to '%2'").arg(QDir::currentPath(), directory);
- QFAIL(qPrintable(message));
- }
-
// If the file expectedoutput.txt exists, compare the
// console output with the content of that file
- const QString expected2 = findExpectedFile(expected);
- QFile expectedFile(expected2);
- if (!expectedFile.exists()) {
- qDebug() << "NO EXPECTATIONS? " << expected2;
- return;
- }
// Launch; force no compression, otherwise the output would be different
// depending on the compression algorithm we're using
QProcess process;
+ process.setWorkingDirectory(directory);
process.start(m_rcc, { "-no-compress", qrcfile });
+ QVERIFY2(process.waitForStarted(), msgProcessStartFailed(process).constData());
if (!process.waitForFinished()) {
- const QString path = QString::fromLocal8Bit(qgetenv("PATH"));
- QString message = QString::fromLatin1("'%1' could not be found when run from '%2'. Path: '%3' ").
- arg(m_rcc, QDir::currentPath(), path);
- QFAIL(qPrintable(message));
+ process.kill();
+ QFAIL(msgProcessTimeout(process).constData());
}
+ QVERIFY2(process.exitStatus() == QProcess::NormalExit,
+ msgProcessCrashed(process).constData());
+ QVERIFY2(process.exitCode() == 0,
+ msgProcessFailed(process).constData());
+
const QChar cr = QLatin1Char('\r');
const QString err = QString::fromLocal8Bit(process.readAllStandardError()).remove(cr);
const QString out = QString::fromLatin1(process.readAllStandardOutput()).remove(cr);
@@ -181,63 +222,20 @@ void tst_rcc::rcc()
const QChar nl = QLatin1Char('\n');
const QStringList actualLines = out.split(nl);
- QVERIFY(expectedFile.open(QIODevice::ReadOnly|QIODevice::Text));
- const QStringList expectedLines = QString::fromLatin1(expectedFile.readAll()).split(nl);
+ const QStringList expectedLines =
+ readLinesFromFile(directory + QLatin1Char('/') + expected, QString::KeepEmptyParts);
+ QVERIFY(!expectedLines.isEmpty());
- const QString diff = doCompare(actualLines, expectedLines);
+ const QString diff = doCompare(actualLines, expectedLines, directory);
if (diff.size())
QFAIL(qPrintable(diff));
}
-
-
-static void createRccBinaryData(const QString &rcc, const QString &baseDir,
- const QString &qrcFileName, const QString &rccFileName)
-{
- QString currentDir = QDir::currentPath();
- QDir::setCurrent(baseDir);
-
- // same as above: force no compression
- QProcess rccProcess;
- rccProcess.start(rcc, { "-binary", "-no-compress", "-o", rccFileName, qrcFileName });
- bool ok = rccProcess.waitForFinished();
- if (!ok) {
- QString errorString = QString::fromLatin1("Could not start rcc (is it in PATH?): %1").arg(rccProcess.errorString());
- QFAIL(qPrintable(errorString));
- }
-
- QByteArray output = rccProcess.readAllStandardOutput();
- if (!output.isEmpty()) {
- QString errorMessage = QString::fromLatin1("rcc stdout: %1").arg(QString::fromLocal8Bit(output));
- QWARN(qPrintable(errorMessage));
- }
-
- output = rccProcess.readAllStandardError();
- if (!output.isEmpty()) {
- QString errorMessage = QString::fromLatin1("rcc stderr: %1").arg(QString::fromLocal8Bit(output));
- QWARN(qPrintable(errorMessage));
- }
-
- QDir::setCurrent(currentDir);
-}
-
-static QStringList readLinesFromFile(const QString &fileName)
-{
- QFile file(fileName);
-
- bool ok = file.open(QIODevice::ReadOnly | QIODevice::Text);
- if (!ok)
- QWARN(qPrintable(QString::fromLatin1("Could not open testdata file %1: %2").arg(fileName, file.errorString())));
-
- QStringList lines = QString::fromUtf8(file.readAll()).split(QLatin1Char('\n'), QString::SkipEmptyParts);
- return lines;
-}
-
static QStringMap readExpectedFiles(const QString &fileName)
{
QStringMap expectedFiles;
- QStringList lines = readLinesFromFile(fileName);
+ QStringList lines = readLinesFromFile(fileName, QString::SkipEmptyParts);
foreach (const QString &line, lines) {
QString resourceFileName = line.section(QLatin1Char(' '), 0, 0, QString::SectionSkipEmpty);
QString actualFileName = line.section(QLatin1Char(' '), 1, 1, QString::SectionSkipEmpty);
@@ -268,9 +266,7 @@ void tst_rcc::binary_data()
QTest::addColumn<QString>("baseDirectory");
QTest::addColumn<QStringMap>("expectedFiles");
- QString dataPath = QFINDTESTDATA("data/binary/");
- if (dataPath.isEmpty())
- QFAIL("data path not found");
+ QString dataPath = m_dataPath + QLatin1String("/binary/");
QDirIterator iter(dataPath, QStringList() << QLatin1String("*.qrc"));
while (iter.hasNext())
@@ -279,12 +275,33 @@ void tst_rcc::binary_data()
QFileInfo qrcFileInfo = iter.fileInfo();
QString absoluteBaseName = QFileInfo(qrcFileInfo.absolutePath(), qrcFileInfo.baseName()).absoluteFilePath();
QString rccFileName = absoluteBaseName + QLatin1String(".rcc");
- createRccBinaryData(m_rcc, dataPath, qrcFileInfo.absoluteFilePath(), rccFileName);
+
+ // same as above: force no compression
+ QProcess rccProcess;
+ rccProcess.setWorkingDirectory(dataPath);
+ rccProcess.start(m_rcc, { "-binary", "-no-compress", "-o", rccFileName, qrcFileInfo.absoluteFilePath() });
+ QVERIFY2(rccProcess.waitForStarted(), msgProcessStartFailed(rccProcess).constData());
+ if (!rccProcess.waitForFinished()) {
+ rccProcess.kill();
+ QFAIL(msgProcessTimeout(rccProcess).constData());
+ }
+ QVERIFY2(rccProcess.exitStatus() == QProcess::NormalExit,
+ msgProcessCrashed(rccProcess).constData());
+ QVERIFY2(rccProcess.exitCode() == 0,
+ msgProcessFailed(rccProcess).constData());
+
+ QByteArray output = rccProcess.readAllStandardOutput();
+ if (!output.isEmpty())
+ qWarning("rcc stdout: %s", output.constData());
+
+ output = rccProcess.readAllStandardError();
+ if (!output.isEmpty())
+ qWarning("rcc stderr: %s", output.constData());
QString localeFileName = absoluteBaseName + QLatin1String(".locale");
QFile localeFile(localeFileName);
if (localeFile.exists()) {
- QStringList locales = readLinesFromFile(localeFileName);
+ QStringList locales = readLinesFromFile(localeFileName, QString::SkipEmptyParts);
foreach (const QString &locale, locales) {
QString expectedFileName = QString::fromLatin1("%1.%2.%3").arg(absoluteBaseName, locale, QLatin1String("expected"));
QStringMap expectedFiles = readExpectedFiles(expectedFileName);
@@ -386,16 +403,12 @@ void tst_rcc::readback()
QFETCH(QString, resourceName);
QFETCH(QString, fileSystemName);
- QString dataPath = QFINDTESTDATA("data/");
- if (dataPath.isEmpty())
- QFAIL("data path not found");
-
QFile resourceFile(resourceName);
QVERIFY(resourceFile.open(QIODevice::ReadOnly));
QByteArray resourceData = resourceFile.readAll();
resourceFile.close();
- QFile fileSystemFile(dataPath + fileSystemName);
+ QFile fileSystemFile(m_dataPath + QLatin1Char('/') + fileSystemName);
QVERIFY(fileSystemFile.open(QIODevice::ReadOnly));
QByteArray fileSystemData = fileSystemFile.readAll();
fileSystemFile.close();
@@ -403,12 +416,39 @@ void tst_rcc::readback()
QCOMPARE(resourceData, fileSystemData);
}
+void tst_rcc::python()
+{
+ const QString path = m_dataPath + QLatin1String("/sizes");
+ const QString testFileRoot = path + QLatin1String("/size-2-0-35-1");
+ const QString qrcFile = testFileRoot + QLatin1String(".qrc");
+ const QString expectedFile = testFileRoot + QLatin1String("_python.expected");
+ const QString actualFile = testFileRoot + QLatin1String(".rcc");
+
+ QProcess process;
+ process.setWorkingDirectory(path);
+ process.start(m_rcc, { "-g", "python", "-o", actualFile, qrcFile});
+ QVERIFY2(process.waitForStarted(), msgProcessStartFailed(process).constData());
+ if (!process.waitForFinished()) {
+ process.kill();
+ QFAIL(msgProcessTimeout(process).constData());
+ }
+ QVERIFY2(process.exitStatus() == QProcess::NormalExit,
+ msgProcessCrashed(process).constData());
+ QVERIFY2(process.exitCode() == 0,
+ msgProcessFailed(process).constData());
+
+ const auto actualLines = readLinesFromFile(actualFile, QString::KeepEmptyParts);
+ QVERIFY(!actualLines.isEmpty());
+ const auto expectedLines = readLinesFromFile(expectedFile, QString::KeepEmptyParts);
+ QVERIFY(!expectedLines.isEmpty());
+ const QString diff = doCompare(actualLines, expectedLines, path);
+ if (!diff.isEmpty())
+ QFAIL(qPrintable(diff));
+}
+
void tst_rcc::cleanupTestCase()
{
- QString dataPath = QFINDTESTDATA("data/binary/");
- if (dataPath.isEmpty())
- return;
- QDir dataDir(dataPath);
+ QDir dataDir(m_dataPath + QLatin1String("/binary"));
QFileInfoList entries = dataDir.entryInfoList(QStringList() << QLatin1String("*.rcc"));
foreach (const QFileInfo &entry, entries)
QFile::remove(entry.absoluteFilePath());