ExtensionSystem: Don't export test symbols without tests configured

We want the plugin manager to support the -test option etc even if
Qt Creator is not configured with WITH_TESTS, so 3rdparty plugins can
still be built and tested with a released Qt Creator.

But we do not want to export functions/classes that are only needed for
Qt Creator tests in that case.

When Qt Creator is configured with WITH_TESTS, the QtCreatorAPI adds the
WITH_TESTS define, and we used the same define for the first case above,
where we only want to add the -test option and corresponding API. Use a
different define EXTENSIONSYSTEM_WITH_TESTOPTION for this. The
EXTENSIONSYSTEM_TEST_EXPORT keeps checking the WITH_TESTS define.

Amends e5a4fdaa1b

Change-Id: I547f1fa7413e3bc452f71ae920c310a05e0193ae
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
Eike Ziller
2024-04-19 14:13:13 +02:00
parent 2ab8e2f35d
commit b5740eb0c6
6 changed files with 32 additions and 21 deletions

View File

@@ -20,10 +20,16 @@ add_qtc_library(ExtensionSystem
find_package(Qt6 COMPONENTS Test QUIET) find_package(Qt6 COMPONENTS Test QUIET)
# If ExtensionSystem was compiled with QtTest, it should provide the test options
# and the test related API, regardless if Qt Creator was compiled with tests or not,
# and regardless if an external plugin is compiled with tests or not.
# ExtensionSystem may not require QtTest in public headers though.
# API with EXTENSIONSYSTEM_TEST_EXPORT (like CppPluginSpec) should only be exported
# if Qt Creator is compiled with tests.
extend_qtc_library(ExtensionSystem extend_qtc_library(ExtensionSystem
CONDITION TARGET Qt::Test CONDITION TARGET Qt::Test
DEPENDS Qt::Test DEPENDS Qt::Test
DEFINES WITH_TESTS PUBLIC_DEFINES EXTENSIONSYSTEM_WITH_TESTOPTION
) )
extend_qtc_library(ExtensionSystem extend_qtc_library(ExtensionSystem

View File

@@ -2,6 +2,7 @@ QtcLibrary {
name: "ExtensionSystem" name: "ExtensionSystem"
cpp.defines: base.concat(["EXTENSIONSYSTEM_LIBRARY", "IDE_TEST_DIR=\".\""]) cpp.defines: base.concat(["EXTENSIONSYSTEM_LIBRARY", "IDE_TEST_DIR=\".\""])
.concat(qtc.withPluginTests ? ["EXTENSIONSYSTEM_WITH_TESTOPTION"] : [])
Depends { name: "Qt"; submodules: ["core", "widgets"] } Depends { name: "Qt"; submodules: ["core", "widgets"] }
Depends { name: "Qt.testlib"; condition: qtc.withPluginTests } Depends { name: "Qt.testlib"; condition: qtc.withPluginTests }
@@ -35,5 +36,7 @@ QtcLibrary {
Export { Export {
Depends { name: "Qt.core" } Depends { name: "Qt.core" }
Depends { name: "qtc" }
cpp.defines: qtc.withPluginTests ? ["EXTENSIONSYSTEM_WITH_TESTOPTION"] : []
} }
} }

View File

@@ -64,7 +64,7 @@ bool OptionsParser::parse()
continue; continue;
if (checkForNoCrashcheckOption()) if (checkForNoCrashcheckOption())
continue; continue;
#ifdef WITH_TESTS #ifdef EXTENSIONSYSTEM_WITH_TESTOPTION
if (checkForTestOptions()) if (checkForTestOptions())
continue; continue;
if (checkForScenarioOption()) if (checkForScenarioOption())

View File

@@ -42,7 +42,7 @@
#include <QTimer> #include <QTimer>
#include <QWriteLocker> #include <QWriteLocker>
#ifdef WITH_TESTS #ifdef EXTENSIONSYSTEM_WITH_TESTOPTION
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <QTest> #include <QTest>
#include <QThread> #include <QThread>
@@ -745,7 +745,7 @@ void PluginManager::formatOptions(QTextStream &str, int optionIndentation, int d
QLatin1String("Disable startup check for previously crashed instance"), QLatin1String("Disable startup check for previously crashed instance"),
optionIndentation, optionIndentation,
descriptionIndentation); descriptionIndentation);
#ifdef WITH_TESTS #ifdef EXTENSIONSYSTEM_WITH_TESTOPTION
formatOption(str, QString::fromLatin1(OptionsParser::TEST_OPTION) formatOption(str, QString::fromLatin1(OptionsParser::TEST_OPTION)
+ QLatin1String(" <plugin>[,testfunction[:testdata]]..."), QString(), + QLatin1String(" <plugin>[,testfunction[:testdata]]..."), QString(),
QLatin1String("Run plugin's tests (by default a separate settings path is used)"), QLatin1String("Run plugin's tests (by default a separate settings path is used)"),
@@ -798,7 +798,7 @@ bool PluginManager::testRunRequested()
return !d->testSpecs.empty(); return !d->testSpecs.empty();
} }
#ifdef WITH_TESTS #ifdef EXTENSIONSYSTEM_WITH_TESTOPTION
// Called in plugin initialization, the scenario function will be called later, from main // Called in plugin initialization, the scenario function will be called later, from main
bool PluginManager::registerScenario(const QString &scenarioId, std::function<bool()> scenarioStarter) bool PluginManager::registerScenario(const QString &scenarioId, std::function<bool()> scenarioStarter)
{ {
@@ -956,17 +956,18 @@ void PluginManagerPrivate::startDelayedInitialize()
} }
NANOTRACE_SHUTDOWN(); NANOTRACE_SHUTDOWN();
emit q->initializationDone(); emit q->initializationDone();
#ifdef WITH_TESTS #ifdef EXTENSIONSYSTEM_WITH_TESTOPTION
if (PluginManager::testRunRequested()) if (PluginManager::testRunRequested())
startTests(); startTests();
else if (PluginManager::isScenarioRequested()) { else if (PluginManager::isScenarioRequested()) {
if (PluginManager::runScenario()) { if (PluginManager::runScenario()) {
const QString info = QString("Successfully started scenario \"%1\"...").arg(d->m_requestedScenario); const QString info
qInfo("%s", qPrintable(info)); = QString("Successfully started scenario \"%1\"...").arg(d->m_requestedScenario);
} else { qInfo("%s", qPrintable(info));
QMetaObject::invokeMethod(this, [] { emit m_instance->scenarioFinished(1); }); } else {
} QMetaObject::invokeMethod(this, [] { emit m_instance->scenarioFinished(1); });
} }
}
#endif #endif
} }
@@ -1068,14 +1069,15 @@ void PluginManagerPrivate::checkForDuplicatePlugins()
static QHash<IPlugin *, QList<TestCreator>> g_testCreators; static QHash<IPlugin *, QList<TestCreator>> g_testCreators;
void PluginManagerPrivate::addTestCreator(IPlugin *plugin, const TestCreator &testCreator) void PluginManagerPrivate::addTestCreator(
[[maybe_unused]] IPlugin *plugin, [[maybe_unused]] const TestCreator &testCreator)
{ {
#ifdef WITH_TESTS #ifdef EXTENSIONSYSTEM_WITH_TESTOPTION
g_testCreators[plugin].append(testCreator); g_testCreators[plugin].append(testCreator);
#endif #endif
} }
#ifdef WITH_TESTS #ifdef EXTENSIONSYSTEM_WITH_TESTOPTION
using TestPlan = QHash<QObject *, QStringList>; // Object -> selected test functions using TestPlan = QHash<QObject *, QStringList>; // Object -> selected test functions
@@ -1456,7 +1458,7 @@ void PluginManagerPrivate::shutdown()
shutdownEventLoop->exec(); shutdownEventLoop->exec();
} }
deleteAll(); deleteAll();
#ifdef WITH_TESTS #ifdef EXTENSIONSYSTEM_WITH_TESTOPTION
if (PluginManager::isScenarioRunning("TestModelManagerInterface")) { if (PluginManager::isScenarioRunning("TestModelManagerInterface")) {
qDebug() << "Point 2: Expect the next call to Point 3 triggers a crash"; qDebug() << "Point 2: Expect the next call to Point 3 triggers a crash";
QThread::sleep(5); QThread::sleep(5);

View File

@@ -106,7 +106,7 @@ public:
static bool testRunRequested(); static bool testRunRequested();
#ifdef WITH_TESTS #ifdef EXTENSIONSYSTEM_WITH_TESTOPTION
static bool registerScenario(const QString &scenarioId, std::function<bool()> scenarioStarter); static bool registerScenario(const QString &scenarioId, std::function<bool()> scenarioStarter);
static bool isScenarioRequested(); static bool isScenarioRequested();
static bool runScenario(); static bool runScenario();

View File

@@ -151,7 +151,7 @@ private:
void deleteAll(); void deleteAll();
void checkForDuplicatePlugins(); void checkForDuplicatePlugins();
#ifdef WITH_TESTS #ifdef EXTENSIONSYSTEM_WITH_TESTOPTION
void startTests(); void startTests();
#endif #endif
}; };