File indexing completed on 2024-05-19 03:56:14

0001 /*
0002     SPDX-FileCopyrightText: 2014 Alex Merry <alex.merry@kde.org>
0003     SPDX-FileCopyrightText: 2021 Alexander Lohnau <alexander.lohnau@gmx.de>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #include <QTest>
0009 
0010 #include <QPluginLoader>
0011 #include <kpluginfactory.h>
0012 #ifndef Q_OS_WIN
0013 #include "plugins.h"
0014 #endif
0015 
0016 class KPluginFactoryTest : public QObject
0017 {
0018     Q_OBJECT
0019 
0020 private Q_SLOTS:
0021     void testCreate()
0022     {
0023 #ifndef Q_OS_WIN
0024         KPluginMetaData data(QStringLiteral("namespace/jsonplugin_cmake_macro"));
0025         QVERIFY(data.isValid());
0026         KPluginFactory::Result<KPluginFactory> factoryResult = KPluginFactory::loadFactory(data);
0027         auto factory = factoryResult.plugin;
0028         QVERIFY(factory);
0029 
0030         const QString testProp = QStringLiteral("testme");
0031         QObject *obj = factory->create<MyPlugin>(this, {testProp});
0032         QVERIFY(obj);
0033         QCOMPARE(obj->metaObject()->className(), "SimplePluginClass");
0034         QCOMPARE(obj->property("arg").toString(), testProp);
0035 
0036         QObject *obj2 = factory->create<MyPlugin2>(this);
0037         QVERIFY(obj2);
0038         QCOMPARE(obj2->metaObject()->className(), "SimplePluginClass2");
0039         QVERIFY(obj != obj2);
0040         delete obj;
0041         delete obj2;
0042 
0043         // Try creating a part without keyword/args
0044         QWidget parentWidget;
0045         QObject *partTest = factory->create<QObject>(&parentWidget, this);
0046         QVERIFY(partTest);
0047         delete partTest;
0048 #endif
0049     }
0050 
0051     void testPluginWithoutMetaData()
0052     {
0053         KPluginFactory::Result<KPluginFactory> factoryResult = KPluginFactory::loadFactory(KPluginMetaData(QStringLiteral("namespace/pluginwithoutmetadata")));
0054         QVERIFY(factoryResult);
0055         auto plugin = factoryResult.plugin->create<QObject>();
0056         QVERIFY(plugin);
0057         QCOMPARE(plugin->metaObject()->className(), "PluginWithoutMetaData");
0058         delete plugin;
0059     }
0060 
0061     void testCreateUsingUtilityMethods()
0062     {
0063         auto result = KPluginFactory::instantiatePlugin<QObject>(KPluginMetaData(QStringLiteral("namespace/jsonplugin_cmake_macro")));
0064         QVERIFY(result.plugin);
0065         QCOMPARE(result.plugin->metaObject()->className(), "SimplePluginClass");
0066         QVERIFY(result.errorString.isEmpty());
0067         QCOMPARE(result.errorReason, KPluginFactory::NO_PLUGIN_ERROR);
0068         delete result.plugin;
0069     }
0070 
0071     void testCreateUsingUtilityMethodsErrorHandling()
0072     {
0073         {
0074             auto result = KPluginFactory::instantiatePlugin<QObject>(KPluginMetaData(QFINDTESTDATA("data/jsonplugin.json")));
0075             QVERIFY(!result.plugin);
0076             QCOMPARE(result.errorReason, KPluginFactory::INVALID_PLUGIN);
0077         }
0078         {
0079             // it is a valid plugin, but does not contain a KPluginFactory
0080             QVERIFY(QPluginLoader(QStringLiteral("namespace/qtplugin")).instance());
0081             auto result = KPluginFactory::instantiatePlugin<QObject>(KPluginMetaData(QStringLiteral("namespace/qtplugin")));
0082             QVERIFY(!result.plugin);
0083             // But does not contain a valid plugin factory
0084             QCOMPARE(result.errorReason, KPluginFactory::INVALID_FACTORY);
0085         }
0086         {
0087             // it is a QObject, but not a KPluginFactoryTest instance
0088             auto result = KPluginFactory::instantiatePlugin<KPluginFactoryTest>(KPluginMetaData(QStringLiteral("namespace/jsonplugin_cmake_macro")));
0089             QVERIFY(!result.plugin);
0090             QCOMPARE(result.errorReason, KPluginFactory::INVALID_KPLUGINFACTORY_INSTANTIATION);
0091             QVERIFY(result.errorText.contains(QStringLiteral("KPluginFactoryTest")));
0092         }
0093     }
0094 
0095     void testStaticPlugins()
0096     {
0097         const auto plugins = KPluginMetaData::findPlugins(QStringLiteral("staticnamespace"));
0098         QCOMPARE(plugins.count(), 1);
0099         auto factory = KPluginFactory::loadFactory(plugins.first()).plugin;
0100         QCOMPARE(factory->metaObject()->className(), "static_jsonplugin_cmake_macro_factory");
0101         auto result = KPluginFactory::instantiatePlugin<QObject>(plugins.first());
0102         QVERIFY(result);
0103         delete result.plugin;
0104     }
0105 
0106     void testNonExistingPlugin()
0107     {
0108         KPluginMetaData data(QStringLiteral("does/not/exist"));
0109         QVERIFY(!data.isValid());
0110         const auto res = KPluginFactory::instantiatePlugin<QObject>(data);
0111         QVERIFY(!res);
0112         QCOMPARE(res.errorReason, KPluginFactory::INVALID_PLUGIN);
0113         QCOMPARE(res.errorText, QStringLiteral("Could not find plugin does/not/exist"));
0114     }
0115 
0116     void testInstantiateWidget()
0117     {
0118         KPluginMetaData data(QStringLiteral("widgets/widgetsplugin"), KPluginMetaData::AllowEmptyMetaData);
0119         QVERIFY(data.isValid());
0120         auto factory = KPluginFactory::loadFactory(data).plugin;
0121         QVERIFY(factory);
0122 
0123         // This has two constructors, make sure we choose the first one that takes args
0124         auto obj = factory->create<QWidget>(nullptr, QVariantList{true});
0125         QVERIFY(obj);
0126         QVERIFY(obj->property("firstarg").toBool());
0127         delete obj;
0128     }
0129 };
0130 
0131 QTEST_MAIN(KPluginFactoryTest)
0132 
0133 #include "kpluginfactorytest.moc"