uic test: Test Python

Add a test that checks for the Presence of Qt for Python
and runs Python compile tests on the baseline files.

Task-number: PYSIDE-797
Change-Id: I7e15c3c75261a7d94fc6654a95d49ba323cbe7d6
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
This commit is contained in:
Friedemann Kleint 2018-12-03 16:57:04 +01:00
parent 7fe52779f4
commit 7a84a0a6d1

View File

@ -73,6 +73,9 @@ private Q_SLOTS:
void compare();
void compare_data() const;
void python();
void python_data() const;
void runCompare();
private:
@ -83,6 +86,7 @@ private:
QTemporaryDir m_generated;
TestEntries m_testEntries;
QRegularExpression m_versionRegexp;
QString m_python;
};
tst_uic::tst_uic()
@ -98,6 +102,32 @@ static QByteArray msgProcessStartFailed(const QString &command, const QString &w
return result.toLocal8Bit();
}
// Locate Python and check whether PySide2 is installed
static QString locatePython(QTemporaryDir &generatedDir)
{
QString python = QStandardPaths::findExecutable(QLatin1String("python"));
if (python.isEmpty()) {
qWarning("Cannot locate python, skipping tests");
return QString();
}
QFile importTestFile(generatedDir.filePath(QLatin1String("import_test.py")));
if (!importTestFile.open(QIODevice::WriteOnly| QIODevice::Text))
return QString();
importTestFile.write("import PySide2.QtCore\n");
importTestFile.close();
QProcess process;
process.start(python, {importTestFile.fileName()});
if (!process.waitForStarted() || !process.waitForFinished())
return QString();
if (process.exitStatus() != QProcess::NormalExit || process.exitCode() != 0) {
const QString stdErr = QString::fromLocal8Bit(process.readAllStandardError()).simplified();
qWarning("PySide2 is not installed (%s)", qPrintable(stdErr));
return QString();
}
importTestFile.remove();
return python;
}
void tst_uic::initTestCase()
{
QVERIFY2(m_generated.isValid(), qPrintable(m_generated.errorString()));
@ -121,6 +151,8 @@ void tst_uic::initTestCase()
populateTestEntries();
QVERIFY(!m_testEntries.isEmpty());
qDebug("%s", qPrintable(msg));
m_python = locatePython(m_generated);
}
void tst_uic::populateTestEntries()
@ -343,5 +375,75 @@ void tst_uic::runCompare()
QCOMPARE(generatedFileContents, originalFileContents);
}
// Let uic generate Python code and verify that it is syntactically
// correct by compiling it into .pyc. This test is executed only
// when python with an installed Qt for Python is detected (see locatePython()).
static inline QByteArray msgCompilePythonFailed(const QByteArray &error)
{
// If there is a line with blanks and caret indicating an error in the line
// above, insert the cursor into the offending line and remove the caret.
QByteArrayList lines = error.trimmed().split('\n');
for (int i = lines.size() - 1; i > 0; --i) {
const auto &line = lines.at(i);
const int caret = line.indexOf('^');
if (caret == 0 || (caret > 0 && line.at(caret - 1) == ' ')) {
lines.removeAt(i);
lines[i - 1].insert(caret, '|');
break;
}
}
return lines.join('\n');
}
void tst_uic::python_data() const
{
QTest::addColumn<QString>("originalFile");
QTest::addColumn<QString>("generatedFile");
const int size = m_python.isEmpty()
? qMin(1, m_testEntries.size()) : m_testEntries.size();
for (int i = 0; i < size; ++i) {
const TestEntry &te = m_testEntries.at(i);
// qprintsettingsoutput: variable named 'from' clashes with Python
if (!te.baselineBaseName.endsWith(QLatin1String("/qprintsettingsoutput"))) {
QString generatedFile = te.generatedFileName;
generatedFile.chop(1); // foo.h -> foo.py
generatedFile.append(QLatin1String("py"));
QTest::newRow(te.name.constData())
<< (te.baselineBaseName + QLatin1String(".ui"))
<< generatedFile;
}
}
}
void tst_uic::python()
{
QFETCH(QString, originalFile);
QFETCH(QString, generatedFile);
if (m_python.isEmpty())
QSKIP("Python was not found");
QStringList uicArguments{QLatin1String("-g"), QLatin1String("python"),
originalFile, QLatin1String("-o"), generatedFile};
QProcess process;
process.setWorkingDirectory(m_generated.path());
process.start(m_command, uicArguments);
QVERIFY2(process.waitForStarted(), msgProcessStartFailed(m_command, process.errorString()));
QVERIFY(process.waitForFinished());
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
QCOMPARE(process.exitCode(), 0);
QVERIFY(QFileInfo::exists(generatedFile));
// Test Python code generation by compiling the file
QStringList compileArguments{QLatin1String("-m"), QLatin1String("py_compile"), generatedFile};
process.start(m_python, compileArguments);
QVERIFY2(process.waitForStarted(), msgProcessStartFailed(m_command, process.errorString()));
QVERIFY(process.waitForFinished());
const bool compiled = process.exitStatus() == QProcess::NormalExit
&& process.exitCode() == 0;
QVERIFY2(compiled, msgCompilePythonFailed(process.readAllStandardError()).constData());
}
QTEST_MAIN(tst_uic)
#include "tst_uic.moc"