Revision control
Copy as Markdown
// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
// Helper functions for global test cases.
#ifndef QT_TESTS_SHARED_GLOBAL_H_INCLUDED
#define QT_TESTS_SHARED_GLOBAL_H_INCLUDED
#include <QtCore/QtCore>
#include <QtTest/QtTest>
QStringList qt_tests_shared_global_get_include_path(const QString &makeFile);
QHash<QString, QString> qt_tests_shared_global_get_modules(const QString &workDir,
const QString &configFile);
QStringList qt_tests_shared_global_get_include_paths();
QStringList qt_tests_shared_run_qmake(const QString &workDir,
const QByteArray &proFileConent,
QStringList(*makeFileParser)(const QString&));
QStringList qt_tests_shared_global_get_export_modules(const QString &makeFile);
void qt_tests_shared_filter_module_list(const QString &workDir, QHash<QString, QString> &modules);
QHash<QString, QString> qt_tests_shared_global_get_modules(const QString &workDir, const QString &configFile)
{
QHash<QString, QString> modules;
QFile file(configFile);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning("Can't open the config file for global.cfg.");
return modules;
}
QXmlStreamReader xml;
xml.setDevice(&file);
while (!xml.atEnd()) {
xml.readNext();
if (xml.tokenType() == QXmlStreamReader::StartElement && xml.name() == QLatin1String("config")) {
xml.readNextStartElement();
if (xml.name() == QLatin1String("modules")) {
while (!xml.atEnd()) {
xml.readNextStartElement();
QString modName;
QString qtModName;
if (xml.name() == QLatin1String("module")) {
modName = xml.attributes().value("name").toString().simplified();
qtModName = xml.attributes().value("qtname").toString().simplified();
if (!modName.isEmpty() && !qtModName.isEmpty())
modules[modName] = qtModName;
}
}
}
}
}
file.close();
qt_tests_shared_filter_module_list(workDir, modules);
qDebug() << "modules keys:" << modules.keys();
qDebug() << "modules values:" << modules.values();
return modules;
}
QByteArray qt_tests_shared_global_get_modules_pro_lines(const QHash<QString, QString> &modules)
{
QByteArray result;
for (const auto & [_, moduleName] : modules.asKeyValueRange()) {
QByteArray module = moduleName.toLatin1();
result += "qtHaveModule(" + module + ") {\n" +
" QT += " + module + "\n" +
" MODULES += " + module + "\n" +
"}\n";
}
result += "QMAKE_EXTRA_VARIABLES += MODULES\n";
return result;
}
QStringList qt_tests_shared_global_get_include_paths(const QString &workDir,
QHash<QString, QString> &modules)
{
return qt_tests_shared_run_qmake(workDir,
qt_tests_shared_global_get_modules_pro_lines(modules),
&qt_tests_shared_global_get_include_path);
}
void qt_tests_shared_filter_module_list(const QString &workDir, QHash<QString, QString> &modules)
{
const QStringList result = qt_tests_shared_run_qmake(workDir,
qt_tests_shared_global_get_modules_pro_lines(modules),
&qt_tests_shared_global_get_export_modules);
const QStringList keys = modules.keys();
for (int i = 0; i < keys.size(); ++i) {
const QString key = keys.at(i);
if (!result.contains(modules[key]))
modules.remove(key);
}
}
QStringList qt_tests_shared_run_qmake(const QString &workDir,
const QByteArray &proFileContent,
QStringList(*makeFileParser)(const QString&))
{
QString proFile = workDir + "/global.pro";
QString makeFile = workDir + "/Makefile";
QStringList result;
#ifndef QT_NO_PROCESS
QFile file(proFile);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qWarning("Can't open the pro file for global.");
return result;
}
file.write(proFileContent);
file.flush();
file.close();
if (!QDir::setCurrent(workDir)) {
qWarning("Change working dir failed.");
return result;
}
QString qmakeApp = "qmake";
QStringList qmakeArgs;
qmakeArgs << "-o"
<< "Makefile";
QProcess proc;
proc.start(qmakeApp, qmakeArgs, QIODevice::ReadOnly);
if (!proc.waitForFinished(6000000)) {
qWarning() << qmakeApp << qmakeArgs << "in" << workDir << "didn't finish" << proc.errorString();
return result;
}
if (proc.exitCode() != 0) {
qWarning() << qmakeApp << qmakeArgs << "in" << workDir << "returned with" << proc.exitCode();
qDebug() << proc.readAllStandardError();
return result;
}
QFile::remove(proFile);
result = makeFileParser(makeFile);
#ifdef Q_OS_WIN
if (result.isEmpty())
result = makeFileParser(makeFile + QLatin1String(".Release"));
#endif
QFile::remove(makeFile);
#else
Q_UNUSED(proFileContent);
Q_UNUSED(makeFileParser);
#endif // QT_NO_PROCESS
return result;
}
QStringList qt_tests_shared_global_get_include_path(const QString &makeFile)
{
QFile file(makeFile);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return QStringList();
QTextStream in(&file);
while (!in.atEnd()) {
QString line = in.readLine();
if (line.contains("=") && line.contains("INCPATH")) {
QString relatives = line.mid(line.indexOf("=")+1);
QStringList list1 = relatives.split(" ");
QStringList list2;
for (int i = 0; i < list1.size(); ++i) {
if (!list1.at(i).startsWith("-I"))
continue;
QString rpath = list1.at(i).mid(2);
QString apath = "-I" + QDir(rpath).absolutePath();
#ifdef Q_OS_WIN
apath.replace('\\', '/');
#endif
list2 << apath;
}
return list2;
}
}
return QStringList();
}
QStringList qt_tests_shared_global_get_export_modules(const QString &makeFile)
{
QFile file(makeFile);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return QStringList();
QTextStream in(&file);
while (!in.atEnd()) {
QString line = in.readLine();
int index = line.indexOf('=');
if (index > 13 && line.startsWith(QLatin1String("EXPORT_MODULES"))) {
QString relatives = line.mid(index + 1);
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
return relatives.split(QChar(' '), Qt::SkipEmptyParts);
#else
return relatives.split(QChar(' '), QString::SkipEmptyParts);
#endif
}
}
return QStringList();
}
#endif // QT_TESTS_SHARED_GLOBAL_H_INCLUDED