diff options
Diffstat (limited to 'tests')
124 files changed, 8461 insertions, 1715 deletions
diff --git a/tests/auto/android/tst_avdmanageroutputparser.cpp b/tests/auto/android/tst_avdmanageroutputparser.cpp index a41022ec5d..e65a2bb15a 100644 --- a/tests/auto/android/tst_avdmanageroutputparser.cpp +++ b/tests/auto/android/tst_avdmanageroutputparser.cpp @@ -80,10 +80,9 @@ void tst_AvdManagerOutputParser::parse() QFETCH(AndroidDeviceInfoList, output); QFETCH(Utils::FilePaths, errorPaths); - Utils::FilePaths avdErrorPaths; - const auto result = parseAvdList(input, &avdErrorPaths); - QCOMPARE(result, output); - QCOMPARE(avdErrorPaths, errorPaths); + const auto result = parseAvdList(input); + QCOMPARE(result.avdList, output); + QCOMPARE(result.errorPaths, errorPaths); } QTEST_GUILESS_MAIN(tst_AvdManagerOutputParser) diff --git a/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp b/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp index 82b5cba5b1..12c3c52852 100644 --- a/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp +++ b/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp @@ -107,6 +107,9 @@ private Q_SLOTS: void shiftWithinInitializer(); void lambdaWithReturnType(); void structuredBinding(); + void subscriptOperatorInFunctionCall(); + void statementMacros(); + void tryCatchClause(); }; struct Line { @@ -2199,6 +2202,75 @@ void tst_CodeFormatter::structuredBinding() checkIndent(data); } +void tst_CodeFormatter::subscriptOperatorInFunctionCall() +{ + QList<Line> data; + data << Line("int main() {") + << Line(" func(array[0],") + << Line(" ~ 0);") + << Line(" func(array[i],") + << Line(" ~ i);") + << Line("}") + ; + checkIndent(data); +} + +void tst_CodeFormatter::statementMacros() +{ + QList<Line> data; + data << Line("MY_MACRO") + << Line("template<int n = 0>") + << Line("~ class C;"); + checkIndent(data); + + data.clear(); + CppCodeStyleSettings settings; + settings.statementMacros << "MY_MACRO"; + data << Line("MY_MACRO") + << Line("template<int n = 0>") + << Line("class C;"); + checkIndent(data, settings); +} + +void tst_CodeFormatter::tryCatchClause() +{ + CppCodeStyleSettings settings; + settings.indentFunctionBody = true; + settings.indentFunctionBraces = false; + settings.indentBlockBody = false; + settings.indentBlockBraces = true; + QList<Line> data; + data << Line("int main()") + << Line("{") + << Line(" try") + << Line(" {") + << Line(" throw;") + << Line(" }") + << Line(" catch (const E &e)") + << Line(" {") + << Line(" handle(e);") + << Line(" }") + << Line(" catch (...)") + << Line(" {") + << Line(" handle();") + << Line(" }") + << Line("}"); + checkIndent(data, settings); + + data.clear(); + data << Line("int main()") + << Line("{") + << Line(" try {") + << Line(" throw;") + << Line(" } catch (const E &e) {") + << Line(" handle(e);") + << Line(" } catch (...) {") + << Line(" handle();") + << Line(" }") + << Line("}"); + checkIndent(data); +} + QTEST_GUILESS_MAIN(tst_CodeFormatter) #include "tst_codeformatter.moc" diff --git a/tests/auto/debugger/CMakeLists.txt b/tests/auto/debugger/CMakeLists.txt index 2f06a6b2fc..01761ba5aa 100644 --- a/tests/auto/debugger/CMakeLists.txt +++ b/tests/auto/debugger/CMakeLists.txt @@ -16,7 +16,7 @@ if (NOT QT_CREATOR_API_DEFINED) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) - set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 55ae944ef6..4385f84084 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -1171,6 +1171,7 @@ private: bool m_isQnxGdb = false; bool m_useGLibCxxDebug = false; int m_totalDumpTime = 0; + int m_totalInnerTime = 0; }; void tst_Dumpers::initTestCase() @@ -1199,7 +1200,28 @@ void tst_Dumpers::initTestCase() if (qEnvironmentVariableIntValue("QTC_USE_CMAKE_FOR_TEST")) m_buildSystem = BuildSystem::CMake; + QProcess qmake; + qmake.start(m_qmakeBinary, {"--version"}); + QVERIFY(qmake.waitForFinished()); + QByteArray output = qmake.readAllStandardOutput(); + QByteArray error = qmake.readAllStandardError(); + int pos0 = output.indexOf("Qt version"); + if (pos0 == -1) { + qCDebug(lcDumpers).noquote() << "Output: " << output; + qCDebug(lcDumpers).noquote() << "Error: " << error; + QVERIFY(false); + } + pos0 += 11; + int pos1 = output.indexOf('.', pos0 + 1); + int major = output.mid(pos0, pos1++ - pos0).toInt(); + int pos2 = output.indexOf('.', pos1 + 1); + int minor = output.mid(pos1, pos2++ - pos1).toInt(); + int pos3 = output.indexOf(' ', pos2 + 1); + int patch = output.mid(pos2, pos3++ - pos2).toInt(); + m_qtVersion = 0x10000 * major + 0x100 * minor + patch; + qCDebug(lcDumpers) << "QMake : " << m_qmakeBinary; + qCDebug(lcDumpers) << "Qt Version : " << m_qtVersion; qCDebug(lcDumpers) << "Use CMake : " << (m_buildSystem == BuildSystem::CMake) << int(m_buildSystem); m_useGLibCxxDebug = qgetenv("QTC_USE_GLIBCXXDEBUG_FOR_TEST").toInt(); @@ -1343,7 +1365,9 @@ void tst_Dumpers::cleanup() void tst_Dumpers::cleanupTestCase() { - qCDebug(lcDumpers) << "Dumpers total: " << QTime::fromMSecsSinceStartOfDay(m_totalDumpTime); + qCDebug(lcDumpers) << QTime::fromMSecsSinceStartOfDay(m_totalDumpTime); + qCDebug(lcDumpers, "TotalOuter: %5d", m_totalDumpTime); + qCDebug(lcDumpers, "TotalInner: %5d", m_totalInnerTime); } void tst_Dumpers::dumper() @@ -1378,27 +1402,6 @@ void tst_Dumpers::dumper() QByteArray error; if (data.neededQtVersion.isRestricted) { - QProcess qmake; - qmake.setWorkingDirectory(t->buildPath); - qmake.start(m_qmakeBinary, {"--version"}); - QVERIFY(qmake.waitForFinished()); - output = qmake.readAllStandardOutput(); - error = qmake.readAllStandardError(); - int pos0 = output.indexOf("Qt version"); - if (pos0 == -1) { - qCDebug(lcDumpers).noquote() << "Output: " << output; - qCDebug(lcDumpers).noquote() << "Error: " << error; - QVERIFY(false); - } - pos0 += 11; - int pos1 = output.indexOf('.', pos0 + 1); - int major = output.mid(pos0, pos1++ - pos0).toInt(); - int pos2 = output.indexOf('.', pos1 + 1); - int minor = output.mid(pos1, pos2++ - pos1).toInt(); - int pos3 = output.indexOf(' ', pos2 + 1); - int patch = output.mid(pos2, pos3++ - pos2).toInt(); - m_qtVersion = 0x10000 * major + 0x100 * minor + patch; - if (data.neededQtVersion.min > m_qtVersion) MSKIP_SINGLE(QByteArray("Need minimum Qt version " + QByteArray::number(data.neededQtVersion.min, 16))); @@ -1790,6 +1793,7 @@ void tst_Dumpers::dumper() "python theDumper.fetchVariables({" + dumperOptions + "'token':2,'fancy':1,'forcens':1," "'autoderef':1,'dyntype':1,'passexceptions':1," + "'qtversion':" + QString::number(m_qtVersion) + ",'qtnamespace':''," "'testing':1,'qobjectnames':1," "'expanded':{" + expandedq + "}})\n"; @@ -1813,6 +1817,7 @@ void tst_Dumpers::dumper() "'token':2,'fancy':1,'forcens':1," "'autoderef':1,'dyntype':1,'passexceptions':0," "'testing':1,'qobjectnames':1," + "'qtversion':" + QString::number(m_qtVersion) + ",'qtnamespace':''," "'expanded':{" + expandedq + "}})\n" "q\n"; } else if (m_debuggerEngine == LldbEngine) { @@ -1837,6 +1842,7 @@ void tst_Dumpers::dumper() "'fancy':1,'forcens':1," "'autoderef':1,'dyntype':1,'passexceptions':1," "'testing':1,'qobjectnames':1," + "'qtversion':" + QString::number(m_qtVersion) + ",'qtnamespace':''," "'expanded':{" + expandedq + "}})\n" "quit\n"; @@ -1859,7 +1865,10 @@ void tst_Dumpers::dumper() dumperTimer.start(); debugger.write(cmds.toLocal8Bit()); QVERIFY(debugger.waitForFinished()); - m_totalDumpTime += dumperTimer.elapsed(); + const int elapsed = dumperTimer.elapsed(); + //< QTime::fromMSecsSinceStartOfDay(elapsed); + qCDebug(lcDumpers, "CaseOuter: %5d", elapsed); + m_totalDumpTime += elapsed; output = debugger.readAllStandardOutput(); QByteArray fullOutput = output; //qCDebug(lcDumpers) << "stdout: " << output; @@ -1890,6 +1899,9 @@ void tst_Dumpers::dumper() actual.fromStringMultiple(QString::fromLocal8Bit(contents)); context.nameSpace = actual["qtnamespace"].data(); + int runtime = actual["runtime"].data().toFloat() * 1000; + qCDebug(lcDumpers, "CaseInner: %5d", runtime); + m_totalInnerTime += runtime; actual = actual["data"]; //qCDebug(lcDumpers) << "FOUND NS: " << context.nameSpace; @@ -1913,7 +1925,13 @@ void tst_Dumpers::dumper() if (context.nameSpace == "::") context.nameSpace.clear(); contents.replace("\\\"", "\""); - actual.fromString(QString::fromLocal8Bit(contents)); + actual.fromStringMultiple(QString::fromLocal8Bit(contents)); + int runtime = actual["runtime"].data().toFloat() * 1000; + qCDebug(lcDumpers, "CaseInner: %5d", runtime); + m_totalInnerTime += runtime; + actual = actual["data"]; + //qCDebug(lcDumpers).noquote() << "\nACTUAL: " << actual.toString() << "\nXYYY"; + } else { QByteArray localsAnswerStart("<qtcreatorcdbext>|R|42|"); QByteArray locals("|script|"); @@ -1967,8 +1985,8 @@ void tst_Dumpers::dumper() auto test = [&](const Check &check, bool *removeIt, bool single) { if (!check.matches(m_debuggerEngine, m_debuggerVersion, context)) { - if (single) - qCDebug(lcDumpers) << "SKIPPING NON-MATCHING TEST " << check; + //if (single) + // qCDebug(lcDumpers) << "SKIPPING NON-MATCHING TEST " << check; return true; // we have not failed } @@ -2071,22 +2089,24 @@ void tst_Dumpers::dumper() } } + int pos1 = 0; + int pos2 = -1; + while (true) { + pos1 = fullOutput.indexOf("bridgemessage={msg=", pos2 + 1); + if (pos1 == -1) + break; + pos1 += 20; + pos2 = fullOutput.indexOf("\"}", pos1 + 1); + if (pos2 == -1) + break; + qCDebug(lcDumpers) << "MSG: " << fullOutput.mid(pos1, pos2 - pos1); + } + if (ok) { m_keepTemp = false; } else { local.forAllChildren([](WatchItem *item) { qCDebug(lcDumpers) << item->internalName(); }); - int pos1 = 0, pos2 = -1; - while (true) { - pos1 = fullOutput.indexOf("bridgemessage={msg=", pos2 + 1); - if (pos1 == -1) - break; - pos1 += 20; - pos2 = fullOutput.indexOf("\"}", pos1 + 1); - if (pos2 == -1) - break; - qCDebug(lcDumpers) << "MSG: " << fullOutput.mid(pos1, pos2 - pos1 - 1); - } qCDebug(lcDumpers).noquote() << "CONTENTS : " << contents; qCDebug(lcDumpers).noquote() << "FULL OUTPUT : " << fullOutput.data(); qCDebug(lcDumpers) << "Qt VERSION : " << QString::number(context.qtVersion, 16); @@ -4374,7 +4394,7 @@ void tst_Dumpers::dumper_data() + NetworkProfile() + Check("ha", ValuePattern(".*127.0.0.1.*"), "@QHostAddress") - + Check("ha.a", "2130706433", TypeDef("unsigned int", "@quint32")) + + Check("ha.a", "2130706433", "@quint32") + Check("ha.ipString", ValuePattern(".*127.0.0.1.*"), "@QString") % QtVersion(0, 0x50800) //+ Check("ha.protocol", "@QAbstractSocket::IPv4Protocol (0)", @@ -4383,7 +4403,7 @@ void tst_Dumpers::dumper_data() // "@QAbstractSocket::NetworkLayerProtocol") % LldbEngine + Check("ha.scopeId", "\"\"", "@QString") + Check("ha1", ValuePattern(".*127.0.0.1.*"), "@QHostAddress") - + Check("ha1.a", "2130706433", TypeDef("unsigned int", "@quint32")) + + Check("ha1.a", "2130706433", "@quint32") + Check("ha1.ipString", "\"127.0.0.1\"", "@QString") % QtVersion(0, 0x50800) //+ Check("ha1.protocol", "@QAbstractSocket::IPv4Protocol (0)", @@ -6226,15 +6246,19 @@ void tst_Dumpers::dumper_data() QTest::newRow("Bitfields") << Data("", - "enum E { V1, V2 };" + "typedef int gint;\n" + "typedef unsigned int guint;\n" + "enum E { V1, V2 };\n" "struct S\n" "{\n" - " S() : front(13), x(2), y(3), z(39), e(V2), c(1), b(0), f(5)," + " S() : front(13), x(2), y(3), z(39), t1(1), t2(1), e(V2), c(1), b(0), f(5)," " g(46), h(47), d(6), i(7) {}\n" " unsigned int front;\n" " unsigned int x : 3;\n" " unsigned int y : 4;\n" " unsigned int z : 18;\n" + " gint t1 : 2;\n" + " guint t2 : 2;\n" " E e : 3;\n" " bool c : 1;\n" " bool b;\n" @@ -6257,7 +6281,7 @@ void tst_Dumpers::dumper_data() + Check("s.x", "2", "unsigned int : 3") % NoCdbEngine + Check("s.y", "3", "unsigned int : 4") % NoCdbEngine + Check("s.z", "39", "unsigned int : 18") % NoCdbEngine - + Check("s.e", "V2 (1)", "E : 3") % GdbEngine + // + Check("s.e", "V2 (1)", "E : 3") % GdbEngine FIXME + Check("s.g", "46", "char : 7") % GdbEngine + Check("s.h", "47", "char") % GdbEngine + Check("s.x", "2", "unsigned int") % CdbEngine @@ -6267,7 +6291,7 @@ void tst_Dumpers::dumper_data() + Check("s.e", "V2 (1)", TypePattern("main::[a-zA-Z0-9_]*::E")) % CdbEngine // checks for the "Expressions" view, GDB-only for now - + Watcher("watch.1", "s;s.b;s.c;s.f;s.d;s.i;s.x;s.y;s.z;s.e;s.g;s.h;s.front") + + Watcher("watch.1", "s;s.b;s.c;s.f;s.d;s.i;s.x;s.y;s.z;s.e;s.g;s.h;s.front;s.t1;s.t2") + Check("watch.1.0", "s", "", "S") % GdbEngine + Check("watch.1.1", "s.b", "0", "bool") % GdbEngine + Check("watch.1.2", "s.c", "1", "bool") % GdbEngine @@ -6280,7 +6304,9 @@ void tst_Dumpers::dumper_data() + Check("watch.1.9", "s.e", "V2 (1)", "E") % GdbEngine + Check("watch.1.10", "s.g", "46", "char") % GdbEngine + Check("watch.1.11", "s.h", "47", "char") % GdbEngine - + Check("watch.1.12", "s.front", "13", "unsigned int") % GdbEngine; + + Check("watch.1.12", "s.front", "13", "unsigned int") % GdbEngine + + Check("watch.1.13", "s.t1", "1", "gint") % GdbEngine + + Check("watch.1.14", "s.t2", "1", "guint") % GdbEngine; QTest::newRow("Bitfield2") @@ -7348,11 +7374,21 @@ void tst_Dumpers::dumper_data() "Base *b = &d;\n", "&d, &b") - + Check("b.@1.a", "a", "21", "int") + Check("b.b", "b", "42", "int"); + // https://bugreports.qt.io/browse/QTCREATORBUG-18450 + QTest::newRow("Bug18450") + << Data("using quint128 = __uint128_t;\n", + + "quint128 x = 42;\n", + + "&x") + + + NoCdbEngine + + Check("x", "42", "quint128"); + // https://bugreports.qt.io/browse/QTCREATORBUG-17823 QTest::newRow("Bug17823") @@ -7615,8 +7651,7 @@ void tst_Dumpers::dumper_data() "&d, &s, &ptrConst, &ref, &refConst, &ptrToPtr, &sharedPtr") - + GdbEngine - + GdbVersion(70500) + + NoCdbEngine + BoostProfile() + Check("d", "", "Derived") @@ -8323,11 +8358,13 @@ void tst_Dumpers::dumper_data() QTest::newRow("Sql") - << Data("#include <QSqlField>\n" + << Data("#include <QCoreApplication>\n" + "#include <QSqlField>\n" "#include <QSqlDatabase>\n" "#include <QSqlQuery>\n" "#include <QSqlRecord>\n", + "QCoreApplication app(argc, argv);\n" "QSqlDatabase db = QSqlDatabase::addDatabase(\"QSQLITE\");\n" "db.setDatabaseName(\":memory:\");\n" "Q_ASSERT(db.open());\n" diff --git a/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp b/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp index e57e71c533..35ed607813 100644 --- a/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp +++ b/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp @@ -47,9 +47,9 @@ class MyClass11 : public MyClass1 Q_OBJECT }; -static QString pluginFolder(const QLatin1String &folder) +static Utils::FilePath pluginFolder(const QLatin1String &folder) { - return QLatin1String(PLUGINMANAGER_TESTS_DIR) + QLatin1String("/") + folder; + return Utils::FilePath::fromUserInput(QLatin1String(PLUGINMANAGER_TESTS_DIR)) / folder; } void tst_PluginManager::init() @@ -138,9 +138,9 @@ void tst_PluginManager::getObject() void tst_PluginManager::circularPlugins() { - PluginManager::setPluginPaths(QStringList() << pluginFolder(QLatin1String("circularplugins"))); + PluginManager::setPluginPaths({pluginFolder(QLatin1String("circularplugins"))}); PluginManager::loadPlugins(); - const QVector<PluginSpec *> plugins = PluginManager::plugins(); + const PluginSpecs plugins = PluginManager::plugins(); QCOMPARE(plugins.count(), 3); for (PluginSpec *spec : plugins) { if (spec->name() == "plugin1") { @@ -160,11 +160,11 @@ void tst_PluginManager::circularPlugins() void tst_PluginManager::correctPlugins1() { - PluginManager::setPluginPaths(QStringList() << pluginFolder(QLatin1String("correctplugins1"))); + PluginManager::setPluginPaths({pluginFolder(QLatin1String("correctplugins1"))}); PluginManager::loadPlugins(); bool specError = false; bool runError = false; - const QVector<PluginSpec *> plugins = PluginManager::plugins(); + const PluginSpecs plugins = PluginManager::plugins(); for (PluginSpec *spec : plugins) { if (spec->hasError()) { qDebug() << spec->filePath(); diff --git a/tests/auto/extensionsystem/pluginspec/CMakeLists.txt b/tests/auto/extensionsystem/pluginspec/CMakeLists.txt index ad91750f28..efb94786d0 100644 --- a/tests/auto/extensionsystem/pluginspec/CMakeLists.txt +++ b/tests/auto/extensionsystem/pluginspec/CMakeLists.txt @@ -5,7 +5,7 @@ add_qtc_test(tst_pluginspec PLUGIN_DIR="${CMAKE_CURRENT_BINARY_DIR}" PLUGINSPEC_DIR="${CMAKE_CURRENT_SOURCE_DIR}" DLL_INFIX="$<$<CONFIG:Debug>:d>" - DEPENDS ExtensionSystem + DEPENDS ExtensionSystem Utils SOURCES tst_pluginspec.cpp ) diff --git a/tests/auto/extensionsystem/pluginspec/test.qbs b/tests/auto/extensionsystem/pluginspec/test.qbs index b8196f93e6..56748fde12 100644 --- a/tests/auto/extensionsystem/pluginspec/test.qbs +++ b/tests/auto/extensionsystem/pluginspec/test.qbs @@ -4,6 +4,8 @@ QtcAutotest { name: "ExtensionSystem pluginspec autotest" Depends { name: "Aggregation" } Depends { name: "ExtensionSystem" } + Depends { name: "Utils" } + Group { name: "Sources" files: "tst_pluginspec.cpp" diff --git a/tests/auto/extensionsystem/pluginspec/testspecs/spec_wrong2.json b/tests/auto/extensionsystem/pluginspec/testspecs/spec_wrong2.json index 2fd9df4d5d..63a7fc5c55 100644 --- a/tests/auto/extensionsystem/pluginspec/testspecs/spec_wrong2.json +++ b/tests/auto/extensionsystem/pluginspec/testspecs/spec_wrong2.json @@ -11,6 +11,7 @@ "end of terms" ], "Description" : [ + "This spec is broken because no name is set.", "This plugin is just a test.", " it demonstrates the great use of the plugin spec." ], diff --git a/tests/auto/extensionsystem/pluginspec/testspecs/spec_wrong3.json b/tests/auto/extensionsystem/pluginspec/testspecs/spec_wrong3.json index 0b053f6014..7c43ef41d2 100644 --- a/tests/auto/extensionsystem/pluginspec/testspecs/spec_wrong3.json +++ b/tests/auto/extensionsystem/pluginspec/testspecs/spec_wrong3.json @@ -11,6 +11,7 @@ "end of terms" ], "Description" : [ + "This spec is wrong because no version is set.", "This plugin is just a test.", " it demonstrates the great use of the plugin spec." ], diff --git a/tests/auto/extensionsystem/pluginspec/testspecs/spec_wrong4.json b/tests/auto/extensionsystem/pluginspec/testspecs/spec_wrong4.json index c3a0d26922..c8e1dd53d9 100644 --- a/tests/auto/extensionsystem/pluginspec/testspecs/spec_wrong4.json +++ b/tests/auto/extensionsystem/pluginspec/testspecs/spec_wrong4.json @@ -12,6 +12,7 @@ "end of terms" ], "Description" : [ + "This spec is wrong because the first dependency has no name.", "This plugin is just a test.", " it demonstrates the great use of the plugin spec." ], diff --git a/tests/auto/extensionsystem/pluginspec/testspecs/spec_wrong5.json b/tests/auto/extensionsystem/pluginspec/testspecs/spec_wrong5.json index bdb095b342..680ec4002a 100644 --- a/tests/auto/extensionsystem/pluginspec/testspecs/spec_wrong5.json +++ b/tests/auto/extensionsystem/pluginspec/testspecs/spec_wrong5.json @@ -12,6 +12,7 @@ "end of terms" ], "Description" : [ + "This spec is wrong because the first dependencies version is invalid.", "This plugin is just a test.", " it demonstrates the great use of the plugin spec." ], diff --git a/tests/auto/extensionsystem/pluginspec/tst_pluginspec.cpp b/tests/auto/extensionsystem/pluginspec/tst_pluginspec.cpp index 762142b95e..66828f8e63 100644 --- a/tests/auto/extensionsystem/pluginspec/tst_pluginspec.cpp +++ b/tests/auto/extensionsystem/pluginspec/tst_pluginspec.cpp @@ -1,10 +1,9 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include <extensionsystem/pluginspec.h> -#include <extensionsystem/pluginspec_p.h> -#include <extensionsystem/pluginmanager_p.h> #include <extensionsystem/pluginmanager.h> +#include <extensionsystem/pluginmanager_p.h> +#include <extensionsystem/pluginspec.h> #include <QJsonDocument> #include <QJsonObject> @@ -15,6 +14,8 @@ using namespace ExtensionSystem; +static const Utils::FilePath PLUGIN_DIR_PATH = Utils::FilePath::fromUserInput(PLUGIN_DIR); + static QJsonObject metaData(const QString &fileName) { QFile f(fileName); @@ -85,109 +86,110 @@ void tst_PluginSpec::cleanupTestCase() void tst_PluginSpec::read() { - Internal::PluginSpecPrivate spec(0); - QCOMPARE(spec.state, PluginSpec::Invalid); + CppPluginSpec spec; + QCOMPARE(spec.state(), PluginSpec::Invalid); QVERIFY(spec.readMetaData(metaData("testspecs/spec1.json"))); - QVERIFY(!spec.hasError); - QVERIFY(spec.errorString.isEmpty()); - QCOMPARE(spec.name, QString("test")); - QCOMPARE(spec.version, QString("1.0.1")); - QCOMPARE(spec.compatVersion, QString("1.0.0")); - QCOMPARE(spec.required, false); - QCOMPARE(spec.experimental, false); - QCOMPARE(spec.enabledBySettings, true); - QCOMPARE(spec.vendor, QString("The Qt Company Ltd")); - QCOMPARE(spec.copyright, QString("(C) 2015 The Qt Company Ltd")); - QCOMPARE(spec.license, QString("This is a default license bla\nblubbblubb\nend of terms")); - QCOMPARE(spec.description, QString("This plugin is just a test.")); + QVERIFY(!spec.hasError()); + QVERIFY(spec.errorString().isEmpty()); + QCOMPARE(spec.name(), QString("test")); + QCOMPARE(spec.version(), QString("1.0.1")); + QCOMPARE(spec.compatVersion(), QString("1.0.0")); + QCOMPARE(spec.isRequired(), false); + QCOMPARE(spec.isExperimental(), false); + QCOMPARE(spec.isEnabledBySettings(), true); + QCOMPARE(spec.vendor(), QString("The Qt Company Ltd")); + QCOMPARE(spec.copyright(), QString("(C) 2015 The Qt Company Ltd")); + QCOMPARE(spec.license(), QString("This is a default license bla\nblubbblubb\nend of terms")); + QCOMPARE(spec.description(), QString("This plugin is just a test.")); QCOMPARE( - spec.longDescription, + spec.longDescription(), QString( "This plugin is just a test.\n it demonstrates the great use of the plugin spec.")); - QCOMPARE(spec.url, QString("http://www.qt.io")); + QCOMPARE(spec.url(), QString("http://www.qt.io")); PluginDependency dep1; dep1.name = QString("SomeOtherPlugin"); dep1.version = QString("2.3.0_2"); PluginDependency dep2; dep2.name = QString("EvenOther"); dep2.version = QString("1.0.0"); - QCOMPARE(spec.dependencies, QVector<PluginDependency>() << dep1 << dep2); + QCOMPARE(spec.dependencies(), QVector<PluginDependency>() << dep1 << dep2); // test missing compatVersion behavior // and 'required' attribute QVERIFY(spec.readMetaData(metaData("testspecs/spec2.json"))); - QCOMPARE(spec.version, QString("3.1.4_10")); - QCOMPARE(spec.compatVersion, QString("3.1.4_10")); - QCOMPARE(spec.required, true); + QCOMPARE(spec.version(), QString("3.1.4_10")); + QCOMPARE(spec.compatVersion(), QString("3.1.4_10")); + QCOMPARE(spec.isRequired(), true); } void tst_PluginSpec::readError() { - Internal::PluginSpecPrivate spec(0); - QCOMPARE(spec.state, PluginSpec::Invalid); + CppPluginSpec spec; + QCOMPARE(spec.state(), PluginSpec::Invalid); QVERIFY(!spec.readMetaData(metaData("non-existing-file.json"))); - QCOMPARE(spec.state, PluginSpec::Invalid); - QVERIFY(!spec.hasError); - QVERIFY(spec.errorString.isEmpty()); + QCOMPARE(spec.state(), PluginSpec::Invalid); + QVERIFY(!spec.hasError()); + QVERIFY(spec.errorString().isEmpty()); QVERIFY(spec.readMetaData(metaData("testspecs/spec_wrong2.json"))); - QCOMPARE(spec.state, PluginSpec::Invalid); - QVERIFY(spec.hasError); - QVERIFY(!spec.errorString.isEmpty()); + QCOMPARE(spec.state(), PluginSpec::Invalid); + QVERIFY(spec.hasError()); + QVERIFY(!spec.errorString().isEmpty()); QVERIFY(spec.readMetaData(metaData("testspecs/spec_wrong3.json"))); - QCOMPARE(spec.state, PluginSpec::Invalid); - QVERIFY(spec.hasError); - QVERIFY(!spec.errorString.isEmpty()); + QCOMPARE(spec.state(), PluginSpec::Invalid); + QVERIFY(spec.hasError()); + QVERIFY(!spec.errorString().isEmpty()); QVERIFY(spec.readMetaData(metaData("testspecs/spec_wrong4.json"))); - QCOMPARE(spec.state, PluginSpec::Invalid); - QVERIFY(spec.hasError); - QVERIFY(!spec.errorString.isEmpty()); + QCOMPARE(spec.state(), PluginSpec::Invalid); + QVERIFY(spec.hasError()); + QVERIFY(!spec.errorString().isEmpty()); QVERIFY(spec.readMetaData(metaData("testspecs/spec_wrong5.json"))); - QCOMPARE(spec.state, PluginSpec::Invalid); - QVERIFY(spec.hasError); - QVERIFY(!spec.errorString.isEmpty()); + QCOMPARE(spec.state(), PluginSpec::Invalid); + QVERIFY(spec.hasError()); + QVERIFY(!spec.errorString().isEmpty()); } void tst_PluginSpec::isValidVersion() { - QVERIFY(Internal::PluginSpecPrivate::isValidVersion("2")); - QVERIFY(Internal::PluginSpecPrivate::isValidVersion("53")); - QVERIFY(Internal::PluginSpecPrivate::isValidVersion("52_1")); - QVERIFY(Internal::PluginSpecPrivate::isValidVersion("3.12")); - QVERIFY(Internal::PluginSpecPrivate::isValidVersion("31.1_12")); - QVERIFY(Internal::PluginSpecPrivate::isValidVersion("31.1.0")); - QVERIFY(Internal::PluginSpecPrivate::isValidVersion("1.0.2_1")); - - QVERIFY(!Internal::PluginSpecPrivate::isValidVersion("")); - QVERIFY(!Internal::PluginSpecPrivate::isValidVersion("1..0")); - QVERIFY(!Internal::PluginSpecPrivate::isValidVersion("1.0_")); - QVERIFY(!Internal::PluginSpecPrivate::isValidVersion("1.0.0.0")); + QVERIFY(PluginSpec::isValidVersion("2")); + QVERIFY(PluginSpec::isValidVersion("53")); + QVERIFY(PluginSpec::isValidVersion("52_1")); + QVERIFY(PluginSpec::isValidVersion("3.12")); + QVERIFY(PluginSpec::isValidVersion("31.1_12")); + QVERIFY(PluginSpec::isValidVersion("31.1.0")); + QVERIFY(PluginSpec::isValidVersion("1.0.2_1")); + + QVERIFY(!PluginSpec::isValidVersion("")); + QVERIFY(!PluginSpec::isValidVersion("1..0")); + QVERIFY(!PluginSpec::isValidVersion("1.0_")); + QVERIFY(!PluginSpec::isValidVersion("1.0.0.0")); } void tst_PluginSpec::versionCompare() { - QVERIFY(Internal::PluginSpecPrivate::versionCompare("3", "3") == 0); - QVERIFY(Internal::PluginSpecPrivate::versionCompare("3.0.0", "3") == 0); - QVERIFY(Internal::PluginSpecPrivate::versionCompare("3.0", "3") == 0); - QVERIFY(Internal::PluginSpecPrivate::versionCompare("3.0.0_1", "3_1") == 0); - QVERIFY(Internal::PluginSpecPrivate::versionCompare("3.0_21", "3_21") == 0); - - QVERIFY(Internal::PluginSpecPrivate::versionCompare("3", "1") > 0); - QVERIFY(Internal::PluginSpecPrivate::versionCompare("3", "1.0_12") > 0); - QVERIFY(Internal::PluginSpecPrivate::versionCompare("3_1", "3") > 0); - QVERIFY(Internal::PluginSpecPrivate::versionCompare("3.1.0_23", "3.1") > 0); - QVERIFY(Internal::PluginSpecPrivate::versionCompare("3.1_23", "3.1_12") > 0); - - QVERIFY(Internal::PluginSpecPrivate::versionCompare("1", "3") < 0); - QVERIFY(Internal::PluginSpecPrivate::versionCompare("1.0_12", "3") < 0); - QVERIFY(Internal::PluginSpecPrivate::versionCompare("3", "3_1") < 0); - QVERIFY(Internal::PluginSpecPrivate::versionCompare("3.1", "3.1.0_23") < 0); - QVERIFY(Internal::PluginSpecPrivate::versionCompare("3.1_12", "3.1_23") < 0); + QVERIFY(PluginSpec::versionCompare("3", "3") == 0); + QVERIFY(PluginSpec::versionCompare("3.0.0", "3") == 0); + QVERIFY(PluginSpec::versionCompare("3.0", "3") == 0); + QVERIFY(PluginSpec::versionCompare("3.0.0_1", "3_1") == 0); + QVERIFY(PluginSpec::versionCompare("3.0_21", "3_21") == 0); + + QVERIFY(PluginSpec::versionCompare("3", "1") > 0); + QVERIFY(PluginSpec::versionCompare("3", "1.0_12") > 0); + QVERIFY(PluginSpec::versionCompare("3_1", "3") > 0); + QVERIFY(PluginSpec::versionCompare("3.1.0_23", "3.1") > 0); + QVERIFY(PluginSpec::versionCompare("3.1_23", "3.1_12") > 0); + + QVERIFY(PluginSpec::versionCompare("1", "3") < 0); + QVERIFY(PluginSpec::versionCompare("1.0_12", "3") < 0); + QVERIFY(PluginSpec::versionCompare("3", "3_1") < 0); + QVERIFY(PluginSpec::versionCompare("3.1", "3.1.0_23") < 0); + QVERIFY(PluginSpec::versionCompare("3.1_12", "3.1_23") < 0); } void tst_PluginSpec::provides() { - Internal::PluginSpecPrivate spec(0); + CppPluginSpec spec; QVERIFY(spec.readMetaData(metaData("testspecs/simplespec.json"))); + QVERIFY(!spec.provides("SomeOtherPlugin", "2.2.3_9")); QVERIFY(!spec.provides("MyPlugin", "2.2.3_10")); QVERIFY(!spec.provides("MyPlugin", "2.2.4")); @@ -211,112 +213,126 @@ void tst_PluginSpec::provides() void tst_PluginSpec::experimental() { - Internal::PluginSpecPrivate spec(0); + CppPluginSpec spec; QVERIFY(spec.readMetaData(metaData("testspecs/simplespec_experimental.json"))); - QCOMPARE(spec.experimental, true); - QCOMPARE(spec.enabledBySettings, false); + + QCOMPARE(spec.isExperimental(), true); + QCOMPARE(spec.isEnabledBySettings(), false); } void tst_PluginSpec::locationAndPath() { - Internal::PluginSpecPrivate spec(0); - QVERIFY(spec.read(QLatin1String(PLUGIN_DIR) + QLatin1String("/testplugin/") + libraryName(QLatin1String("test")))); - QCOMPARE(spec.location, QString(QLatin1String(PLUGIN_DIR) + QLatin1String("/testplugin"))); - QCOMPARE(spec.filePath, QString(QLatin1String(PLUGIN_DIR) + QLatin1String("/testplugin/") + libraryName(QLatin1String("test")))); + Utils::expected_str<PluginSpec *> ps = readCppPluginSpec( + PLUGIN_DIR_PATH / "testplugin" / libraryName(QLatin1String("test"))); + QVERIFY(ps); + CppPluginSpec *spec = static_cast<CppPluginSpec *>(ps.value()); + QCOMPARE(spec->location(), PLUGIN_DIR_PATH / "testplugin"); + QCOMPARE(spec->filePath(), PLUGIN_DIR_PATH / "testplugin" / libraryName(QLatin1String("test"))); } void tst_PluginSpec::resolveDependencies() { - QVector<PluginSpec *> specs; - PluginSpec *spec1 = Internal::PluginManagerPrivate::createSpec(); + PluginSpecs specs; + PluginSpec *spec1 = new CppPluginSpec(); specs.append(spec1); - Internal::PluginSpecPrivate *spec1Priv = Internal::PluginManagerPrivate::privateSpec(spec1); - spec1Priv->readMetaData(metaData("testdependencies/spec1.json")); - spec1Priv->state = PluginSpec::Read; // fake read state for plugin resolving + spec1->readMetaData(metaData("testdependencies/spec1.json")); + spec1->setState(PluginSpec::Read); // fake read state for plugin resolving - PluginSpec *spec2 = Internal::PluginManagerPrivate::createSpec(); + PluginSpec *spec2 = new CppPluginSpec(); specs.append(spec2); - Internal::PluginSpecPrivate *spec2Priv = Internal::PluginManagerPrivate::privateSpec(spec2); - spec2Priv->readMetaData(metaData("testdependencies/spec2.json")); - spec2Priv->state = PluginSpec::Read; // fake read state for plugin resolving + spec2->readMetaData(metaData("testdependencies/spec2.json")); + spec2->setState(PluginSpec::Read); // fake read state for plugin resolving - PluginSpec *spec3 = Internal::PluginManagerPrivate::createSpec(); + PluginSpec *spec3 = new CppPluginSpec(); specs.append(spec3); - Internal::PluginSpecPrivate *spec3Priv = Internal::PluginManagerPrivate::privateSpec(spec3); - spec3Priv->readMetaData(metaData("testdependencies/spec3.json")); - spec3Priv->state = PluginSpec::Read; // fake read state for plugin resolving + spec3->readMetaData(metaData("testdependencies/spec3.json")); + spec3->setState(PluginSpec::Read); // fake read state for plugin resolving - PluginSpec *spec4 = Internal::PluginManagerPrivate::createSpec(); + PluginSpec *spec4 = new CppPluginSpec(); specs.append(spec4); - Internal::PluginSpecPrivate *spec4Priv = Internal::PluginManagerPrivate::privateSpec(spec4); - spec4Priv->readMetaData(metaData("testdependencies/spec4.json")); - spec4Priv->state = PluginSpec::Read; // fake read state for plugin resolving + spec4->readMetaData(metaData("testdependencies/spec4.json")); + spec4->setState(PluginSpec::Read); // fake read state for plugin resolving - PluginSpec *spec5 = Internal::PluginManagerPrivate::createSpec(); + PluginSpec *spec5 = new CppPluginSpec(); specs.append(spec5); - Internal::PluginSpecPrivate *spec5Priv = Internal::PluginManagerPrivate::privateSpec(spec5); - spec5Priv->readMetaData(metaData("testdependencies/spec5.json")); - spec5Priv->state = PluginSpec::Read; // fake read state for plugin resolving - - QVERIFY(spec1Priv->resolveDependencies(specs)); - QCOMPARE(spec1Priv->dependencySpecs.size(), 2); - QVERIFY(!spec1Priv->dependencySpecs.key(spec2).name.isEmpty()); - QVERIFY(!spec1Priv->dependencySpecs.key(spec3).name.isEmpty()); - QCOMPARE(spec1Priv->state, PluginSpec::Resolved); - QVERIFY(!spec4Priv->resolveDependencies(specs)); - QVERIFY(spec4Priv->hasError); - QCOMPARE(spec4Priv->state, PluginSpec::Read); + spec5->readMetaData(metaData("testdependencies/spec5.json")); + spec5->setState(PluginSpec::Read); // fake read state for plugin resolving + + QVERIFY(spec1->resolveDependencies(specs)); + QCOMPARE(spec1->dependencySpecs().size(), 2); + QVERIFY(!spec1->dependencySpecs().key(spec2).name.isEmpty()); + QVERIFY(!spec1->dependencySpecs().key(spec3).name.isEmpty()); + QCOMPARE(spec1->state(), PluginSpec::Resolved); + QVERIFY(!spec4->resolveDependencies(specs)); + QVERIFY(spec4->hasError()); + QCOMPARE(spec4->state(), PluginSpec::Read); } void tst_PluginSpec::loadLibrary() { - PluginSpec *ps = Internal::PluginManagerPrivate::createSpec(); - Internal::PluginSpecPrivate *spec = Internal::PluginManagerPrivate::privateSpec(ps); - QVERIFY(spec->read(QLatin1String(PLUGIN_DIR) + QLatin1String("/testplugin/") + libraryName(QLatin1String("test")))); - QVERIFY(spec->resolveDependencies(QVector<PluginSpec *>())); - QVERIFY2(spec->loadLibrary(), qPrintable(spec->errorString)); - QVERIFY(spec->plugin != 0); - QVERIFY(QLatin1String(spec->plugin->metaObject()->className()) == QLatin1String("MyPlugin::MyPluginImpl")); - QCOMPARE(spec->state, PluginSpec::Loaded); - QVERIFY(!spec->hasError); - QCOMPARE(spec->plugin, ps->plugin()); - delete ps; + Utils::expected_str<PluginSpec *> ps = readCppPluginSpec( + PLUGIN_DIR_PATH / "testplugin" / libraryName(QLatin1String("test"))); + + QVERIFY(ps); + CppPluginSpec *spec = static_cast<CppPluginSpec *>(ps.value()); + + QVERIFY(spec->resolveDependencies({})); + QVERIFY2(spec->loadLibrary(), qPrintable(spec->errorString())); + QVERIFY(spec->plugin() != 0); + QVERIFY(QLatin1String(spec->plugin()->metaObject()->className()) + == QLatin1String("MyPlugin::MyPluginImpl")); + QCOMPARE(spec->state(), PluginSpec::Loaded); + QVERIFY(!spec->hasError()); + + delete *ps; } void tst_PluginSpec::initializePlugin() { - Internal::PluginSpecPrivate spec(0); - QVERIFY(spec.read(QLatin1String(PLUGIN_DIR) + QLatin1String("/testplugin/") + libraryName(QLatin1String("test")))); - QVERIFY(spec.resolveDependencies(QVector<PluginSpec *>())); - QVERIFY2(spec.loadLibrary(), qPrintable(spec.errorString)); + Utils::expected_str<PluginSpec *> ps = readCppPluginSpec( + PLUGIN_DIR_PATH / "testplugin" / libraryName(QLatin1String("test"))); + QVERIFY(ps); + CppPluginSpec *spec = static_cast<CppPluginSpec *>(ps.value()); + QVERIFY(spec->resolveDependencies({})); + QVERIFY2(spec->loadLibrary(), qPrintable(spec->errorString())); bool isInitialized; - QMetaObject::invokeMethod(spec.plugin, "isInitialized", - Qt::DirectConnection, Q_RETURN_ARG(bool, isInitialized)); + QMetaObject::invokeMethod(spec->plugin(), + "isInitialized", + Qt::DirectConnection, + Q_RETURN_ARG(bool, isInitialized)); QVERIFY(!isInitialized); - QVERIFY(spec.initializePlugin()); - QCOMPARE(spec.state, PluginSpec::Initialized); - QVERIFY(!spec.hasError); - QMetaObject::invokeMethod(spec.plugin, "isInitialized", - Qt::DirectConnection, Q_RETURN_ARG(bool, isInitialized)); + QVERIFY(spec->initializePlugin()); + QCOMPARE(spec->state(), PluginSpec::Initialized); + QVERIFY(!spec->hasError()); + QMetaObject::invokeMethod(spec->plugin(), + "isInitialized", + Qt::DirectConnection, + Q_RETURN_ARG(bool, isInitialized)); QVERIFY(isInitialized); } void tst_PluginSpec::initializeExtensions() { - Internal::PluginSpecPrivate spec(0); - QVERIFY(spec.read(QLatin1String(PLUGIN_DIR) + QLatin1String("/testplugin/") + libraryName(QLatin1String("test")))); - QVERIFY(spec.resolveDependencies(QVector<PluginSpec *>())); - QVERIFY2(spec.loadLibrary(), qPrintable(spec.errorString)); + Utils::expected_str<PluginSpec *> ps = readCppPluginSpec( + PLUGIN_DIR_PATH / "testplugin" / libraryName(QLatin1String("test"))); + QVERIFY(ps); + CppPluginSpec *spec = static_cast<CppPluginSpec *>(ps.value()); + QVERIFY(spec->resolveDependencies({})); + QVERIFY2(spec->loadLibrary(), qPrintable(spec->errorString())); bool isExtensionsInitialized; - QVERIFY(spec.initializePlugin()); - QMetaObject::invokeMethod(spec.plugin, "isExtensionsInitialized", - Qt::DirectConnection, Q_RETURN_ARG(bool, isExtensionsInitialized)); + QVERIFY(spec->initializePlugin()); + QMetaObject::invokeMethod(spec->plugin(), + "isExtensionsInitialized", + Qt::DirectConnection, + Q_RETURN_ARG(bool, isExtensionsInitialized)); QVERIFY(!isExtensionsInitialized); - QVERIFY(spec.initializeExtensions()); - QCOMPARE(spec.state, PluginSpec::Running); - QVERIFY(!spec.hasError); - QMetaObject::invokeMethod(spec.plugin, "isExtensionsInitialized", - Qt::DirectConnection, Q_RETURN_ARG(bool, isExtensionsInitialized)); + QVERIFY(spec->initializeExtensions()); + QCOMPARE(spec->state(), PluginSpec::Running); + QVERIFY(!spec->hasError()); + QMetaObject::invokeMethod(spec->plugin(), + "isExtensionsInitialized", + Qt::DirectConnection, + Q_RETURN_ARG(bool, isExtensionsInitialized)); QVERIFY(isExtensionsInitialized); } diff --git a/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp b/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp index 9be03d2261..d37b639cd0 100644 --- a/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp +++ b/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp @@ -149,6 +149,7 @@ public: QString defaultPuppetToplevelBuildDirectory() const override { return {}; } QString qmlPuppetFallbackDirectory() const override { return {}; } QUrl projectUrl() const override { return {}; } + QString projectName() const override { return {}; } void parseItemLibraryDescriptions() override {} const QmlDesigner::DesignerSettings &designerSettings() const override { return settings; } void undoOnCurrentDesignDocument() override {} @@ -182,8 +183,11 @@ ModelPointer createModel(const QString &typeName, { QApplication::processEvents(); +#ifdef QDS_USE_PROJECTSTORAGE + auto model = metaInfoPropxyModel->createModel(typeName.toUtf8()); +#else auto model = QmlDesigner::Model::create(typeName.toUtf8(), major, minor, metaInfoPropxyModel); - +#endif QPlainTextEdit *textEdit = new QPlainTextEdit; QObject::connect(model.get(), &QObject::destroyed, textEdit, &QObject::deleteLater); textEdit->setPlainText(QString("import %1 %3.%4; %2{}") @@ -695,17 +699,17 @@ void tst_TestCore::testRewriterDynamicProperties() QCOMPARE(rootModelNode.properties().count(), 18); QVERIFY(rootModelNode.hasVariantProperty("i")); QCOMPARE(rootModelNode.variantProperty("i").dynamicTypeName(), QmlDesigner::TypeName("int")); - QCOMPARE(rootModelNode.variantProperty("i").value().type(), QVariant::Int); + QCOMPARE(rootModelNode.variantProperty("i").value().typeId(), QMetaType::Int); QCOMPARE(testRewriterView1->rootModelNode().variantProperty("i").value().toInt(), 0); QVERIFY(rootModelNode.hasVariantProperty("ii")); QCOMPARE(rootModelNode.variantProperty("ii").dynamicTypeName(), QmlDesigner::TypeName("int")); - QCOMPARE(rootModelNode.variantProperty("ii").value().type(), QVariant::Int); + QCOMPARE(rootModelNode.variantProperty("ii").value().typeId(), QMetaType::Int); QCOMPARE(testRewriterView1->rootModelNode().variantProperty("ii").value().toInt(), 1); QVERIFY(rootModelNode.hasVariantProperty("b")); QCOMPARE(rootModelNode.variantProperty("b").dynamicTypeName(), QmlDesigner::TypeName("bool")); - QCOMPARE(rootModelNode.variantProperty("b").value().type(), QVariant::Bool); + QCOMPARE(rootModelNode.variantProperty("b").value().typeId(), QMetaType::Bool); QCOMPARE(testRewriterView1->rootModelNode().variantProperty("b").value().toBool(), false); QVERIFY(rootModelNode.hasVariantProperty("bb")); @@ -713,7 +717,7 @@ void tst_TestCore::testRewriterDynamicProperties() QVERIFY(rootModelNode.hasVariantProperty("d")); QCOMPARE(rootModelNode.variantProperty("d").dynamicTypeName(), QmlDesigner::TypeName("double")); - QCOMPARE(rootModelNode.variantProperty("d").value().type(), QVariant::Double); + QCOMPARE(rootModelNode.variantProperty("d").value().typeId(), QMetaType::Double); QCOMPARE(testRewriterView1->rootModelNode().variantProperty("d").value().toDouble(), 0.0); QVERIFY(rootModelNode.hasVariantProperty("dd")); @@ -721,7 +725,7 @@ void tst_TestCore::testRewriterDynamicProperties() QVERIFY(rootModelNode.hasVariantProperty("r")); QCOMPARE(rootModelNode.variantProperty("r").dynamicTypeName(), QmlDesigner::TypeName("real")); - QCOMPARE(rootModelNode.variantProperty("r").value().type(), QVariant::Double); + QCOMPARE(rootModelNode.variantProperty("r").value().typeId(), QMetaType::Double); QCOMPARE(testRewriterView1->rootModelNode().variantProperty("r").value().toDouble(), 0.0); QVERIFY(rootModelNode.hasVariantProperty("rr")); @@ -729,7 +733,7 @@ void tst_TestCore::testRewriterDynamicProperties() QVERIFY(rootModelNode.hasVariantProperty("s")); QCOMPARE(rootModelNode.variantProperty("s").dynamicTypeName(), QmlDesigner::TypeName("string")); - QCOMPARE(rootModelNode.variantProperty("s").value().type(), QVariant::String); + QCOMPARE(rootModelNode.variantProperty("s").value().typeId(), QMetaType::QString); QCOMPARE(testRewriterView1->rootModelNode().variantProperty("s").value().toString(), QString()); QVERIFY(rootModelNode.hasVariantProperty("ss")); @@ -737,7 +741,7 @@ void tst_TestCore::testRewriterDynamicProperties() QVERIFY(rootModelNode.hasVariantProperty("u")); QCOMPARE(rootModelNode.variantProperty("u").dynamicTypeName(), QmlDesigner::TypeName("url")); - QCOMPARE(rootModelNode.variantProperty("u").value().type(), QVariant::Url); + QCOMPARE(rootModelNode.variantProperty("u").value().typeId(), QMetaType::QUrl); QCOMPARE(testRewriterView1->rootModelNode().variantProperty("u").value().toUrl(), QUrl()); QVERIFY(rootModelNode.hasVariantProperty("uu")); @@ -745,7 +749,7 @@ void tst_TestCore::testRewriterDynamicProperties() QVERIFY(rootModelNode.hasVariantProperty("c")); QCOMPARE(rootModelNode.variantProperty("c").dynamicTypeName(), QmlDesigner::TypeName("color")); - QCOMPARE(rootModelNode.variantProperty("c").value().type(), QVariant::Color); + QCOMPARE(rootModelNode.variantProperty("c").value().typeId(), QMetaType::QColor); QCOMPARE(testRewriterView1->rootModelNode().variantProperty("c").value().value<QColor>(), QColor()); QVERIFY(rootModelNode.hasVariantProperty("cc")); @@ -753,7 +757,7 @@ void tst_TestCore::testRewriterDynamicProperties() QVERIFY(rootModelNode.hasVariantProperty("t")); QCOMPARE(rootModelNode.variantProperty("t").dynamicTypeName(), QmlDesigner::TypeName("date")); - QCOMPARE(rootModelNode.variantProperty("t").value().type(), QVariant::Date); + QCOMPARE(rootModelNode.variantProperty("t").value().typeId(), QMetaType::QDate); QCOMPARE(testRewriterView1->rootModelNode().variantProperty("t").value().value<QDate>(), QDate()); QVERIFY(rootModelNode.hasVariantProperty("tt")); @@ -761,8 +765,8 @@ void tst_TestCore::testRewriterDynamicProperties() QVERIFY(rootModelNode.hasVariantProperty("v")); QCOMPARE(rootModelNode.variantProperty("v").dynamicTypeName(), QmlDesigner::TypeName("variant")); - const int type = rootModelNode.variantProperty("v").value().type(); - QCOMPARE(type, QMetaType::type("QVariant")); + const int type = rootModelNode.variantProperty("v").value().typeId(); + QCOMPARE(type, QMetaType::fromName("QVariant").id()); QVERIFY(rootModelNode.hasVariantProperty("vv")); const QString inThere = testRewriterView1->rootModelNode().variantProperty("vv").value().value<QString>(); @@ -1365,6 +1369,14 @@ void tst_TestCore::testRewriterBehaivours() QVERIFY(metaInfo.isValid()); +#ifdef QDS_USE_PROJECTSTORAGE + ModelNode newBehavior = testRewriterView->createModelNode("Behavior", + {}, + {}, + {}, + ModelNode::NodeWithoutSource, + "height"); +#else ModelNode newBehavior = testRewriterView->createModelNode("QtQuick.Behavior", metaInfo.majorVersion(), metaInfo.minorVersion(), @@ -1373,17 +1385,20 @@ void tst_TestCore::testRewriterBehaivours() {}, ModelNode::NodeWithoutSource, "height"); - +#endif rootModelNode.defaultNodeListProperty().reparentHere(newBehavior); QCOMPARE(newBehavior.behaviorPropertyName(), "height"); metaInfo = animation.metaInfo(); QVERIFY(metaInfo.isValid()); +#ifdef QDS_USE_PROJECTSTORAGE + ModelNode newAnimation = testRewriterView->createModelNode(model->exportedTypeNameForMetaInfo(metaInfo).name.toQByteArray()); +#else ModelNode newAnimation = testRewriterView->createModelNode(metaInfo.typeName(), metaInfo.majorVersion(), metaInfo.minorVersion()); - +#endif newBehavior.defaultNodeListProperty().reparentHere(newAnimation); newAnimation.variantProperty("duration").setValue(500); @@ -1666,8 +1681,10 @@ void tst_TestCore::testStatesVersionFailing() QCOMPARE(QmlItemNode(rootModelNode).states().state("state2"), newState); +#ifndef QDS_USE_PROJECTSTORAGE QCOMPARE(stateInfo.majorVersion(), newState.modelNode().majorVersion()); QCOMPARE(stateInfo.minorVersion(), newState.modelNode().minorVersion()); +#endif ModelNode rect1Node = view->modelNodeForId("rect1"); QVERIFY(rect1Node.isValid()); @@ -1708,8 +1725,10 @@ void tst_TestCore::testStatesVersionFailing() QVERIFY(changes2.modelNode().hasProperty("x")); QVERIFY(oldText != textEdit.toPlainText()); +#ifndef QDS_USE_PROJECTSTORAGE QCOMPARE(changeInfo.majorVersion(), changes2.modelNode().majorVersion()); QCOMPARE(changeInfo.minorVersion(), changes2.modelNode().minorVersion()); +#endif } void tst_TestCore::loadSubItems() @@ -1987,8 +2006,10 @@ void tst_TestCore::testBasicStatesQtQuick20() QCOMPARE(rootModelNode.majorVersion(), 2); //QCOMPARE(rootModelNode.majorQtQuickVersion(), 2); +#ifndef QDS_USE_PROJECTSTORAGE qDebug() << rootModelNode.nodeListProperty("states").toModelNodeList().first().metaInfo().majorVersion(); qDebug() << rootModelNode.nodeListProperty("states").toModelNodeList().first().metaInfo().typeName(); +#endif QSKIP("No qml2puppet"); @@ -3852,8 +3873,8 @@ void tst_TestCore::testRewriterPreserveType() QCOMPARE(rootNode.type(), QmlDesigner::TypeName("QtQuick.Rectangle")); ModelNode textNode = rootNode.directSubModelNodes().first(); - QCOMPARE(QVariant::Bool, textNode.variantProperty("font.bold").value().type()); - QCOMPARE(QVariant::Double, textNode.variantProperty("font.pointSize").value().type()); + QCOMPARE(QMetaType::Bool, textNode.variantProperty("font.bold").value().typeId()); + QCOMPARE(QMetaType::Double, textNode.variantProperty("font.pointSize").value().typeId()); textNode.variantProperty("font.bold").setValue(QVariant(false)); textNode.variantProperty("font.bold").setValue(QVariant(true)); textNode.variantProperty("font.pointSize").setValue(QVariant(13.0)); @@ -3863,8 +3884,8 @@ void tst_TestCore::testRewriterPreserveType() newTextNode.variantProperty("font.bold").setValue(QVariant(true)); newTextNode.variantProperty("font.pointSize").setValue(QVariant(13.0)); - QCOMPARE(QVariant::Bool, newTextNode.variantProperty("font.bold").value().type()); - QCOMPARE(QVariant::Double, newTextNode.variantProperty("font.pointSize").value().type()); + QCOMPARE(QMetaType::Bool, newTextNode.variantProperty("font.bold").value().typeId()); + QCOMPARE(QMetaType::Double, newTextNode.variantProperty("font.pointSize").value().typeId()); } void tst_TestCore::testRewriterForArrayMagic() @@ -4833,9 +4854,11 @@ void tst_TestCore::testMetaInfoSimpleType() NodeMetaInfo itemMetaInfo = model->metaInfo("QtQuick.Item", 2, 1); QVERIFY(itemMetaInfo.isValid()); +#ifndef QDS_USE_PROJECTSTORAGE QCOMPARE(itemMetaInfo.typeName(), QmlDesigner::TypeName("QtQuick.Item")); QCOMPARE(itemMetaInfo.majorVersion(), 2); QCOMPARE(itemMetaInfo.minorVersion(), 1); +#endif // super classes NodeMetaInfo qobject = itemMetaInfo.prototypes()[1]; @@ -4857,13 +4880,17 @@ void tst_TestCore::testMetaInfoUncreatableType() QVERIFY(animationTypeInfo.isValid()); QVERIFY(animationTypeInfo.isValid()); +#ifndef QDS_USE_PROJECTSTORAGE QCOMPARE(animationTypeInfo.typeName(), QmlDesigner::TypeName("QtQuick.Animation")); QCOMPARE(animationTypeInfo.majorVersion(), 2); QCOMPARE(animationTypeInfo.minorVersion(), 1); +#endif NodeMetaInfo qObjectTypeInfo = animationTypeInfo.prototypes()[1]; QVERIFY(qObjectTypeInfo.isValid()); +#ifndef QDS_USE_PROJECTSTORAGE QCOMPARE(qObjectTypeInfo.simplifiedTypeName(), QmlDesigner::TypeName("QtObject")); +#endif QCOMPARE(animationTypeInfo.prototypes().size(), 2); } @@ -4903,9 +4930,11 @@ void tst_TestCore::testMetaInfoCustomType() NodeMetaInfo stateOperationInfo = propertyChangesInfo.prototypes()[1]; QVERIFY(stateOperationInfo.isValid()); +#ifndef QDS_USE_PROJECTSTORAGE QCOMPARE(stateOperationInfo.typeName(), QmlDesigner::TypeName("QtQuick.QQuickStateOperation")); QCOMPARE(stateOperationInfo.majorVersion(), -1); QCOMPARE(stateOperationInfo.minorVersion(), -1); +#endif QCOMPARE(propertyChangesInfo.prototypes().size(), 3); // DeclarativePropertyChanges just has 3 properties @@ -4923,25 +4952,31 @@ void tst_TestCore::testMetaInfoEnums() QVERIFY(view.data()); model->attachView(view.data()); +#ifndef QDS_USE_PROJECTSTORAGE QCOMPARE(view->rootModelNode().metaInfo().typeName(), QmlDesigner::TypeName("QtQuick.Text")); +#endif QVERIFY(view->rootModelNode().metaInfo().hasProperty("transformOrigin")); QVERIFY(view->rootModelNode().metaInfo().property("transformOrigin").isEnumType()); +#ifndef QDS_USE_PROJECTSTORAGE QCOMPARE(view->rootModelNode() .metaInfo() .property("transformOrigin") .propertyType() .simplifiedTypeName(), QmlDesigner::TypeName("TransformOrigin")); +#endif QVERIFY(view->rootModelNode().metaInfo().property("horizontalAlignment").isEnumType()); +#ifndef QDS_USE_PROJECTSTORAGE QCOMPARE(view->rootModelNode() .metaInfo() .property("horizontalAlignment") .propertyType() .simplifiedTypeName(), QmlDesigner::TypeName("HAlignment")); +#endif QApplication::processEvents(); } @@ -5038,10 +5073,12 @@ void tst_TestCore::testMetaInfoDotProperties() QVERIFY(model->hasNodeMetaInfo("QtQuick.Text")); QVERIFY(model->metaInfo("QtQuick.Rectangle").hasProperty("border")); +#ifndef QDS_USE_PROJECTSTORAGE QCOMPARE(model->metaInfo("QtQuick.Rectangle").property("border").propertyType().typeName(), QmlDesigner::TypeName("<cpp>.QQuickPen")); QCOMPARE(view->rootModelNode().metaInfo().typeName(), QmlDesigner::TypeName("QtQuick.Text")); +#endif QVERIFY(view->rootModelNode().metaInfo().hasProperty("font")); QVERIFY(view->rootModelNode().metaInfo().hasProperty("font.bold")); @@ -5071,7 +5108,9 @@ void tst_TestCore::testMetaInfoListProperties() model->attachView(view.data()); QVERIFY(model->hasNodeMetaInfo("QtQuick.Item")); +#ifndef QDS_USE_PROJECTSTORAGE QCOMPARE(view->rootModelNode().metaInfo().typeName(), QmlDesigner::TypeName("QtQuick.Item")); +#endif QVERIFY(view->rootModelNode().metaInfo().hasProperty("states")); QVERIFY(view->rootModelNode().metaInfo().property("states").isListProperty()); @@ -5108,10 +5147,12 @@ void tst_TestCore::testQtQuick20Basic() QVERIFY(testRewriterView->errors().isEmpty()); ModelNode rootModelNode(testRewriterView->rootModelNode()); QVERIFY(rootModelNode.isValid()); +#ifndef QDS_USE_PROJECTSTORAGE QCOMPARE(rootModelNode.metaInfo().majorVersion(), 2); QCOMPARE(rootModelNode.metaInfo().minorVersion(), 0); //QCOMPARE(rootModelNode.majorQtQuickVersion(), 2); QCOMPARE(rootModelNode.majorVersion(), 2); +#endif } void tst_TestCore::testQtQuick20BasicRectangle() @@ -5133,11 +5174,13 @@ void tst_TestCore::testQtQuick20BasicRectangle() QVERIFY(testRewriterView->errors().isEmpty()); ModelNode rootModelNode(testRewriterView->rootModelNode()); QVERIFY(rootModelNode.isValid()); +#ifndef QDS_USE_PROJECTSTORAGE QCOMPARE(rootModelNode.type(), QmlDesigner::TypeName("QtQuick.Rectangle")); QCOMPARE(rootModelNode.metaInfo().majorVersion(), 2); QCOMPARE(rootModelNode.metaInfo().minorVersion(), 0); //QCOMPARE(rootModelNode.majorQtQuickVersion(), 2); QCOMPARE(rootModelNode.majorVersion(), 2); +#endif } void tst_TestCore::testQtQuickControls2() @@ -6915,9 +6958,9 @@ void tst_TestCore::testModelPropertyValueTypes() ModelNode rootModelNode(testRewriterView1->rootModelNode()); QVERIFY(rootModelNode.isValid()); - QCOMPARE(rootModelNode.variantProperty("width").value().type(), QVariant::Double); - QCOMPARE(rootModelNode.variantProperty("radius").value().type(), QVariant::Double); - QCOMPARE(rootModelNode.variantProperty("color").value().type(), QVariant::Color); + QCOMPARE(rootModelNode.variantProperty("width").value().typeId(), QMetaType::Double); + QCOMPARE(rootModelNode.variantProperty("radius").value().typeId(), QMetaType::Double); + QCOMPARE(rootModelNode.variantProperty("color").value().typeId(), QMetaType::QColor); } void tst_TestCore::testModelNodeInHierarchy() @@ -8921,18 +8964,18 @@ void tst_TestCore::loadGradient() QCOMPARE(pOne.id(), QString("pOne")); QCOMPARE(pOne.directSubModelNodes().size(), 0); QCOMPARE(pOne.propertyNames().size(), 2); - QCOMPARE(pOne.variantProperty("position").value().type(), QVariant::Double); + QCOMPARE(pOne.variantProperty("position").value().typeId(), QMetaType::Double); QCOMPARE(pOne.variantProperty("position").value().toDouble(), 0.0); - QCOMPARE(pOne.variantProperty("color").value().type(), QVariant::Color); + QCOMPARE(pOne.variantProperty("color").value().typeId(), QMetaType::QColor); QCOMPARE(pOne.variantProperty("color").value().value<QColor>(), QColor("lightsteelblue")); QCOMPARE(pTwo.type(), QmlDesigner::TypeName("QtQuick.GradientStop")); QCOMPARE(pTwo.id(), QString("pTwo")); QCOMPARE(pTwo.directSubModelNodes().size(), 0); QCOMPARE(pTwo.propertyNames().size(), 2); - QCOMPARE(pTwo.variantProperty("position").value().type(), QVariant::Double); + QCOMPARE(pTwo.variantProperty("position").value().typeId(), QMetaType::Double); QCOMPARE(pTwo.variantProperty("position").value().toDouble(), 1.0); - QCOMPARE(pTwo.variantProperty("color").value().type(), QVariant::Color); + QCOMPARE(pTwo.variantProperty("color").value().typeId(), QMetaType::QColor); QCOMPARE(pTwo.variantProperty("color").value().value<QColor>(), QColor("blue")); } @@ -8961,18 +9004,18 @@ void tst_TestCore::loadGradient() QCOMPARE(nOne.id(), QString("nOne")); QCOMPARE(nOne.directSubModelNodes().size(), 0); QCOMPARE(nOne.propertyNames().size(), 2); - QCOMPARE(nOne.variantProperty("position").value().type(), QVariant::Double); + QCOMPARE(nOne.variantProperty("position").value().typeId(), QMetaType::Double); QCOMPARE(nOne.variantProperty("position").value().toDouble(), 0.0); - QCOMPARE(nOne.variantProperty("color").value().type(), QVariant::Color); + QCOMPARE(nOne.variantProperty("color").value().typeId(), QMetaType::QColor); QCOMPARE(nOne.variantProperty("color").value().value<QColor>(), QColor("blue")); QCOMPARE(nTwo.type(), QmlDesigner::TypeName("QtQuick.GradientStop")); QCOMPARE(nTwo.id(), QString("nTwo")); QCOMPARE(nTwo.directSubModelNodes().size(), 0); QCOMPARE(nTwo.propertyNames().size(), 2); - QCOMPARE(nTwo.variantProperty("position").value().type(), QVariant::Double); + QCOMPARE(nTwo.variantProperty("position").value().typeId(), QMetaType::Double); QCOMPARE(nTwo.variantProperty("position").value().toDouble(), 1.0); - QCOMPARE(nTwo.variantProperty("color").value().type(), QVariant::Color); + QCOMPARE(nTwo.variantProperty("color").value().typeId(), QMetaType::QColor); QCOMPARE(nTwo.variantProperty("color").value().value<QColor>(), QColor("lightsteelblue")); } } diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index ee1972c061..db293d4ebf 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -117,6 +117,7 @@ private slots: void storageIO(); void storageOperators(); void storageDestructor(); + void storageZeroInitialization(); void restart(); void destructorOfTaskEmittingDone(); }; @@ -3083,6 +3084,41 @@ void tst_Tasking::testTree_data() logErrorLong, 1, DoneWith::Error, 1}; } + { + // This tests ensures the task done handlers are invoked in a different order + // than the corresponding setup handlers. + + const QList<milliseconds> tasks { 1000000ms, 0ms }; + const LoopList iterator(tasks); + + const auto onSetup = [storage, iterator](TaskObject &taskObject) { + taskObject = *iterator; + storage->m_log.append({iterator.iteration(), Handler::Setup}); + }; + + const auto onDone = [storage, iterator](DoneWith result) { + const Handler handler = result == DoneWith::Cancel ? Handler::Canceled : Handler::Error; + storage->m_log.append({iterator.iteration(), handler}); + return DoneResult::Error; + }; + + const Group root { + storage, + parallel, + iterator, + TestTask(onSetup, onDone) + }; + + const Log log { + {0, Handler::Setup}, + {1, Handler::Setup}, + {1, Handler::Error}, + {0, Handler::Canceled} + }; + + QTest::newRow("ParallelDisorder") << TestData{storage, root, log, 2, DoneWith::Error, 1}; + } + // This test checks if storage shadowing works OK. QTest::newRow("StorageShadowing") << storageShadowingData(); } @@ -3380,7 +3416,7 @@ void tst_Tasking::storageDestructor() }; QCOMPARE(CustomStorage::instanceCount(), 0); { - Storage<CustomStorage> storage; + const Storage<CustomStorage> storage; const auto setupSleepingTask = [](TaskObject &taskObject) { taskObject = 1000ms; }; @@ -3401,6 +3437,21 @@ void tst_Tasking::storageDestructor() QVERIFY(!doneCalled); } +// This test ensures that the storage data is zero-initialized. +void tst_Tasking::storageZeroInitialization() +{ + const Storage<int> storage; + std::optional<int> defaultValue; + + const auto onSetup = [storage, &defaultValue] { defaultValue = *storage; }; + + TaskTree taskTree({ storage, onGroupSetup(onSetup) }); + taskTree.runBlocking(); + + QVERIFY(defaultValue); + QCOMPARE(defaultValue, 0); +} + void tst_Tasking::restart() { TaskTree taskTree({TestTask([](TaskObject &taskObject) { taskObject = 1000ms; })}); diff --git a/tests/auto/texteditor/highlighter/tst_highlighter.cpp b/tests/auto/texteditor/highlighter/tst_highlighter.cpp index 9044065a01..e080638298 100644 --- a/tests/auto/texteditor/highlighter/tst_highlighter.cpp +++ b/tests/auto/texteditor/highlighter/tst_highlighter.cpp @@ -7,7 +7,6 @@ #include <texteditor/semantichighlighter.h> #include <texteditor/syntaxhighlighter.h> -#include <texteditor/syntaxhighlighterrunner.h> #include <texteditor/texteditorsettings.h> #include <QObject> @@ -32,7 +31,7 @@ private slots: private: QTextDocument *doc = nullptr; - SyntaxHighlighterRunner *highlighterRunner = nullptr; + SyntaxHighlighter *highlighter = nullptr; FontSettings fontsettings; QHash<int, QTextCharFormat> formatHash; QTextCharFormat whitespaceFormat; @@ -58,8 +57,7 @@ Last)"; doc = new QTextDocument(); doc->setPlainText(text); - auto highlighter = new SyntaxHighlighter(doc, fontsettings); - highlighterRunner = new SyntaxHighlighterRunner(highlighter, doc, false); + highlighter = new SyntaxHighlighter(doc, fontsettings); } static const HighlightingResults &highlightingResults() @@ -77,7 +75,7 @@ void tst_highlighter::test_setExtraAdditionalFormats() { QCOMPARE(doc->blockCount(), 4); - SemanticHighlighter::setExtraAdditionalFormats(highlighterRunner, highlightingResults(), formatHash); + SemanticHighlighter::setExtraAdditionalFormats(highlighter, highlightingResults(), formatHash); for (auto block = doc->firstBlock(); block.isValid(); block = block.next()) { QVERIFY(block.blockNumber() < 4); @@ -140,17 +138,17 @@ void tst_highlighter::test_clearExtraFormats() { QCOMPARE(doc->blockCount(), 4); - SemanticHighlighter::setExtraAdditionalFormats(highlighterRunner, highlightingResults(), formatHash); + SemanticHighlighter::setExtraAdditionalFormats(highlighter, highlightingResults(), formatHash); QTextBlock firstBlock = doc->findBlockByNumber(0); QTextBlock spacesLineBlock = doc->findBlockByNumber(1); QTextBlock emptyLineBlock = doc->findBlockByNumber(2); QTextBlock lastBlock = doc->findBlockByNumber(3); - highlighterRunner->clearExtraFormats({emptyLineBlock.blockNumber()}); + highlighter->clearExtraFormats(emptyLineBlock); QVERIFY(emptyLineBlock.layout()->formats().isEmpty()); - highlighterRunner->clearExtraFormats({spacesLineBlock.blockNumber()}); + highlighter->clearExtraFormats(spacesLineBlock); auto formats = spacesLineBlock.layout()->formats(); // the spaces are not extra formats and should remain when clearing extra formats @@ -185,7 +183,7 @@ void tst_highlighter::test_clearExtraFormats() QCOMPARE(formats.at(1).start, 0); QCOMPARE(formats.at(1).length, 5); - highlighterRunner->clearAllExtraFormats(); + highlighter->clearAllExtraFormats(); QVERIFY(firstBlock.layout()->formats().isEmpty()); QVERIFY(emptyLineBlock.layout()->formats().isEmpty()); @@ -221,7 +219,7 @@ void tst_highlighter::test_incrementalApplyAdditionalFormats() QFutureInterface<HighlightingResult> fiOld; fiOld.reportResults(highlightingResults()); - SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighterRunner, + SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighter, fiOld.future(), 2, 0, @@ -229,7 +227,7 @@ void tst_highlighter::test_incrementalApplyAdditionalFormats() auto formats = firstBlock.layout()->formats(); QVERIFY(formats.isEmpty()); - SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighterRunner, + SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighter, fiOld.future(), 0, 2, @@ -254,7 +252,7 @@ void tst_highlighter::test_incrementalApplyAdditionalFormats() QCOMPARE(formats.at(1).start, 11); QCOMPARE(formats.at(1).length, 1); - SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighterRunner, + SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighter, fiOld.future(), 3, 6, @@ -280,7 +278,7 @@ void tst_highlighter::test_incrementalApplyAdditionalFormats() QFutureInterface<HighlightingResult> fiNew; fiNew.reportResults(newResults); - SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighterRunner, + SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighter, fiNew.future(), 0, 3, @@ -294,7 +292,7 @@ void tst_highlighter::test_incrementalApplyAdditionalFormats() QCOMPARE(formats.at(0).start, 0); QCOMPARE(formats.at(0).length, 1); - SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighterRunner, + SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighter, fiNew.future(), 3, 4, @@ -305,14 +303,14 @@ void tst_highlighter::test_incrementalApplyAdditionalFormats() QVERIFY(formats.isEmpty()); // QTCREATORBUG-29218 - highlighterRunner->clearAllExtraFormats(); + highlighter->clearAllExtraFormats(); const HighlightingResults bug29218Results{HighlightingResult(1, 1, 2, 0), HighlightingResult(1, 3, 2, 1)}; QFutureInterface<HighlightingResult> fi29218; fi29218.reportResults(bug29218Results); formats = firstBlock.layout()->formats(); QVERIFY(formats.isEmpty()); - SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighterRunner, + SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighter, fi29218.future(), 0, 1, @@ -323,7 +321,7 @@ void tst_highlighter::test_incrementalApplyAdditionalFormats() QCOMPARE(formats.at(0).format.fontOverline(), false); QCOMPARE(formats.at(0).start, 0); QCOMPARE(formats.at(0).length, 2); - SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighterRunner, + SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighter, fi29218.future(), 1, 2, @@ -347,7 +345,7 @@ void tst_highlighter::test_preeditText() QTextBlock firstBlock = doc->findBlockByNumber(0); firstBlock.layout()->setPreeditArea(2, "uaf"); - SemanticHighlighter::setExtraAdditionalFormats(highlighterRunner, highlightingResults(), formatHash); + SemanticHighlighter::setExtraAdditionalFormats(highlighter, highlightingResults(), formatHash); auto formats = firstBlock.layout()->formats(); QCOMPARE(formats.size(), 2); @@ -366,7 +364,7 @@ void tst_highlighter::cleanup() { delete doc; doc = nullptr; - highlighterRunner = nullptr; + highlighter = nullptr; } } // namespace TextEditor diff --git a/tests/auto/utils/async/tst_async.cpp b/tests/auto/utils/async/tst_async.cpp index e25a443cce..1c3f7a19f2 100644 --- a/tests/auto/utils/async/tst_async.cpp +++ b/tests/auto/utils/async/tst_async.cpp @@ -392,8 +392,7 @@ public: void tst_Async::onResultReady() { -// TODO: Re-enable when QTBUG-119169 is fixed. -#if 0 +#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0) { // lambda QObject context; QFuture<QString> f = Utils::asyncRun([](QPromise<QString> &fi) { diff --git a/tests/auto/utils/commandline/tst_commandline.cpp b/tests/auto/utils/commandline/tst_commandline.cpp index 1c7b7d4f80..aca984adf5 100644 --- a/tests/auto/utils/commandline/tst_commandline.cpp +++ b/tests/auto/utils/commandline/tst_commandline.cpp @@ -8,7 +8,7 @@ #include <utils/hostosinfo.h> #include <utils/launcherinterface.h> #include <utils/macroexpander.h> -#include <utils/process.h> +#include <utils/qtcprocess.h> #include <utils/processinterface.h> #include <utils/temporarydirectory.h> @@ -125,6 +125,31 @@ private slots: QCOMPARE(actual, expected); } + void testConstructor_data() + { + QTest::addColumn<CommandLine>("command"); + QTest::addColumn<FilePath>("executable"); + QTest::addColumn<QStringList>("arguments"); + + const FilePath filePath("some_path"); + const QString arg("-arg"); + const QStringList args{"-a", "-b", "-c"}; + + QTest::newRow("mixed-strings") << CommandLine{filePath, {"-A", arg, args}} + << filePath << (QStringList{"-A"} << arg << args); + } + + void testConstructor() + { + QFETCH(CommandLine, command); + QFETCH(FilePath, executable); + QFETCH(QStringList, arguments); + + QCOMPARE(command.executable(), executable); + QCOMPARE(command.arguments(), arguments.join(' ')); + QCOMPARE(command.splitArguments(), arguments); + } + void testFromUserInput_data() { QTest::addColumn<QString>("input"); diff --git a/tests/auto/utils/deviceshell/tst_deviceshell.cpp b/tests/auto/utils/deviceshell/tst_deviceshell.cpp index 6e081495c3..75150add83 100644 --- a/tests/auto/utils/deviceshell/tst_deviceshell.cpp +++ b/tests/auto/utils/deviceshell/tst_deviceshell.cpp @@ -8,7 +8,7 @@ #include <utils/environment.h> #include <utils/hostosinfo.h> #include <utils/launcherinterface.h> -#include <utils/process.h> +#include <utils/qtcprocess.h> #include <utils/temporarydirectory.h> #include <QObject> @@ -111,7 +111,7 @@ private slots: const FilePath executable = Environment::systemEnvironment() .searchInPath(shell, {"/usr/local/bin"}); if (executable.exists()) - m_availableShells.append({executable, {}}); + m_availableShells.append(CommandLine{executable}); } } @@ -210,7 +210,7 @@ private slots: QRandomGenerator generator; - const RunResult result = shell.runInShell({"cat", {}}, testData.toUtf8()); + const RunResult result = shell.runInShell(CommandLine{"cat"}, testData.toUtf8()); QCOMPARE(result.exitCode, 0); const QString resultAsUtf8 = QString::fromUtf8(result.stdOut); QCOMPARE(resultAsUtf8.size(), testData.size()); @@ -236,7 +236,7 @@ private slots: TestShell shell(cmdLine); QCOMPARE(shell.state(), DeviceShell::State::Succeeded); - const RunResult result = shell.runInShell({"cat", {}}, m_asciiTestData); + const RunResult result = shell.runInShell(CommandLine{"cat"}, m_asciiTestData); QCOMPARE(result.stdOut, m_asciiTestData); } @@ -259,7 +259,7 @@ private slots: TestShell shell(cmdLine); QCOMPARE(shell.state(), DeviceShell::State::Succeeded); - const RunResult result = shell.runInShell({"cat", {}}, m_asciiTestData); + const RunResult result = shell.runInShell(CommandLine{"cat"}, m_asciiTestData); QCOMPARE(result.stdOut, m_asciiTestData); QVERIFY(result.stdErr.isEmpty()); diff --git a/tests/auto/utils/persistentsettings/tst_persistentsettings.cpp b/tests/auto/utils/persistentsettings/tst_persistentsettings.cpp index e2fde29909..9890545a7e 100644 --- a/tests/auto/utils/persistentsettings/tst_persistentsettings.cpp +++ b/tests/auto/utils/persistentsettings/tst_persistentsettings.cpp @@ -61,18 +61,18 @@ void PersistentSettingsTest::tst_readwrite() auto found = restored.find(it.key()); QVERIFY(found != restoredEnd); QVERIFY(found.value().isValid()); - if (it.value().type() == QVariant::List) { + if (it.value().typeId() == QMetaType::QVariantList) { const QVariantList origList = it.value().toList(); const QVariantList foundList = found.value().toList(); QCOMPARE(foundList.size(), origList.size()); for (int i = 0, vEnd = foundList.size(); i < vEnd; ++i) { - if (foundList.at(i).type() == QVariant::Rect) + if (foundList.at(i).typeId() == QMetaType::QRect) qDebug() << foundList.at(i).toRect() << origList.at(i).toRect(); QCOMPARE(foundList.at(i), origList.at(i)); } } - if (it.value().type() == QVariant::Rect) + if (it.value().typeId() == QMetaType::QRect) qDebug() << found.value().toRect() << "vs" << it.value().toRect(); QCOMPARE(found.value(), it.value()); } diff --git a/tests/auto/utils/process/processtestapp/main.cpp b/tests/auto/utils/process/processtestapp/main.cpp index 34923c407a..5b0dda04b3 100644 --- a/tests/auto/utils/process/processtestapp/main.cpp +++ b/tests/auto/utils/process/processtestapp/main.cpp @@ -6,7 +6,7 @@ #include <app/app_version.h> #include <utils/launcherinterface.h> -#include <utils/process.h> +#include <utils/qtcprocess.h> #include <utils/temporarydirectory.h> #include <QCoreApplication> diff --git a/tests/auto/utils/process/processtestapp/processtestapp.cpp b/tests/auto/utils/process/processtestapp/processtestapp.cpp index e080b58020..b85cdabede 100644 --- a/tests/auto/utils/process/processtestapp/processtestapp.cpp +++ b/tests/auto/utils/process/processtestapp/processtestapp.cpp @@ -3,7 +3,7 @@ #include "processtestapp.h" -#include <utils/process.h> +#include <utils/qtcprocess.h> #include <QCoreApplication> #include <QDebug> @@ -84,7 +84,7 @@ void SubProcessConfig::setupSubProcess(Process *subProcess) const subProcess->setEnvironment(m_environment); const FilePath filePath = FilePath::fromString(s_pathToProcessTestApp + QLatin1String("/processtestapp")).withExecutableSuffix(); - subProcess->setCommand(CommandLine(filePath, {})); + subProcess->setCommand(CommandLine{filePath}); } void SubProcessConfig::setupSubProcess(QProcess *subProcess) const diff --git a/tests/auto/utils/process/tst_process.cpp b/tests/auto/utils/process/tst_process.cpp index 60f3a72aa6..a1e92edfe2 100644 --- a/tests/auto/utils/process/tst_process.cpp +++ b/tests/auto/utils/process/tst_process.cpp @@ -8,7 +8,7 @@ #include <utils/environment.h> #include <utils/hostosinfo.h> #include <utils/launcherinterface.h> -#include <utils/process.h> +#include <utils/qtcprocess.h> #include <utils/processinfo.h> #include <utils/processinterface.h> #include <utils/qtcassert.h> @@ -114,7 +114,7 @@ private slots: QCOMPARE(qproc.exitCode(), 0); Process proc; - proc.setCommand({envPath, {}}); + proc.setCommand(CommandLine{envPath}); proc.runBlocking(); QCOMPARE(proc.exitCode(), 0); const QByteArray output = proc.rawStdOut() + proc.rawStdErr(); @@ -1138,8 +1138,7 @@ void tst_Process::notRunningAfterStartingNonExistingProgram() QFETCH(ProcessSignalType, signalType); Process process; - process.setCommand({ FilePath::fromString( - "there_is_a_big_chance_that_executable_with_that_name_does_not_exists"), {} }); + process.setCommand(CommandLine{"there_is_a_big_chance_that_executable_with_that_name_does_not_exists"}); int doneCount = 0; QObject::connect(&process, &Process::done, [&process, &doneCount]() { @@ -1556,7 +1555,7 @@ void tst_Process::stdinToShell() QSKIP("Skipping env test on Windows"); Process proc; - proc.setCommand({"sh", {}}); + proc.setCommand(CommandLine{"sh"}); proc.setWriteData("echo hallo"); proc.runBlocking(); @@ -1595,8 +1594,8 @@ void tst_Process::eventLoopMode() { Process process; - process.setCommand({FilePath::fromString( - "there_is_a_big_chance_that_executable_with_that_name_does_not_exists"), {} }); + process.setCommand( + CommandLine{"there_is_a_big_chance_that_executable_with_that_name_does_not_exists"}); process.setProcessImpl(processImpl); process.runBlocking(10s, eventLoopMode); QCOMPARE(process.result(), ProcessResult::StartFailed); diff --git a/tests/cppmodelmanager/testdata_optionalindexing/lib1.cpp b/tests/cppmodelmanager/testdata_optionalindexing/lib1.cpp new file mode 100644 index 0000000000..c6d43676a0 --- /dev/null +++ b/tests/cppmodelmanager/testdata_optionalindexing/lib1.cpp @@ -0,0 +1 @@ +void foo1() {} diff --git a/tests/cppmodelmanager/testdata_optionalindexing/lib1.pro b/tests/cppmodelmanager/testdata_optionalindexing/lib1.pro new file mode 100644 index 0000000000..93241765c5 --- /dev/null +++ b/tests/cppmodelmanager/testdata_optionalindexing/lib1.pro @@ -0,0 +1,3 @@ +TEMPLATE=lib + +SOURCES=lib1.cpp diff --git a/tests/cppmodelmanager/testdata_optionalindexing/lib2.cpp b/tests/cppmodelmanager/testdata_optionalindexing/lib2.cpp new file mode 100644 index 0000000000..a5b73164ec --- /dev/null +++ b/tests/cppmodelmanager/testdata_optionalindexing/lib2.cpp @@ -0,0 +1 @@ +void foo2() {} diff --git a/tests/cppmodelmanager/testdata_optionalindexing/lib2.pro b/tests/cppmodelmanager/testdata_optionalindexing/lib2.pro new file mode 100644 index 0000000000..fc480dbf7c --- /dev/null +++ b/tests/cppmodelmanager/testdata_optionalindexing/lib2.pro @@ -0,0 +1,3 @@ +TEMPLATE=lib + +SOURCES=lib2.cpp diff --git a/tests/cppmodelmanager/testdata_renameheaders/header.h b/tests/cppmodelmanager/testdata_renameheaders/header.h new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/cppmodelmanager/testdata_renameheaders/header.h diff --git a/tests/cppmodelmanager/testdata_renameheaders/main.cpp b/tests/cppmodelmanager/testdata_renameheaders/main.cpp new file mode 100644 index 0000000000..629f20001f --- /dev/null +++ b/tests/cppmodelmanager/testdata_renameheaders/main.cpp @@ -0,0 +1,5 @@ +#include "header.h" +#include "subdir1/header1.h" +#include <header2.h> + +int main() {} diff --git a/tests/cppmodelmanager/testdata_renameheaders/subdir1/file1.cpp b/tests/cppmodelmanager/testdata_renameheaders/subdir1/file1.cpp new file mode 100644 index 0000000000..e22ce8100c --- /dev/null +++ b/tests/cppmodelmanager/testdata_renameheaders/subdir1/file1.cpp @@ -0,0 +1,3 @@ +#include "header1.h" +#include "../header.h" +#include "../subdir2/header2.h" diff --git a/tests/cppmodelmanager/testdata_renameheaders/subdir1/header1.h b/tests/cppmodelmanager/testdata_renameheaders/subdir1/header1.h new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/cppmodelmanager/testdata_renameheaders/subdir1/header1.h diff --git a/tests/cppmodelmanager/testdata_renameheaders/subdir2/file2.cpp b/tests/cppmodelmanager/testdata_renameheaders/subdir2/file2.cpp new file mode 100644 index 0000000000..8c83d5ef03 --- /dev/null +++ b/tests/cppmodelmanager/testdata_renameheaders/subdir2/file2.cpp @@ -0,0 +1,3 @@ +#include "header2.h" +#include "../header.h" +#include "../subdir1/header1.h" diff --git a/tests/cppmodelmanager/testdata_renameheaders/subdir2/header2.h b/tests/cppmodelmanager/testdata_renameheaders/subdir2/header2.h new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/cppmodelmanager/testdata_renameheaders/subdir2/header2.h diff --git a/tests/cppmodelmanager/testdata_renameheaders/testdata_renameheaders.pro b/tests/cppmodelmanager/testdata_renameheaders/testdata_renameheaders.pro new file mode 100644 index 0000000000..f5f09586ff --- /dev/null +++ b/tests/cppmodelmanager/testdata_renameheaders/testdata_renameheaders.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = testdata_renameheaders +INCLUDEPATH += subdir2 +CONFIG += no_include_pwd + +HEADERS = header.h subdir1/header1.h subdir2/header2.h +SOURCES = main.cpp subdir1/file1.cpp subdir2/file2.cpp diff --git a/tests/manual/debugger/gui/CMakeLists.txt b/tests/manual/debugger/gui/CMakeLists.txt index 412b0cdc42..1201ebd4f1 100644 --- a/tests/manual/debugger/gui/CMakeLists.txt +++ b/tests/manual/debugger/gui/CMakeLists.txt @@ -5,7 +5,7 @@ project(manual_test_debugger_gui LANGUAGES CXX) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets) diff --git a/tests/manual/deviceshell/tst_deviceshell.cpp b/tests/manual/deviceshell/tst_deviceshell.cpp index 99c506d1bd..88f95fd711 100644 --- a/tests/manual/deviceshell/tst_deviceshell.cpp +++ b/tests/manual/deviceshell/tst_deviceshell.cpp @@ -6,7 +6,7 @@ #include <utils/deviceshell.h> #include <utils/environment.h> #include <utils/launcherinterface.h> -#include <utils/process.h> +#include <utils/qtcprocess.h> #include <utils/temporarydirectory.h> #include <QObject> @@ -33,19 +33,17 @@ public: const FilePath shExecutable = Environment::systemEnvironment() .searchInPath("sh", {"/usr/local/bin"}); - if (dockerExecutable.exists()) { + if (dockerExecutable.exists()) cmd = {dockerExecutable, {"run", "-i", "--rm","alpine"}}; - } else if (dashExecutable.exists()) { - cmd = {dashExecutable, {}}; - } else if (bashExecutable.exists()) { - cmd = {bashExecutable, {}}; - } else if (shExecutable.exists()) { - cmd = {shExecutable, {}}; - } - - if (cmd.isEmpty()) { + else if (dashExecutable.exists()) + cmd = CommandLine{dashExecutable}; + else if (bashExecutable.exists()) + cmd = CommandLine{bashExecutable}; + else if (shExecutable.exists()) + cmd = CommandLine{shExecutable}; + + if (cmd.isEmpty()) return cmd; - } qDebug() << "Using shell cmd:" << cmd; } @@ -97,7 +95,7 @@ class tst_DeviceShell : public QObject t.start(); const auto cat = [&shell](const QByteArray &data) { - return shell.runInShell({"cat", {}}, data).stdOut; + return shell.runInShell(CommandLine{"cat"}, data).stdOut; }; const QList<QByteArray> results = QtConcurrent::blockingMapped(testArray, cat); QCOMPARE(results, testArray); @@ -164,7 +162,7 @@ private slots: TestShell shell; QCOMPARE(shell.state(), DeviceShell::State::Succeeded); - const RunResult r = shell.runInShell({"cat", {}}, utf8string.toUtf8()); + const RunResult r = shell.runInShell(CommandLine{"cat"}, utf8string.toUtf8()); const QString output = QString::fromUtf8(r.stdOut); QCOMPARE(output, utf8string); } diff --git a/tests/manual/layoutbuilder/v2/CMakeLists.txt b/tests/manual/layoutbuilder/v2/CMakeLists.txt new file mode 100644 index 0000000000..f0d59c3768 --- /dev/null +++ b/tests/manual/layoutbuilder/v2/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.5) + +project(lb LANGUAGES CXX) + +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +add_executable(lb lb.h lb.cpp main.cpp) + +target_link_libraries(lb PRIVATE Qt${QT_VERSION_MAJOR}::Widgets) diff --git a/tests/manual/layoutbuilder/v2/lb.cpp b/tests/manual/layoutbuilder/v2/lb.cpp new file mode 100644 index 0000000000..de8f674177 --- /dev/null +++ b/tests/manual/layoutbuilder/v2/lb.cpp @@ -0,0 +1,972 @@ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "lb.h" + +#include <QDebug> +#include <QFormLayout> +#include <QGridLayout> +#include <QGroupBox> +#include <QLabel> +#include <QPushButton> +#include <QSpacerItem> +#include <QSpinBox> +#include <QSplitter> +#include <QStackedLayout> +#include <QStackedWidget> +#include <QStyle> +#include <QTabWidget> +#include <QTextEdit> +#include <QToolBar> + +namespace Layouting { + +// That's cut down qtcassert.{c,h} to avoid the dependency. +#define QTC_STRINGIFY_HELPER(x) #x +#define QTC_STRINGIFY(x) QTC_STRINGIFY_HELPER(x) +#define QTC_STRING(cond) qDebug("SOFT ASSERT: \"%s\" in %s: %s", cond, __FILE__, QTC_STRINGIFY(__LINE__)) +#define QTC_ASSERT(cond, action) if (Q_LIKELY(cond)) {} else { QTC_STRING(#cond); action; } do {} while (0) +#define QTC_CHECK(cond) if (cond) {} else { QTC_STRING(#cond); } do {} while (0) + +template <typename X> +X::Implementation *access(const X *x) +{ + return static_cast<X::Implementation *>(x->ptr); +} + +template <typename X> +void apply(X *x, std::initializer_list<typename X::I> ps) +{ + for (auto && p : ps) + p.apply(x); +} + +// FlowLayout + +class FlowLayout : public QLayout +{ +public: + explicit FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1) + : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing) + { + setContentsMargins(margin, margin, margin, margin); + } + + FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1) + : m_hSpace(hSpacing), m_vSpace(vSpacing) + { + setContentsMargins(margin, margin, margin, margin); + } + + ~FlowLayout() override + { + QLayoutItem *item; + while ((item = takeAt(0))) + delete item; + } + + void addItem(QLayoutItem *item) override { itemList.append(item); } + + int horizontalSpacing() const + { + if (m_hSpace >= 0) + return m_hSpace; + else + return smartSpacing(QStyle::PM_LayoutHorizontalSpacing); + } + + int verticalSpacing() const + { + if (m_vSpace >= 0) + return m_vSpace; + else + return smartSpacing(QStyle::PM_LayoutVerticalSpacing); + } + + Qt::Orientations expandingDirections() const override + { + return {}; + } + + bool hasHeightForWidth() const override { return true; } + + int heightForWidth(int width) const override + { + int height = doLayout(QRect(0, 0, width, 0), true); + return height; + } + + int count() const override { return itemList.size(); } + + QLayoutItem *itemAt(int index) const override + { + return itemList.value(index); + } + + QSize minimumSize() const override + { + QSize size; + for (QLayoutItem *item : itemList) + size = size.expandedTo(item->minimumSize()); + + int left, top, right, bottom; + getContentsMargins(&left, &top, &right, &bottom); + size += QSize(left + right, top + bottom); + return size; + } + + void setGeometry(const QRect &rect) override + { + QLayout::setGeometry(rect); + doLayout(rect, false); + } + + QSize sizeHint() const override + { + return minimumSize(); + } + + QLayoutItem *takeAt(int index) override + { + if (index >= 0 && index < itemList.size()) + return itemList.takeAt(index); + else + return nullptr; + } + +private: + int doLayout(const QRect &rect, bool testOnly) const + { + int left, top, right, bottom; + getContentsMargins(&left, &top, &right, &bottom); + QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); + int x = effectiveRect.x(); + int y = effectiveRect.y(); + int lineHeight = 0; + + for (QLayoutItem *item : itemList) { + QWidget *wid = item->widget(); + int spaceX = horizontalSpacing(); + if (spaceX == -1) + spaceX = wid->style()->layoutSpacing( + QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal); + int spaceY = verticalSpacing(); + if (spaceY == -1) + spaceY = wid->style()->layoutSpacing( + QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical); + int nextX = x + item->sizeHint().width() + spaceX; + if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) { + x = effectiveRect.x(); + y = y + lineHeight + spaceY; + nextX = x + item->sizeHint().width() + spaceX; + lineHeight = 0; + } + + if (!testOnly) + item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); + + x = nextX; + lineHeight = qMax(lineHeight, item->sizeHint().height()); + } + return y + lineHeight - rect.y() + bottom; + } + + int smartSpacing(QStyle::PixelMetric pm) const + { + QObject *parent = this->parent(); + if (!parent) { + return -1; + } else if (parent->isWidgetType()) { + auto pw = static_cast<QWidget *>(parent); + return pw->style()->pixelMetric(pm, nullptr, pw); + } else { + return static_cast<QLayout *>(parent)->spacing(); + } + } + + QList<QLayoutItem *> itemList; + int m_hSpace; + int m_vSpace; +}; + +/*! + \namespace Layouting + \inmodule QtCreator + + \brief The Layouting namespace contains classes and functions to conveniently + create layouts in code. + + Classes in the namespace help to create create QLayout or QWidget derived class, + instances should be used locally within a function and never stored. + + \sa Layouting::Widget, Layouting::Layout +*/ + + +/*! + \class Layouting::Layout + \inmodule QtCreator + + The Layout class is a base class for more specific builder + classes to create QLayout derived objects. + */ + +/*! + \class Layouting::Widget + \inmodule QtCreator + + The Widget class is a base class for more specific builder + classes to create QWidget derived objects. +*/ + +/*! + \class Layouting::LayoutItem + \inmodule QtCreator + + The LayoutItem class is used for intermediate results + while creating layouts with a concept of rows and spans, such + as Form and Grid. +*/ + +Layout::LayoutItem::LayoutItem() = default; + +Layout::LayoutItem::~LayoutItem() = default; + +Layout::LayoutItem::LayoutItem(const LayoutModifier &inner) +{ + ownerModifier = inner; +} + +/*! + \fn template <class T> LayoutItem(const T &t) + \internal + + Constructs a layout item proxy for \a t. + + T could be + \list + \li \c {QString} + \li \c {QWidget *} + \li \c {QLayout *} + \endlist +*/ + +// Object + +Object::Object(std::initializer_list<I> ps) +{ + ptr = new Implementation; + apply(this, ps); +} + +static QWidget *widgetForItem(QLayoutItem *item) +{ + if (QWidget *w = item->widget()) + return w; + if (item->spacerItem()) + return nullptr; + if (QLayout *l = item->layout()) { + for (int i = 0, n = l->count(); i < n; ++i) { + if (QWidget *w = widgetForItem(l->itemAt(i))) + return w; + } + } + return nullptr; +} + +static QLabel *createLabel(const QString &text) +{ + auto label = new QLabel(text); + label->setTextInteractionFlags(Qt::TextSelectableByMouse); + return label; +} + +using LayoutItem = Layout::LayoutItem; + +static void addItemToBoxLayout(QBoxLayout *layout, const LayoutItem &item) +{ + if (QWidget *w = item.widget) { + layout->addWidget(w); + } else if (QLayout *l = item.layout) { + layout->addLayout(l); + } else if (item.stretch != -1) { + layout->addStretch(item.stretch); + } else if (!item.text.isEmpty()) { + layout->addWidget(createLabel(item.text)); + } else if (item.empty) { + // Nothing to do, but no reason to warn, either. + } else { + QTC_CHECK(false); + } +} + +static void addItemToFlowLayout(FlowLayout *layout, const LayoutItem &item) +{ + if (QWidget *w = item.widget) { + layout->addWidget(w); + } else if (QLayout *l = item.layout) { + layout->addItem(l); +// } else if (item.stretch != -1) { +// layout->addStretch(item.stretch); + } else if (item.empty) { + // Nothing to do, but no reason to warn, either + } else if (!item.text.isEmpty()) { + layout->addWidget(createLabel(item.text)); + } else { + QTC_CHECK(false); + } +} + +/*! + \class Layouting::Space + \inmodule QtCreator + + \brief The Space class represents some empty space in a layout. + */ + +/*! + \class Layouting::Stretch + \inmodule QtCreator + + \brief The Stretch class represents some stretch in a layout. + */ + + +// Layout + +void Layout::span(int cols, int rows) +{ + QTC_ASSERT(!pendingItems.empty(), return); + pendingItems.back().spanCols = cols; + pendingItems.back().spanRows = rows; +} + +void Layout::noMargin() +{ + customMargin({}); +} + +void Layout::normalMargin() +{ + customMargin({9, 9, 9, 9}); +} + +void Layout::customMargin(const QMargins &margin) +{ + access(this)->setContentsMargins(margin); +} + +/*! + Attaches the constructed layout to the provided QWidget \a w. + + This operation can only be performed once per LayoutBuilder instance. + */ +void Layout::attachTo(QWidget *widget) +{ + flush(); + widget->setLayout(access(this)); +} + +/*! + Adds the layout item \a item as sub items. + */ +void Layout::addItem(I item) +{ + item.apply(this); +} + +void Layout::addItemHelper(const LayoutItem &item) +{ + if (QBoxLayout *lt = asBox()) + addItemToBoxLayout(lt, item); + else if (FlowLayout *lt = asFlow()) + addItemToFlowLayout(lt, item); + else + pendingItems.push_back(item); +} + +/*! + Adds the layout items \a items as sub items. + */ +void Layout::addItems(std::initializer_list<I> items) +{ + for (const I &item : items) + item.apply(this); +} + +/*! + Starts a new row containing \a items. The row can be further extended by + other items using \c addItem() or \c addItems(). + + \sa addItem(), addItems() + */ + +void Layout::addRow(std::initializer_list<I> items) +{ + for (const I &item : items) + item.apply(this); + flush(); +} + +void Layout::setSpacing(int spacing) +{ + access(this)->setSpacing(spacing); +} + +void Layout::setColumnStretch(int column, int stretch) +{ + if (auto grid = qobject_cast<QGridLayout *>(access(this))) { + grid->setColumnStretch(column, stretch); + } else { + QTC_CHECK(false); + } +} + +void addToWidget(Widget *widget, const Layout &layout) +{ + layout.flush_(); + access(widget)->setLayout(access(&layout)); +} + +void addToLayout(Layout *layout, const Widget &inner) +{ + LayoutItem item; + item.widget = access(&inner); + layout->addItemHelper(item); +} + +void addToLayout(Layout *layout, QWidget *inner) +{ + LayoutItem item; + item.widget = inner; + layout->addItemHelper(item); +} + +void addToLayout(Layout *layout, QLayout *inner) +{ + LayoutItem item; + item.layout = inner; + layout->addItemHelper(item); +} + +void addToLayout(Layout *layout, const Layout &inner) +{ + inner.flush_(); + LayoutItem item; + item.layout = access(&inner); + layout->addItemHelper(item); +} + +void addToLayout(Layout *layout, const LayoutModifier &inner) +{ + inner(layout); +} + +void addToLayout(Layout *layout, const QString &inner) +{ + LayoutItem item; + item.text = inner; + layout->addItemHelper(item); +} + +void empty(Layout *iface) +{ + LayoutItem item; + item.empty = true; + iface->addItemHelper(item); +} + +void hr(Layout *layout) +{ + layout->addItemHelper(createHr()); +} + +void br(Layout *iface) +{ + iface->flush(); +} + +void st(Layout *iface) +{ + LayoutItem item; + item.stretch = 1; + iface->addItemHelper(item); +} + +void noMargin(Layout *iface) +{ + iface->noMargin(); +} + +void normalMargin(Layout *iface) +{ + iface->normalMargin(); +} + +QFormLayout *Layout::asForm() +{ + return qobject_cast<QFormLayout *>(access(this)); +} + +QGridLayout *Layout::asGrid() +{ + return qobject_cast<QGridLayout *>(access(this)); +} + +QBoxLayout *Layout::asBox() +{ + return qobject_cast<QBoxLayout *>(access(this)); +} + +FlowLayout *Layout::asFlow() +{ + return dynamic_cast<FlowLayout *>(access(this)); +} + +void Layout::flush() +{ + if (pendingItems.empty()) + return; + + if (QGridLayout *lt = asGrid()) { + for (const LayoutItem &item : std::as_const(pendingItems)) { + Qt::Alignment a; + if (currentGridColumn == 0 && useFormAlignment) { + // if (auto widget = builder.stack.at(builder.stack.size() - 2).widget) { + // a = widget->style()->styleHint(QStyle::SH_FormLayoutLabelAlignment); + } + if (item.widget) + lt->addWidget(item.widget, currentGridRow, currentGridColumn, item.spanRows, item.spanCols, a); + else if (item.layout) + lt->addLayout(item.layout, currentGridRow, currentGridColumn, item.spanRows, item.spanCols, a); + else if (!item.text.isEmpty()) + lt->addWidget(createLabel(item.text), currentGridRow, currentGridColumn, item.spanRows, item.spanCols, a); + currentGridColumn += item.spanCols; + // Intentionally not used, use 'br'/'empty' for vertical progress. + // currentGridRow += item.spanRows; + } + ++currentGridRow; + currentGridColumn = 0; + pendingItems.clear(); + return; + } + + if (QFormLayout *fl = asForm()) { + if (pendingItems.size() > 2) { + auto hbox = new QHBoxLayout; + hbox->setContentsMargins(0, 0, 0, 0); + for (size_t i = 1; i < pendingItems.size(); ++i) + addItemToBoxLayout(hbox, pendingItems.at(i)); + while (pendingItems.size() > 1) + pendingItems.pop_back(); + pendingItems.push_back(hbox); + } + + if (pendingItems.size() == 1) { // Only one item given, so this spans both columns. + const LayoutItem &f0 = pendingItems.at(0); + if (auto layout = f0.layout) + fl->addRow(layout); + else if (auto widget = f0.widget) + fl->addRow(widget); + } else if (pendingItems.size() == 2) { // Normal case, both columns used. + LayoutItem &f1 = pendingItems[1]; + const LayoutItem &f0 = pendingItems.at(0); + if (!f1.widget && !f1.layout && !f1.text.isEmpty()) + f1.widget = createLabel(f1.text); + + // QFormLayout accepts only widgets or text in the first column. + // FIXME: Should we be more generous? + if (f0.widget) { + if (f1.layout) + fl->addRow(f0.widget, f1.layout); + else if (f1.widget) + fl->addRow(f0.widget, f1.widget); + } else { + if (f1.layout) + fl->addRow(createLabel(f0.text), f1.layout); + else if (f1.widget) + fl->addRow(createLabel(f0.text), f1.widget); + } + } else { + QTC_CHECK(false); + } + + // Set up label as buddy if possible. + const int lastRow = fl->rowCount() - 1; + QLayoutItem *l = fl->itemAt(lastRow, QFormLayout::LabelRole); + QLayoutItem *f = fl->itemAt(lastRow, QFormLayout::FieldRole); + if (l && f) { + if (QLabel *label = qobject_cast<QLabel *>(l->widget())) { + if (QWidget *widget = widgetForItem(f)) + label->setBuddy(widget); + } + } + + pendingItems.clear(); + return; + } + + QTC_CHECK(false); // The other layouts shouldn't use flush() +} + +void Layout::flush_() const +{ + const_cast<Layout *>(this)->flush(); +} + +void withFormAlignment(Layout *iface) +{ + iface->useFormAlignment = true; +} + +// Flow + +Flow::Flow(std::initializer_list<I> ps) +{ + ptr = new FlowLayout; + apply(this, ps); + flush(); +} + +// Row & Column + +Row::Row(std::initializer_list<I> ps) +{ + ptr = new QHBoxLayout; + apply(this, ps); + flush(); +} + +Column::Column(std::initializer_list<I> ps) +{ + ptr = new QVBoxLayout; + apply(this, ps); + flush(); +} + +// Grid + +Grid::Grid() +{ + ptr = new QGridLayout; +} + +Grid::Grid(std::initializer_list<I> ps) +{ + ptr = new QGridLayout; + apply(this, ps); + flush(); +} + +// Form + +Form::Form() +{ + ptr = new QFormLayout; +} + +Form::Form(std::initializer_list<I> ps) +{ + auto lt = new QFormLayout; + ptr = lt; + lt->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); + apply(this, ps); + flush(); +} + +void Layout::fieldGrowthPolicy(int policy) +{ + if (auto lt = asForm()) + lt->setFieldGrowthPolicy(QFormLayout::FieldGrowthPolicy(policy)); +} + +QWidget *Layout::emerge() const +{ + const_cast<Layout *>(this)->flush(); + QWidget *widget = new QWidget; + widget->setLayout(access(this)); + return widget; +} + +// "Widgets" + +Widget::Widget(std::initializer_list<I> ps) +{ + ptr = new Implementation; + apply(this, ps); +} + +void Widget::resize(int w, int h) +{ + access(this)->resize(w, h); +} + +void Widget::setLayout(const Layout &layout) +{ + access(this)->setLayout(access(&layout)); +} + +void Widget::setWindowTitle(const QString &title) +{ + access(this)->setWindowTitle(title); +} + +void Widget::setToolTip(const QString &title) +{ + access(this)->setToolTip(title); +} + +void Widget::show() +{ + access(this)->show(); +} + +void Widget::noMargin(int) +{ + customMargin({}); +} + +void Widget::normalMargin(int) +{ + customMargin({9, 9, 9, 9}); +} + +void Widget::customMargin(const QMargins &margin) +{ + access(this)->setContentsMargins(margin); +} + +QWidget *Widget::emerge() const +{ + return access(this); +} + +// Label + +Label::Label(std::initializer_list<I> ps) +{ + ptr = new Implementation; + apply(this, ps); +} + +Label::Label(const QString &text) +{ + ptr = new Implementation; + setText(text); +} + +void Label::setText(const QString &text) +{ + access(this)->setText(text); +} + +// Group + +Group::Group(std::initializer_list<I> ps) +{ + ptr = new Implementation; + apply(this, ps); +} + +void Group::setTitle(const QString &title) +{ + access(this)->setTitle(title); + access(this)->setObjectName(title); +} + +void Group::setGroupChecker(const std::function<void (QObject *)> &checker) +{ + checker(access(this)); +} + +// SpinBox + +SpinBox::SpinBox(std::initializer_list<I> ps) +{ + ptr = new Implementation; + apply(this, ps); +} + +void SpinBox::setValue(int val) +{ + access(this)->setValue(val); +} + +void SpinBox::onTextChanged(const std::function<void (QString)> &func) +{ + QObject::connect(access(this), &QSpinBox::textChanged, func); +} + +// TextEdit + +TextEdit::TextEdit(std::initializer_list<I> ps) +{ + ptr = new Implementation; + apply(this, ps); +} + +void TextEdit::setText(const QString &text) +{ + access(this)->setText(text); +} + +// PushButton + +PushButton::PushButton(std::initializer_list<I> ps) +{ + ptr = new Implementation; + apply(this, ps); +} + +void PushButton::setText(const QString &text) +{ + access(this)->setText(text); +} + +void PushButton::onClicked(const std::function<void ()> &func, QObject *guard) +{ + QObject::connect(access(this), &QAbstractButton::clicked, guard, func); +} + +// Stack + +// We use a QStackedWidget instead of a QStackedLayout here because the latter will call +// "setVisible()" when a child is added, which can lead to the widget being spawned as a +// top-level widget. This can lead to the focus shifting away from the main application. +Stack::Stack(std::initializer_list<I> ps) +{ + ptr = new Implementation; + apply(this, ps); +} + +void addToStack(Stack *stack, const Widget &inner) +{ + access(stack)->addWidget(inner.emerge()); +} + +void addToStack(Stack *stack, const Layout &inner) +{ + inner.flush_(); + access(stack)->addWidget(inner.emerge()); +} + +void addToStack(Stack *stack, QWidget *inner) +{ + access(stack)->addWidget(inner); +} + +// Splitter + +Splitter::Splitter(std::initializer_list<I> ps) +{ + ptr = new Implementation; + access(this)->setOrientation(Qt::Vertical); + apply(this, ps); +} + +void addToSplitter(Splitter *splitter, QWidget *inner) +{ + access(splitter)->addWidget(inner); +} + +void addToSplitter(Splitter *splitter, const Widget &inner) +{ + access(splitter)->addWidget(inner.emerge()); +} + +void addToSplitter(Splitter *splitter, const Layout &inner) +{ + inner.flush_(); + access(splitter)->addWidget(inner.emerge()); +} + +// ToolBar + +ToolBar::ToolBar(std::initializer_list<I> ps) +{ + ptr = new Implementation; + apply(this, ps); + access(this)->setOrientation(Qt::Horizontal); +} + +// TabWidget + +TabWidget::TabWidget(std::initializer_list<I> ps) +{ + ptr = new Implementation; + apply(this, ps); +} + +Tab::Tab(const QString &tabName, const Layout &inner) + : tabName(tabName), inner(inner) +{} + +void addToTabWidget(TabWidget *tabWidget, const Tab &tab) +{ + access(tabWidget)->addTab(tab.inner.emerge(), tab.tabName); +} + +// Special If + +If::If(bool condition, + const std::initializer_list<Layout::I> ifcase, + const std::initializer_list<Layout::I> thencase) + : used(condition ? ifcase : thencase) +{} + +void addToLayout(Layout *layout, const If &inner) +{ + for (const Layout::I &item : inner.used) + item.apply(layout); +} + +// Specials + +QWidget *createHr(QWidget *parent) +{ + auto frame = new QFrame(parent); + frame->setFrameShape(QFrame::HLine); + frame->setFrameShadow(QFrame::Sunken); + return frame; +} + +Span::Span(int n, const Layout::I &item) + : item(item), spanCols(n) +{} + +void addToLayout(Layout *layout, const Span &inner) +{ + LayoutItem item; + layout->addItem(inner.item); + QTC_ASSERT(!layout->pendingItems.empty(), return); + layout->pendingItems.back().spanCols = inner.spanCols; + layout->pendingItems.back().spanRows = inner.spanRows; +} + +LayoutModifier spacing(int space) +{ + return [space](Layout *iface) { iface->setSpacing(space); }; +} + +void addToLayout(Layout *layout, const Space &inner) +{ + if (auto lt = layout->asBox()) + lt->addSpacing(inner.space); +} + +void addToLayout(Layout *layout, const Stretch &inner) +{ + if (auto lt = layout->asBox()) + lt->addStretch(inner.stretch); +} + +// void createItem(LayoutItem *item, QWidget *t) +// { +// if (auto l = qobject_cast<QLabel *>(t)) +// l->setTextInteractionFlags(l->textInteractionFlags() | Qt::TextSelectableByMouse); + +// item->onAdd = [t](LayoutBuilder &builder) { doAddWidget(builder, t); }; +// } + + +} // Layouting diff --git a/tests/manual/layoutbuilder/v2/lb.h b/tests/manual/layoutbuilder/v2/lb.h new file mode 100644 index 0000000000..99c87af564 --- /dev/null +++ b/tests/manual/layoutbuilder/v2/lb.h @@ -0,0 +1,553 @@ +// Copyright (C) 2023 André Pönitz +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#pragma once + +#include <QMargins> +#include <QString> + +#include <functional> +#include <initializer_list> + +#if defined(UTILS_LIBRARY) +# define QTCREATOR_UTILS_EXPORT Q_DECL_EXPORT +#elif defined(UTILS_STATIC_LIBRARY) +# define QTCREATOR_UTILS_EXPORT +#else +# define QTCREATOR_UTILS_EXPORT Q_DECL_IMPORT +#endif + +QT_BEGIN_NAMESPACE +class QBoxLayout; +class QFormLayout; +class QGridLayout; +class QGroupBox; +class QHBoxLayout; +class QLabel; +class QLayout; +class QMargins; +class QObject; +class QPushButton; +class QSpinBox; +class QSplitter; +class QStackedWidget; +class QTabWidget; +class QTextEdit; +class QToolBar; +class QVBoxLayout; +class QWidget; +QT_END_NAMESPACE + +namespace Layouting { + +class NestId {}; + +template <typename T1, typename T2> +class IdAndArg +{ +public: + IdAndArg(const T1 &id, const T2 &arg) : id(id), arg(arg) {} + const T1 id; + const T2 arg; // FIXME: Could be const &, but this would currently break bindTo(). +}; + +// The main dispatcher + +void doit(auto x, auto id, auto p); + +template <typename X> class BuilderItem +{ +public: + // Nested child object + template <typename Inner> + BuilderItem(Inner && p) + { + apply = [&p](X *x) { doit(x, NestId{}, std::forward<Inner>(p)); }; + } + + // Property setter + template <typename Id, typename Arg> + BuilderItem(IdAndArg<Id, Arg> && idarg) + { + apply = [&idarg](X *x) { doit(x, idarg.id, idarg.arg); }; + } + + std::function<void(X *)> apply; +}; + + +////////////////////////////////////////////// + +// +// Basic +// + +class QTCREATOR_UTILS_EXPORT Thing +{ +public: + void *ptr; // The product. +}; + +class QTCREATOR_UTILS_EXPORT Object : public Thing +{ +public: + using Implementation = QObject; + using I = BuilderItem<Object>; + + Object() = default; + Object(std::initializer_list<I> ps); +}; + +// +// Layouts +// + +class FlowLayout; +class Layout; +using LayoutModifier = std::function<void(Layout *)>; +// using LayoutModifier = void(*)(Layout *); + +class QTCREATOR_UTILS_EXPORT Layout : public Object +{ +public: + using Implementation = QLayout; + using I = BuilderItem<Layout>; + + Layout() = default; + Layout(Implementation *w) { ptr = w; } + + class LayoutItem + { + public: + ~LayoutItem(); + LayoutItem(); + LayoutItem(QLayout *l) : layout(l) {} + LayoutItem(QWidget *w) : widget(w) {} + LayoutItem(const QString &t) : text(t) {} + LayoutItem(const LayoutModifier &inner); + + QString text; + QLayout *layout = nullptr; + QWidget *widget = nullptr; + int stretch = -1; + int spanCols = 1; + int spanRows = 1; + bool empty = false; + LayoutModifier ownerModifier; + //Qt::Alignment align = {}; + }; + + void span(int cols, int rows); + void noMargin(); + void normalMargin(); + void customMargin(const QMargins &margin); + void setColumnStretch(int cols, int rows); + void setSpacing(int space); + + void attachTo(QWidget *); + void addItemHelper(const LayoutItem &item); + void addItem(I item); + void addItems(std::initializer_list<I> items); + void addRow(std::initializer_list<I> items); + + void flush(); + void flush_() const; + void fieldGrowthPolicy(int policy); + + QWidget *emerge() const; + + QFormLayout *asForm(); + QGridLayout *asGrid(); + QBoxLayout *asBox(); + FlowLayout *asFlow(); + + // Grid-only + int currentGridColumn = 0; + int currentGridRow = 0; + //Qt::Alignment align = {}; + bool useFormAlignment = false; + + std::vector<LayoutItem> pendingItems; +}; + +class QTCREATOR_UTILS_EXPORT Column : public Layout +{ +public: + using Implementation = QVBoxLayout; + using I = BuilderItem<Column>; + + Column(std::initializer_list<I> ps); +}; + +class QTCREATOR_UTILS_EXPORT Row : public Layout +{ +public: + using Implementation = QHBoxLayout; + using I = BuilderItem<Row>; + + Row(std::initializer_list<I> ps); +}; + +class QTCREATOR_UTILS_EXPORT Form : public Layout +{ +public: + using Implementation = QFormLayout; + using I = BuilderItem<Form>; + + Form(); + Form(std::initializer_list<I> ps); +}; + +class QTCREATOR_UTILS_EXPORT Grid : public Layout +{ +public: + using Implementation = QGridLayout; + using I = BuilderItem<Grid>; + + Grid(); + Grid(std::initializer_list<I> ps); +}; + +class QTCREATOR_UTILS_EXPORT Flow : public Layout +{ +public: + Flow(std::initializer_list<I> ps); +}; + +class QTCREATOR_UTILS_EXPORT Stretch +{ +public: + explicit Stretch(int stretch) : stretch(stretch) {} + + int stretch; +}; + +class QTCREATOR_UTILS_EXPORT Space +{ +public: + explicit Space(int space) : space(space) {} + + int space; +}; + +class QTCREATOR_UTILS_EXPORT Span +{ +public: + Span(int n, const Layout::I &item); + + Layout::I item; + int spanCols = 1; + int spanRows = 1; +}; + +// +// Widgets +// + +class QTCREATOR_UTILS_EXPORT Widget : public Object +{ +public: + using Implementation = QWidget; + using I = BuilderItem<Widget>; + + Widget() = default; + Widget(std::initializer_list<I> ps); + Widget(Implementation *w) { ptr = w; } + + QWidget *emerge() const; + + void show(); + void resize(int, int); + void setLayout(const Layout &layout); + void setWindowTitle(const QString &); + void setToolTip(const QString &); + void noMargin(int = 0); + void normalMargin(int = 0); + void customMargin(const QMargins &margin); +}; + +class QTCREATOR_UTILS_EXPORT Label : public Widget +{ +public: + using Implementation = QLabel; + using I = BuilderItem<Label>; + + Label(std::initializer_list<I> ps); + Label(const QString &text); + + void setText(const QString &); +}; + +class QTCREATOR_UTILS_EXPORT Group : public Widget +{ +public: + using Implementation = QGroupBox; + using I = BuilderItem<Group>; + + Group(std::initializer_list<I> ps); + + void setTitle(const QString &); + void setGroupChecker(const std::function<void(QObject *)> &); +}; + +class QTCREATOR_UTILS_EXPORT SpinBox : public Widget +{ +public: + using Implementation = QSpinBox; + using I = BuilderItem<SpinBox>; + + SpinBox(std::initializer_list<I> ps); + + void setValue(int); + void onTextChanged(const std::function<void(QString)> &); +}; + +class QTCREATOR_UTILS_EXPORT PushButton : public Widget +{ +public: + using Implementation = QPushButton; + using I = BuilderItem<PushButton>; + + PushButton(std::initializer_list<I> ps); + + void setText(const QString &); + void onClicked(const std::function<void()> &, QObject *guard); +}; + +class QTCREATOR_UTILS_EXPORT TextEdit : public Widget +{ +public: + using Implementation = QTextEdit; + using I = BuilderItem<TextEdit>; + using Id = Implementation *; + + TextEdit(std::initializer_list<I> ps); + + void setText(const QString &); +}; + +class QTCREATOR_UTILS_EXPORT Splitter : public Widget +{ +public: + using Implementation = QSplitter; + using I = BuilderItem<Splitter>; + + Splitter(std::initializer_list<I> items); +}; + +class QTCREATOR_UTILS_EXPORT Stack : public Widget +{ +public: + using Implementation = QStackedWidget; + using I = BuilderItem<Stack>; + + Stack() : Stack({}) {} + Stack(std::initializer_list<I> items); +}; + +class QTCREATOR_UTILS_EXPORT Tab : public Widget +{ +public: + using Implementation = QWidget; + + Tab(const QString &tabName, const Layout &inner); + + const QString tabName; + const Layout inner; +}; + +class QTCREATOR_UTILS_EXPORT TabWidget : public Widget +{ +public: + using Implementation = QTabWidget; + using I = BuilderItem<TabWidget>; + + TabWidget(std::initializer_list<I> items); +}; + +class QTCREATOR_UTILS_EXPORT ToolBar : public Widget +{ +public: + using Implementation = QToolBar; + using I = Layouting::BuilderItem<ToolBar>; + + ToolBar(std::initializer_list<I> items); +}; + +// Special + +class QTCREATOR_UTILS_EXPORT If +{ +public: + If(bool condition, + const std::initializer_list<Layout::I> ifcase, + const std::initializer_list<Layout::I> thencase = {}); + + const std::initializer_list<Layout::I> used; +}; + +// +// Dispatchers +// + +// We need one 'Id' (and a corresponding function wrapping arguments into a +// tuple marked by this id) per 'name' of "backend" setter member function, +// i.e. one 'text' is sufficient for QLabel::setText, QLineEdit::setText. +// The name of the Id does not have to match the backend names as it +// is mapped per-backend-type in the respective setter implementation +// but we assume that it generally makes sense to stay close to the +// wrapped API name-wise. + +// These are free functions overloaded on the type of builder object +// and setter id. The function implementations are independent, but +// the base expectation is that they will forwards to the backend +// type's setter. + +// Special dispatchers + + +class BindToId {}; + +template <typename T> +auto bindTo(T **p) +{ + return IdAndArg{BindToId{}, p}; +} + +template <typename Interface> +void doit(Interface *x, BindToId, auto p) +{ + *p = static_cast<Interface::Implementation *>(x->ptr); +} + +class IdId {}; +auto id(auto p) { return IdAndArg{IdId{}, p}; } + +template <typename Interface> +void doit(Interface *x, IdId, auto p) +{ + *p = static_cast<Interface::Implementation *>(x->ptr); +} + +// Setter dispatchers + +class SizeId {}; +auto size(auto w, auto h) { return IdAndArg{SizeId{}, std::pair{w, h}}; } +void doit(auto x, SizeId, auto p) { x->resize(p.first, p.second); } + +class TextId {}; +auto text(auto p) { return IdAndArg{TextId{}, p}; } +void doit(auto x, TextId, auto p) { x->setText(p); } + +class TitleId {}; +auto title(auto p) { return IdAndArg{TitleId{}, p}; } +void doit(auto x, TitleId, auto p) { x->setTitle(p); } + +class GroupCheckerId {}; +auto groupChecker(auto p) { return IdAndArg{GroupCheckerId{}, p}; } +void doit(auto x, GroupCheckerId, auto p) { x->setGroupChecker(p); } + +class ToolTipId {}; +auto toolTip(auto p) { return IdAndArg{ToolTipId{}, p}; } +void doit(auto x, ToolTipId, auto p) { x->setToolTip(p); } + +class WindowTitleId {}; +auto windowTitle(auto p) { return IdAndArg{WindowTitleId{}, p}; } +void doit(auto x, WindowTitleId, auto p) { x->setWindowTitle(p); } + +class OnTextChangedId {}; +auto onTextChanged(auto p) { return IdAndArg{OnTextChangedId{}, p}; } +void doit(auto x, OnTextChangedId, auto p) { x->onTextChanged(p); } + +class OnClickedId {}; +auto onClicked(auto p, auto guard) { return IdAndArg{OnClickedId{}, std::pair{p, guard}}; } +void doit(auto x, OnClickedId, auto p) { x->onClicked(p.first, p.second); } + +class CustomMarginId {}; +inline auto customMargin(const QMargins &p) { return IdAndArg{CustomMarginId{}, p}; } +void doit(auto x, CustomMarginId, auto p) { x->customMargin(p); } + +class FieldGrowthPolicyId {}; +inline auto fieldGrowthPolicy(auto p) { return IdAndArg{FieldGrowthPolicyId{}, p}; } +void doit(auto x, FieldGrowthPolicyId, auto p) { x->fieldGrowthPolicy(p); } + +class ColumnStretchId {}; +inline auto columnStretch(int column, int stretch) { return IdAndArg{ColumnStretchId{}, std::pair{column, stretch}}; } +void doit(auto x, ColumnStretchId, auto p) { x->setColumnStretch(p.first, p.second); } + +// Nesting dispatchers + +QTCREATOR_UTILS_EXPORT void addToLayout(Layout *layout, const Layout &inner); +QTCREATOR_UTILS_EXPORT void addToLayout(Layout *layout, const Widget &inner); +QTCREATOR_UTILS_EXPORT void addToLayout(Layout *layout, QWidget *inner); +QTCREATOR_UTILS_EXPORT void addToLayout(Layout *layout, QLayout *inner); +QTCREATOR_UTILS_EXPORT void addToLayout(Layout *layout, const LayoutModifier &inner); +QTCREATOR_UTILS_EXPORT void addToLayout(Layout *layout, const QString &inner); +QTCREATOR_UTILS_EXPORT void addToLayout(Layout *layout, const Space &inner); +QTCREATOR_UTILS_EXPORT void addToLayout(Layout *layout, const Stretch &inner); +QTCREATOR_UTILS_EXPORT void addToLayout(Layout *layout, const If &inner); +QTCREATOR_UTILS_EXPORT void addToLayout(Layout *layout, const Span &inner); +// ... can be added to anywhere later to support "user types" + +QTCREATOR_UTILS_EXPORT void addToWidget(Widget *widget, const Layout &layout); + +QTCREATOR_UTILS_EXPORT void addToTabWidget(TabWidget *tabWidget, const Tab &inner); + +QTCREATOR_UTILS_EXPORT void addToSplitter(Splitter *splitter, QWidget *inner); +QTCREATOR_UTILS_EXPORT void addToSplitter(Splitter *splitter, const Widget &inner); +QTCREATOR_UTILS_EXPORT void addToSplitter(Splitter *splitter, const Layout &inner); + +QTCREATOR_UTILS_EXPORT void addToStack(Stack *stack, QWidget *inner); +QTCREATOR_UTILS_EXPORT void addToStack(Stack *stack, const Widget &inner); +QTCREATOR_UTILS_EXPORT void addToStack(Stack *stack, const Layout &inner); + +template <class Inner> +void doit_nested(Layout *outer, Inner && inner) +{ + addToLayout(outer, std::forward<Inner>(inner)); +} + +void doit_nested(Widget *outer, auto inner) +{ + addToWidget(outer, inner); +} + +void doit_nested(TabWidget *outer, auto inner) +{ + addToTabWidget(outer, inner); +} + +void doit_nested(Stack *outer, auto inner) +{ + addToStack(outer, inner); +} + +void doit_nested(Splitter *outer, auto inner) +{ + addToSplitter(outer, inner); +} + +template <class Inner> +void doit(auto outer, NestId, Inner && inner) +{ + doit_nested(outer, std::forward<Inner>(inner)); +} + +// Special layout items + +QTCREATOR_UTILS_EXPORT void empty(Layout *); +QTCREATOR_UTILS_EXPORT void br(Layout *); +QTCREATOR_UTILS_EXPORT void st(Layout *); +QTCREATOR_UTILS_EXPORT void noMargin(Layout *); +QTCREATOR_UTILS_EXPORT void normalMargin(Layout *); +QTCREATOR_UTILS_EXPORT void withFormAlignment(Layout *); +QTCREATOR_UTILS_EXPORT void hr(Layout *); + +QTCREATOR_UTILS_EXPORT LayoutModifier spacing(int space); + +// Convenience + +QTCREATOR_UTILS_EXPORT QWidget *createHr(QWidget *parent = nullptr); + +} // Layouting diff --git a/tests/manual/layoutbuilder/v2/main.cpp b/tests/manual/layoutbuilder/v2/main.cpp new file mode 100644 index 0000000000..702d467016 --- /dev/null +++ b/tests/manual/layoutbuilder/v2/main.cpp @@ -0,0 +1,79 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "lb.h" + +#include <QApplication> +#include <QWidget> +#include <QLabel> +#include <QGroupBox> +#include <QTextEdit> + +using namespace Layouting; + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + TextEdit::Id textId; + + QWidget *w = nullptr; + QGroupBox *g = nullptr; + QLabel *l = nullptr; + + Group { + bindTo(&w), // Works, as GroupInterface derives from WidgetInterface + // bindTo(&l), // Does (intentionally) not work, GroupInterface does not derive from LabelInterface + bindTo(&g), + size(300, 200), + title("HHHHHHH"), + Form { + "Hallo", + Group { + title("Title"), + Column { + Label { + text("World") + }, + TextEdit { + id(&textId), + text("Och noe") + } + } + }, + br, + "Col", + Column { + Row { "1", "2", "3" }, + Row { "3", "4", "6" } + }, + br, + "Grid", + Grid { + Span { 2, QString("1111111") }, "3", br, + "3", "4", "6", br, + "4", empty, "6", br, + hr, "4", "6" + }, + br, + Column { + Label { + text("Hi"), + size(30, 20) + }, + Row { + SpinBox { + onTextChanged([&](const QString &text) { textId->setText(text); }) + }, + st, + PushButton { + text("Quit"), + onClicked(QApplication::quit, nullptr) + } + } + } + } + }.show(); + + return app.exec(); +} diff --git a/tests/manual/otherfiles/dummy_taskfile.tasks b/tests/manual/otherfiles/dummy_taskfile.tasks new file mode 100644 index 0000000000..1317a0e4c1 --- /dev/null +++ b/tests/manual/otherfiles/dummy_taskfile.tasks @@ -0,0 +1,65 @@ +ba/Z6xF/M0IIRI2d5pvaSyknCSyOAissFvJYsntwrQ.h 4762 other unused +/iQTQFzlxBsJGnfJbt5rCA8YH4oe7rqvyW3hCrWO84QN.cpp 4104 error dummy information +/2Sm4hfyhGRG8TAXhYv874ysHRuEuabzjz1/gdng7MHZIhyp2S.h 9442 other syntax error +/Oc2S9dMhbZDZymQChSiiv3Brqqp1FzSUUfnxhFHAvnwk3rSbMd.cpp 282 warn missing information +/igZwSBi65YI9RZCkYucjgnA0nFzyhwQHsR5zIHbCFBz69oSo.h 2266 error missing information +/Z6hIBPwiXv3lxn2WggqDP62WLthQxPdQmzjSHd.cpp 9289 error unknown error +sdef/rpx9V404NdbmV/9Ph7jXqAsK7wsB31y6Tx9KIBG.h 8316 other missing information +/tRdL//67g/paZsnLpdGN4J6q6/RdBYYVXSpP1djxfg3w.cpp 4717 error not found +/EdL/stJAk2wbrL1V21xUSbfX3OVV5hWDz0O9r6fYsV93yU.h 1894 warn unknown error +/aAokPAGz8zR6AiBN19mndJRs7w84oQlxUFkBSYrn.cpp 1102 other syntax error +/6uwjGfQ2o/j5/SEUbs57xxqxIMSl14deuLY7km5oLBc.h 9359 warn unused +/nBQ8eQ63Sb4HZc5lE2yvWZwck6OSx9zwT9hpzL.cpp 2969 warn syntax error +sdf/SqzyeibvrCAHNelVI715AtjFC83Q4feZpepvCMr78Kb8.h 3691 error unknown error +/xhlVpBsiOkm0ZmH01wXXk0QHImeJbcCOF7/M4f.cpp 1038 other unused +/8gvIBNXwX3l224T/4l75YAzmOvMcyHW/plILha7.h 2525 warn unused +/uu46Fvj6IwAptMDDaN23HzoyBQ61Ls917LOoWMZfhLX.cpp 4573 other dummy information +/rJcO7WZR2fGNYO3pTvnyXOFELxAfsuSCffRb/aMfm5.h 5148 warn missing information +/Srj2krdE/UPV1OYlZSYOu6w10kgzBscAfqw//9776pSGa8L76.cpp 4690 warn dummy information +/VlJRNSuHVpjFqCQVVWPf7R4gOSoRuGPxtGpO/xjuLceiHf.h 9683 error syntax error +sdf/Q/YgTtEdgAj9PzbPyBF604wEZSYXrciun69ut57e.cpp 8272 error not found +/rapyyxw6cXoUd9XHWCx4V4IwO9g0LlVyXFmh5sXJk8xvuZCq.h 4329 warn syntax error +/TVizFLbV7VZVeX56p3Mc2olEeNWSEIpI9iZaBhmgm/.cpp 692 error not found +sdf/Yaoc6iF24WOdamUb5j2/SDfeBoW5U92nig/6XkpE3pyEX9m.h 8336 warn syntax error +/rnUQ3Ew7J8yWckFBbfMg8qAMuEMgTIv0UryeYMw.cpp 8612 error unused +/6AJYrSTsALywqx8TinQxxsfu7Qu19xgb4Shm3uxUVmOC.h 3948 warn dummy information +/owg0bC1TF0ImRR7acppvAJhdBT6cUadw8696pOVgpx2oa40.cpp 4850 error not found +//LbsNqHaAIdYRDMwBKr7nmZ1b4njJTb1h1WSl60F.h 4893 warn missing information +/ivHIukAf5HoFD6cxs34JkKnHrlrxD73WRi7UvfzBQt.cpp 7724 warn dummy information +/Tivy85ab71MZu5bta8ordtMzAa38Y8LAZcs61eJLHNXP.h 7556 error unused +sdf/RZEHytd0Kmq5VUCoLqNAhAI3hlZlxltDTDdWU3WV2yuktyfg.cpp 6721 error dummy information +/ENk8j0noHhsZbTlqRJ46cDhjZ7PHDhfa7te8n1OsXgVO.h 5374 error missing information +/edEInJsvjm3dqakU9oyYMT7Nybmet4L6olT/dedWLDltWEjz.cpp 9621 other missing information +/q1MlgSvwv8Ikq4Bjcqa0X9OY/q1GRQ5ARhejOOZKu15XDVb7/M.h 1068 error dummy information +/EvcJN3d5iiIP4H2TLC6ssHeQoTUf/HHC1/gq8m.cpp 7062 warn dummy information +sdfxc/XISMZsHJSJNL1jKTYE1ZyJK9ekBnx4WpyrVdNjmRasxm.h 8513 error unknown error +/uJWF20pUZPpedDMfGNz0cCCwIymTW1JtxK5ut4fHScwq.cpp 1234 error syntax error +/kgQCRBmcKWNd966rPIz4IPfekDqxjQm1eAZ7/Y3Vl8.h 476 error unknown error +/I3aGZ2vLcuMjmcUI40eB4XTwsYQ34sSIgcj28SRPVRyu8.cpp 2175 error dummy information +/q3M0KxZi3Umo2CWe9EzDqMo4LcNVeQhrnV2Yu7zR.h 3969 error syntax error +/tcVCRlsoFo61oIMMwP8seWKpKfC8KskferbtgI.cpp 10 warn not found +sdf/wQSRjPZZJwzREWemLQ96RisR0x2HKpVvZTohxwWRVevBIrtN2.h 5836 error unknown error +/cgMEkzRs9dJfJZvejXqppDjyhbT8gs6/Q07mSJPOQD.cpp 3882 error unknown error +/CBipJCtJq5JHOtz5njHmH6eM5dvPjRQ3KO0PDXUIghI3rO6pm.h 3818 error not found +/ucFWsPMwDK3d8OuKH2d5kfrHTsz2Nlw8wZV4MfNzm.cpp 1303 error missing information +/eiWeH306mDV9AZKSqRV/h2OhJlmXuvPUuLrmUoDfvK.h 887 warn dummy information +/nSaLMeLNeFgWkppVcacpGzQbnwDgnHy43/P0zDb6y/4PWkIyKq.cpp 7644 error unknown error +/BF1mxdQbpB7spT8uj/XPjkxRyKJXO53v0RDs3c.h 4909 other unknown error +/HLpMI/AdAabKQJgZ3CfoZ3IkUH8d2AKak6WME/Ff2.cpp 92 error dummy information +/rM2GH8fkUddRFYRc4ZAxoNmZVnccOQ13sRTAMp.h 2487 error dummy information +/pQ4QD264U3z1H1odOUGSuDpvq9FIMlonytSsNpUnVkBMTl.cpp 835 error syntax error +/olSx6ZAKh7x43uFC6TeSqfdRsnNHozb1Oa8jgHuAx.h 8006 error unknown error +/36QcXAGehPbcSpreu8Dps1jTYaGLhYokbga3Ez.cpp 1219 warn missing information +/kLtmnkB88UvQNB2tNpQkEIRBPk2w9VQY4XKWwkcNsGYN.h 9212 warn dummy information +/HdhlYekmcIsnI4752ng8bT/sJEzpP/rbqrOLJ47.cpp 2818 warn syntax error +/nSQVu9In4/D3Mo2JQfjLuMzz49ZC1K/OQkO0t6Vibrl.h 6785 error missing information +/uOyhgr9Y5cvev6HeW9GAiy2g6QMDzUBABLNb5KIHLaJiKHsUXu.cpp 5833 warn syntax error +/vej4BOeRTak5ILrWzxPhYLXCx7akC8LXkVKwbJyok4r80tstgr.h 1863 other syntax error +/jGz0VyhokwjE4mmQSMpPoKK5teActVfmL2CGupQT39.cpp 175 warn unknown error +/PCcGDSa7h208wlJz1wa81nREtA/Kx/ZAMraQQ9QYTg.h 7977 other unused +/OaEQzW35Ng2yeSqs41f6ji/RWSnx71G4BlmlWX.cpp 3650 warn not found +/1e6Ric7K9WElXkBE6ymSMPXtFuu86QbI8mYAEy63c1Asp/hO.h 3725 error unknown error +/qaPzTGefWpHBNGX3XWne5zBkkLCBiMi3mm9x2cIU9l9szD.cpp 1338 warn syntax error +/YAPg7LHxjrOeBJ4CZBVkoXR6lKI7jrSV5bD7kfXOAf8mzM.h 3389 error unused +/IMjUnSaqSsKs5xCzhDcrgk1saAcr2wKnJZ3tyxI6VbSeX.cpp 2404 other unknown error +/5rQ9UzSyJFvYZhyI9sItDZHnBrANcz84rtDfDfJh.h 7293 warn not found diff --git a/tests/manual/pluginview/plugindialog.cpp b/tests/manual/pluginview/plugindialog.cpp index d1ed1d906d..24232540d9 100644 --- a/tests/manual/pluginview/plugindialog.cpp +++ b/tests/manual/pluginview/plugindialog.cpp @@ -114,7 +114,7 @@ int main(int argc, char *argv[]) QObject::connect(&app, &QCoreApplication::aboutToQuit, &manager, &ExtensionSystem::PluginManager::shutdown); PluginDialog dialog; - manager.setPluginPaths(QStringList() << app.applicationDirPath() + "/plugins"); + manager.setPluginPaths({FilePath::fromUserInput(app.applicationDirPath()) / "plugins"}); manager.loadPlugins(); dialog.show(); app.exec(); diff --git a/tests/manual/spinner/main.cpp b/tests/manual/spinner/main.cpp index ac98284fb8..6aab09f0c7 100644 --- a/tests/manual/spinner/main.cpp +++ b/tests/manual/spinner/main.cpp @@ -50,6 +50,20 @@ QGroupBox *createGroupBox(SpinnerSize size, QWidget *widget) return groupBox; } +QGroupBox *createColorsGroupBox() +{ + QGroupBox *groupBox = new QGroupBox("Spinner::setColor(const QColor &color)"); + auto layout = new QHBoxLayout(groupBox); + for (auto color : {Qt::red, Qt::darkGreen, Qt::blue, Qt::darkYellow}) { + auto widget = new QWidget; + widget->setFixedSize(30, 30); + auto spinner = new Spinner(SpinnerSize::Medium, widget); + spinner->setColor(color); + layout->addWidget(widget); + } + return groupBox; +} + static QWidget *hr() { auto frame = new QFrame; @@ -91,6 +105,8 @@ int main(int argc, char *argv[]) QGroupBox *largeGroupBox = createGroupBox(SpinnerSize::Large, largeWidget); mainLayout->addWidget(largeGroupBox); + mainLayout->addWidget(createColorsGroupBox()); + mainWidget.show(); return app.exec(); diff --git a/tests/manual/subdirfilecontainer/tst_subdirfilecontainer.cpp b/tests/manual/subdirfilecontainer/tst_subdirfilecontainer.cpp index 89993b6a2b..ca4925a943 100644 --- a/tests/manual/subdirfilecontainer/tst_subdirfilecontainer.cpp +++ b/tests/manual/subdirfilecontainer/tst_subdirfilecontainer.cpp @@ -247,12 +247,7 @@ private slots: QDirIterator it(m_tempDir->path(), s_filters, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks); while (it.hasNext()) { -#if QT_VERSION >= QT_VERSION_CHECK(6, 3, 0) const QFileInfo fi = it.nextFileInfo(); -#else - it.next(); - const QFileInfo fi = it.fileInfo(); -#endif if (fi.isDir()) { ++dirsCount; } else { diff --git a/tests/manual/tasking/dataexchange/recipe.cpp b/tests/manual/tasking/dataexchange/recipe.cpp index 445f246bba..cb472eafd4 100644 --- a/tests/manual/tasking/dataexchange/recipe.cpp +++ b/tests/manual/tasking/dataexchange/recipe.cpp @@ -76,7 +76,7 @@ Group recipe(const Storage<ExternalData> &externalStorage) ConcurrentCallTask<QImage>(onReadSetup, onReadDone), Group { repeater, - parallelLimit(QThread::idealThreadCount() - 1), + parallelIdealThreadCountLimit, ConcurrentCallTask<QImage>(onScaleSetup, onScaleDone) } }; diff --git a/tests/manual/widgets/layoutbuilder/tst_manual_widgets_layoutbuilder.cpp b/tests/manual/widgets/layoutbuilder/tst_manual_widgets_layoutbuilder.cpp index 343c500c28..eda6a565b1 100644 --- a/tests/manual/widgets/layoutbuilder/tst_manual_widgets_layoutbuilder.cpp +++ b/tests/manual/widgets/layoutbuilder/tst_manual_widgets_layoutbuilder.cpp @@ -24,9 +24,9 @@ int main(int argc, char *argv[]) }; Row { - PushButton { text("-"), onClicked(minusClick) }, + PushButton { text("-"), onClicked(minusClick, nullptr) }, lineEdit, - PushButton { text("+"), onClicked(plusClick) }, + PushButton { text("+"), onClicked(plusClick, nullptr) }, Group { title("Splitter in Group"), Column { @@ -52,8 +52,8 @@ int main(int argc, char *argv[]) Splitter { windowTitle("Splitter with sub layouts"), - Column {"First Widget"}, - Row {"Second Widget"}, + Column { QString("First Widget") }, + Row { QString("Second Widget") }, }.emerge()->show(); return app.exec(); diff --git a/tests/manual/widgets/uifonts/tst_manual_widgets_uifonts.cpp b/tests/manual/widgets/uifonts/tst_manual_widgets_uifonts.cpp index 4d324ec265..247bba6772 100644 --- a/tests/manual/widgets/uifonts/tst_manual_widgets_uifonts.cpp +++ b/tests/manual/widgets/uifonts/tst_manual_widgets_uifonts.cpp @@ -67,18 +67,20 @@ int main(int argc, char *argv[]) } html.append("</table></body></html>"); - Column { - windowTitle("Utils::StyleHelper::uiFont"), - Group { - title("As QFont in QLabel"), - fontLabels, - }, - Group { - title("As inline CSS in HTML elements"), - Row { html }, - }, - st, - }.emerge()->show(); + Widget { + windowTitle(QString("Utils::StyleHelper::uiFont")), + Column { + Group { + title(QString("As QFont in QLabel")), + fontLabels, + }, + Group { + title(QString("As inline CSS in HTML elements")), + Row { html }, + }, + st, + } + }.show(); return app.exec(); } diff --git a/tests/system/shared/debugger.py b/tests/system/shared/debugger.py index 5ee31dec20..17f357881b 100644 --- a/tests/system/shared/debugger.py +++ b/tests/system/shared/debugger.py @@ -126,7 +126,7 @@ def doSimpleDebugging(currentKit, currentConfigName, expectedBPOrder=[], enableQ expectedLabelTexts.append("Running\.") switchViewTo(ViewConstants.PROJECTS) switchToBuildOrRunSettingsFor(currentKit, ProjectSettings.RUN) - selectFromCombo(":EnableQMLDebugger_ComboBox", "Enabled" if enableQml else "Disabled") + selectFromCombo(":EnableQMLDebugger_ComboBox", "Enable" if enableQml else "Disable") switchViewTo(ViewConstants.EDIT) if not __startDebugger__(currentKit, currentConfigName): return False diff --git a/tests/system/shared/project_explorer.py b/tests/system/shared/project_explorer.py index 447b8057d5..f74e3a107e 100644 --- a/tests/system/shared/project_explorer.py +++ b/tests/system/shared/project_explorer.py @@ -24,6 +24,9 @@ def iterateConfiguredKits(): kitIndices = dumpIndices(treeView.model(), waitForObject(bAndRIndex)) configuredKitNames = map(lambda t: str(t.data(0)), filter(__kitIsActivated__, kitIndices)) + # Remove hide/show entries which are in tree but not kits + configuredKitNames = filter(lambda n: n != "Hide Inactive Kits" and n != "Show All Kits", + configuredKitNames) return map(Targets.getIdForTargetName, configuredKitNames) diff --git a/tests/system/shared/utils.py b/tests/system/shared/utils.py index 623287563a..221e4eeada 100644 --- a/tests/system/shared/utils.py +++ b/tests/system/shared/utils.py @@ -265,7 +265,6 @@ def selectFromFileDialog(fileName, waitForFile=False, ignoreFinalSnooze=False): def addHelpDocumentation(which): invokeMenuItem("Edit", "Preferences...") mouseClick(waitForObjectItem(":Options_QListView", "Help")) - waitForObject("{container=':Options.qt_tabwidget_tabbar_QTabBar' type='TabItem' text='Documentation'}") clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "Documentation") # get rid of all docs already registered listWidget = waitForObject("{type='QListView' name='docsListView' visible='1'}") @@ -293,7 +292,6 @@ def addCurrentCreatorDocumentation(): return invokeMenuItem("Edit", "Preferences...") mouseClick(waitForObjectItem(":Options_QListView", "Help")) - waitForObject("{container=':Options.qt_tabwidget_tabbar_QTabBar' type='TabItem' text='Documentation'}") clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "Documentation") clickButton(waitForObject("{type='QPushButton' name='addButton' visible='1' text='Add...'}")) selectFromFileDialog(docPath) @@ -472,13 +470,6 @@ def setFixedHelpViewer(helpViewer): selectFromCombo(":Startup.contextHelpComboBox_QComboBox", mode) clickButton(waitForObject(":Options.OK_QPushButton")) -def removePackagingDirectory(projectPath): - qtcPackaging = os.path.join(projectPath, "qtc_packaging") - if os.path.exists(qtcPackaging): - test.log("Removing old packaging directory '%s'" % qtcPackaging) - deleteDirIfExists(qtcPackaging) - else: - test.log("Couldn't remove packaging directory '%s' - did not exist." % qtcPackaging) # returns the indices from a QAbstractItemModel def dumpIndices(model, parent=None, column=0): @@ -547,6 +538,7 @@ def clickOnTab(tabBarStr, tabText, timeout=5000): test.log("Using workaround for Mac and Windows.") setWindowState(tabBar, WindowState.Normal) tabBar = waitForObject(tabBarStr, 2000) + waitForObject("{container='%s' type='TabItem' text='%s'}" % (tabBarStr, tabText)) clickTab(tabBar, tabText) waitFor("str(tabBar.tabText(tabBar.currentIndex)) == '%s'" % tabText, timeout) @@ -638,3 +630,13 @@ class GitClone: def __exit__(self, exc_type, exc_value, traceback): deleteDirIfExists(self.localPath) + + +def setReloadBehavior(to): + # QC 14 changed the default, so change the preferences + invokeMenuItem("Edit", "Preferences...") + mouseClick(waitForObjectItem(":Options_QListView", "Environment")) + clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "System") + selectFromCombo("{type='QComboBox' unnamed='1' leftWidget={type='QLabel' " + "text='When files are externally modified:'}}", to) + clickButton(":Options.OK_QPushButton") diff --git a/tests/system/suite_WELP/tst_WELP03/test.py b/tests/system/suite_WELP/tst_WELP03/test.py index 50f7b503cc..8d4fa29a9b 100644 --- a/tests/system/suite_WELP/tst_WELP03/test.py +++ b/tests/system/suite_WELP/tst_WELP03/test.py @@ -83,8 +83,6 @@ def main(): proFiles = [os.path.join(p, "opengl", "2dpainting", "2dpainting.pro") for p in QtPath.getPaths(QtPath.EXAMPLES)] cleanUpUserFiles(proFiles) - for p in proFiles: - removePackagingDirectory(os.path.dirname(p)) example = openExample(examplesLineEdit, "2d painting", "2D Painting.*", "2D Painting Example") if example is not None: @@ -96,17 +94,12 @@ def main(): waitFor("navTree.model().rowCount(navTree.rootIndex()) == 0", 2000) test.verify(not checkIfObjectItemExists(":Qt Creator_Utils::NavigationTreeView", "2dpainting"), "Verifying: The first example is closed.") - # clean up created packaging directories - for p in proFiles: - removePackagingDirectory(os.path.dirname(p)) # go to "Welcome" page and choose another example switchViewTo(ViewConstants.WELCOME) proFiles = [os.path.join(p, "widgets", "itemviews", "addressbook", "addressbook.pro") for p in QtPath.getPaths(QtPath.EXAMPLES)] cleanUpUserFiles(proFiles) - for p in proFiles: - removePackagingDirectory(os.path.dirname(p)) examplesLineEdit = waitForObject(search %(expect[1][0], expect[1][1])) example = openExample(examplesLineEdit, "address book", "(0000 )?Address Book.*", "Address Book Example", 3) @@ -122,8 +115,5 @@ def main(): waitFor("navTree.model().rowCount(navTree.rootIndex()) == 0", 2000) test.verify(not checkIfObjectItemExists(":Qt Creator_Utils::NavigationTreeView", "addressbook"), "Verifying: The second example is closed.") - # clean up created packaging directories - for p in proFiles: - removePackagingDirectory(os.path.dirname(p)) # exit Qt Creator invokeMenuItem("File", "Exit") diff --git a/tests/system/suite_debugger/tst_qml_js_console/test.py b/tests/system/suite_debugger/tst_qml_js_console/test.py index 4760296cf6..a64a24ad77 100644 --- a/tests/system/suite_debugger/tst_qml_js_console/test.py +++ b/tests/system/suite_debugger/tst_qml_js_console/test.py @@ -114,7 +114,7 @@ def main(): # make sure QML Debugging is enabled switchViewTo(ViewConstants.PROJECTS) switchToBuildOrRunSettingsFor(Targets.getDefaultKit(), ProjectSettings.RUN) - selectFromCombo(":EnableQMLDebugger_ComboBox", "Enabled") + selectFromCombo(":EnableQMLDebugger_ComboBox", "Enable") switchViewTo(ViewConstants.EDIT) # start debugging clickButton(fancyDebugButton) diff --git a/tests/system/suite_debugger/tst_qml_locals/test.py b/tests/system/suite_debugger/tst_qml_locals/test.py index 37ecb515cc..80c04167e1 100644 --- a/tests/system/suite_debugger/tst_qml_locals/test.py +++ b/tests/system/suite_debugger/tst_qml_locals/test.py @@ -35,7 +35,7 @@ def main(): return switchViewTo(ViewConstants.PROJECTS) switchToBuildOrRunSettingsFor(Targets.getDefaultKit(), ProjectSettings.RUN) - selectFromCombo(":EnableQMLDebugger_ComboBox", "Enabled") + selectFromCombo(":EnableQMLDebugger_ComboBox", "Enable") switchViewTo(ViewConstants.EDIT) clickButton(fancyDebugButton) locAndExprTV = waitForObject(":Locals and Expressions_Debugger::Internal::WatchTreeView") diff --git a/tests/system/suite_editors/tst_clean_whitespaces/test.py b/tests/system/suite_editors/tst_clean_whitespaces/test.py index 7803027f86..1f5eb7a255 100644 --- a/tests/system/suite_editors/tst_clean_whitespaces/test.py +++ b/tests/system/suite_editors/tst_clean_whitespaces/test.py @@ -111,8 +111,6 @@ def isIgnoredFile(fileName, ignoredFiles): def ignoredFilesFromSettings(): invokeMenuItem("Edit", "Preferences...") mouseClick(waitForObjectItem(":Options_QListView", "Text Editor")) - waitForObject("{container=':Options.qt_tabwidget_tabbar_QTabBar' type='TabItem' " - "text='Behavior'}") clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "Behavior") cleanWhiteSpaceCB = "{type='QCheckBox' text='Skip clean whitespace for file types:'}" ensureChecked(cleanWhiteSpaceCB) diff --git a/tests/system/suite_editors/tst_delete_externally/test.py b/tests/system/suite_editors/tst_delete_externally/test.py index e36377cb56..31583877c7 100644 --- a/tests/system/suite_editors/tst_delete_externally/test.py +++ b/tests/system/suite_editors/tst_delete_externally/test.py @@ -10,6 +10,9 @@ def main(): startQC() if not startedWithoutPluginError(): return + + setReloadBehavior("Always Ask") + for currentFile in files: test.log("Opening file %s" % currentFile) invokeMenuItem("File", "Open File or Project...") diff --git a/tests/system/suite_editors/tst_edit_externally/test.py b/tests/system/suite_editors/tst_edit_externally/test.py index e04ab19670..13cd68127f 100644 --- a/tests/system/suite_editors/tst_edit_externally/test.py +++ b/tests/system/suite_editors/tst_edit_externally/test.py @@ -23,6 +23,8 @@ def main(): if not startedWithoutPluginError(): return + setReloadBehavior("Always Ask") + mBox = ("{text?='The file * has been changed on disk. Do you want to reload it?' " "type='QMessageBox' unnamed='1' visible='1'}") popupText = ("<p>The file <i>%s</i> has been changed on disk. Do you want to reload it?</p>" diff --git a/tests/system/suite_editors/tst_generic_highlighter/test.py b/tests/system/suite_editors/tst_generic_highlighter/test.py index ea6c7aee40..13dda9bada 100644 --- a/tests/system/suite_editors/tst_generic_highlighter/test.py +++ b/tests/system/suite_editors/tst_generic_highlighter/test.py @@ -32,8 +32,6 @@ def getOrModifyFilePatternsFor(mimeType, filter='', toBePresent=None): result = [] invokeMenuItem("Edit", "Preferences...") mouseClick(waitForObjectItem(":Options_QListView", "Environment")) - waitForObject("{container=':Options.qt_tabwidget_tabbar_QTabBar' type='TabItem' " - "text='MIME Types'}") clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "MIME Types") replaceEditorContent(waitForObject("{name='filterLineEdit' type='Utils::FancyLineEdit' " "visible='1'}"), filter) @@ -95,8 +93,6 @@ def addHighlighterDefinition(*languages): test.log("Updating highlighter definitions...") invokeMenuItem("Edit", "Preferences...") mouseClick(waitForObjectItem(":Options_QListView", "Text Editor")) - waitForObject("{container=':Options.qt_tabwidget_tabbar_QTabBar' type='TabItem' " - "text='Generic Highlighter'}") clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "Generic Highlighter") test.log("Trying to download definitions...") diff --git a/tests/system/suite_general/tst_create_proj_wizard/test.py b/tests/system/suite_general/tst_create_proj_wizard/test.py index 78178d82bb..176b606b8b 100644 --- a/tests/system/suite_general/tst_create_proj_wizard/test.py +++ b/tests/system/suite_general/tst_create_proj_wizard/test.py @@ -113,10 +113,7 @@ def handleBuildSystemVerifyKits(category, template, kits, displayedPlatforms, return fixedBuildSystems = list(availableBuildSystems) - if template == 'Qt Quick Application': - fixedBuildSystems.remove('qmake') - test.log("Skipped qmake (not supported).") - elif template == 'Qt Quick 2 Extension Plugin': + if template == 'Qt Quick 2 Extension Plugin': fixedBuildSystems.remove('Qbs') test.log("Skipped Qbs (not supported).") @@ -126,7 +123,7 @@ def handleBuildSystemVerifyKits(category, template, kits, displayedPlatforms, clickButton(waitForObject(":Next_QPushButton")) if specialHandlingFunc: specialHandlingFunc(displayedPlatforms, *args) - if not ('Plain C' in template or template == 'Qt Quick Application'): + if not ('Plain C' in template): __createProjectHandleTranslationSelection__() verifyKitCheckboxes(kits, displayedPlatforms) safeClickButton("Cancel") diff --git a/tests/system/suite_general/tst_installed_languages/test.py b/tests/system/suite_general/tst_installed_languages/test.py index 75a60e8fd0..e48abed67f 100644 --- a/tests/system/suite_general/tst_installed_languages/test.py +++ b/tests/system/suite_general/tst_installed_languages/test.py @@ -32,6 +32,5 @@ def main(): except: test.fail("Creator seems to be missing %s translation" % languageName) sendEvent("QCloseEvent", ":Qt Creator_Core::Internal::MainWindow") - waitForCleanShutdown() __removeTestingDir__() copySettingsToTmpDir() diff --git a/tests/system/suite_general/tst_remove_kits/test.py b/tests/system/suite_general/tst_remove_kits/test.py index 365f4b217f..652390e010 100644 --- a/tests/system/suite_general/tst_remove_kits/test.py +++ b/tests/system/suite_general/tst_remove_kits/test.py @@ -8,7 +8,9 @@ def verifyProjectsMode(expectedKits): bAndRIndex = getQModelIndexStr("text='Build & Run'", ":Projects.ProjectNavigationTreeView") foundKits = dumpItems(treeView.model(), waitForObject(bAndRIndex)) - relevantKits = list(filter(lambda x: 'Python' not in x,foundKits)) # ignore Python kits + # ignore Python kits and non-kit item + excludes = ('Python', 'Hide Inactive Kits', 'Show All Kits') + relevantKits = list(filter(lambda x: all(ex not in x for ex in excludes), foundKits)) test.compare(len(relevantKits), len(expectedKits), "Verify number of listed kits.") test.compare(set(relevantKits), set(expectedKits), "Verify if expected kits are listed.") hasKits = len(expectedKits) > 0 diff --git a/tests/system/suite_tools/tst_designer_autocomplete/test.py b/tests/system/suite_tools/tst_designer_autocomplete/test.py index b378407f81..c77d4b5f18 100644 --- a/tests/system/suite_tools/tst_designer_autocomplete/test.py +++ b/tests/system/suite_tools/tst_designer_autocomplete/test.py @@ -48,12 +48,15 @@ def main(): snooze(1) type(editor, ">") snooze(1) + proposalExists = lambda: object.exists(':popupFrame_TextEditor::GenericProposalWidget') nativeType("%s" % buttonName[0]) - test.verify(waitFor("object.exists(':popupFrame_TextEditor::GenericProposalWidget')", 1500), - "Verify that GenericProposalWidget is being shown.") - nativeType("<Return>") - test.verify(waitFor('str(lineUnderCursor(editor)).strip() == "ui->%s" % buttonName', 1000), - 'Comparing line "%s" to expected "%s"' % (lineUnderCursor(editor), "ui->%s" % buttonName)) + if test.verify(waitFor(proposalExists, 4000), + "Verify that GenericProposalWidget is being shown."): + nativeType("<Return>") + lineCorrect = lambda: str(lineUnderCursor(editor)).strip() == "ui->%s" % buttonName + test.verify(waitFor(lineCorrect, 1000), + ('Comparing line "%s" to expected "%s"' + % (lineUnderCursor(editor), "ui->%s" % buttonName))) type(editor, "<Shift+Delete>") # Delete line selectFromLocator("mainwindow.ui") saveAndExit() diff --git a/tests/tools/qml-ast2dot/CMakeLists.txt b/tests/tools/qml-ast2dot/CMakeLists.txt index ba4acfb9dc..69ecc371f9 100644 --- a/tests/tools/qml-ast2dot/CMakeLists.txt +++ b/tests/tools/qml-ast2dot/CMakeLists.txt @@ -1,6 +1,6 @@ add_qtc_executable(qml_ast2dot BUILD_DEFAULT OFF - DEPENDS Qt::Core Qt::Gui QmlJS + DEPENDS Qt::Core Qt::Gui QmlJS Utils SOURCES main.cpp ) diff --git a/tests/tools/qml-ast2dot/main.cpp b/tests/tools/qml-ast2dot/main.cpp index eed9c8604a..8b3508e99e 100644 --- a/tests/tools/qml-ast2dot/main.cpp +++ b/tests/tools/qml-ast2dot/main.cpp @@ -7,6 +7,8 @@ #include <qmljs/qmljsdocument.h> #include <qmljs/qmljsmodelmanagerinterface.h> +#include <utils/filepath.h> + #include <QFile> #include <QList> #include <QCoreApplication> @@ -307,7 +309,8 @@ int main(int argc, char *argv[]) const QByteArray source = file.readAll(); file.close(); - Document::MutablePtr doc = Document::create(fileName, ModelManagerInterface::guessLanguageOfFile(fileName)); + const Utils::FilePath filePath = Utils::FilePath::fromUserInput(fileName); + Document::MutablePtr doc = Document::create(filePath, ModelManagerInterface::guessLanguageOfFile(filePath)); doc->setSource(QString::fromUtf8(source)); doc->parse(); diff --git a/tests/tools/qml-ast2dot/qml-ast2dot.qbs b/tests/tools/qml-ast2dot/qml-ast2dot.qbs index 2fbf3676c9..1b067995ad 100644 --- a/tests/tools/qml-ast2dot/qml-ast2dot.qbs +++ b/tests/tools/qml-ast2dot/qml-ast2dot.qbs @@ -2,6 +2,7 @@ import qbs.FileInfo CppApplication { Depends { name: "QmlJS" } + Depends { name: "Utils" } Depends { name: "Qt.gui" } cpp.cxxLanguageVersion: "c++17" diff --git a/tests/unit/.clang-format b/tests/unit/.clang-format index 87648a2057..366f82f76f 100644 --- a/tests/unit/.clang-format +++ b/tests/unit/.clang-format @@ -1,92 +1,32 @@ Language: Cpp AccessModifierOffset: -4 -AlignAfterOpenBracket: Align -AlignConsecutiveAssignments: false -AlignConsecutiveDeclarations: false AlignEscapedNewlines: DontAlign -AlignOperands: true -AlignTrailingComments: true -AllowAllArgumentsOnNextLine: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortBlocksOnASingleLine: false -AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: Inline -AllowShortLambdasOnASingleLine: All -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: true +AlwaysBreakTemplateDeclarations: true # use with clang 19 BinPackArguments: false BinPackParameters: false BraceWrapping: AfterClass: true - AfterControlStatement: false - AfterEnum: false AfterFunction: true - AfterNamespace: false - AfterObjCDeclaration: false AfterStruct: true - AfterUnion: false - BeforeCatch: false - BeforeElse: false - IndentBraces: false SplitEmptyFunction: false SplitEmptyRecord: false SplitEmptyNamespace: false -BreakAfterAttributes: Never BreakBeforeBinaryOperators: All BreakBeforeBraces: Custom -BreakBeforeConceptDeclarations: Always -BreakBeforeInheritanceComma: false -BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: false BreakConstructorInitializers: BeforeComma -BreakAfterJavaFieldAnnotations: false BreakInheritanceList: AfterComma -BreakStringLiterals: true +# BreakTemplateDeclarations: Yes # use with clang 19 ColumnLimit: 100 -CommentPragmas: '^ IWYU pragma:' -CompactNamespaces: false -ConstructorInitializerAllOnOneLineOrOnePerLine: false -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 4 -Cpp11BracedListStyle: true -DerivePointerAlignment: false -DisableFormat: false -EmptyLineAfterAccessModifier: Never -EmptyLineBeforeAccessModifier: LogicalBlock -ExperimentalAutoDetectBinPacking: false -FixNamespaceComments: true -ForEachMacros: - - forever # avoids { wrapped to next line - - foreach - - Q_FOREACH - - BOOST_FOREACH -#IncludeBlocks: Regroup IncludeCategories: - - Regex: '^<Q.*' - Priority: 200 -IncludeIsMainRegex: '(Test)?$' -IndentCaseBlocks: false -IndentCaseLabels: false + - Regex: 'Q.*' + Priority: 8 + CaseSensitive: true IndentPPDirectives: AfterHash -IndentRequiresClause: true IndentWidth: 4 -IndentWrappedFunctionNames: false -InsertBraces : false -JavaScriptQuotes: Leave -JavaScriptWrapImports: true KeepEmptyLinesAtTheStartOfBlocks: false # Do not add QT_BEGIN_NAMESPACE/QT_END_NAMESPACE as this will indent lines in between. -LambdaBodyIndentation: Signature -MacroBlockBegin: "" -MacroBlockEnd: "" -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: None ObjCBlockIndentWidth: 4 -ObjCSpaceAfterProperty: false -ObjCSpaceBeforeProtocolList: true PPIndentWidth: 2 PackConstructorInitializers: Never PenaltyBreakAssignment: 500 @@ -96,40 +36,15 @@ PenaltyBreakFirstLessLess: 400 PenaltyBreakString: 600 PenaltyExcessCharacter: 7 PenaltyReturnTypeOnItsOwnLine: 300 -PointerAlignment: Right QualifierAlignment: Custom QualifierOrder: ['friend', 'inline', 'static', 'constexpr', 'const', 'type'] -ReflowComments: false ReferenceAlignment: Right -RequiresClausePosition: OwnLine +ReflowComments: false SeparateDefinitionBlocks: Always -ShortNamespaceLines: 1 -SortIncludes: CaseInsensitive SortUsingDeclarations: Lexicographic SpaceAfterCStyleCast: true -SpaceAfterLogicalNot: false SpaceAfterTemplateKeyword: false -SpaceBeforeAssignmentOperators: true -SpaceInEmptyParentheses: false -SpaceBeforeCpp11BracedList: false -SpaceBeforeCtorInitializerColon: true -SpaceBeforeInheritanceColon: true SpaceBeforeParens: ControlStatementsExceptControlMacros -SpaceBeforeRangeBasedForLoopColon: true -SpaceBeforeSquareBrackets: false -SpaceInEmptyBlock: false -SpacesBeforeTrailingComments: 1 -SpacesInAngles: Never -SpacesInConditionalStatement: false SpacesInContainerLiterals: false -SpacesInLineCommentPrefix: - Minimum: 1 - Maximum: -1 -SpacesInCStyleCastParentheses: false -SpacesInParentheses: false -SpacesInSquareBrackets: false -Standard: Latest StatementAttributeLikeMacros: [emit] -StatementMacros: [Q_UNUSED] TabWidth: 4 -UseTab: Never diff --git a/tests/unit/tests/matchers/projectstorage-matcher.h b/tests/unit/tests/matchers/projectstorage-matcher.h index 5ce6512c14..56b4ad9d6a 100644 --- a/tests/unit/tests/matchers/projectstorage-matcher.h +++ b/tests/unit/tests/matchers/projectstorage-matcher.h @@ -20,6 +20,7 @@ MATCHER_P2(IsTypeHint, template<typename PropertiesMatcher, typename ExtraFilePathsMatcher> auto IsItemLibraryEntry(QmlDesigner::TypeId typeId, + Utils::SmallStringView typeName, Utils::SmallStringView name, Utils::SmallStringView iconPath, Utils::SmallStringView category, @@ -31,6 +32,7 @@ auto IsItemLibraryEntry(QmlDesigner::TypeId typeId, { using QmlDesigner::Storage::Info::ItemLibraryEntry; return AllOf(Field("typeId", &ItemLibraryEntry::typeId, typeId), + Field("typeName", &ItemLibraryEntry::typeName, typeName), Field("name", &ItemLibraryEntry::name, name), Field("iconPath", &ItemLibraryEntry::iconPath, iconPath), Field("category", &ItemLibraryEntry::category, category), @@ -53,3 +55,24 @@ MATCHER_P3(IsItemLibraryProperty, return property.name == name && property.type == type && property.value == value; } + +template<typename IconPathMatcher, typename TypeTraitsMatcher, typename HintsJsonMatcher, typename ItemLibraryJsonMatcher> +auto IsTypeAnnotation(QmlDesigner::SourceId sourceId, + QmlDesigner::SourceId directorySourceId, + Utils::SmallStringView typeName, + QmlDesigner::ModuleId moduleId, + IconPathMatcher iconPath, + TypeTraitsMatcher traits, + HintsJsonMatcher hintsJsonMatcher, + ItemLibraryJsonMatcher itemLibraryJsonMatcher) +{ + using QmlDesigner::Storage::Synchronization::TypeAnnotation; + return AllOf(Field("sourceId", &TypeAnnotation::sourceId, sourceId), + Field("directory sourceId", &TypeAnnotation::directorySourceId, directorySourceId), + Field("typeName", &TypeAnnotation::typeName, typeName), + Field("moduleId", &TypeAnnotation::moduleId, moduleId), + Field("iconPath", &TypeAnnotation::iconPath, iconPath), + Field("traits", &TypeAnnotation::traits, traits), + Field("hintsJson", &TypeAnnotation::hintsJson, hintsJsonMatcher), + Field("itemLibraryJson", &TypeAnnotation::itemLibraryJson, itemLibraryJsonMatcher)); +} diff --git a/tests/unit/tests/matchers/unittest-matchers.h b/tests/unit/tests/matchers/unittest-matchers.h index 7c52d973b8..faa99a48a2 100644 --- a/tests/unit/tests/matchers/unittest-matchers.h +++ b/tests/unit/tests/matchers/unittest-matchers.h @@ -95,6 +95,64 @@ private: const QString m_suffix; }; +template<typename StringType> +class StartsWithMatcher +{ +public: + explicit StartsWithMatcher(const StringType &prefix) + : m_prefix(prefix) + {} + + template<typename CharType> + bool MatchAndExplain(CharType *s, testing::MatchResultListener *listener) const + { + return s != NULL && MatchAndExplain(StringType(s), listener); + } + + template<typename MatcheeStringType> + bool MatchAndExplain(const MatcheeStringType &s, testing::MatchResultListener * /* listener */) const + { + return s.startsWith(m_prefix); + } + + void DescribeTo(::std::ostream *os) const { *os << "ends with " << m_prefix; } + + void DescribeNegationTo(::std::ostream *os) const { *os << "doesn't end with " << m_prefix; } + + StartsWithMatcher(const StartsWithMatcher &) = default; + StartsWithMatcher &operator=(const StartsWithMatcher &) = delete; + +private: + const StringType m_prefix; +}; + +class QStringStartsWithMatcher +{ +public: + explicit QStringStartsWithMatcher(const QString &prefix) + : m_prefix(prefix) + {} + + template<typename MatcheeStringType> + bool MatchAndExplain(const MatcheeStringType &s, testing::MatchResultListener * /* listener */) const + { + return s.startsWith(m_prefix); + } + + void DescribeTo(::std::ostream *os) const + { + *os << "ends with " << testing::PrintToString(m_prefix); + } + + void DescribeNegationTo(::std::ostream *os) const + { + *os << "doesn't end with " << testing::PrintToString(m_prefix); + } + +private: + const QString m_prefix; +}; + class IsEmptyMatcher { public: @@ -157,6 +215,16 @@ inline auto EndsWith(const QStringView &suffix) return ::testing::PolymorphicMatcher(Internal::QStringEndsWithMatcher(suffix.toString())); } +inline auto StartsWith(const Utils::SmallStringView &prefix) +{ + return ::testing::PolymorphicMatcher(Internal::StartsWithMatcher(prefix)); +} + +inline auto StartsWith(const QStringView &prefix) +{ + return ::testing::PolymorphicMatcher(Internal::QStringStartsWithMatcher(prefix.toString())); +} + inline auto IsEmpty() { return ::testing::PolymorphicMatcher(Internal::IsEmptyMatcher()); diff --git a/tests/unit/tests/mocks/CMakeLists.txt b/tests/unit/tests/mocks/CMakeLists.txt index d209043262..0fdfa639c0 100644 --- a/tests/unit/tests/mocks/CMakeLists.txt +++ b/tests/unit/tests/mocks/CMakeLists.txt @@ -22,6 +22,7 @@ add_qtc_library(TestMocks OBJECT mocktimestampprovider.h modelresourcemanagementmock.h propertycomponentgeneratormock.h + projectstorageerrornotifiermock.h projectstoragemock.cpp projectstoragemock.h projectstorageobservermock.h diff --git a/tests/unit/tests/mocks/externaldependenciesmock.h b/tests/unit/tests/mocks/externaldependenciesmock.h index c4cfe6cd3b..df70a7fcdb 100644 --- a/tests/unit/tests/mocks/externaldependenciesmock.h +++ b/tests/unit/tests/mocks/externaldependenciesmock.h @@ -15,6 +15,7 @@ public: MOCK_METHOD(QString, qmlPuppetFallbackDirectory, (), (const, override)); MOCK_METHOD(QString, defaultPuppetToplevelBuildDirectory, (), (const, override)); MOCK_METHOD(QUrl, projectUrl, (), (const, override)); + MOCK_METHOD(QString, projectName, (), (const, override)); MOCK_METHOD(QString, currentProjectDirPath, (), (const, override)); MOCK_METHOD(QUrl, currentResourcePath, (), (const, override)); MOCK_METHOD(void, parseItemLibraryDescriptions, (), (override)); diff --git a/tests/unit/tests/mocks/filesystemmock.h b/tests/unit/tests/mocks/filesystemmock.h index cb1d4df4bc..f8544e509f 100644 --- a/tests/unit/tests/mocks/filesystemmock.h +++ b/tests/unit/tests/mocks/filesystemmock.h @@ -20,4 +20,5 @@ public: MOCK_METHOD(QmlDesigner::FileStatus, fileStatus, (QmlDesigner::SourceId sourceId), (const, override)); MOCK_METHOD(void, remove, (const QmlDesigner::SourceIds &sourceIds), (override)); MOCK_METHOD(QString, contentAsQString, (const QString &filePath), (const, override)); + MOCK_METHOD(QStringList, subdirectories, (const QString &directoryPath), (const, override)); }; diff --git a/tests/unit/tests/mocks/mocksqlitestatement.h b/tests/unit/tests/mocks/mocksqlitestatement.h index f34b13f6d0..1e55d4c74f 100644 --- a/tests/unit/tests/mocks/mocksqlitestatement.h +++ b/tests/unit/tests/mocks/mocksqlitestatement.h @@ -50,6 +50,8 @@ public: SqliteDatabaseMock &database() { return *m_databaseMock; } + MOCK_METHOD(std::uintptr_t, handle, (), (const)); + private: SqliteDatabaseMock *m_databaseMock = nullptr; }; diff --git a/tests/unit/tests/mocks/projectstorageerrornotifiermock.h b/tests/unit/tests/mocks/projectstorageerrornotifiermock.h new file mode 100644 index 0000000000..730c70a66a --- /dev/null +++ b/tests/unit/tests/mocks/projectstorageerrornotifiermock.h @@ -0,0 +1,17 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "../utils/googletest.h" + +#include <projectstorage/projectstorageerrornotifierinterface.h> + +class ProjectStorageErrorNotifierMock : public QmlDesigner::ProjectStorageErrorNotifierInterface +{ +public: + MOCK_METHOD(void, + typeNameCannotBeResolved, + (Utils::SmallStringView typeName, QmlDesigner::SourceId souceId), + (override)); +}; diff --git a/tests/unit/tests/mocks/projectstoragemock.cpp b/tests/unit/tests/mocks/projectstoragemock.cpp index 83ff85fe9a..d4a28d1ae6 100644 --- a/tests/unit/tests/mocks/projectstoragemock.cpp +++ b/tests/unit/tests/mocks/projectstoragemock.cpp @@ -12,9 +12,10 @@ using QmlDesigner::ImportId; using QmlDesigner::ModuleId; using QmlDesigner::PropertyDeclarationId; using QmlDesigner::SourceId; +using QmlDesigner::Storage::ModuleKind; +using QmlDesigner::Storage::PropertyDeclarationTraits; using QmlDesigner::TypeId; using QmlDesigner::TypeIds; -using QmlDesigner::Storage::PropertyDeclarationTraits; namespace Storage = QmlDesigner::Storage; @@ -41,17 +42,20 @@ void setupIsBasedOn(ProjectStorageMock &mock) } // namespace -ModuleId ProjectStorageMock::createModule(Utils::SmallStringView moduleName) +ModuleId ProjectStorageMock::createModule(Utils::SmallStringView moduleName, + QmlDesigner::Storage::ModuleKind moduleKind) { - if (auto id = moduleId(moduleName)) { + if (auto id = moduleId(moduleName, moduleKind)) { return id; } static ModuleId moduleId; incrementBasicId(moduleId); - ON_CALL(*this, moduleId(Eq(moduleName))).WillByDefault(Return(moduleId)); - ON_CALL(*this, fetchModuleIdUnguarded(Eq(moduleName))).WillByDefault(Return(moduleId)); + ON_CALL(*this, moduleId(Eq(moduleName), Eq(moduleKind))).WillByDefault(Return(moduleId)); + ON_CALL(*this, module(Eq(moduleId))) + .WillByDefault(Return(QmlDesigner::Storage::Module{moduleName, moduleKind})); + ON_CALL(*this, fetchModuleIdUnguarded(Eq(moduleName), Eq(moduleKind))).WillByDefault(Return(moduleId)); return moduleId; } @@ -122,6 +126,14 @@ void ProjectStorageMock::addExportedTypeName(QmlDesigner::TypeId typeId, exportedTypeName[typeId].emplace_back(moduleId, typeName); } +void ProjectStorageMock::addExportedTypeNameBySourceId(QmlDesigner::TypeId typeId, + QmlDesigner::ModuleId moduleId, + Utils::SmallStringView typeName, + QmlDesigner::SourceId sourceId) +{ + exportedTypeNameBySourceId[{typeId, sourceId}].emplace_back(moduleId, typeName); +} + void ProjectStorageMock::removeExportedTypeName(QmlDesigner::TypeId typeId, QmlDesigner::ModuleId moduleId, Utils::SmallStringView typeName) @@ -227,7 +239,9 @@ void ProjectStorageMock::setItemLibraryEntries( } namespace { -void addBaseProperties(TypeId typeId, TypeIds baseTypeIds, ProjectStorageMock &storage) +void addBaseProperties(TypeId typeId, + const QmlDesigner::SmallTypeIds<16> &baseTypeIds, + ProjectStorageMock &storage) { for (TypeId baseTypeId : baseTypeIds) { for (const auto &propertyId : storage.localPropertyDeclarationIds(baseTypeId)) { @@ -254,7 +268,7 @@ TypeId ProjectStorageMock::createType(ModuleId moduleId, PropertyDeclarationTraits defaultPropertyTraits, TypeId defaultPropertyTypeId, Storage::TypeTraits typeTraits, - TypeIds baseTypeIds, + const QmlDesigner::SmallTypeIds<16> &baseTypeIds, SourceId sourceId) { if (auto id = typeId(moduleId, typeName)) { @@ -282,18 +296,19 @@ TypeId ProjectStorageMock::createType(ModuleId moduleId, defaultPropertyTypeId); } - ON_CALL(*this, type(Eq(typeId))) - .WillByDefault(Return(Storage::Info::Type{defaultPropertyDeclarationId, sourceId, typeTraits})); + ON_CALL(*this, type(Eq(typeId))).WillByDefault(Return(Storage::Info::Type{sourceId, typeTraits})); + + ON_CALL(*this, defaultPropertyDeclarationId(Eq(typeId))) + .WillByDefault(Return(defaultPropertyDeclarationId)); ON_CALL(*this, isBasedOn(Eq(typeId), Eq(typeId))).WillByDefault(Return(true)); for (TypeId baseTypeId : baseTypeIds) ON_CALL(*this, isBasedOn(Eq(typeId), Eq(baseTypeId))).WillByDefault(Return(true)); - TypeIds selfAndPrototypes; - selfAndPrototypes.reserve(baseTypeIds.size() + 1); + QmlDesigner::SmallTypeIds<16> selfAndPrototypes; selfAndPrototypes.push_back(typeId); - selfAndPrototypes.insert(selfAndPrototypes.end(), baseTypeIds.begin(), baseTypeIds.end()); + std::copy(baseTypeIds.begin(), baseTypeIds.end(), std::back_inserter(selfAndPrototypes)); ON_CALL(*this, prototypeAndSelfIds(Eq(typeId))).WillByDefault(Return(selfAndPrototypes)); ON_CALL(*this, prototypeIds(Eq(typeId))).WillByDefault(Return(baseTypeIds)); @@ -314,7 +329,7 @@ void ProjectStorageMock::removeType(QmlDesigner::ModuleId moduleId, Utils::Small QmlDesigner::TypeId ProjectStorageMock::createType(QmlDesigner::ModuleId moduleId, Utils::SmallStringView typeName, QmlDesigner::Storage::TypeTraits typeTraits, - QmlDesigner::TypeIds baseTypeIds, + const QmlDesigner::SmallTypeIds<16> &baseTypeIds, SourceId sourceId) { return createType(moduleId, typeName, {}, {}, TypeId{}, typeTraits, baseTypeIds, sourceId); @@ -325,7 +340,7 @@ TypeId ProjectStorageMock::createObject(ModuleId moduleId, Utils::SmallStringView defaultPropertyName, PropertyDeclarationTraits defaultPropertyTraits, QmlDesigner::TypeId defaultPropertyTypeId, - TypeIds baseTypeIds, + const QmlDesigner::SmallTypeIds<16> &baseTypeIds, QmlDesigner::SourceId sourceId) { return createType(moduleId, @@ -340,19 +355,20 @@ TypeId ProjectStorageMock::createObject(ModuleId moduleId, TypeId ProjectStorageMock::createObject(ModuleId moduleId, Utils::SmallStringView typeName, - TypeIds baseTypeIds) + const QmlDesigner::SmallTypeIds<16> &baseTypeIds) { return createType(moduleId, typeName, Storage::TypeTraitsKind::Reference, baseTypeIds); } QmlDesigner::TypeId ProjectStorageMock::createValue(QmlDesigner::ModuleId moduleId, Utils::SmallStringView typeName, - QmlDesigner::TypeIds baseTypeIds) + const QmlDesigner::SmallTypeIds<16> &baseTypeIds) { return createType(moduleId, typeName, Storage::TypeTraitsKind::Value, baseTypeIds); } -void ProjectStorageMock::setHeirs(QmlDesigner::TypeId typeId, QmlDesigner::TypeIds heirIds) +void ProjectStorageMock::setHeirs(QmlDesigner::TypeId typeId, + const QmlDesigner::SmallTypeIds<64> &heirIds) { ON_CALL(*this, heirIds(typeId)).WillByDefault(Return(heirIds)); } @@ -362,17 +378,21 @@ ProjectStorageMock::ProjectStorageMock() ON_CALL(*this, exportedTypeNames(_)).WillByDefault([&](TypeId id) { return exportedTypeName[id]; }); + + ON_CALL(*this, exportedTypeNames(_, _)).WillByDefault([&](TypeId typeId, SourceId sourceId) { + return exportedTypeNameBySourceId[{typeId, sourceId}]; + }); } void ProjectStorageMock::setupQtQuick() { setupIsBasedOn(*this); - auto qmlModuleId = createModule("QML"); - auto qmlNativeModuleId = createModule("QML-cppnative"); - auto qtQmlModelsModuleId = createModule("QtQml.Models"); - auto qtQuickModuleId = createModule("QtQuick"); - auto qtQuickNativeModuleId = createModule("QtQuick-cppnative"); + auto qmlModuleId = createModule("QML", ModuleKind::QmlLibrary); + auto qmlNativeModuleId = createModule("QML", ModuleKind::CppLibrary); + auto qtQmlModelsModuleId = createModule("QtQml.Models", ModuleKind::QmlLibrary); + auto qtQuickModuleId = createModule("QtQuick", ModuleKind::QmlLibrary); + auto qtQuickNativeModuleId = createModule("QtQuick", ModuleKind::CppLibrary); auto boolId = createValue(qmlModuleId, "bool"); auto intId = createValue(qmlModuleId, "int"); @@ -446,11 +466,11 @@ void ProjectStorageMock::setupQtQuick() {qtObjectId}); createObject(qtQuickModuleId, "PropertyChanges", {qtObjectId, stateOperationsId}); - auto qtQuickTimelineModuleId = createModule("QtQuick.Timeline"); + auto qtQuickTimelineModuleId = createModule("QtQuick.Timeline", ModuleKind::QmlLibrary); createObject(qtQuickTimelineModuleId, "KeyframeGroup", {qtObjectId}); createObject(qtQuickTimelineModuleId, "Keyframe", {qtObjectId}); - auto flowViewModuleId = createModule("FlowView"); + auto flowViewModuleId = createModule("FlowView", ModuleKind::QmlLibrary); createObject(flowViewModuleId, "FlowActionArea", "data", @@ -475,12 +495,12 @@ void ProjectStorageMock::setupQtQuick() void ProjectStorageMock::setupQtQuickImportedTypeNameIds(QmlDesigner::SourceId sourceId) { - auto qmlModuleId = moduleId("QML"); - auto qtQmlModelsModuleId = moduleId("QtQml.Models"); - auto qtQuickModuleId = moduleId("QtQuick"); - auto qtQuickNativeModuleId = moduleId("QtQuick-cppnative"); - auto qtQuickTimelineModuleId = moduleId("QtQuick.Timeline"); - auto flowViewModuleId = moduleId("FlowView"); + auto qmlModuleId = moduleId("QML", ModuleKind::QmlLibrary); + auto qtQmlModelsModuleId = moduleId("QtQml.Models", ModuleKind::QmlLibrary); + auto qtQuickModuleId = moduleId("QtQuick", ModuleKind::QmlLibrary); + auto qtQuickNativeModuleId = moduleId("QtQuick", ModuleKind::CppLibrary); + auto qtQuickTimelineModuleId = moduleId("QtQuick.Timeline", ModuleKind::QmlLibrary); + auto flowViewModuleId = moduleId("FlowView", ModuleKind::QmlLibrary); createImportedTypeNameId(sourceId, "int", qmlModuleId); createImportedTypeNameId(sourceId, "QtObject", qmlModuleId); diff --git a/tests/unit/tests/mocks/projectstoragemock.h b/tests/unit/tests/mocks/projectstoragemock.h index 198e54b370..8d9c3381b2 100644 --- a/tests/unit/tests/mocks/projectstoragemock.h +++ b/tests/unit/tests/mocks/projectstoragemock.h @@ -23,7 +23,8 @@ public: void setupQtQuickImportedTypeNameIds(QmlDesigner::SourceId sourceId); void setupCommonTypeCache(); - QmlDesigner::ModuleId createModule(Utils::SmallStringView moduleName); + QmlDesigner::ModuleId createModule(Utils::SmallStringView moduleName, + QmlDesigner::Storage::ModuleKind moduleKind); QmlDesigner::ImportedTypeNameId createImportedTypeNameId(QmlDesigner::SourceId sourceId, Utils::SmallStringView typeName, @@ -46,6 +47,11 @@ public: QmlDesigner::ModuleId moduleId, Utils::SmallStringView typeName); + void addExportedTypeNameBySourceId(QmlDesigner::TypeId typeId, + QmlDesigner::ModuleId moduleId, + Utils::SmallStringView typeName, + QmlDesigner::SourceId sourceId); + void removeExportedTypeName(QmlDesigner::TypeId typeId, QmlDesigner::ModuleId moduleId, Utils::SmallStringView typeName); @@ -56,7 +62,7 @@ public: QmlDesigner::Storage::PropertyDeclarationTraits defaultPropertyTraits, QmlDesigner::TypeId defaultPropertyTypeId, QmlDesigner::Storage::TypeTraits typeTraits, - QmlDesigner::TypeIds baseTypeIds = {}, + const QmlDesigner::SmallTypeIds<16> &baseTypeIds = {}, QmlDesigner::SourceId sourceId = QmlDesigner::SourceId{}); void removeType(QmlDesigner::ModuleId moduleId, Utils::SmallStringView typeName); @@ -64,27 +70,26 @@ public: QmlDesigner::TypeId createType(QmlDesigner::ModuleId moduleId, Utils::SmallStringView typeName, QmlDesigner::Storage::TypeTraits typeTraits, - QmlDesigner::TypeIds baseTypeIds = {}, + const QmlDesigner::SmallTypeIds<16> &baseTypeIds = {}, QmlDesigner::SourceId sourceId = QmlDesigner::SourceId{}); - QmlDesigner::TypeId createObject( - QmlDesigner::ModuleId moduleId, - Utils::SmallStringView typeName, - Utils::SmallStringView defaultPropertyName, - QmlDesigner::Storage::PropertyDeclarationTraits defaultPropertyTraits, - QmlDesigner::TypeId defaultPropertyTypeId, - QmlDesigner::TypeIds baseTypeIds = {}, - QmlDesigner::SourceId sourceId = QmlDesigner::SourceId{}); + QmlDesigner::TypeId createObject(QmlDesigner::ModuleId moduleId, + Utils::SmallStringView typeName, + Utils::SmallStringView defaultPropertyName, + QmlDesigner::Storage::PropertyDeclarationTraits defaultPropertyTraits, + QmlDesigner::TypeId defaultPropertyTypeId, + const QmlDesigner::SmallTypeIds<16> &baseTypeIds = {}, + QmlDesigner::SourceId sourceId = QmlDesigner::SourceId{}); QmlDesigner::TypeId createObject(QmlDesigner::ModuleId moduleId, Utils::SmallStringView typeName, - QmlDesigner::TypeIds baseTypeIds = {}); + const QmlDesigner::SmallTypeIds<16> &baseTypeIds = {}); QmlDesigner::TypeId createValue(QmlDesigner::ModuleId moduleId, Utils::SmallStringView typeName, - QmlDesigner::TypeIds baseTypeIds = {}); + const QmlDesigner::SmallTypeIds<16> &baseTypeIds = {}); - void setHeirs(QmlDesigner::TypeId typeId, QmlDesigner::TypeIds heirIds); + void setHeirs(QmlDesigner::TypeId typeId, const QmlDesigner::SmallTypeIds<64> &heirIds); QmlDesigner::PropertyDeclarationId createProperty( QmlDesigner::TypeId typeId, @@ -122,7 +127,11 @@ public: MOCK_METHOD(void, addObserver, (QmlDesigner::ProjectStorageObserver *), (override)); MOCK_METHOD(void, removeObserver, (QmlDesigner::ProjectStorageObserver *), (override)); - MOCK_METHOD(QmlDesigner::ModuleId, moduleId, (::Utils::SmallStringView), (const, override)); + MOCK_METHOD(QmlDesigner::ModuleId, + moduleId, + (::Utils::SmallStringView, QmlDesigner::Storage::ModuleKind moduleKind), + (const, override)); + MOCK_METHOD(QmlDesigner::Storage::Module, module, (QmlDesigner::ModuleId), (const, override)); MOCK_METHOD(std::optional<QmlDesigner::Storage::Info::PropertyDeclaration>, propertyDeclaration, @@ -182,10 +191,19 @@ public: propertyDeclarationId, (QmlDesigner::TypeId typeId, ::Utils::SmallStringView propertyName), (const, override)); + MOCK_METHOD(QmlDesigner::PropertyDeclarationId, + defaultPropertyDeclarationId, + (QmlDesigner::TypeId typeId), + (const, override)); MOCK_METHOD(std::optional<QmlDesigner::Storage::Info::Type>, type, (QmlDesigner::TypeId typeId), (const, override)); + MOCK_METHOD(QmlDesigner::SmallSourceIds<4>, + typeAnnotationSourceIds, + (QmlDesigner::SourceId directoryId), + (const, override)); + MOCK_METHOD(QmlDesigner::SmallSourceIds<64>, typeAnnotationDirectorySourceIds, (), (const, override)); MOCK_METHOD(Utils::PathString, typeIconPath, (QmlDesigner::TypeId typeId), (const, override)); MOCK_METHOD(QmlDesigner::Storage::Info::TypeHints, typeHints, @@ -215,9 +233,15 @@ public: propertyName, (QmlDesigner::PropertyDeclarationId propertyDeclarationId), (const, override)); - MOCK_METHOD(QmlDesigner::TypeIds, prototypeAndSelfIds, (QmlDesigner::TypeId type), (const, override)); - MOCK_METHOD(QmlDesigner::TypeIds, prototypeIds, (QmlDesigner::TypeId type), (const, override)); - MOCK_METHOD(QmlDesigner::TypeIds, heirIds, (QmlDesigner::TypeId type), (const, override)); + MOCK_METHOD(QmlDesigner::SmallTypeIds<16>, + prototypeAndSelfIds, + (QmlDesigner::TypeId type), + (const, override)); + MOCK_METHOD(QmlDesigner::SmallTypeIds<16>, + prototypeIds, + (QmlDesigner::TypeId type), + (const, override)); + MOCK_METHOD(QmlDesigner::SmallTypeIds<64>, heirIds, (QmlDesigner::TypeId type), (const, override)); MOCK_METHOD(bool, isBasedOn, (QmlDesigner::TypeId typeId, QmlDesigner::TypeId), (const, override)); MOCK_METHOD(bool, isBasedOn, @@ -276,13 +300,23 @@ public: (QmlDesigner::SourceId sourceId), (const, override)); - MOCK_METHOD(QmlDesigner::Storage::Synchronization::ProjectDatas, - fetchProjectDatas, + MOCK_METHOD(QmlDesigner::Storage::Synchronization::DirectoryInfos, + fetchDirectoryInfos, + (QmlDesigner::SourceId sourceId), + (const, override)); + + MOCK_METHOD(QmlDesigner::Storage::Synchronization::DirectoryInfos, + fetchDirectoryInfos, + (QmlDesigner::SourceId sourceId, QmlDesigner::Storage::Synchronization::FileType), + (const, override)); + + MOCK_METHOD(QmlDesigner::SmallSourceIds<32>, + fetchSubdirectorySourceIds, (QmlDesigner::SourceId sourceId), (const, override)); - MOCK_METHOD(std::optional<QmlDesigner::Storage::Synchronization::ProjectData>, - fetchProjectData, + MOCK_METHOD(std::optional<QmlDesigner::Storage::Synchronization::DirectoryInfo>, + fetchDirectoryInfo, (QmlDesigner::SourceId sourceId), (const, override)); @@ -317,7 +351,7 @@ public: (const, override)); MOCK_METHOD(QmlDesigner::ModuleId, fetchModuleIdUnguarded, - (Utils::SmallStringView name), + (Utils::SmallStringView name, QmlDesigner::Storage::ModuleKind), (const, override)); MOCK_METHOD(QmlDesigner::TypeId, fetchTypeIdByModuleIdAndExportedName, @@ -326,6 +360,8 @@ public: QmlDesigner::Storage::Info::CommonTypeCache<QmlDesigner::ProjectStorageInterface> typeCache{*this}; std::map<QmlDesigner::TypeId, QmlDesigner::Storage::Info::ExportedTypeNames> exportedTypeName; + std::map<std::pair<QmlDesigner::TypeId, QmlDesigner::SourceId>, QmlDesigner::Storage::Info::ExportedTypeNames> + exportedTypeNameBySourceId; }; class ProjectStorageMockWithQtQtuick : public ProjectStorageMock diff --git a/tests/unit/tests/mocks/qmltypesparsermock.h b/tests/unit/tests/mocks/qmltypesparsermock.h index e3fa1ca605..0f57c634d0 100644 --- a/tests/unit/tests/mocks/qmltypesparsermock.h +++ b/tests/unit/tests/mocks/qmltypesparsermock.h @@ -15,6 +15,6 @@ public: (const QString &sourceContent, QmlDesigner::Storage::Imports &imports, QmlDesigner::Storage::Synchronization::Types &types, - const QmlDesigner::Storage::Synchronization::ProjectData &projectData), + const QmlDesigner::Storage::Synchronization::DirectoryInfo &directoryInfo), (override)); }; diff --git a/tests/unit/tests/printers/gtest-creator-printing.cpp b/tests/unit/tests/printers/gtest-creator-printing.cpp index 1bff6df492..8ca65f4526 100644 --- a/tests/unit/tests/printers/gtest-creator-printing.cpp +++ b/tests/unit/tests/printers/gtest-creator-printing.cpp @@ -675,7 +675,7 @@ std::ostream &operator<<(std::ostream &out, const PropertyDeclaration &propertyD std::ostream &operator<<(std::ostream &out, const Type &type) { - return out << "(" << type.defaultPropertyId << ")"; + return out << "(" << type.sourceId << ")"; } std::ostream &operator<<(std::ostream &out, const ExportedTypeName &name) @@ -695,10 +695,10 @@ std::ostream &operator<<(std::ostream &out, const ItemLibraryProperty &property) std::ostream &operator<<(std::ostream &out, const ItemLibraryEntry &entry) { - return out << R"((")" << entry.name << R"(", ")" << entry.iconPath << R"(", ")" - << entry.category << R"(", ")" << entry.import << R"(", ")" << entry.toolTip - << R"(", ")" << entry.templatePath << R"(", )" << entry.properties << ", " - << entry.extraFilePaths << ")"; + return out << R"((")" << entry.typeName << R"(", ")" << entry.name << R"(", ")" + << entry.iconPath << R"(", ")" << entry.category << R"(", ")" << entry.import + << R"(", ")" << entry.toolTip << R"(", ")" << entry.templatePath << R"(", )" + << entry.properties << ", " << entry.extraFilePaths << ")"; } } // namespace Storage::Info @@ -754,6 +754,8 @@ const char *fileTypeToText(FileType fileType) return "QmlDocument"; case FileType::QmlTypes: return "QmlTypes"; + case FileType::Directory: + return "Directory"; } return ""; @@ -791,16 +793,19 @@ std::ostream &operator<<(std::ostream &out, const SynchronizationPackage &packag << ", updatedSourceIds: " << package.updatedSourceIds << ", fileStatuses: " << package.fileStatuses << ", updatedFileStatusSourceIds: " << package.updatedFileStatusSourceIds - << ", updatedProjectSourceIds: " << package.updatedProjectSourceIds - << ", projectDatas: " << package.projectDatas + << ", updatedDirectoryInfoSourceIds: " << package.updatedDirectoryInfoSourceIds + << ", directoryInfos: " << package.directoryInfos << ", propertyEditorQmlPaths: " << package.propertyEditorQmlPaths << ", updatedPropertyEditorQmlPathSourceIds: " - << package.updatedPropertyEditorQmlPathSourceIds << ")"; + << package.updatedPropertyEditorQmlPathSourceIds + << ", typeAnnotations: " << package.typeAnnotations + << ", updatedTypeAnnotationSourceIds: " << package.updatedTypeAnnotationSourceIds + << ")"; } -std::ostream &operator<<(std::ostream &out, const ProjectData &data) +std::ostream &operator<<(std::ostream &out, const DirectoryInfo &data) { - return out << "(" << data.projectSourceId << ", " << data.sourceId << ", " << data.moduleId + return out << "(" << data.directorySourceId << ", " << data.sourceId << ", " << data.moduleId << ", " << data.fileType << ")"; } @@ -828,8 +833,9 @@ std::ostream &operator<<(std::ostream &out, const Type &type) { using std::operator<<; using Utils::operator<<; - return out << "( typename: \"" << type.typeName << "\", prototype: " << type.prototype << ", " - << type.prototypeId << ", " << type.traits << ", source: " << type.sourceId + return out << "( typename: \"" << type.typeName << "\", prototype: {\"" << type.prototype + << "\", " << type.prototypeId << "}, " << "\", extension: {\"" << type.extension + << "\", " << type.extensionId << "}, " << type.traits << ", source: " << type.sourceId << ", exports: " << type.exportedTypes << ", properties: " << type.propertyDeclarations << ", functions: " << type.functionDeclarations << ", signals: " << type.signalDeclarations << ", changeLevel: " << type.changeLevel diff --git a/tests/unit/tests/printers/gtest-creator-printing.h b/tests/unit/tests/printers/gtest-creator-printing.h index 8d0c77888e..2444b9d98b 100644 --- a/tests/unit/tests/printers/gtest-creator-printing.h +++ b/tests/unit/tests/printers/gtest-creator-printing.h @@ -207,7 +207,7 @@ class EnumeratorDeclaration; enum class ImportKind : char; enum class IsAutoVersion : char; enum class IsQualified : int; -class ProjectData; +class DirectoryInfo; class SynchronizationPackage; enum class FileType : char; enum class ChangeLevel : char; @@ -227,7 +227,7 @@ std::ostream &operator<<(std::ostream &out, const EnumerationDeclaration &enumer std::ostream &operator<<(std::ostream &out, const EnumeratorDeclaration &enumeratorDeclaration); std::ostream &operator<<(std::ostream &out, const ImportKind &importKind); std::ostream &operator<<(std::ostream &out, IsQualified isQualified); -std::ostream &operator<<(std::ostream &out, const ProjectData &data); +std::ostream &operator<<(std::ostream &out, const DirectoryInfo &data); std::ostream &operator<<(std::ostream &out, const SynchronizationPackage &package); std::ostream &operator<<(std::ostream &out, FileType fileType); std::ostream &operator<<(std::ostream &out, ChangeLevel changeLevel); diff --git a/tests/unit/tests/stubs/qmldesigner/designercore/include/rewriterview.h b/tests/unit/tests/stubs/qmldesigner/designercore/include/rewriterview.h index a10da0133c..4c59440b0f 100644 --- a/tests/unit/tests/stubs/qmldesigner/designercore/include/rewriterview.h +++ b/tests/unit/tests/stubs/qmldesigner/designercore/include/rewriterview.h @@ -128,8 +128,6 @@ public: void setCheckSemanticErrors(bool) {} - QString pathForImport(const Import &) { return {}; } - QStringList importDirectories() const { return {}; } QSet<QPair<QString, QString>> qrcMapping() const { return {}; } diff --git a/tests/unit/tests/testdesignercore/CMakeLists.txt b/tests/unit/tests/testdesignercore/CMakeLists.txt index 0bdf3452d6..c446af81a3 100644 --- a/tests/unit/tests/testdesignercore/CMakeLists.txt +++ b/tests/unit/tests/testdesignercore/CMakeLists.txt @@ -125,6 +125,8 @@ add_qtc_library(TestDesignerCore OBJECT projectstorage/projectstorageinterface.h projectstorage/projectstorageobserver.h projectstorage/projectstorage.cpp projectstorage/projectstorage.h + projectstorage/projectstorageerrornotifierinterface.h + projectstorage/projectstorageerrornotifier.cpp projectstorage/projectstorageerrornotifier.h projectstorage/projectstoragepathwatcher.h projectstorage/projectstoragepathwatcherinterface.h projectstorage/projectstoragepathwatchernotifierinterface.h @@ -147,6 +149,8 @@ add_qtc_library(TestDesignerCore OBJECT tracing/qmldesignertracing.cpp tracing/qmldesignertracing.h rewritertransaction.cpp rewritertransaction.h + uniquename.cpp + uniquename.h ) extend_qtc_library(TestDesignerCore diff --git a/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp b/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp index 10e4cc3252..b36966dda1 100644 --- a/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp +++ b/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp @@ -11,6 +11,7 @@ #include <propertycomponentgenerator.h> using namespace Qt::StringLiterals; +using QmlDesigner::Storage::ModuleKind; namespace QmlDesigner { @@ -74,7 +75,7 @@ protected: { if (auto property = node->property(name)) { const auto &value = property.value; - if (value.type() == QVariant::List) { + if (value.typeId() == QMetaType::QVariantList) { auto list = value.toList(); if (list.size()) return list.front().value<Type>(); @@ -182,7 +183,7 @@ protected: resourceManagementMock)}; QmlDesigner::PropertyComponentGenerator generator{QString{sourcesPath}, &model}; QmlDesigner::NodeMetaInfo itemMetaInfo = model.qtQuickItemMetaInfo(); - QmlDesigner::ModuleId qmlModuleId = projectStorageMock.createModule("QML"); + QmlDesigner::ModuleId qmlModuleId = projectStorageMock.createModule("QML", ModuleKind::QmlLibrary); }; TEST_F(PropertyComponentGenerator, @@ -345,7 +346,8 @@ TEST_F(PropertyComponentGenerator, after_refresh_meta_infos_type_was_deleted) auto xProperty = itemMetaInfo.property("x"); auto doubleMetaInfo = model.doubleMetaInfo(); projectStorageMock.removeExportedTypeName(doubleMetaInfo.id(), - projectStorageMock.createModule("QML"), + projectStorageMock.createModule("QML", + ModuleKind::QmlLibrary), "real"); generator.refreshMetaInfos({doubleMetaInfo.id()}); @@ -359,11 +361,13 @@ TEST_F(PropertyComponentGenerator, after_refresh_meta_infos_type_was_added) auto xProperty = itemMetaInfo.property("x"); auto doubleMetaInfo = model.doubleMetaInfo(); projectStorageMock.removeExportedTypeName(doubleMetaInfo.id(), - projectStorageMock.createModule("QML"), + projectStorageMock.createModule("QML", + ModuleKind::QmlLibrary), "real"); generator.refreshMetaInfos({doubleMetaInfo.id()}); projectStorageMock.addExportedTypeName(doubleMetaInfo.id(), - projectStorageMock.createModule("QML"), + projectStorageMock.createModule("QML", + ModuleKind::QmlLibrary), "real"); generator.refreshMetaInfos({}); diff --git a/tests/unit/tests/unittests/componentcore/propertyeditorcomponentgenerator-test.cpp b/tests/unit/tests/unittests/componentcore/propertyeditorcomponentgenerator-test.cpp index 3b9a8bbfe2..398c54bfad 100644 --- a/tests/unit/tests/unittests/componentcore/propertyeditorcomponentgenerator-test.cpp +++ b/tests/unit/tests/unittests/componentcore/propertyeditorcomponentgenerator-test.cpp @@ -13,12 +13,13 @@ namespace { using BasicProperty = QmlDesigner::PropertyComponentGenerator::BasicProperty; using ComplexProperty = QmlDesigner::PropertyComponentGenerator::ComplexProperty; using QmlDesigner::PropertyMetaInfo; +using QmlDesigner::Storage::ModuleKind; class PropertyEditorComponentGenerator : public ::testing::Test { protected: QmlDesigner::NodeMetaInfo createType(Utils::SmallStringView name, - QmlDesigner::TypeIds baseTypeIds = {}) + const QmlDesigner::SmallTypeIds<16> &baseTypeIds = {}) { auto typeId = projectStorageMock.createValue(qtQuickModuleId, name, baseTypeIds); @@ -86,7 +87,8 @@ protected: NiceMock<ProjectStorageMockWithQtQtuick> projectStorageMock{sourceId}; NiceMock<PropertyComponentGeneratorMock> propertyGeneratorMock; QmlDesigner::PropertyEditorComponentGenerator generator{propertyGeneratorMock}; - QmlDesigner::ModuleId qtQuickModuleId = projectStorageMock.createModule("QtQuick"); + QmlDesigner::ModuleId qtQuickModuleId = projectStorageMock.createModule("QtQuick", + ModuleKind::QmlLibrary); QmlDesigner::NodeMetaInfo fooTypeInfo = createType("Foo"); QmlDesigner::TypeId dummyTypeId = projectStorageMock.commonTypeCache().builtinTypeId<double>(); }; diff --git a/tests/unit/tests/unittests/imagecache/taskqueue-test.cpp b/tests/unit/tests/unittests/imagecache/taskqueue-test.cpp index 537f4b3ea3..ea295c5733 100644 --- a/tests/unit/tests/unittests/imagecache/taskqueue-test.cpp +++ b/tests/unit/tests/unittests/imagecache/taskqueue-test.cpp @@ -100,4 +100,22 @@ TEST_F(TaskQueue, clean_task_in_queue) queue.clean(); } +TEST_F(TaskQueue, sleeping_queue_is_recovering) +{ + Queue queue{mockDispatchCallback.AsStdFunction(), mockCleanCallback.AsStdFunction()}; + EXPECT_CALL(mockDispatchCallback, Call(IsTask(5))).WillRepeatedly([&](Task) { + notification.notify(); + }); + queue.addTask(5); + notification.wait(); + queue.putThreadToSleep(); + + EXPECT_CALL(mockDispatchCallback, Call(IsTask(22))).WillRepeatedly([&](Task) { + notification.notify(); + }); + + queue.addTask(22); + notification.wait(); +} + } // namespace diff --git a/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp b/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp index f8bef106ac..06ab4f930c 100644 --- a/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp +++ b/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp @@ -511,7 +511,7 @@ TEST_F(ListModelEditor, convert_string_float_to_float) model.setValue(1, 1, "25.5"); ASSERT_THAT(element2.variantProperty("name").value().value<double>(), 25.5); - ASSERT_THAT(element2.variantProperty("name").value().type(), QVariant::Double); + ASSERT_THAT(element2.variantProperty("name").value().typeId(), QMetaType::Double); } TEST_F(ListModelEditor, convert_string_integer_to_double) @@ -521,7 +521,7 @@ TEST_F(ListModelEditor, convert_string_integer_to_double) model.setValue(1, 1, "25"); ASSERT_THAT(element2.variantProperty("name").value().value<double>(), 25); - ASSERT_THAT(element2.variantProperty("name").value().type(), QVariant::Double); + ASSERT_THAT(element2.variantProperty("name").value().typeId(), QMetaType::Double); } TEST_F(ListModelEditor, dont_convert_string_to_number) @@ -531,7 +531,7 @@ TEST_F(ListModelEditor, dont_convert_string_to_number) model.setValue(1, 1, "hello"); ASSERT_THAT(element2.variantProperty("name").value().value<QString>(), u"hello"); - ASSERT_THAT(element2.variantProperty("name").value().type(), QVariant::String); + ASSERT_THAT(element2.variantProperty("name").value().typeId(), QMetaType::QString); } TEST_F(ListModelEditor, empty_strings_removes_property) @@ -558,7 +558,7 @@ TEST_F(ListModelEditor, dispay_value_is_changed_to_double) model.setValue(1, 1, "25.5"); - ASSERT_THAT(displayValues()[1][1].type(), QVariant::Double); + ASSERT_THAT(displayValues()[1][1].typeId(), QMetaType::Double); } TEST_F(ListModelEditor, string_dispay_value_is_not_changed) @@ -567,7 +567,7 @@ TEST_F(ListModelEditor, string_dispay_value_is_not_changed) model.setValue(1, 1, "25.5a"); - ASSERT_THAT(displayValues()[1][1].type(), QVariant::String); + ASSERT_THAT(displayValues()[1][1].typeId(), QMetaType::QString); } TEST_F(ListModelEditor, set_invalid_to_dark_yellow_background_color) diff --git a/tests/unit/tests/unittests/metainfo/nodemetainfo-test.cpp b/tests/unit/tests/unittests/metainfo/nodemetainfo-test.cpp index af8c4bd220..c96def356a 100644 --- a/tests/unit/tests/unittests/metainfo/nodemetainfo-test.cpp +++ b/tests/unit/tests/unittests/metainfo/nodemetainfo-test.cpp @@ -17,6 +17,7 @@ namespace { using QmlDesigner::FlagIs; using QmlDesigner::ModelNode; using QmlDesigner::ModelNodes; +using QmlDesigner::Storage::ModuleKind; using QmlDesigner::Storage::TypeTraits; using QmlDesigner::Storage::TypeTraitsKind; @@ -68,9 +69,10 @@ protected: } QmlDesigner::NodeMetaInfo createDerivedDummyMetaInfo(Utils::SmallStringView moduleName, + ModuleKind moduleKind, Utils::SmallStringView typeName) { - auto moduleId = projectStorageMock.createModule(moduleName); + auto moduleId = projectStorageMock.createModule(moduleName, moduleKind); auto typeId = projectStorageMock.createType(moduleId, typeName, {}); return createDerivedDummyMetaInfo(typeId); @@ -86,10 +88,11 @@ protected: } QmlDesigner::NodeMetaInfo createMetaInfo(Utils::SmallStringView moduleName, + ModuleKind moduleKind, Utils::SmallStringView typeName, QmlDesigner::Storage::TypeTraits typeTraits = {}) { - auto moduleId = projectStorageMock.createModule(moduleName); + auto moduleId = projectStorageMock.createModule(moduleName, moduleKind); auto typeId = projectStorageMock.createType(moduleId, typeName, typeTraits); return QmlDesigner::NodeMetaInfo{typeId, &projectStorageMock}; @@ -109,8 +112,9 @@ protected: ModelNode object = model.createModelNode("QtObject"); QmlDesigner::NodeMetaInfo itemMetaInfo = item.metaInfo(); QmlDesigner::NodeMetaInfo objectMetaInfo = object.metaInfo(); - QmlDesigner::ModuleId qmlModuleId = projectStorageMock.createModule("QML"); - QmlDesigner::ModuleId qtQuickModuleId = projectStorageMock.createModule("QtQuick"); + QmlDesigner::ModuleId qmlModuleId = projectStorageMock.createModule("QML", ModuleKind::QmlLibrary); + QmlDesigner::ModuleId qtQuickModuleId = projectStorageMock.createModule("QtQuick", + ModuleKind::QmlLibrary); QmlDesigner::TypeId intTypeId = projectStorageMock.typeId(qmlModuleId, "int", QmlDesigner::Storage::Version{}); @@ -215,7 +219,7 @@ TEST_F(NodeMetaInfo, invalid_is_not_file_component) TEST_F(NodeMetaInfo, component_is_file_component) { - auto moduleId = projectStorageMock.createModule("/path/to/project"); + auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); TypeTraits traits{TypeTraitsKind::Reference}; traits.isFileComponent = true; auto typeId = projectStorageMock.createType(moduleId, "Foo", traits); @@ -228,7 +232,7 @@ TEST_F(NodeMetaInfo, component_is_file_component) TEST_F(NodeMetaInfo, is_project_component) { - auto moduleId = projectStorageMock.createModule("/path/to/project"); + auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); TypeTraits traits{TypeTraitsKind::Reference}; traits.isProjectComponent = true; auto typeId = projectStorageMock.createType(moduleId, "Foo", traits); @@ -242,7 +246,7 @@ TEST_F(NodeMetaInfo, is_project_component) TEST_F(NodeMetaInfo, is_not_project_component) { using QmlDesigner::Storage::TypeTraits; - auto moduleId = projectStorageMock.createModule("/path/to/project"); + auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); auto typeId = projectStorageMock.createType(moduleId, "Foo", {}); QmlDesigner::NodeMetaInfo metaInfo{typeId, &projectStorageMock}; @@ -262,7 +266,7 @@ TEST_F(NodeMetaInfo, invalid_is_not_project_component) TEST_F(NodeMetaInfo, is_in_project_module) { - auto moduleId = projectStorageMock.createModule("/path/to/project"); + auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); TypeTraits traits{TypeTraitsKind::Reference}; traits.isInProjectModule = true; auto typeId = projectStorageMock.createType(moduleId, "Foo", traits); @@ -276,7 +280,7 @@ TEST_F(NodeMetaInfo, is_in_project_module) TEST_F(NodeMetaInfo, is_not_in_project_module) { using QmlDesigner::Storage::TypeTraits; - auto moduleId = projectStorageMock.createModule("/path/to/project"); + auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); auto typeId = projectStorageMock.createType(moduleId, "Foo", {}); QmlDesigner::NodeMetaInfo metaInfo{typeId, &projectStorageMock}; @@ -873,7 +877,7 @@ TEST_F(NodeMetaInfo, second_input_is_invalid_for_common_base_returns_invalid) TEST_F(NodeMetaInfo, source_id) { - auto moduleId = projectStorageMock.createModule("/path/to/project"); + auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); auto typeSourceId = QmlDesigner::SourceId::create(999); auto typeId = projectStorageMock.createType(moduleId, "Foo", {}, {}, typeSourceId); QmlDesigner::NodeMetaInfo metaInfo{typeId, &projectStorageMock}; @@ -930,7 +934,7 @@ TEST_F(NodeMetaInfo, default_is_not_color) TEST_F(NodeMetaInfo, float_is_a_floating_type) { - auto metaInfo = createMetaInfo("QML-cppnative", "float"); + auto metaInfo = createMetaInfo("QML", ModuleKind::CppLibrary, "float"); bool isType = metaInfo.isFloat(); @@ -957,7 +961,7 @@ TEST_F(NodeMetaInfo, default_is_not_float) TEST_F(NodeMetaInfo, is_FlowView_FlowActionArea) { - auto metaInfo = createDerivedDummyMetaInfo("FlowView", "FlowActionArea"); + auto metaInfo = createDerivedDummyMetaInfo("FlowView", ModuleKind::QmlLibrary, "FlowActionArea"); bool isType = metaInfo.isFlowViewFlowActionArea(); @@ -975,7 +979,7 @@ TEST_F(NodeMetaInfo, default_is_not_FlowView_FlowActionArea) TEST_F(NodeMetaInfo, is_FlowView_FlowDecision) { - auto metaInfo = createDerivedDummyMetaInfo("FlowView", "FlowDecision"); + auto metaInfo = createDerivedDummyMetaInfo("FlowView", ModuleKind::QmlLibrary, "FlowDecision"); bool isType = metaInfo.isFlowViewFlowDecision(); @@ -993,7 +997,7 @@ TEST_F(NodeMetaInfo, default_is_not_FlowView_FlowDecision) TEST_F(NodeMetaInfo, is_FlowView_FlowItem) { - auto metaInfo = createDerivedDummyMetaInfo("FlowView", "FlowItem"); + auto metaInfo = createDerivedDummyMetaInfo("FlowView", ModuleKind::QmlLibrary, "FlowItem"); bool isType = metaInfo.isFlowViewFlowItem(); @@ -1011,7 +1015,7 @@ TEST_F(NodeMetaInfo, default_is_not_FlowView_FlowItem) TEST_F(NodeMetaInfo, is_FlowView_FlowTransition) { - auto metaInfo = createDerivedDummyMetaInfo("FlowView", "FlowTransition"); + auto metaInfo = createDerivedDummyMetaInfo("FlowView", ModuleKind::QmlLibrary, "FlowTransition"); bool isType = metaInfo.isFlowViewFlowTransition(); @@ -1029,7 +1033,7 @@ TEST_F(NodeMetaInfo, default_is_not_FlowView_FlowTransition) TEST_F(NodeMetaInfo, is_FlowView_FlowView) { - auto metaInfo = createDerivedDummyMetaInfo("FlowView", "FlowView"); + auto metaInfo = createDerivedDummyMetaInfo("FlowView", ModuleKind::QmlLibrary, "FlowView"); bool isType = metaInfo.isFlowViewFlowView(); @@ -1047,7 +1051,7 @@ TEST_F(NodeMetaInfo, default_is_not_FlowView_FlowView) TEST_F(NodeMetaInfo, is_FlowView_FlowWildcard) { - auto metaInfo = createDerivedDummyMetaInfo("FlowView", "FlowWildcard"); + auto metaInfo = createDerivedDummyMetaInfo("FlowView", ModuleKind::QmlLibrary, "FlowWildcard"); bool isType = metaInfo.isFlowViewFlowWildcard(); @@ -1065,7 +1069,7 @@ TEST_F(NodeMetaInfo, default_is_not_FlowView_FlowWildcard) TEST_F(NodeMetaInfo, FlowItem_is_FlowView_item) { - auto metaInfo = createDerivedDummyMetaInfo("FlowView", "FlowItem"); + auto metaInfo = createDerivedDummyMetaInfo("FlowView", ModuleKind::QmlLibrary, "FlowItem"); bool isType = metaInfo.isFlowViewItem(); @@ -1074,7 +1078,7 @@ TEST_F(NodeMetaInfo, FlowItem_is_FlowView_item) TEST_F(NodeMetaInfo, FlowWildcard_is_FlowView_item) { - auto metaInfo = createDerivedDummyMetaInfo("FlowView", "FlowWildcard"); + auto metaInfo = createDerivedDummyMetaInfo("FlowView", ModuleKind::QmlLibrary, "FlowWildcard"); bool isType = metaInfo.isFlowViewItem(); @@ -1083,7 +1087,7 @@ TEST_F(NodeMetaInfo, FlowWildcard_is_FlowView_item) TEST_F(NodeMetaInfo, FlowDecision_is_FlowView_item) { - auto metaInfo = createDerivedDummyMetaInfo("FlowView", "FlowDecision"); + auto metaInfo = createDerivedDummyMetaInfo("FlowView", ModuleKind::QmlLibrary, "FlowDecision"); bool isType = metaInfo.isFlowViewItem(); @@ -1128,7 +1132,7 @@ TEST_F(NodeMetaInfo, QtQuick_Item_is_graphical_item) TEST_F(NodeMetaInfo, QtQuickWindow_Window_is_graphical_item) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Window", "Window"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Window", ModuleKind::QmlLibrary, "Window"); bool isType = metaInfo.isGraphicalItem(); @@ -1137,7 +1141,7 @@ TEST_F(NodeMetaInfo, QtQuickWindow_Window_is_graphical_item) TEST_F(NodeMetaInfo, QtQuickDialogs_Dialogs_is_graphical_item) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Dialogs", "Dialog"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Dialogs", ModuleKind::QmlLibrary, "Dialog"); bool isType = metaInfo.isGraphicalItem(); @@ -1146,7 +1150,7 @@ TEST_F(NodeMetaInfo, QtQuickDialogs_Dialogs_is_graphical_item) TEST_F(NodeMetaInfo, QtQuickControls_Popup_is_graphical_item) { - auto metaInfo = createMetaInfo("QtQuick.Controls", "Popup"); + auto metaInfo = createMetaInfo("QtQuick.Controls", ModuleKind::QmlLibrary, "Popup"); bool isType = metaInfo.isGraphicalItem(); @@ -1191,7 +1195,7 @@ TEST_F(NodeMetaInfo, QtQuick_Positioner_is_layoutable) TEST_F(NodeMetaInfo, QtQuick_Layouts_Layout_is_layoutable) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Layouts", "Layout"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Layouts", ModuleKind::QmlLibrary, "Layout"); bool isType = metaInfo.isLayoutable(); @@ -1200,7 +1204,7 @@ TEST_F(NodeMetaInfo, QtQuick_Layouts_Layout_is_layoutable) TEST_F(NodeMetaInfo, QtQuick_Controls_SplitView_is_layoutable) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Controls", "SplitView"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Controls", ModuleKind::QmlLibrary, "SplitView"); bool isType = metaInfo.isLayoutable(); @@ -1263,7 +1267,8 @@ TEST_F(NodeMetaInfo, default_is_not_qml_component) TEST_F(NodeMetaInfo, is_QtMultimedia_SoundEffect) { - auto qtMultimediaModuleId = projectStorageMock.createModule("QtMultimedia"); + auto qtMultimediaModuleId = projectStorageMock.createModule("QtMultimedia", + ModuleKind::QmlLibrary); auto metaInfo = createDerivedDummyMetaInfo(qtMultimediaModuleId, "SoundEffect"); bool isType = metaInfo.isQtMultimediaSoundEffect(); @@ -1300,7 +1305,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtObject) TEST_F(NodeMetaInfo, is_QtQuick3D_BakedLightmap) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "BakedLightmap"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", ModuleKind::QmlLibrary, "BakedLightmap"); bool isType = metaInfo.isQtQuick3DBakedLightmap(); @@ -1318,7 +1323,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_BakedLightmap) TEST_F(NodeMetaInfo, is_QtQuick3D_Camera) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "Camera"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", ModuleKind::QmlLibrary, "Camera"); bool isType = metaInfo.isQtQuick3DCamera(); @@ -1336,7 +1341,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_Camera) TEST_F(NodeMetaInfo, is_QtQuick3D_Command) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "Command"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", ModuleKind::QmlLibrary, "Command"); bool isType = metaInfo.isQtQuick3DCommand(); @@ -1354,7 +1359,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_Command) TEST_F(NodeMetaInfo, is_QtQuick3D_DefaultMaterial) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "DefaultMaterial"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", ModuleKind::QmlLibrary, "DefaultMaterial"); bool isType = metaInfo.isQtQuick3DDefaultMaterial(); @@ -1372,7 +1377,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_DefaultMaterial) TEST_F(NodeMetaInfo, is_QtQuick3D_Effect) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "Effect"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", ModuleKind::QmlLibrary, "Effect"); bool isType = metaInfo.isQtQuick3DEffect(); @@ -1390,7 +1395,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_Effect) TEST_F(NodeMetaInfo, is_QtQuick3D_InstanceList) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "InstanceList"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", ModuleKind::QmlLibrary, "InstanceList"); bool isType = metaInfo.isQtQuick3DInstanceList(); @@ -1408,7 +1413,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_InstanceList) TEST_F(NodeMetaInfo, is_QtQuick3D_InstanceListEntry) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "InstanceListEntry"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", ModuleKind::QmlLibrary, "InstanceListEntry"); bool isType = metaInfo.isQtQuick3DInstanceListEntry(); @@ -1426,7 +1431,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_InstanceListEntry) TEST_F(NodeMetaInfo, is_QtQuick3D_Light) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "Light"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", ModuleKind::QmlLibrary, "Light"); bool isType = metaInfo.isQtQuick3DLight(); @@ -1444,7 +1449,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_Light) TEST_F(NodeMetaInfo, is_QtQuick3D_Material) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "Material"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", ModuleKind::QmlLibrary, "Material"); bool isType = metaInfo.isQtQuick3DMaterial(); @@ -1462,7 +1467,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_Material) TEST_F(NodeMetaInfo, is_QtQuick3D_Model) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "Model"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", ModuleKind::QmlLibrary, "Model"); bool isType = metaInfo.isQtQuick3DModel(); @@ -1480,7 +1485,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_Model) TEST_F(NodeMetaInfo, is_QtQuick3D_Node) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "Node"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", ModuleKind::QmlLibrary, "Node"); bool isType = metaInfo.isQtQuick3DNode(); @@ -1498,7 +1503,8 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_Node) TEST_F(NodeMetaInfo, is_QtQuick3D_Particles3D_cppnative_QQuick3DParticleAbstractShape) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D.Particles3D-cppnative", + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D.Particles3D", + ModuleKind::CppLibrary, "QQuick3DParticleAbstractShape"); bool isType = metaInfo.isQtQuick3DParticlesAbstractShape(); @@ -1517,7 +1523,9 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_Particles3D_cppnative_QQuick3DPart TEST_F(NodeMetaInfo, is_QtQuick3D_Particles3D_Affector3D) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D.Particles3D", "Affector3D"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D.Particles3D", + ModuleKind::QmlLibrary, + "Affector3D"); bool isType = metaInfo.isQtQuick3DParticles3DAffector3D(); @@ -1535,7 +1543,9 @@ TEST_F(NodeMetaInfo, QtQuick3D_Particles3D_Affector3D) TEST_F(NodeMetaInfo, is_QtQuick3D_Particles3D_Attractor3D) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D.Particles3D", "Attractor3D"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D.Particles3D", + ModuleKind::QmlLibrary, + "Attractor3D"); bool isType = metaInfo.isQtQuick3DParticles3DAttractor3D(); @@ -1553,7 +1563,9 @@ TEST_F(NodeMetaInfo, QtQuick3D_Particles3D_Attractor3D) TEST_F(NodeMetaInfo, is_QtQuick3D_Particles3D_Particle3D) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D.Particles3D", "Particle3D"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D.Particles3D", + ModuleKind::QmlLibrary, + "Particle3D"); bool isType = metaInfo.isQtQuick3DParticles3DParticle3D(); @@ -1571,7 +1583,9 @@ TEST_F(NodeMetaInfo, QtQuick3D_Particles3D_Particle3D) TEST_F(NodeMetaInfo, is_QtQuick3D_Particles3D_ParticleEmitter3D) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D.Particles3D", "ParticleEmitter3D"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D.Particles3D", + ModuleKind::QmlLibrary, + "ParticleEmitter3D"); bool isType = metaInfo.isQtQuick3DParticles3DParticleEmitter3D(); @@ -1589,7 +1603,9 @@ TEST_F(NodeMetaInfo, QtQuick3D_Particles3D_ParticleEmitter3D) TEST_F(NodeMetaInfo, is_QtQuick3D_Particles3D_SpriteParticle3D) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D.Particles3D", "SpriteParticle3D"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D.Particles3D", + ModuleKind::QmlLibrary, + "SpriteParticle3D"); bool isType = metaInfo.isQtQuick3DParticles3DSpriteParticle3D(); @@ -1607,7 +1623,7 @@ TEST_F(NodeMetaInfo, QtQuick3D_Particles3D_SpriteParticle3D) TEST_F(NodeMetaInfo, is_QtQuick3D_Pass) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "Pass"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", ModuleKind::QmlLibrary, "Pass"); bool isType = metaInfo.isQtQuick3DPass(); @@ -1625,7 +1641,9 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_Pass) TEST_F(NodeMetaInfo, is_QtQuick3D_PrincipledMaterial) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "PrincipledMaterial"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", + ModuleKind::QmlLibrary, + "PrincipledMaterial"); bool isType = metaInfo.isQtQuick3DPrincipledMaterial(); @@ -1643,7 +1661,9 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_PrincipledMaterial) TEST_F(NodeMetaInfo, is_QtQuick3D_SpecularGlossyMaterial) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "SpecularGlossyMaterial"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", + ModuleKind::QmlLibrary, + "SpecularGlossyMaterial"); bool isType = metaInfo.isQtQuick3DSpecularGlossyMaterial(); @@ -1661,7 +1681,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_SpecularGlossyMaterial) TEST_F(NodeMetaInfo, is_QtQuick3D_SceneEnvironment) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "SceneEnvironment"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", ModuleKind::QmlLibrary, "SceneEnvironment"); bool isType = metaInfo.isQtQuick3DSceneEnvironment(); @@ -1679,7 +1699,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_SceneEnvironment) TEST_F(NodeMetaInfo, is_QtQuick3D_Shader) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "Shader"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", ModuleKind::QmlLibrary, "Shader"); bool isType = metaInfo.isQtQuick3DShader(); @@ -1697,7 +1717,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_Shader) TEST_F(NodeMetaInfo, is_QtQuick3D_Texture) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "Texture"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", ModuleKind::QmlLibrary, "Texture"); bool isType = metaInfo.isQtQuick3DTexture(); @@ -1715,7 +1735,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_Texture) TEST_F(NodeMetaInfo, is_QtQuick3D_TextureInput) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "TextureInput"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", ModuleKind::QmlLibrary, "TextureInput"); bool isType = metaInfo.isQtQuick3DTextureInput(); @@ -1733,7 +1753,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_TextureInput) TEST_F(NodeMetaInfo, is_QtQuick3D_CubeMapTexture) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "CubeMapTexture"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", ModuleKind::QmlLibrary, "CubeMapTexture"); bool isType = metaInfo.isQtQuick3DCubeMapTexture(); @@ -1751,7 +1771,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_CubeMapTexture) TEST_F(NodeMetaInfo, is_QtQuick3D_View3D) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", "View3D"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick3D", ModuleKind::QmlLibrary, "View3D"); bool isType = metaInfo.isQtQuick3DView3D(); @@ -1769,7 +1789,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick3D_View3D) TEST_F(NodeMetaInfo, is_QtQuick_BorderImage) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick", "BorderImage"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick", ModuleKind::QmlLibrary, "BorderImage"); bool isType = metaInfo.isQtQuickBorderImage(); @@ -1787,7 +1807,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick_BorderImage) TEST_F(NodeMetaInfo, is_QtQuickControls_SwipeView) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Controls", "SwipeView"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Controls", ModuleKind::QmlLibrary, "SwipeView"); bool isType = metaInfo.isQtQuickControlsSwipeView(); @@ -1805,7 +1825,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuickControls_SwipeView) TEST_F(NodeMetaInfo, is_QtQuickControls_TabBar) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Controls", "TabBar"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Controls", ModuleKind::QmlLibrary, "TabBar"); bool isType = metaInfo.isQtQuickControlsTabBar(); @@ -1823,7 +1843,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuickControls_TabBar) TEST_F(NodeMetaInfo, is_QtQuickExtras_Picture) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Extras", "Picture"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Extras", ModuleKind::QmlLibrary, "Picture"); bool isType = metaInfo.isQtQuickExtrasPicture(); @@ -1841,7 +1861,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuickExtras_Picture) TEST_F(NodeMetaInfo, is_QtQuick_Image) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick", "Image"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick", ModuleKind::QmlLibrary, "Image"); bool isType = metaInfo.isQtQuickImage(); @@ -1859,7 +1879,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick_Image) TEST_F(NodeMetaInfo, is_QtQuick_Item) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick", "Item"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick", ModuleKind::QmlLibrary, "Item"); bool isType = metaInfo.isQtQuickItem(); @@ -1877,7 +1897,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick_Item) TEST_F(NodeMetaInfo, is_QtQuickLayouts_BorderImage) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Layouts", "Layout"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Layouts", ModuleKind::QmlLibrary, "Layout"); bool isType = metaInfo.isQtQuickLayoutsLayout(); @@ -1895,7 +1915,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuickLayouts_Layout) TEST_F(NodeMetaInfo, is_QtQuick_Loader) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick", "Loader"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick", ModuleKind::QmlLibrary, "Loader"); bool isType = metaInfo.isQtQuickLoader(); @@ -1913,7 +1933,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick_Loader) TEST_F(NodeMetaInfo, is_QtQuick_Path) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick", "Path"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick", ModuleKind::QmlLibrary, "Path"); bool isType = metaInfo.isQtQuickPath(); @@ -1931,7 +1951,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick_Path) TEST_F(NodeMetaInfo, is_QtQuick_PauseAnimation) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick", "PauseAnimation"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick", ModuleKind::QmlLibrary, "PauseAnimation"); bool isType = metaInfo.isQtQuickPauseAnimation(); @@ -1949,7 +1969,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick_PauseAnimation) TEST_F(NodeMetaInfo, is_QtQuick_Positioner) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick", "Positioner"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick", ModuleKind::QmlLibrary, "Positioner"); bool isType = metaInfo.isQtQuickPositioner(); @@ -1967,7 +1987,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick_Positioner) TEST_F(NodeMetaInfo, is_QtQuick_PropertyAnimation) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick", "PropertyAnimation"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick", ModuleKind::QmlLibrary, "PropertyAnimation"); bool isType = metaInfo.isQtQuickPropertyAnimation(); @@ -1985,7 +2005,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick_PropertyAnimation) TEST_F(NodeMetaInfo, is_QtQuick_PropertyChanges) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick", "PropertyChanges"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick", ModuleKind::QmlLibrary, "PropertyChanges"); bool isType = metaInfo.isQtQuickPropertyChanges(); @@ -2003,7 +2023,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick_PropertyChanges) TEST_F(NodeMetaInfo, is_QtQuick_Repeater) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick", "Repeater"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick", ModuleKind::QmlLibrary, "Repeater"); bool isType = metaInfo.isQtQuickRepeater(); @@ -2021,7 +2041,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick_Repeater) TEST_F(NodeMetaInfo, is_QtQuick_State) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick", "State"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick", ModuleKind::QmlLibrary, "State"); bool isType = metaInfo.isQtQuickState(); @@ -2039,7 +2059,9 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick_State) TEST_F(NodeMetaInfo, is_QtQuickNative_StateOperation) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick-cppnative", "QQuickStateOperation"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick", + ModuleKind::CppLibrary, + "QQuickStateOperation"); bool isType = metaInfo.isQtQuickStateOperation(); @@ -2057,7 +2079,9 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuickNative_StateOperation) TEST_F(NodeMetaInfo, is_QtQuickStudioComponents_GroupItem) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Studio.Components", "GroupItem"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Studio.Components", + ModuleKind::QmlLibrary, + "GroupItem"); bool isType = metaInfo.isQtQuickStudioComponentsGroupItem(); @@ -2075,7 +2099,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuickStudioComponents_GroupItem) TEST_F(NodeMetaInfo, is_QtQuick_Text) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick", "Text"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick", ModuleKind::QmlLibrary, "Text"); bool isType = metaInfo.isQtQuickText(); @@ -2093,7 +2117,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick_Text) TEST_F(NodeMetaInfo, is_QtQuickTimeline_Keyframe) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Timeline", "Keyframe"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Timeline", ModuleKind::QmlLibrary, "Keyframe"); bool isType = metaInfo.isQtQuickTimelineKeyframe(); @@ -2111,7 +2135,9 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick_Keyframe) TEST_F(NodeMetaInfo, is_QtQuickTimeline_KeyframeGroup) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Timeline", "KeyframeGroup"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Timeline", + ModuleKind::QmlLibrary, + "KeyframeGroup"); bool isType = metaInfo.isQtQuickTimelineKeyframeGroup(); @@ -2129,7 +2155,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick_KeyframeGroup) TEST_F(NodeMetaInfo, is_QtQuickTimeline_Timeline) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Timeline", "Timeline"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Timeline", ModuleKind::QmlLibrary, "Timeline"); bool isType = metaInfo.isQtQuickTimelineTimeline(); @@ -2147,7 +2173,9 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick_Timeline) TEST_F(NodeMetaInfo, is_QtQuickTimeline_TimelineAnimation) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Timeline", "TimelineAnimation"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Timeline", + ModuleKind::QmlLibrary, + "TimelineAnimation"); bool isType = metaInfo.isQtQuickTimelineTimelineAnimation(); @@ -2165,7 +2193,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick_TimelineAnimation) TEST_F(NodeMetaInfo, is_QtQuick_Transition) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick", "Transition"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick", ModuleKind::QmlLibrary, "Transition"); bool isType = metaInfo.isQtQuickTransition(); @@ -2183,7 +2211,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuick_Transition) TEST_F(NodeMetaInfo, is_QtQuickWindow_Window) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Window", "Window"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Window", ModuleKind::QmlLibrary, "Window"); bool isType = metaInfo.isQtQuickWindowWindow(); @@ -2201,7 +2229,9 @@ TEST_F(NodeMetaInfo, default_is_not_QtQuickWindow_Window) TEST_F(NodeMetaInfo, is_QtSafeRenderer_SafeRendererPicture) { - auto metaInfo = createDerivedDummyMetaInfo("Qt.SafeRenderer", "SafeRendererPicture"); + auto metaInfo = createDerivedDummyMetaInfo("Qt.SafeRenderer", + ModuleKind::QmlLibrary, + "SafeRendererPicture"); bool isType = metaInfo.isQtSafeRendererSafeRendererPicture(); @@ -2219,7 +2249,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtSafeRenderer_SafeRendererPicture) TEST_F(NodeMetaInfo, is_QtSafeRenderer_SafePicture) { - auto metaInfo = createDerivedDummyMetaInfo("Qt.SafeRenderer", "SafePicture"); + auto metaInfo = createDerivedDummyMetaInfo("Qt.SafeRenderer", ModuleKind::QmlLibrary, "SafePicture"); bool isType = metaInfo.isQtSafeRendererSafePicture(); @@ -2237,7 +2267,7 @@ TEST_F(NodeMetaInfo, default_is_not_QtSafeRenderer_SafePicture) TEST_F(NodeMetaInfo, is_string) { - auto metaInfo = createMetaInfo("QML", "string"); + auto metaInfo = createMetaInfo("QML", ModuleKind::QmlLibrary, "string"); bool isType = metaInfo.isString(); @@ -2255,7 +2285,7 @@ TEST_F(NodeMetaInfo, default_is_not_string) TEST_F(NodeMetaInfo, QtQuick_Item_is_suitable_for_MouseArea_fill) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick", "Item"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick", ModuleKind::QmlLibrary, "Item"); bool isType = metaInfo.isSuitableForMouseAreaFill(); @@ -2264,7 +2294,7 @@ TEST_F(NodeMetaInfo, QtQuick_Item_is_suitable_for_MouseArea_fill) TEST_F(NodeMetaInfo, QtQuick_MouseArea_is_suitable_for_MouseArea_fill) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick", "MouseArea"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick", ModuleKind::QmlLibrary, "MouseArea"); bool isType = metaInfo.isSuitableForMouseAreaFill(); @@ -2273,7 +2303,7 @@ TEST_F(NodeMetaInfo, QtQuick_MouseArea_is_suitable_for_MouseArea_fill) TEST_F(NodeMetaInfo, QtQuickControls_Control_is_suitable_for_MouseArea_fill) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Controls", "Control"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Controls", ModuleKind::QmlLibrary, "Control"); bool isType = metaInfo.isSuitableForMouseAreaFill(); @@ -2282,7 +2312,7 @@ TEST_F(NodeMetaInfo, QtQuickControls_Control_is_suitable_for_MouseArea_fill) TEST_F(NodeMetaInfo, QtQuickTemplates_Control_is_suitable_for_MouseArea_fill) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Templates", "Control"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick.Templates", ModuleKind::QmlLibrary, "Control"); bool isType = metaInfo.isSuitableForMouseAreaFill(); @@ -2300,7 +2330,7 @@ TEST_F(NodeMetaInfo, default_is_not_suitable_for_MouseArea_fill) TEST_F(NodeMetaInfo, is_url) { - auto metaInfo = createMetaInfo("QML", "url"); + auto metaInfo = createMetaInfo("QML", ModuleKind::QmlLibrary, "url"); bool isType = metaInfo.isUrl(); @@ -2318,7 +2348,7 @@ TEST_F(NodeMetaInfo, default_is_not_url) TEST_F(NodeMetaInfo, is_variant) { - auto metaInfo = createMetaInfo("QML", "var"); + auto metaInfo = createMetaInfo("QML", ModuleKind::QmlLibrary, "var"); bool isType = metaInfo.isVariant(); @@ -2336,7 +2366,7 @@ TEST_F(NodeMetaInfo, default_is_not_variant) TEST_F(NodeMetaInfo, is_vector2d) { - auto metaInfo = createMetaInfo("QtQuick", "vector2d"); + auto metaInfo = createMetaInfo("QtQuick", ModuleKind::QmlLibrary, "vector2d"); bool isType = metaInfo.isVector2D(); @@ -2354,7 +2384,7 @@ TEST_F(NodeMetaInfo, default_is_not_vector2d) TEST_F(NodeMetaInfo, is_vector3d) { - auto metaInfo = createMetaInfo("QtQuick", "vector3d"); + auto metaInfo = createMetaInfo("QtQuick", ModuleKind::QmlLibrary, "vector3d"); bool isType = metaInfo.isVector3D(); @@ -2372,7 +2402,7 @@ TEST_F(NodeMetaInfo, default_is_not_vector3d) TEST_F(NodeMetaInfo, is_vector4d) { - auto metaInfo = createMetaInfo("QtQuick", "vector4d"); + auto metaInfo = createMetaInfo("QtQuick", ModuleKind::QmlLibrary, "vector4d"); bool isType = metaInfo.isVector4D(); @@ -2390,7 +2420,7 @@ TEST_F(NodeMetaInfo, default_is_not_vector4d) TEST_F(NodeMetaInfo, QtQuick_ListView_is_view) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick", "ListView"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick", ModuleKind::QmlLibrary, "ListView"); bool isType = metaInfo.isView(); @@ -2399,7 +2429,7 @@ TEST_F(NodeMetaInfo, QtQuick_ListView_is_view) TEST_F(NodeMetaInfo, QtQuick_GridView_is_view) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick", "GridView"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick", ModuleKind::QmlLibrary, "GridView"); bool isType = metaInfo.isView(); @@ -2408,7 +2438,7 @@ TEST_F(NodeMetaInfo, QtQuick_GridView_is_view) TEST_F(NodeMetaInfo, QtQuick_PathView_is_view) { - auto metaInfo = createDerivedDummyMetaInfo("QtQuick", "PathView"); + auto metaInfo = createDerivedDummyMetaInfo("QtQuick", ModuleKind::QmlLibrary, "PathView"); bool isType = metaInfo.isView(); @@ -2428,7 +2458,7 @@ TEST_F(NodeMetaInfo, is_enumeration) { TypeTraits traits; traits.isEnum = true; - auto metaInfo = createMetaInfo("QML", "Foo", traits); + auto metaInfo = createMetaInfo("QML", ModuleKind::QmlLibrary, "Foo", traits); bool isType = metaInfo.isEnumeration(); @@ -2437,7 +2467,7 @@ TEST_F(NodeMetaInfo, is_enumeration) TEST_F(NodeMetaInfo, is_not_enumeration) { - auto metaInfo = createMetaInfo("QML", "Foo", {}); + auto metaInfo = createMetaInfo("QML", ModuleKind::QmlLibrary, "Foo", {}); bool isType = metaInfo.isEnumeration(); @@ -2457,7 +2487,7 @@ TEST_F(NodeMetaInfo, all_external_type_names) { QmlDesigner::Storage::Info::ExportedTypeNames names{{qmlModuleId, "Object", 2, -1}, {qmlModuleId, "Obj", 2, 1}}; - auto metaInfo = createMetaInfo("QML", "Foo"); + auto metaInfo = createMetaInfo("QML", ModuleKind::QmlLibrary, "Foo"); ON_CALL(projectStorageMock, exportedTypeNames(metaInfo.id())).WillByDefault(Return(names)); auto exportedTypeNames = metaInfo.allExportedTypeNames(); @@ -2483,7 +2513,7 @@ TEST_F(NodeMetaInfo, external_type_names_for_source_id) { QmlDesigner::Storage::Info::ExportedTypeNames names{{qmlModuleId, "Object", 2, -1}, {qmlModuleId, "Obj", 2, 1}}; - auto metaInfo = createMetaInfo("QML", "Foo"); + auto metaInfo = createMetaInfo("QML", ModuleKind::QmlLibrary, "Foo"); ON_CALL(projectStorageMock, exportedTypeNames(metaInfo.id(), model.fileUrlSourceId())) .WillByDefault(Return(names)); @@ -2511,7 +2541,7 @@ TEST_F(NodeMetaInfo, invalid_source_id_has_no_external_type_names_for_source_id) { QmlDesigner::Storage::Info::ExportedTypeNames names{{qmlModuleId, "Object", 2, -1}, {qmlModuleId, "Obj", 2, 1}}; - auto metaInfo = createMetaInfo("QML", "Foo"); + auto metaInfo = createMetaInfo("QML", ModuleKind::QmlLibrary, "Foo"); ON_CALL(projectStorageMock, exportedTypeNames(metaInfo.id(), model.fileUrlSourceId())) .WillByDefault(Return(names)); QmlDesigner::SourceId sourceId; @@ -2523,7 +2553,7 @@ TEST_F(NodeMetaInfo, invalid_source_id_has_no_external_type_names_for_source_id) TEST_F(NodeMetaInfo, float_is_a_number) { - auto metaInfo = createMetaInfo("QML-cppnative", "float"); + auto metaInfo = createMetaInfo("QML", ModuleKind::CppLibrary, "float"); bool isType = metaInfo.isNumber(); @@ -2550,7 +2580,7 @@ TEST_F(NodeMetaInfo, int_is_a_number) TEST_F(NodeMetaInfo, uint_is_a_number) { - auto metaInfo = createMetaInfo("QML-cppnative", "uint"); + auto metaInfo = createMetaInfo("QML", ModuleKind::CppLibrary, "uint"); bool isType = metaInfo.isNumber(); @@ -2568,7 +2598,7 @@ TEST_F(NodeMetaInfo, default_is_not_number) TEST_F(NodeMetaInfo, property_editor_specifics_path) { - auto metaInfo = createMetaInfo("QtQuick", "Item"); + auto metaInfo = createMetaInfo("QtQuick", ModuleKind::QmlLibrary, "Item"); auto pathId = QmlDesigner::SourceId::create(45); ON_CALL(projectStorageMock, propertyEditorPathId(metaInfo.id())).WillByDefault(Return(pathId)); @@ -2588,7 +2618,7 @@ TEST_F(NodeMetaInfo, default_property_editor_specifics_path_is_empty) TEST_F(NodeMetaInfo, is_reference) { - auto metaInfo = createMetaInfo("QtQuick", "Item", TypeTraitsKind::Reference); + auto metaInfo = createMetaInfo("QtQuick", ModuleKind::QmlLibrary, "Item", TypeTraitsKind::Reference); auto type = metaInfo.type(); @@ -2597,7 +2627,7 @@ TEST_F(NodeMetaInfo, is_reference) TEST_F(NodeMetaInfo, is_value) { - auto metaInfo = createMetaInfo("QML", "bool", TypeTraitsKind::Value); + auto metaInfo = createMetaInfo("QML", ModuleKind::QmlLibrary, "bool", TypeTraitsKind::Value); auto type = metaInfo.type(); @@ -2606,7 +2636,7 @@ TEST_F(NodeMetaInfo, is_value) TEST_F(NodeMetaInfo, is_sequence) { - auto metaInfo = createMetaInfo("QML", "QObjectList", TypeTraitsKind::Sequence); + auto metaInfo = createMetaInfo("QML", ModuleKind::QmlLibrary, "QObjectList", TypeTraitsKind::Sequence); auto type = metaInfo.type(); @@ -2615,7 +2645,7 @@ TEST_F(NodeMetaInfo, is_sequence) TEST_F(NodeMetaInfo, is_none) { - auto metaInfo = createMetaInfo("QML", "void", TypeTraitsKind::None); + auto metaInfo = createMetaInfo("QML", ModuleKind::QmlLibrary, "void", TypeTraitsKind::None); auto type = metaInfo.type(); @@ -2657,7 +2687,7 @@ TEST_F(NodeMetaInfo, invalid_can_not_be_container) TEST_F(NodeMetaInfo, component_can_be_container) { - auto moduleId = projectStorageMock.createModule("/path/to/project"); + auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); TypeTraits traits{TypeTraitsKind::Reference}; traits.canBeContainer = FlagIs::True; auto typeId = projectStorageMock.createType(moduleId, "Foo", traits); @@ -2694,7 +2724,7 @@ TEST_F(NodeMetaInfo, invalid_do_no_forces_clipping) TEST_F(NodeMetaInfo, component_forces_clipping) { - auto moduleId = projectStorageMock.createModule("/path/to/project"); + auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); TypeTraits traits{TypeTraitsKind::Reference}; traits.forceClip = FlagIs::True; auto typeId = projectStorageMock.createType(moduleId, "Foo", traits); @@ -2731,7 +2761,7 @@ TEST_F(NodeMetaInfo, invalid_does_not_layout_children) TEST_F(NodeMetaInfo, component_layouts_children) { - auto moduleId = projectStorageMock.createModule("/path/to/project"); + auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); TypeTraits traits{TypeTraitsKind::Reference}; traits.doesLayoutChildren = FlagIs::True; auto typeId = projectStorageMock.createType(moduleId, "Foo", traits); @@ -2768,7 +2798,7 @@ TEST_F(NodeMetaInfo, invalid_cannot_be_dropped_in_form_editor) TEST_F(NodeMetaInfo, component_can_be_dropped_in_form_editor) { - auto moduleId = projectStorageMock.createModule("/path/to/project"); + auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); TypeTraits traits{TypeTraitsKind::Reference}; traits.canBeDroppedInFormEditor = FlagIs::True; auto typeId = projectStorageMock.createType(moduleId, "Foo", traits); @@ -2805,7 +2835,7 @@ TEST_F(NodeMetaInfo, invalid_cannot_be_dropped_in_navigator) TEST_F(NodeMetaInfo, component_can_be_dropped_in_navigator) { - auto moduleId = projectStorageMock.createModule("/path/to/project"); + auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); TypeTraits traits{TypeTraitsKind::Reference}; traits.canBeDroppedInNavigator = FlagIs::True; auto typeId = projectStorageMock.createType(moduleId, "Foo", traits); @@ -2842,7 +2872,7 @@ TEST_F(NodeMetaInfo, invalid_cannot_be_dropped_in_3d_view) TEST_F(NodeMetaInfo, component_can_be_dropped_in_3d_view) { - auto moduleId = projectStorageMock.createModule("/path/to/project"); + auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); TypeTraits traits{TypeTraitsKind::Reference}; traits.canBeDroppedInView3D = FlagIs::True; auto typeId = projectStorageMock.createType(moduleId, "Foo", traits); @@ -2879,7 +2909,7 @@ TEST_F(NodeMetaInfo, invalid_is_not_movable) TEST_F(NodeMetaInfo, component_is_movable) { - auto moduleId = projectStorageMock.createModule("/path/to/project"); + auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); TypeTraits traits{TypeTraitsKind::Reference}; traits.isMovable = FlagIs::True; auto typeId = projectStorageMock.createType(moduleId, "Foo", traits); @@ -2916,7 +2946,7 @@ TEST_F(NodeMetaInfo, invalid_is_not_resizable) TEST_F(NodeMetaInfo, component_is_resizable) { - auto moduleId = projectStorageMock.createModule("/path/to/project"); + auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); TypeTraits traits{TypeTraitsKind::Reference}; traits.isResizable = FlagIs::True; auto typeId = projectStorageMock.createType(moduleId, "Foo", traits); @@ -2953,7 +2983,7 @@ TEST_F(NodeMetaInfo, invalid_has_not_form_editor_item) TEST_F(NodeMetaInfo, component_has_form_editor_item) { - auto moduleId = projectStorageMock.createModule("/path/to/project"); + auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); TypeTraits traits{TypeTraitsKind::Reference}; traits.hasFormEditorItem = FlagIs::True; auto typeId = projectStorageMock.createType(moduleId, "Foo", traits); @@ -2990,7 +3020,7 @@ TEST_F(NodeMetaInfo, invalid_is_not_stacked_container) TEST_F(NodeMetaInfo, component_is_stacked_container) { - auto moduleId = projectStorageMock.createModule("/path/to/project"); + auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); TypeTraits traits{TypeTraitsKind::Reference}; traits.isStackedContainer = FlagIs::True; auto typeId = projectStorageMock.createType(moduleId, "Foo", traits); @@ -3027,7 +3057,7 @@ TEST_F(NodeMetaInfo, invalid_dont_takes_over_rendering_of_children) TEST_F(NodeMetaInfo, component_takes_over_rendering_of_children) { - auto moduleId = projectStorageMock.createModule("/path/to/project"); + auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); TypeTraits traits{TypeTraitsKind::Reference}; traits.takesOverRenderingOfChildren = FlagIs::True; auto typeId = projectStorageMock.createType(moduleId, "Foo", traits); @@ -3064,7 +3094,7 @@ TEST_F(NodeMetaInfo, invalid_is_not_visible_in_navigator) TEST_F(NodeMetaInfo, component_is_visible_in_navigator) { - auto moduleId = projectStorageMock.createModule("/path/to/project"); + auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); TypeTraits traits{TypeTraitsKind::Reference}; traits.visibleInNavigator = FlagIs::True; auto typeId = projectStorageMock.createType(moduleId, "Foo", traits); @@ -3101,7 +3131,7 @@ TEST_F(NodeMetaInfo, invalid_is_not_visible_in_library) TEST_F(NodeMetaInfo, component_is_visible_in_library) { - auto moduleId = projectStorageMock.createModule("/path/to/project"); + auto moduleId = projectStorageMock.createModule("/path/to/project", ModuleKind::PathLibrary); TypeTraits traits{TypeTraitsKind::Reference}; traits.visibleInLibrary = FlagIs::True; auto typeId = projectStorageMock.createType(moduleId, "Foo", traits); @@ -3152,6 +3182,7 @@ TEST_F(NodeMetaInfo, item_library_entries) { projectStorageMock.setItemLibraryEntries(objectMetaInfo.id(), {{objectMetaInfo.id(), + "QtObject", "Object", "/icon/path", "Basic", @@ -3163,6 +3194,7 @@ TEST_F(NodeMetaInfo, item_library_entries) ASSERT_THAT(entries, ElementsAre(IsItemLibraryEntry(objectMetaInfo.id(), + "QtObject", "Object", "/icon/path", "Basic", diff --git a/tests/unit/tests/unittests/metainfo/propertymetainfo-test.cpp b/tests/unit/tests/unittests/metainfo/propertymetainfo-test.cpp index 25436264ae..d2ec90b7a8 100644 --- a/tests/unit/tests/unittests/metainfo/propertymetainfo-test.cpp +++ b/tests/unit/tests/unittests/metainfo/propertymetainfo-test.cpp @@ -22,6 +22,7 @@ namespace { using QmlDesigner::Enumeration; using QmlDesigner::ModelNode; using QmlDesigner::ModelNodes; +using QmlDesigner::Storage::ModuleKind; using QmlDesigner::Storage::PropertyDeclarationTraits; using QmlDesigner::Storage::TypeTraits; @@ -29,10 +30,11 @@ class PropertyMetaInfo : public ::testing::Test { protected: QmlDesigner::NodeMetaInfo createNodeMetaInfo(Utils::SmallStringView moduleName, + ModuleKind moduleKind, Utils::SmallStringView typeName, QmlDesigner::Storage::TypeTraits typeTraits = {}) { - auto moduleId = projectStorageMock.createModule(moduleName); + auto moduleId = projectStorageMock.createModule(moduleName, moduleKind); auto typeId = projectStorageMock.createType(moduleId, typeName, typeTraits); return QmlDesigner::NodeMetaInfo{typeId, &projectStorageMock}; @@ -47,7 +49,7 @@ protected: QmlDesigner::Import::createLibraryImport("QtQuick"), QmlDesigner::Import::createLibraryImport("QtQml.Models")}, QUrl::fromLocalFile(pathCache.path.toQString())}; - QmlDesigner::NodeMetaInfo nodeInfo = createNodeMetaInfo("QtQuick", "Foo"); + QmlDesigner::NodeMetaInfo nodeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "Foo"); }; TEST_F(PropertyMetaInfo, name) @@ -71,7 +73,7 @@ TEST_F(PropertyMetaInfo, default_has_no_name) TEST_F(PropertyMetaInfo, property_type) { - auto barInfo = createNodeMetaInfo("QtQuick", "Bar"); + auto barInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "Bar"); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, barInfo.id()); auto propertyInfo = nodeInfo.property("bar"); @@ -91,7 +93,7 @@ TEST_F(PropertyMetaInfo, default_hads_invalid_property_type) TEST_F(PropertyMetaInfo, type) { - auto barInfo = createNodeMetaInfo("QtQuick", "Bar"); + auto barInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "Bar"); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, barInfo.id()); auto propertyInfo = nodeInfo.property("bar"); @@ -181,7 +183,7 @@ TEST_F(PropertyMetaInfo, is_enumeration) { TypeTraits traits; traits.isEnum = true; - auto enumInfo = createNodeMetaInfo("QtQuick", "MyEnum", traits); + auto enumInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "MyEnum", traits); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, enumInfo.id()); auto propertyInfo = nodeInfo.property("bar"); @@ -192,7 +194,7 @@ TEST_F(PropertyMetaInfo, is_enumeration) TEST_F(PropertyMetaInfo, is_not_enumeration) { - auto notEnumInfo = createNodeMetaInfo("QtQuick", "NoEnum", {}); + auto notEnumInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "NoEnum", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, notEnumInfo.id()); auto propertyInfo = nodeInfo.property("bar"); @@ -275,7 +277,7 @@ TEST_F(PropertyMetaInfo, cast_to_enumeration) { TypeTraits traits; traits.isEnum = true; - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "MyEnum", traits); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "MyEnum", traits); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); Enumeration enumeration{"MyEnum.Foo"}; @@ -288,7 +290,7 @@ TEST_F(PropertyMetaInfo, cast_to_enumeration) TEST_F(PropertyMetaInfo, dont_to_cast_enumeration_if_property_type_is_not_enumeration) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "MyEnum", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "MyEnum", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); Enumeration enumeration{"MyEnum.Foo"}; @@ -303,7 +305,7 @@ TEST_F(PropertyMetaInfo, dont_to_cast_enumeration_if_value_is_not_Enumeration) { TypeTraits traits; traits.isEnum = true; - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "MyEnum", traits); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "MyEnum", traits); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(QString{"enumeration"}); @@ -315,7 +317,7 @@ TEST_F(PropertyMetaInfo, dont_to_cast_enumeration_if_value_is_not_Enumeration) TEST_F(PropertyMetaInfo, cast_to_model_node) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "var", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "var", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(model.rootModelNode()); @@ -327,7 +329,7 @@ TEST_F(PropertyMetaInfo, cast_to_model_node) TEST_F(PropertyMetaInfo, cast_to_qvariant_always_returns_the_save_variant_if_the_property_type_is_var) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "var", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "var", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(QString{"foo"}); @@ -339,7 +341,7 @@ TEST_F(PropertyMetaInfo, cast_to_qvariant_always_returns_the_save_variant_if_the TEST_F(PropertyMetaInfo, cast_double_to_double) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "double", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "double", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(14.2); @@ -351,7 +353,7 @@ TEST_F(PropertyMetaInfo, cast_double_to_double) TEST_F(PropertyMetaInfo, cast_int_to_double_returns_number_variant) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "double", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "double", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(14); @@ -363,7 +365,7 @@ TEST_F(PropertyMetaInfo, cast_int_to_double_returns_number_variant) TEST_F(PropertyMetaInfo, cast_default_to_double_returns_zero_variant) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "double", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "double", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(); @@ -375,7 +377,7 @@ TEST_F(PropertyMetaInfo, cast_default_to_double_returns_zero_variant) TEST_F(PropertyMetaInfo, cast_qstring_to_double_returns_zero_variant) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "double", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "double", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(QString{"foo"}); @@ -387,7 +389,7 @@ TEST_F(PropertyMetaInfo, cast_qstring_to_double_returns_zero_variant) TEST_F(PropertyMetaInfo, cast_float_to_float) { - auto propertyTypeInfo = createNodeMetaInfo("QML-cppnative", "float", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::CppLibrary, "float", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(14.2f); @@ -399,7 +401,7 @@ TEST_F(PropertyMetaInfo, cast_float_to_float) TEST_F(PropertyMetaInfo, cast_int_to_float_returns_number_variant) { - auto propertyTypeInfo = createNodeMetaInfo("QML-cppnative", "float", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::CppLibrary, "float", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(14); @@ -411,7 +413,7 @@ TEST_F(PropertyMetaInfo, cast_int_to_float_returns_number_variant) TEST_F(PropertyMetaInfo, cast_default_to_float_returns_zero_variant) { - auto propertyTypeInfo = createNodeMetaInfo("QML-cppnative", "float", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::CppLibrary, "float", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(); @@ -423,7 +425,7 @@ TEST_F(PropertyMetaInfo, cast_default_to_float_returns_zero_variant) TEST_F(PropertyMetaInfo, cast_qstring_to_float_returns_zero_variant) { - auto propertyTypeInfo = createNodeMetaInfo("QML-cppnative", "float", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::CppLibrary, "float", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(QString{"foo"}); @@ -435,7 +437,7 @@ TEST_F(PropertyMetaInfo, cast_qstring_to_float_returns_zero_variant) TEST_F(PropertyMetaInfo, cast_int_to_int) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "int", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "int", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(14); @@ -447,7 +449,7 @@ TEST_F(PropertyMetaInfo, cast_int_to_int) TEST_F(PropertyMetaInfo, cast_double_to_int_returns_number_variant) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "int", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "int", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(14.2); @@ -459,7 +461,7 @@ TEST_F(PropertyMetaInfo, cast_double_to_int_returns_number_variant) TEST_F(PropertyMetaInfo, cast_default_to_int_returns_zero_variant) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "int", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "int", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(); @@ -471,7 +473,7 @@ TEST_F(PropertyMetaInfo, cast_default_to_int_returns_zero_variant) TEST_F(PropertyMetaInfo, cast_qstring_to_int_returns_zero_variant) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "int", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "int", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(QString{"foo"}); @@ -483,7 +485,7 @@ TEST_F(PropertyMetaInfo, cast_qstring_to_int_returns_zero_variant) TEST_F(PropertyMetaInfo, cast_bool_to_bool) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "bool", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "bool", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(true); @@ -495,7 +497,7 @@ TEST_F(PropertyMetaInfo, cast_bool_to_bool) TEST_F(PropertyMetaInfo, cast_float_to_bool_returns_boolean_variant) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "bool", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "bool", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(14.2f); @@ -507,7 +509,7 @@ TEST_F(PropertyMetaInfo, cast_float_to_bool_returns_boolean_variant) TEST_F(PropertyMetaInfo, cast_double_to_bool_returns_boolean_variant) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "bool", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "bool", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(14.2); @@ -519,7 +521,7 @@ TEST_F(PropertyMetaInfo, cast_double_to_bool_returns_boolean_variant) TEST_F(PropertyMetaInfo, cast_int_to_bool_returns_boolean_variant) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "bool", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "bool", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(14); @@ -531,7 +533,7 @@ TEST_F(PropertyMetaInfo, cast_int_to_bool_returns_boolean_variant) TEST_F(PropertyMetaInfo, cast_long_to_bool_returns_boolean_variant) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "bool", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "bool", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(14L); @@ -543,7 +545,7 @@ TEST_F(PropertyMetaInfo, cast_long_to_bool_returns_boolean_variant) TEST_F(PropertyMetaInfo, cast_long_long_to_bool_returns_boolean_variant) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "bool", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "bool", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(14LL); @@ -555,7 +557,7 @@ TEST_F(PropertyMetaInfo, cast_long_long_to_bool_returns_boolean_variant) TEST_F(PropertyMetaInfo, cast_default_to_bool_returns_zero_variant) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "bool", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "bool", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(); @@ -567,7 +569,7 @@ TEST_F(PropertyMetaInfo, cast_default_to_bool_returns_zero_variant) TEST_F(PropertyMetaInfo, cast_qstring_to_bool_returns_zero_variant) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "bool", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "bool", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(QString{"foo"}); @@ -579,7 +581,7 @@ TEST_F(PropertyMetaInfo, cast_qstring_to_bool_returns_zero_variant) TEST_F(PropertyMetaInfo, cast_string_to_string) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "string", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "string", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(QString{"foo"}); @@ -591,7 +593,7 @@ TEST_F(PropertyMetaInfo, cast_string_to_string) TEST_F(PropertyMetaInfo, cast_QByteArray_to_empty_string) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "string", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "string", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(QByteArray{"foo"}); @@ -603,7 +605,7 @@ TEST_F(PropertyMetaInfo, cast_QByteArray_to_empty_string) TEST_F(PropertyMetaInfo, cast_int_to_empty_string) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "string", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "string", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(14); @@ -615,7 +617,7 @@ TEST_F(PropertyMetaInfo, cast_int_to_empty_string) TEST_F(PropertyMetaInfo, cast_default_to_empty_string) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "string", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "string", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(); @@ -627,7 +629,7 @@ TEST_F(PropertyMetaInfo, cast_default_to_empty_string) TEST_F(PropertyMetaInfo, cast_datatime_to_datetime) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "date", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "date", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto dataTime = QDateTime::currentDateTime(); @@ -640,7 +642,7 @@ TEST_F(PropertyMetaInfo, cast_datatime_to_datetime) TEST_F(PropertyMetaInfo, cast_int_to_datetime_returns_default_datetime) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "date", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "date", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(14); @@ -652,7 +654,7 @@ TEST_F(PropertyMetaInfo, cast_int_to_datetime_returns_default_datetime) TEST_F(PropertyMetaInfo, cast_string_to_datetime_returns_default_datetime) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "date", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "date", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(QString{"Monday"}); @@ -664,7 +666,7 @@ TEST_F(PropertyMetaInfo, cast_string_to_datetime_returns_default_datetime) TEST_F(PropertyMetaInfo, cast_default_to_datetime_returns_default_datetime) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "date", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "date", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(); @@ -676,7 +678,7 @@ TEST_F(PropertyMetaInfo, cast_default_to_datetime_returns_default_datetime) TEST_F(PropertyMetaInfo, cast_url_to_url) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "url", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "url", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto url = QUrl("http://www.qt.io/future"); @@ -689,7 +691,7 @@ TEST_F(PropertyMetaInfo, cast_url_to_url) TEST_F(PropertyMetaInfo, cast_string_to_empty_url) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "url", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "url", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant::fromValue(QString{"http://www.qt.io/future"}); @@ -701,7 +703,7 @@ TEST_F(PropertyMetaInfo, cast_string_to_empty_url) TEST_F(PropertyMetaInfo, cast_default_to_empty_url) { - auto propertyTypeInfo = createNodeMetaInfo("QML", "url", {}); + auto propertyTypeInfo = createNodeMetaInfo("QML", ModuleKind::QmlLibrary, "url", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(); @@ -713,7 +715,7 @@ TEST_F(PropertyMetaInfo, cast_default_to_empty_url) TEST_F(PropertyMetaInfo, cast_color_to_color) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "color", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "color", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto color = QColor(Qt::red); @@ -726,7 +728,7 @@ TEST_F(PropertyMetaInfo, cast_color_to_color) TEST_F(PropertyMetaInfo, cast_string_to_null_color) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "color", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "color", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant("red"); @@ -738,7 +740,7 @@ TEST_F(PropertyMetaInfo, cast_string_to_null_color) TEST_F(PropertyMetaInfo, cast_int_to_null_color) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "color", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "color", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(14); @@ -750,7 +752,7 @@ TEST_F(PropertyMetaInfo, cast_int_to_null_color) TEST_F(PropertyMetaInfo, cast_default_to_null_color) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "color", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "color", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(); @@ -762,7 +764,7 @@ TEST_F(PropertyMetaInfo, cast_default_to_null_color) TEST_F(PropertyMetaInfo, cast_vector2d_to_vector2d) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector2d", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "vector2d", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto vector2d = QVector2D{32.2f, 2.2f}; @@ -775,7 +777,7 @@ TEST_F(PropertyMetaInfo, cast_vector2d_to_vector2d) TEST_F(PropertyMetaInfo, cast_string_to_vector2d_returns_an_empty_vector2d) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector2d", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "vector2d", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(QString{"foo"}); @@ -787,7 +789,7 @@ TEST_F(PropertyMetaInfo, cast_string_to_vector2d_returns_an_empty_vector2d) TEST_F(PropertyMetaInfo, cast_int_to_vector2d_returns_an_empty_vector2d) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector2d", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "vector2d", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(12); @@ -799,7 +801,7 @@ TEST_F(PropertyMetaInfo, cast_int_to_vector2d_returns_an_empty_vector2d) TEST_F(PropertyMetaInfo, cast_vector3d_to_vector2d_returns_an_empty_vector2d) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector2d", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "vector2d", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(QVector3D{32.2f, 2.2f, 784.f}); @@ -811,7 +813,7 @@ TEST_F(PropertyMetaInfo, cast_vector3d_to_vector2d_returns_an_empty_vector2d) TEST_F(PropertyMetaInfo, cast_default_to_vector2d_returns_an_empty_vector2d) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector2d", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "vector2d", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(); @@ -823,7 +825,7 @@ TEST_F(PropertyMetaInfo, cast_default_to_vector2d_returns_an_empty_vector2d) TEST_F(PropertyMetaInfo, cast_vector3d_to_vector3d) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector3d", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "vector3d", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto vector3d = QVector3D{32.2f, 2.2f, 44.4f}; @@ -836,7 +838,7 @@ TEST_F(PropertyMetaInfo, cast_vector3d_to_vector3d) TEST_F(PropertyMetaInfo, cast_string_to_vector3d_returns_an_empty_vector3d) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector3d", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "vector3d", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(QString{"foo"}); @@ -848,7 +850,7 @@ TEST_F(PropertyMetaInfo, cast_string_to_vector3d_returns_an_empty_vector3d) TEST_F(PropertyMetaInfo, cast_int_to_vector3d_returns_an_empty_vector3d) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector3d", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "vector3d", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(12); @@ -860,7 +862,7 @@ TEST_F(PropertyMetaInfo, cast_int_to_vector3d_returns_an_empty_vector3d) TEST_F(PropertyMetaInfo, cast_vector4d_to_vector3d_returns_an_empty_vector3d) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector3d", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "vector3d", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(QVector4D{32.2f, 2.2f, 784.f, 99.f}); @@ -872,7 +874,7 @@ TEST_F(PropertyMetaInfo, cast_vector4d_to_vector3d_returns_an_empty_vector3d) TEST_F(PropertyMetaInfo, cast_default_to_vector3d_returns_an_empty_vector3d) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector3d", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "vector3d", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(); @@ -884,7 +886,7 @@ TEST_F(PropertyMetaInfo, cast_default_to_vector3d_returns_an_empty_vector3d) TEST_F(PropertyMetaInfo, cast_vector4d_to_vector4d) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector4d", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "vector4d", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto vector4d = QVector4D{32.2f, 2.2f, 44.4f, 23.f}; @@ -897,7 +899,7 @@ TEST_F(PropertyMetaInfo, cast_vector4d_to_vector4d) TEST_F(PropertyMetaInfo, cast_string_to_vector4d_returns_an_empty_vector4d) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector4d", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "vector4d", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(QString{"foo"}); @@ -909,7 +911,7 @@ TEST_F(PropertyMetaInfo, cast_string_to_vector4d_returns_an_empty_vector4d) TEST_F(PropertyMetaInfo, cast_int_to_vector4d_returns_an_empty_vector4d) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector4d", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "vector4d", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(12); @@ -921,7 +923,7 @@ TEST_F(PropertyMetaInfo, cast_int_to_vector4d_returns_an_empty_vector4d) TEST_F(PropertyMetaInfo, cast_vector2d_to_vector4d_returns_an_empty_vector4d) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector4d", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "vector4d", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(QVector2D{32.2f, 2.2f}); @@ -933,7 +935,7 @@ TEST_F(PropertyMetaInfo, cast_vector2d_to_vector4d_returns_an_empty_vector4d) TEST_F(PropertyMetaInfo, cast_default_to_vector4d_returns_an_empty_vector4d) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector4d", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "vector4d", {}); projectStorageMock.createProperty(nodeInfo.id(), "bar", {}, propertyTypeInfo.id()); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(); @@ -955,7 +957,7 @@ TEST_F(PropertyMetaInfo, default_cast_to_invalid_variant) TEST_F(PropertyMetaInfo, not_existing_property_cast_returns_invalid_value) { - auto propertyTypeInfo = createNodeMetaInfo("QtQuick", "vector4d", {}); + auto propertyTypeInfo = createNodeMetaInfo("QtQuick", ModuleKind::QmlLibrary, "vector4d", {}); auto propertyInfo = nodeInfo.property("bar"); auto value = QVariant(43); diff --git a/tests/unit/tests/unittests/model/CMakeLists.txt b/tests/unit/tests/unittests/model/CMakeLists.txt index 75c81cca6f..43d6154c50 100644 --- a/tests/unit/tests/unittests/model/CMakeLists.txt +++ b/tests/unit/tests/unittests/model/CMakeLists.txt @@ -7,5 +7,5 @@ extend_qtc_test(unittest modelresourcemanagement-test.cpp modelutils-test.cpp nodelistproperty-test.cpp - + uniquename-test.cpp ) diff --git a/tests/unit/tests/unittests/model/model-test.cpp b/tests/unit/tests/unittests/model/model-test.cpp index 949efb3ee0..227360c01f 100644 --- a/tests/unit/tests/unittests/model/model-test.cpp +++ b/tests/unit/tests/unittests/model/model-test.cpp @@ -26,6 +26,7 @@ using QmlDesigner::AbstractProperty; using QmlDesigner::ModelNode; using QmlDesigner::ModelNodes; using QmlDesigner::ModelResourceSet; +using QmlDesigner::Storage::ModuleKind; MATCHER(IsSorted, std::string(negation ? "isn't sorted" : "is sorted")) { @@ -35,7 +36,8 @@ MATCHER(IsSorted, std::string(negation ? "isn't sorted" : "is sorted")) } template<typename PropertiesMatcher, typename ExtraFilePathsMatcher> -auto IsItemLibraryEntry(const QmlDesigner::NodeMetaInfo &metaInfo, +auto IsItemLibraryEntry(QmlDesigner::TypeId typeId, + QByteArrayView typeName, QStringView name, QStringView iconPath, QStringView category, @@ -46,7 +48,8 @@ auto IsItemLibraryEntry(const QmlDesigner::NodeMetaInfo &metaInfo, ExtraFilePathsMatcher extraFilePathsMatcher) { using QmlDesigner::ItemLibraryEntry; - return AllOf(Property("metaInfo", &ItemLibraryEntry::metaInfo, metaInfo), + return AllOf(Property("typeId", &ItemLibraryEntry::typeId, typeId), + Property("typeName", &ItemLibraryEntry::typeName, typeName), Property("name", &ItemLibraryEntry::name, name), Property("libraryEntryIconPath", &ItemLibraryEntry::libraryEntryIconPath, iconPath), Property("category", &ItemLibraryEntry::category, category), @@ -89,7 +92,7 @@ protected: auto createNodeWithParent(const ModelNode &parentNode, const QString &id = {}) { - auto node = viewMock.createModelNode("QtQuick.Item"); + auto node = parentNode.view()->createModelNode("QtQuick.Item"); node.setIdWithoutRefactoring(id); parentNode.defaultNodeAbstractProperty().reparentHere(node); @@ -113,22 +116,22 @@ protected: } protected: - NiceMock<AbstractViewMock> viewMock; NiceMock<SourcePathCacheMockWithPaths> pathCacheMock{"/path/foo.qml"}; NiceMock<ProjectStorageMockWithQtQtuick> projectStorageMock{pathCacheMock.sourceId}; NiceMock<ModelResourceManagementMock> resourceManagementMock; + QmlDesigner::Imports imports = {QmlDesigner::Import::createLibraryImport("QtQuick")}; QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, "Item", - -1, - -1, - nullptr, + imports, + pathCacheMock.path.toQString(), std::make_unique<ModelResourceManagementMockWrapper>( resourceManagementMock)}; + NiceMock<AbstractViewMock> viewMock; QmlDesigner::SourceId filePathId = pathCacheMock.sourceId; - QmlDesigner::TypeId itemTypeId = projectStorageMock.typeId(projectStorageMock.moduleId( - "QtQuick"), - "Item", - QmlDesigner::Storage::Version{}); + QmlDesigner::TypeId itemTypeId = projectStorageMock.typeId( + projectStorageMock.moduleId("QtQuick", ModuleKind::QmlLibrary), + "Item", + QmlDesigner::Storage::Version{}); QmlDesigner::ImportedTypeNameId itemTypeNameId = projectStorageMock.createImportedTypeNameId( filePathId, "Item", itemTypeId); ModelNode rootNode; @@ -515,8 +518,8 @@ TEST_F(Model, TEST_F(Model, by_default_remove_model_node_removes_node) { - model.detachView(&viewMock); QmlDesigner::Model newModel{{projectStorageMock, pathCacheMock}, "QtQuick.Item"}; + NiceMock<AbstractViewMock> viewMock; newModel.attachView(&viewMock); auto node = createNodeWithParent(viewMock.rootModelNode()); @@ -527,8 +530,8 @@ TEST_F(Model, by_default_remove_model_node_removes_node) TEST_F(Model, by_default_remove_properties_removes_property) { - model.detachView(&viewMock); QmlDesigner::Model newModel{{projectStorageMock, pathCacheMock}, "QtQuick.Item"}; + NiceMock<AbstractViewMock> viewMock; newModel.attachView(&viewMock); rootNode = viewMock.rootModelNode(); auto property = createProperty(rootNode, "yi"); @@ -541,7 +544,10 @@ TEST_F(Model, by_default_remove_properties_removes_property) TEST_F(Model, by_default_remove_model_node_in_factory_method_calls_removes_node) { model.detachView(&viewMock); - auto newModel = QmlDesigner::Model::create({projectStorageMock, pathCacheMock}, "QtQuick.Item"); + auto newModel = QmlDesigner::Model::create({projectStorageMock, pathCacheMock}, + "Item", + imports, + pathCacheMock.path.toQString()); newModel->attachView(&viewMock); auto node = createNodeWithParent(viewMock.rootModelNode()); @@ -553,7 +559,10 @@ TEST_F(Model, by_default_remove_model_node_in_factory_method_calls_removes_node) TEST_F(Model, by_default_remove_properties_in_factory_method_calls_remove_property) { model.detachView(&viewMock); - auto newModel = QmlDesigner::Model::create({projectStorageMock, pathCacheMock}, "QtQuick.Item"); + auto newModel = QmlDesigner::Model::create({projectStorageMock, pathCacheMock}, + "Item", + imports, + pathCacheMock.path.toQString()); newModel->attachView(&viewMock); rootNode = viewMock.rootModelNode(); auto property = createProperty(rootNode, "yi"); @@ -644,8 +653,8 @@ TEST_F(Model, remove_model_nodes_bypasses_model_resource_management) TEST_F(Model, by_default_remove_model_nodes_in_factory_method_calls_removes_node) { - model.detachView(&viewMock); QmlDesigner::Model newModel{{projectStorageMock, pathCacheMock}, "QtQuick.Item"}; + NiceMock<AbstractViewMock> viewMock; newModel.attachView(&viewMock); rootNode = viewMock.rootModelNode(); auto node = createNodeWithParent(rootNode, "yi"); @@ -753,8 +762,8 @@ TEST_F(Model, change_imports_is_synchronizing_imports_with_project_storage) { QmlDesigner::SourceId directoryPathId = QmlDesigner::SourceId::create(2); ON_CALL(pathCacheMock, sourceId(Eq("/path/foo/."))).WillByDefault(Return(directoryPathId)); - auto qtQuickModuleId = projectStorageMock.moduleId("QtQuick"); - auto qtQmlModelsModuleId = projectStorageMock.moduleId("QtQml.Models"); + auto qtQuickModuleId = projectStorageMock.moduleId("QtQuick", ModuleKind::QmlLibrary); + auto qtQmlModelsModuleId = projectStorageMock.moduleId("QtQml.Models", ModuleKind::QmlLibrary); auto qtQuickImport = QmlDesigner::Import::createLibraryImport("QtQuick", "2.1"); auto qtQmlModelsImport = QmlDesigner::Import::createLibraryImport("QtQml.Models"); auto directoryImport = QmlDesigner::Import::createFileImport("foo"); @@ -787,8 +796,8 @@ TEST_F(Model, change_imports_is_adding_import_in_project_storage) { QmlDesigner::SourceId directoryPathId = QmlDesigner::SourceId::create(2); ON_CALL(pathCacheMock, sourceId(Eq("/path/foo/."))).WillByDefault(Return(directoryPathId)); - auto qtQuickModuleId = projectStorageMock.moduleId("QtQuick"); - auto qtQmlModelsModuleId = projectStorageMock.moduleId("QtQml.Models"); + auto qtQuickModuleId = projectStorageMock.moduleId("QtQuick", ModuleKind::QmlLibrary); + auto qtQmlModelsModuleId = projectStorageMock.moduleId("QtQml.Models", ModuleKind::QmlLibrary); auto qtQuickImport = QmlDesigner::Import::createLibraryImport("QtQuick", "2.1"); auto qtQmlModelsImport = QmlDesigner::Import::createLibraryImport("QtQml.Models"); auto directoryImport = QmlDesigner::Import::createFileImport("foo"); @@ -807,7 +816,7 @@ TEST_F(Model, change_imports_is_removing_import_in_project_storage) { QmlDesigner::SourceId directoryPathId = QmlDesigner::SourceId::create(2); ON_CALL(pathCacheMock, sourceId(Eq("/path/foo/."))).WillByDefault(Return(directoryPathId)); - auto qtQmlModelsModuleId = projectStorageMock.moduleId("QtQml.Models"); + auto qtQmlModelsModuleId = projectStorageMock.moduleId("QtQml.Models", ModuleKind::QmlLibrary); auto qtQuickImport = QmlDesigner::Import::createLibraryImport("QtQuick", "2.1"); auto qtQmlModelsImport = QmlDesigner::Import::createLibraryImport("QtQml.Models"); auto directoryImport = QmlDesigner::Import::createFileImport("foo"); @@ -840,8 +849,8 @@ TEST_F(Model, change_imports_is_changing_import_version_with_project_storage) { QmlDesigner::SourceId directoryPathId = QmlDesigner::SourceId::create(2); ON_CALL(pathCacheMock, sourceId(Eq("/path/foo/."))).WillByDefault(Return(directoryPathId)); - auto qtQuickModuleId = projectStorageMock.moduleId("QtQuick"); - auto qtQmlModelsModuleId = projectStorageMock.moduleId("QtQml.Models"); + auto qtQuickModuleId = projectStorageMock.moduleId("QtQuick", ModuleKind::QmlLibrary); + auto qtQmlModelsModuleId = projectStorageMock.moduleId("QtQml.Models", ModuleKind::QmlLibrary); auto qtQuickImport = QmlDesigner::Import::createLibraryImport("QtQuick", "2.1"); auto qtQmlModelsImport = QmlDesigner::Import::createLibraryImport("QtQml.Models"); auto directoryImport = QmlDesigner::Import::createFileImport("foo"); @@ -867,7 +876,7 @@ TEST_F(Model, create_model_node_has_meta_info) TEST_F(Model, create_qualified_model_node_has_meta_info) { auto qtQmlModelsImport = QmlDesigner::Import::createLibraryImport("QtQml.Models", "", "Foo"); - auto qtQmlModelsModulesId = projectStorageMock.moduleId("QtQml.Models"); + auto qtQmlModelsModulesId = projectStorageMock.moduleId("QtQml.Models", ModuleKind::QmlLibrary); auto importId = projectStorageMock.createImportId(qtQmlModelsModulesId, filePathId); auto listModelTypeId = projectStorageMock.typeId(qtQmlModelsModulesId, "ListModel", @@ -907,23 +916,23 @@ TEST_F(Model, meta_info_of_not_existing_type_is_invalid) TEST_F(Model, module_is_valid) { - auto module = model.module("QML"); + auto module = model.module("QML", ModuleKind::QmlLibrary); ASSERT_THAT(module, IsTrue()); } TEST_F(Model, module_returns_always_the_same) { - auto oldModule = model.module("QML"); + auto oldModule = model.module("QML", ModuleKind::QmlLibrary); - auto module = model.module("QML"); + auto module = model.module("QML", ModuleKind::QmlLibrary); ASSERT_THAT(module, oldModule); } TEST_F(Model, get_meta_info_by_module) { - auto module = model.module("QML"); + auto module = model.module("QML", ModuleKind::QmlLibrary); auto metaInfo = model.metaInfo(module, "QtObject"); @@ -932,7 +941,7 @@ TEST_F(Model, get_meta_info_by_module) TEST_F(Model, get_invalid_meta_info_by_module_for_wrong_name) { - auto module = model.module("QML"); + auto module = model.module("QML", ModuleKind::QmlLibrary); auto metaInfo = model.metaInfo(module, "Object"); @@ -941,7 +950,7 @@ TEST_F(Model, get_invalid_meta_info_by_module_for_wrong_name) TEST_F(Model, get_invalid_meta_info_by_module_for_wrong_module) { - auto module = model.module("Qml"); + auto module = model.module("Qml", ModuleKind::QmlLibrary); auto metaInfo = model.metaInfo(module, "Object"); @@ -980,8 +989,8 @@ TEST_F(Model, refresh_callback_is_calling_abstract_view) TEST_F(Model, meta_infos_for_mdoule) { - projectStorageMock.createModule("Foo"); - auto module = model.module("Foo"); + projectStorageMock.createModule("Foo", ModuleKind::QmlLibrary); + auto module = model.module("Foo", ModuleKind::QmlLibrary); auto typeId = projectStorageMock.createObject(module.id(), "Bar"); ON_CALL(projectStorageMock, typeIds(module.id())) .WillByDefault(Return(QVarLengthArray<QmlDesigner::TypeId, 256>{typeId})); @@ -994,18 +1003,24 @@ TEST_F(Model, meta_infos_for_mdoule) TEST_F(Model, item_library_entries) { using namespace Qt::StringLiterals; - QmlDesigner::Storage::Info::ItemLibraryEntries storageEntries{ - {itemTypeId, "Item", "/path/to/icon", "basic category", "QtQuick", "It's a item", "/path/to/template"}}; + QmlDesigner::Storage::Info::ItemLibraryEntries storageEntries{{itemTypeId, + "Item", + "Item", + "/path/to/icon", + "basic category", + "QtQuick", + "It's a item", + "/path/to/template"}}; storageEntries.front().properties.emplace_back("x", "double", Sqlite::ValueView::create(1)); storageEntries.front().extraFilePaths.emplace_back("/extra/file/path"); projectStorageMock.setItemLibraryEntries(pathCacheMock.sourceId, storageEntries); - QmlDesigner::NodeMetaInfo metaInfo{itemTypeId, &projectStorageMock}; auto entries = model.itemLibraryEntries(); ASSERT_THAT(entries, ElementsAre( - IsItemLibraryEntry(metaInfo, + IsItemLibraryEntry(itemTypeId, + "Item", u"Item", u"/path/to/icon", u"basic category", diff --git a/tests/unit/tests/unittests/model/modelresourcemanagement-test.cpp b/tests/unit/tests/unittests/model/modelresourcemanagement-test.cpp index 40b94f872d..fd3d3c70c3 100644 --- a/tests/unit/tests/unittests/model/modelresourcemanagement-test.cpp +++ b/tests/unit/tests/unittests/model/modelresourcemanagement-test.cpp @@ -280,7 +280,6 @@ INSTANTIATE_TEST_SUITE_P( ForTarget, testing::Values(TargetData{"QtQuick.Item", "QtQuick.PropertyChanges", "target"}, TargetData{"QtQuick.Item", "QtQuick.Timeline.KeyframeGroup", "target"}, - TargetData{"FlowView.FlowTransition", "FlowView.FlowActionArea", "target"}, TargetData{"QtQuick.Item", "QtQuick.PropertyAnimation", "target"}, TargetData{"FlowView.FlowItem", "FlowView.FlowTransition", "to"}, TargetData{"FlowView.FlowItem", "FlowView.FlowTransition", "from"})); diff --git a/tests/unit/tests/unittests/model/modelutils-test.cpp b/tests/unit/tests/unittests/model/modelutils-test.cpp index c7a70cfbdb..2d49c6c94e 100644 --- a/tests/unit/tests/unittests/model/modelutils-test.cpp +++ b/tests/unit/tests/unittests/model/modelutils-test.cpp @@ -13,6 +13,7 @@ namespace { using QmlDesigner::ModelNode; using QmlDesigner::ModelNodes; +using QmlDesigner::Storage::ModuleKind; class ModelUtils : public ::testing::Test { @@ -20,7 +21,7 @@ protected: NiceMock<SourcePathCacheMockWithPaths> pathCacheMock{"/path/model.qml"}; QmlDesigner::SourceId sourceId = pathCacheMock.createSourceId("/path/foo.qml"); NiceMock<ProjectStorageMockWithQtQtuick> projectStorageMock{pathCacheMock.sourceId}; - QmlDesigner::ModuleId moduleId = projectStorageMock.moduleId("QtQuick"); + QmlDesigner::ModuleId moduleId = projectStorageMock.moduleId("QtQuick", ModuleKind::QmlLibrary); QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, "Item", {QmlDesigner::Import::createLibraryImport("QML"), @@ -141,7 +142,7 @@ TEST_F(ModelUtils, find_lowest_common_ancestor_when_one_of_the_nodes_is_parent) ASSERT_THAT(commonAncestor, parentNode); } -TEST_F(ModelUtils, lowest_common_ancestor_for_uncle_and_nephew_should_return_the_grandFather) +TEST_F(ModelUtils, lowest_common_ancestor_for_uncle_and_nephew_should_return_the_grandfather) { auto grandFatherNode = model.createModelNode("Item"); auto fatherNode = model.createModelNode("Item"); diff --git a/tests/unit/tests/unittests/model/nodelistproperty-test.cpp b/tests/unit/tests/unittests/model/nodelistproperty-test.cpp index 6783bde3e7..238e2f5d15 100644 --- a/tests/unit/tests/unittests/model/nodelistproperty-test.cpp +++ b/tests/unit/tests/unittests/model/nodelistproperty-test.cpp @@ -44,11 +44,6 @@ protected: ~NodeListProperty() { model->detachView(&abstractViewMock); } - void setModuleId(Utils::SmallStringView moduleName, ModuleId moduleId) - { - ON_CALL(projectStorageMock, moduleId(Eq(moduleName))).WillByDefault(Return(moduleId)); - } - void setType(ModuleId moduleId, Utils::SmallStringView typeName, Utils::SmallString defaultPeopertyName) @@ -61,8 +56,8 @@ protected: ++defaultPropertyIdNumber); ON_CALL(projectStorageMock, typeId(Eq(moduleId), Eq(typeName), _)).WillByDefault(Return(typeId)); - ON_CALL(projectStorageMock, type(Eq(typeId))) - .WillByDefault(Return(Info::Type{defaultPropertyId, QmlDesigner::SourceId{}, {}})); + ON_CALL(projectStorageMock, defaultPropertyDeclarationId(Eq(typeId))) + .WillByDefault(Return(defaultPropertyId)); ON_CALL(projectStorageMock, propertyName(Eq(defaultPropertyId))) .WillByDefault(Return(defaultPeopertyName)); } diff --git a/tests/unit/tests/unittests/model/uniquename-test.cpp b/tests/unit/tests/unittests/model/uniquename-test.cpp new file mode 100644 index 0000000000..ca32972b6d --- /dev/null +++ b/tests/unit/tests/unittests/model/uniquename-test.cpp @@ -0,0 +1,112 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include <googletest.h> + +#include <uniquename.h> + +namespace { + +namespace UniqueName = QmlDesigner::UniqueName; + +TEST(UniqueName, generate_returns_same_input_if_predicate_returns_false) +{ + auto pred = [] (const QString &name) -> bool { + return false; + }; + QString name = "abc"; + + QString uniqueName = UniqueName::generate(name, pred); + + ASSERT_THAT(uniqueName, "abc"); +} + +TEST(UniqueName, generateId_returns_properly_formatted_id_when_predicate_is_not_provided) +{ + QString id = " A bc d _"; + + QString uniqueId = UniqueName::generateId(id); + + ASSERT_THAT(uniqueId, "aBcD_"); +} + +TEST(UniqueName, generateId_returns_properly_formatted_id) +{ + auto pred = [] (const QString &id) -> bool { + return false; + }; + QString id = " A bc d _"; + + QString uniqueId = UniqueName::generateId(id, pred); + + ASSERT_THAT(uniqueId, "aBcD_"); +} + +TEST(UniqueName, generateId_returns_properly_formatted_unique_id_when_id_exists) +{ + QStringList existingIds = {"aBcD009", "aBcD010"}; + auto pred = [&] (const QString &id) -> bool { + return existingIds.contains(id); + }; + QString id = " A bc d 0 \t 0 9\n"; + + QString uniqueId = UniqueName::generateId(id, pred); + + ASSERT_THAT(uniqueId, "aBcD011"); +} + +TEST(UniqueName, generateId_properly_handles_dot_separated_words) +{ + auto pred = [&] (const QString &id) -> bool { + return false; + }; + QString id = "Foo.bar*foo"; + + QString uniqueId = UniqueName::generateId(id, pred); + + ASSERT_THAT(uniqueId, "fooBarFoo"); +} + +TEST(UniqueName, generateId_prefixes_with_underscore_if_id_is_a_reserved_word) +{ + auto pred = [&] (const QString &id) -> bool { + return false; + }; + QString id = "for"; + + QString uniqueId = UniqueName::generateId(id, pred); + + ASSERT_THAT(uniqueId, "_for"); +} + +TEST(UniqueName, generateId_prefixes_with_underscore_if_id_is_a_number) +{ + auto pred = [&] (const QString &id) -> bool { + return false; + }; + QString id = "436"; + + QString uniqueId = UniqueName::generateId(id, pred); + + ASSERT_THAT(uniqueId, "_436"); +} + +TEST(UniqueName, generatePath_returns_same_path_when_path_doesnt_exist) +{ + QString path = "<<<non/existing/path>>>"; + + QString uniquePath = UniqueName::generatePath(path); + + ASSERT_THAT(uniquePath, path); +} + +TEST(UniqueName, generatePath_returns_unique_path_when_path_exists) +{ + QString path = UNITTEST_DIR; + + QString uniquePath = UniqueName::generatePath(path); + + ASSERT_THAT(uniquePath, QString(UNITTEST_DIR).append("1")); +} + +} // namespace diff --git a/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick/Controls/designer/qtquickcontrols2.metainfo b/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick/Controls/designer/qtquickcontrols2.metainfo new file mode 100644 index 0000000000..0cd3959cf8 --- /dev/null +++ b/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick/Controls/designer/qtquickcontrols2.metainfo @@ -0,0 +1,575 @@ +MetaInfo { + Type { + name: "QtQuick.Controls.BusyIndicator" + icon: "images/busyindicator-icon16.png" + + ItemLibraryEntry { + name: "Busy Indicator" + category: "Qt Quick - Controls 2" + libraryIcon: "images/busyindicator-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("Indicates activity while, for example, content is being loaded.") + } + } + + Type { + name: "QtQuick.Controls.Button" + icon: "images/button-icon16.png" + + ItemLibraryEntry { + name: "Button" + category: "Qt Quick - Controls 2" + libraryIcon: "images/button-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A button with text.") + + Property { name: "text"; type: "binding"; value: "qsTr(\"Button\")" } + } + } + + Type { + name: "QtQuick.Controls.CheckBox" + icon: "images/checkbox-icon16.png" + + ItemLibraryEntry { + name: "Check Box" + category: "Qt Quick - Controls 2" + libraryIcon: "images/checkbox-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A checkbox with a text label.") + + Property { name: "text"; type: "binding"; value: "qsTr(\"Check Box\")" } + } + } + + Type { + name: "QtQuick.Controls.CheckDelegate" + icon: "images/checkbox-icon16.png" + + ItemLibraryEntry { + name: "Check Delegate" + category: "Qt Quick - Controls 2" + libraryIcon: "images/checkbox-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("Presents items from a model as checkboxes.") + + Property { name: "text"; type: "binding"; value: "qsTr(\"Check Delegate\")" } + } + } + + Type { + name: "QtQuick.Controls.ComboBox" + icon: "images/combobox-icon16.png" + + ItemLibraryEntry { + name: "Combo Box" + category: "Qt Quick - Controls 2" + libraryIcon: "images/combobox-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("An editable drop-down list.") + } + } + + Type { + name: "QtQuick.Controls.Control" + icon: "images/control-icon16.png" + + ItemLibraryEntry { + name: "Control" + category: "Qt Quick - Controls 2" + libraryIcon: "images/control-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("An abstract base type for UI controls.") + } + } + + Type { + name: "QtQuick.Controls.DelayButton" + icon: "images/button-icon16.png" + + ItemLibraryEntry { + name: "Delay Button" + category: "Qt Quick - Controls 2" + libraryIcon: "images/delaybutton-icon.png" + version: "2.2" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A button with a delay preventing accidental presses.") + + Property { name: "text"; type: "binding"; value: "qsTr(\"Delay Button\")" } + } + } + + Type { + name: "QtQuick.Controls.Dial" + icon: "images/dial-icon16.png" + + ItemLibraryEntry { + name: "Dial" + category: "Qt Quick - Controls 2" + libraryIcon: "images/dial-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + + toolTip: qsTr("A circular dial that is rotated to set a value.") + } + } + + Type { + name: "QtQuick.Controls.Frame" + icon: "images/frame-icon16.png" + + ItemLibraryEntry { + name: "Frame" + category: "Qt Quick - Controls 2" + libraryIcon: "images/frame-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("An untitled container for a group of controls.") + + Property { name: "width"; type: "int"; value: 200 } + Property { name: "height"; type: "int"; value: 200 } + } + } + + Type { + name: "QtQuick.Controls.GroupBox" + icon: "images/groupbox-icon16.png" + + ItemLibraryEntry { + name: "Group Box" + category: "Qt Quick - Controls 2" + libraryIcon: "images/groupbox-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A titled container for a group of controls.") + + Property { name: "width"; type: "int"; value: 200 } + Property { name: "height"; type: "int"; value: 200 } + Property { name: "title"; type: "binding"; value: "qsTr(\"Group Box\")" } + } + } + + Type { + name: "QtQuick.Controls.ItemDelegate" + icon: "images/itemdelegate-icon16.png" + + ItemLibraryEntry { + name: "Item Delegate" + category: "Qt Quick - Controls 2" + libraryIcon: "images/itemdelegate-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("Presents a standard view item. It can be used as a delegate in various views and controls, such as ListView and ComboBox.") + + Property { name: "text"; type: "binding"; value: "qsTr(\"Item Delegate\")" } + } + } + + Type { + name: "QtQuick.Controls.Label" + icon: "images/label-icon16.png" + + ItemLibraryEntry { + name: "Label" + category: "Qt Quick - Controls 2" + libraryIcon: "images/label-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A text label.") + + Property { name: "text"; type: "binding"; value: "qsTr(\"Label\")" } + } + } + + Type { + name: "QtQuick.Controls.Page" + icon: "images/page-icon16.png" + + ItemLibraryEntry { + name: "Page" + category: "Qt Quick - Controls 2" + libraryIcon: "images/page-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A page with header and footer.") + + Property { name: "width"; type: "int"; value: 200 } + Property { name: "height"; type: "int"; value: 200 } + } + } + + Type { + name: "QtQuick.Controls.PageIndicator" + icon: "images/pageindicator-icon16.png" + + ItemLibraryEntry { + name: "Page Indicator" + category: "Qt Quick - Controls 2" + libraryIcon: "images/pageindicator-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("Indicates the currently active page.") + + Property { name: "count"; type: "int"; value: 3 } + } + } + + Type { + name: "QtQuick.Controls.Pane" + icon: "images/pane-icon16.png" + + ItemLibraryEntry { + name: "Pane" + category: "Qt Quick - Controls 2" + libraryIcon: "images/pane-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("Provides a background matching the application style and theme.") + + Property { name: "width"; type: "int"; value: 200 } + Property { name: "height"; type: "int"; value: 200 } + } + } + + Type { + name: "QtQuick.Controls.ProgressBar" + icon: "images/progressbar-icon16.png" + + ItemLibraryEntry { + name: "Progress Bar" + category: "Qt Quick - Controls 2" + libraryIcon: "images/progressbar-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A bar indicating the progress of an operation.") + + Property { name: "value"; type: "real"; value: 0.5 } + } + } + + Type { + name: "QtQuick.Controls.RadioButton" + icon: "images/radiobutton-icon16.png" + + ItemLibraryEntry { + name: "Radio Button" + category: "Qt Quick - Controls 2" + libraryIcon: "images/radiobutton-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("An option button that you can toggle on or off.") + + Property { name: "text"; type: "binding"; value: "qsTr(\"Radio Button\")" } + } + } + + Type { + name: "QtQuick.Controls.RadioDelegate" + icon: "images/radiobutton-icon16.png" + + ItemLibraryEntry { + name: "Radio Delegate" + category: "Qt Quick - Controls 2" + libraryIcon: "images/radiobutton-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("Presents items from a model as radio buttons.") + + Property { name: "text"; type: "binding"; value: "qsTr(\"Radio Delegate\")" } + } + } + + Type { + name: "QtQuick.Controls.RangeSlider" + icon: "images/rangeslider-icon16.png" + + ItemLibraryEntry { + name: "Range Slider" + category: "Qt Quick - Controls 2" + libraryIcon: "images/rangeslider-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A bar with adjustable start and end points.") + + Property { name: "first.value"; type: "real"; value: 0.25 } + Property { name: "second.value"; type: "real"; value: 0.75 } + } + } + + Type { + name: "QtQuick.Controls.RoundButton" + icon: "images/roundbutton-icon16.png" + + ItemLibraryEntry { + name: "Round Button" + category: "Qt Quick - Controls 2" + libraryIcon: "images/roundbutton-icon.png" + version: "2.1" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A round button with text.") + + Property { name: "text"; type: "string"; value: "+" } + } + } + + Type { + name: "QtQuick.Controls.Slider" + icon: "images/slider-icon16.png" + + ItemLibraryEntry { + name: "Slider" + category: "Qt Quick - Controls 2" + libraryIcon: "images/slider-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("An adjustable slider.") + + Property { name: "value"; type: "real"; value: 0.5 } + } + } + + Type { + name: "QtQuick.Controls.SpinBox" + icon: "images/spinbox-icon16.png" + + ItemLibraryEntry { + name: "Spin Box" + category: "Qt Quick - Controls 2" + libraryIcon: "images/spinbox-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A box with an adjustable number.") + } + } + + Type { + name: "QtQuick.Controls.ScrollView" + icon: "images/scrollview-icon16.png" + + ItemLibraryEntry { + name: "Scroll View" + category: "Qt Quick - Controls 2" + libraryIcon: "images/scrollview-icon.png" + version: "2.2" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A scrollable area.") + + Property { name: "width"; type: "int"; value: 200 } + Property { name: "height"; type: "int"; value: 200 } + } + } + + Type { + name: "QtQuick.Controls.StackView" + icon: "images/stackview-icon16.png" + + ItemLibraryEntry { + name: "Stack View" + category: "Qt Quick - Controls 2" + libraryIcon: "images/stackview-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("Provides a stack-based navigation for a set of pages.") + + Property { name: "width"; type: "int"; value: 200 } + Property { name: "height"; type: "int"; value: 200 } + } + } + + Type { + name: "QtQuick.Controls.SwipeDelegate" + icon: "images/itemdelegate-icon16.png" + + ItemLibraryEntry { + name: "Swipe Delegate" + category: "Qt Quick - Controls 2" + libraryIcon: "images/itemdelegate-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("Presents items from a model as items that you can swipe to expose more options.") + + Property { name: "text"; type: "binding"; value: "qsTr(\"Swipe Delegate\")" } + } + } + + Type { + name: "QtQuick.Controls.SwipeView" + icon: "images/swipeview-icon16.png" + + ItemLibraryEntry { + name: "Swipe View" + category: "Qt Quick - Controls 2" + libraryIcon: "images/swipeview-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("Provides a view where you can navigate pages by swiping.") + + Property { name: "width"; type: "int"; value: 200 } + Property { name: "height"; type: "int"; value: 200 } + } + } + + Type { + name: "QtQuick.Controls.Switch" + icon: "images/switch-icon16.png" + + ItemLibraryEntry { + name: "Switch" + category: "Qt Quick - Controls 2" + libraryIcon: "images/switch-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A button that you can toggle on and off.") + + Property { name: "text"; type: "binding"; value: "qsTr(\"Switch\")" } + } + } + + Type { + name: "QtQuick.Controls.SwitchDelegate" + icon: "images/switch-icon16.png" + + ItemLibraryEntry { + name: "Switch Delegate" + category: "Qt Quick - Controls 2" + libraryIcon: "images/switch-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("Presents items from a model as toggle switches.") + + Property { name: "text"; type: "binding"; value: "qsTr(\"Switch Delegate\")" } + } + } + + Type { + name: "QtQuick.Controls.TabBar" + icon: "images/toolbar-icon16.png" + + ItemLibraryEntry { + name: "Tab Bar" + category: "Qt Quick - Controls 2" + libraryIcon: "images/toolbar-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A tab-based navigation model.") + + Property { name: "width"; type: "int"; value: 240 } + } + } + + Type { + name: "QtQuick.Controls.TabButton" + icon: "images/toolbutton-icon16.png" + + ItemLibraryEntry { + name: "Tab Button" + category: "Qt Quick - Controls 2" + libraryIcon: "images/toolbutton-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A button suitable for a tab bar.") + + Property { name: "text"; type: "binding"; value: "qsTr(\"Tab Button\")" } + } + } + + Type { + name: "QtQuick.Controls.TextArea" + icon: "images/textarea-icon16.png" + + ItemLibraryEntry { + name: "Text Area" + category: "Qt Quick - Controls 2" + libraryIcon: "images/textarea-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A multi-line text box.") + + Property { name: "placeholderText"; type: "binding"; value: "qsTr(\"Text Area\")" } + } + } + + Type { + name: "QtQuick.Controls.TextField" + icon: "images/textfield-icon16.png" + + ItemLibraryEntry { + name: "Text Field" + category: "Qt Quick - Controls 2" + libraryIcon: "images/textfield-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A single-line text box.") + + Property { name: "placeholderText"; type: "binding"; value: "qsTr(\"Text Field\")" } + } + } + + Type { + name: "QtQuick.Controls.ToolBar" + icon: "images/toolbar-icon16.png" + + ItemLibraryEntry { + name: "Tool Bar" + category: "Qt Quick - Controls 2" + libraryIcon: "images/toolbar-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A row that can hold actions and buttons.") + + Property { name: "width"; type: "int"; value: 360 } + } + } + + Type { + name: "QtQuick.Controls.ToolButton" + icon: "images/toolbutton-icon16.png" + + ItemLibraryEntry { + name: "Tool Button" + category: "Qt Quick - Controls 2" + libraryIcon: "images/toolbutton-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A button suitable for a tool bar.") + + Property { name: "text"; type: "binding"; value: "qsTr(\"Tool Button\")" } + } + } + + Type { + name: "QtQuick.Controls.ToolSeparator" + icon: "images/toolseparator-icon16.png" + + ItemLibraryEntry { + name: "Tool Separator" + category: "Qt Quick - Controls 2" + libraryIcon: "images/toolseparator-icon.png" + version: "2.1" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A line to separate sections in a tool bar.") + } + } + + Type { + name: "QtQuick.Controls.Tumbler" + icon: "images/tumbler-icon16.png" + + ItemLibraryEntry { + name: "Tumbler" + category: "Qt Quick - Controls 2" + libraryIcon: "images/tumbler-icon.png" + version: "2.0" + requiredImport: "QtQuick.Controls" + toolTip: qsTr("A spinnable wheel of selectable items.") + + Property { name: "model"; type: "int"; value: "10" } + } + } +} diff --git a/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/AssetUtils/designer/assetutils.metainfo b/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/AssetUtils/designer/assetutils.metainfo new file mode 100644 index 0000000000..47abeea7a3 --- /dev/null +++ b/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/AssetUtils/designer/assetutils.metainfo @@ -0,0 +1,21 @@ +MetaInfo { + Type { + name: "QtQuick3D.AssetUtils.RuntimeLoader" + icon: "images/runtimeloader16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Runtime Loader" + category: "AssetUtils" + libraryIcon: "images/runtimeloader.png" + version: "6.2" + requiredImport: "QtQuick3D.AssetUtils" + } + } +} diff --git a/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/Effects/designer/effectlib.metainfo b/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/Effects/designer/effectlib.metainfo new file mode 100644 index 0000000000..7ad3357894 --- /dev/null +++ b/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/Effects/designer/effectlib.metainfo @@ -0,0 +1,401 @@ +MetaInfo { + Type { + name: "QtQuick3D.Effects.AdditiveColorGradient" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Additive Color Gradient" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.Blur" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Blur" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.BrushStrokes" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Brush Strokes" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.ChromaticAberration" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Chromatic Aberration" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.ColorMaster" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Color Master" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.DepthOfFieldHQBlur" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Depth of Field HQ Blur" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.Desaturate" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Desaturate" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.DistortionRipple" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Distortion Ripple" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.DistortionSphere" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Distortion Sphere" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.DistortionSpiral" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Distortion Spiral" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.EdgeDetect" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Edge Detect" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.Emboss" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Emboss" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.Flip" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Flip" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.Fxaa" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Fxaa" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.GaussianBlur" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Gaussian Blur" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.HDRBloomTonemap" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "HDR Bloom Tonemap" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.MotionBlur" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Motion Blur" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.Scatter" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Scatter" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.SCurveTonemap" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "SCurve Tonemap" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.TiltShift" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Tilt Shift" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } + Type { + name: "QtQuick3D.Effects.Vignette" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Vignette" + category: "Qt Quick 3D Effects" + libraryIcon: "images/effect.png" + version: "1.0" + requiredImport: "QtQuick3D.Effects" + } + } +} diff --git a/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/Helpers/designer/helpers.metainfo b/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/Helpers/designer/helpers.metainfo new file mode 100644 index 0000000000..83492e2c81 --- /dev/null +++ b/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/Helpers/designer/helpers.metainfo @@ -0,0 +1,261 @@ +MetaInfo { + Type { + name: "QtQuick3D.Helpers.LookAtNode" + icon: "images/lookatnode16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Look-at Node" + category: "Helpers" + libraryIcon: "images/lookatnode.png" + version: "6.4" + requiredImport: "QtQuick3D.Helpers" + } + } + + Type { + name: "QtQuick3D.Helpers.AxisHelper" + icon: "images/axishelper16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Axis Helper" + category: "Helpers" + libraryIcon: "images/axishelper.png" + version: "6.0" + requiredImport: "QtQuick3D.Helpers" + } + } + + Type { + name: "QtQuick3D.Helpers.DebugView" + icon: "images/debugview16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: true + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Debug View" + category: "Helpers" + libraryIcon: "images/debugview.png" + version: "6.0" + requiredImport: "QtQuick3D.Helpers" + } + } + + Type { + name: "QtQuick3D.Helpers.GridGeometry" + icon: "images/gridgeometry16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Grid Geometry" + category: "Helpers" + libraryIcon: "images/gridgeometry.png" + version: "6.0" + requiredImport: "QtQuick3D.Helpers" + } + } + + Type { + name: "QtQuick3D.Helpers.HeightFieldGeometry" + icon: "images/heightfieldgeometry16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Height Field Geometry" + category: "Helpers" + libraryIcon: "images/heightfieldgeometry.png" + version: "6.4" + requiredImport: "QtQuick3D.Helpers" + } + } + + Type { + name: "QtQuick3D.Helpers.InstanceModel" + icon: "images/instancemodel16.png" + + Hints { + visibleInNavigator: false + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Instance Model" + category: "Helpers" + libraryIcon: "images/instancemodel.png" + version: "6.4" + requiredImport: "QtQuick3D.Helpers" + } + } + + Type { + name: "QtQuick3D.Helpers.InstanceRepeater" + icon: "images/instancerepeater16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Instance Repeater" + category: "Helpers" + libraryIcon: "images/instancerepeater.png" + version: "6.4" + requiredImport: "QtQuick3D.Helpers" + } + } + + Type { + name: "QtQuick3D.Helpers.WasdController" + icon: "images/wasdcontroller16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: true + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Wasd Controller" + category: "Helpers" + libraryIcon: "images/wasdcontroller.png" + version: "6.0" + requiredImport: "QtQuick3D.Helpers" + } + } + + Type { + name: "QtQuick3D.Helpers.InfiniteGrid" + icon: "images/infinitegrid16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Infinite Grid" + category: "Helpers" + libraryIcon: "images/infinitegrid.png" + version: "6.5" + requiredImport: "QtQuick3D.Helpers" + } + } + + Type { + name: "QtQuick3D.Helpers.OrbitCameraController" + icon: "images/orbitcameracontroller16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: true + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Orbit Camera Controller" + category: "Helpers" + libraryIcon: "images/orbitcameracontroller.png" + version: "6.4" + requiredImport: "QtQuick3D.Helpers" + } + } + + Type { + name: "QtQuick3D.Helpers.ProceduralSkyTextureData" + icon: "images/proceduralskytexturedata16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Procedural Sky Texture Data" + category: "Helpers" + libraryIcon: "images/proceduralskytexturedata.png" + version: "6.4" + requiredImport: "QtQuick3D.Helpers" + } + } + + Type { + name: "QtQuick3D.Helpers.ExtendedSceneEnvironment" + icon: "images/extendedsceneenvironment16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Extended Scene Environment" + category: "Helpers" + libraryIcon: "images/extendedsceneenvironment.png" + version: "6.5" + requiredImport: "QtQuick3D.Helpers" + } + } + + Type { + name: "QtQuick3D.Helpers.LodManager" + icon: "images/lodmanager16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Lod Manager" + category: "Helpers" + libraryIcon: "images/lodmanager.png" + version: "6.5" + requiredImport: "QtQuick3D.Helpers" + } + } +} diff --git a/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/ParticleEffects/designer/particleeffects.metainfo b/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/ParticleEffects/designer/particleeffects.metainfo new file mode 100644 index 0000000000..d9bc305b4a --- /dev/null +++ b/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/ParticleEffects/designer/particleeffects.metainfo @@ -0,0 +1,246 @@ +MetaInfo { + Type { + name: "QtQuick3D.Particle3D.ParticleSystem3D" + icon: "images/dummy16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Clouds" + category: "Qt Quick 3D Particle Effects" + libraryIcon: "images/dummy.png" + version: "6.2" + requiredImport: "QtQuick3D.ParticleEffects" + QmlSource { source: "./source/particleeffect_clouds.qml" } + ExtraFile { source: "images/smoke_sprite2.png" } + } + } + + Type { + name: "QtQuick3D.Particle3D.ParticleSystem3D" + icon: "images/dummy16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Dust" + category: "Qt Quick 3D Particle Effects" + libraryIcon: "images/dummy.png" + version: "6.2" + requiredImport: "QtQuick3D.ParticleEffects" + QmlSource { source: "./source/particleeffect_dust.qml" } + ExtraFile { source: "images/sphere.png" } + } + } + + Type { + name: "QtQuick3D.Particle3D.ParticleSystem3D" + icon: "images/dummy16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Exhaust" + category: "Qt Quick 3D Particle Effects" + libraryIcon: "images/dummy.png" + version: "6.2" + requiredImport: "QtQuick3D.ParticleEffects" + QmlSource { source: "./source/particleeffect_exhaust.qml" } + ExtraFile { source: "images/smoke2.png" } + } + } + + Type { + name: "QtQuick3D.Particle3D.ParticleSystem3D" + icon: "images/dummy16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Fire" + category: "Qt Quick 3D Particle Effects" + libraryIcon: "images/dummy.png" + version: "6.2" + requiredImport: "QtQuick3D.ParticleEffects" + QmlSource { source: "./source/particleeffect_fire.qml" } + ExtraFile { source: "images/smoke_sprite.png" } + ExtraFile { source: "images/sphere.png" } + ExtraFile { source: "images/color_table.png" } + ExtraFile { source: "images/color_table2.png" } + } + } + + Type { + name: "QtQuick3D.Particle3D.ParticleSystem3D" + icon: "images/dummy16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Heavy Rain" + category: "Qt Quick 3D Particle Effects" + libraryIcon: "images/dummy.png" + version: "6.2" + requiredImport: "QtQuick3D.ParticleEffects" + QmlSource { source: "./source/particleeffect_heavyrain.qml" } + ExtraFile { source: "images/rain.png" } + ExtraFile { source: "images/sphere.png" } + ExtraFile { source: "images/ripple.png" } + ExtraFile { source: "images/splash7.png" } + } + } + + Type { + name: "QtQuick3D.Particle3D.ParticleSystem3D" + icon: "images/dummy16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Heavy Rain - Tire Spray" + category: "Qt Quick 3D Particle Effects" + libraryIcon: "images/dummy.png" + version: "6.2" + requiredImport: "QtQuick3D.ParticleEffects" + QmlSource { source: "./source/particleeffect_heavyrain_tirespray.qml" } + ExtraFile { source: "images/smoke2.png" } + } + } + + Type { + name: "QtQuick3D.Particle3D.ParticleSystem3D" + icon: "images/dummy16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Light Rain" + category: "Qt Quick 3D Particle Effects" + libraryIcon: "images/dummy.png" + version: "6.2" + requiredImport: "QtQuick3D.ParticleEffects" + QmlSource { source: "./source/particleeffect_lightrain.qml" } + ExtraFile { source: "images/rain.png" } + ExtraFile { source: "images/splash7.png" } + } + } + Type { + name: "QtQuick3D.Particle3D.ParticleSystem3D" + icon: "images/dummy16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Light Rain - Tire Spray" + category: "Qt Quick 3D Particle Effects" + libraryIcon: "images/dummy.png" + version: "6.2" + requiredImport: "QtQuick3D.ParticleEffects" + QmlSource { source: "./source/particleeffect_lightrain_tirespray.qml" } + ExtraFile { source: "images/smoke2.png" } + } + } + Type { + name: "QtQuick3D.Particle3D.ParticleSystem3D" + icon: "images/dummy16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Rain Mist" + category: "Qt Quick 3D Particle Effects" + libraryIcon: "images/dummy.png" + version: "6.2" + requiredImport: "QtQuick3D.ParticleEffects" + QmlSource { source: "./source/particleeffect_rainmist.qml" } + ExtraFile { source: "images/smoke2.png" } + } + } + Type { + name: "QtQuick3D.Particle3D.ParticleSystem3D" + icon: "images/dummy16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Snow" + category: "Qt Quick 3D Particle Effects" + libraryIcon: "images/dummy.png" + version: "6.2" + requiredImport: "QtQuick3D.ParticleEffects" + QmlSource { source: "./source/particleeffect_snow.qml" } + ExtraFile { source: "images/snowflake.png" } + } + } + Type { + name: "QtQuick3D.Particle3D.ParticleSystem3D" + icon: "images/dummy16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Steam" + category: "Qt Quick 3D Particle Effects" + libraryIcon: "images/dummy.png" + version: "6.2" + requiredImport: "QtQuick3D.ParticleEffects" + QmlSource { source: "./source/particleeffect_steam.qml" } + ExtraFile { source: "images/smoke2.png" } + } + } +} diff --git a/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/Particles3D/designer/particles3d.metainfo b/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/Particles3D/designer/particles3d.metainfo new file mode 100644 index 0000000000..d2a2999c50 --- /dev/null +++ b/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/Particles3D/designer/particles3d.metainfo @@ -0,0 +1,562 @@ +MetaInfo { + Type { + name: "QtQuick3D.Particles3D.Attractor3D" + icon: "images/attractor-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Attractor" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/attractor-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + } + } + Type { + name: "QtQuick3D.Particles3D.DynamicBurst3D" + icon: "images/emit-burst-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Dynamic Burst" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/emit-burst-24px.png" + version: "6.3" + requiredImport: "QtQuick3D.Particles3D" + } + } + Type { + name: "QtQuick3D.Particles3D.EmitBurst3D" + icon: "images/emit-burst-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Emit Burst" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/emit-burst-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + } + } + Type { + name: "QtQuick3D.Particles3D.ParticleEmitter3D" + icon: "images/emitter-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Emitter" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/emitter-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + } + } + Type { + name: "QtQuick3D.Particles3D.Gravity3D" + icon: "images/gravity-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Gravity" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/gravity-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + } + } + Type { + name: "QtQuick3D.Particles3D.ModelBlendParticle3D" + icon: "images/model-blend-particle-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Model Blend Particle" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/model-blend-particle-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + } + } + Type { + name: "QtQuick3D.Particles3D.ModelParticle3D" + icon: "images/model-particle-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Model Particle" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/model-particle-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + } + } + Type { + name: "QtQuick3D.Particles3D.ParticleCustomShape3D" + icon: "images/particle-custom-shape-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Custom Shape" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/particle-custom-shape-24px.png" + version: "6.3" + requiredImport: "QtQuick3D.Particles3D" + } + } + Type { + name: "QtQuick3D.Particles3D.ParticleModelShape3D" + icon: "images/model-shape-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Model Shape" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/model-shape-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + } + } + Type { + name: "QtQuick3D.Particles3D.PointRotator3D" + icon: "images/point-rotator-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Point Rotator" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/point-rotator-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + } + } + Type { + name: "QtQuick3D.Particles3D.ParticleShape3D" + icon: "images/particle-shape-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Particle Shape" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/particle-shape-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + } + } + Type { + name: "QtQuick3D.Particles3D.SpriteParticle3D" + icon: "images/sprite-particle-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Sprite Particle" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/sprite-particle-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + } + } + Type { + name: "QtQuick3D.Particles3D.SpriteSequence3D" + icon: "images/sprite-sequence-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Sprite Sequence" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/sprite-sequence-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + } + } + Type { + name: "QtQuick3D.Particles3D.ParticleSystem3D" + icon: "images/particle-system-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Particle System" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/particle-system-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + QmlSource { source: "./source/particlesystem_template.qml" } + } + } + Type { + name: "QtQuick3D.Particles3D.TargetDirection3D" + icon: "images/target-direction-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Target Direction" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/target-direction-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + } + } + Type { + name: "QtQuick3D.Particles3D.TrailEmitter3D" + icon: "images/trail-emitter-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Trail Emitter" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/trail-emitter-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + } + } + Type { + name: "QtQuick3D.Particles3D.VectorDirection3D" + icon: "images/vector-direction-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Vector Direction" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/vector-direction-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + } + } + Type { + name: "QtQuick3D.Particles3D.Wander3D" + icon: "images/wander-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Wander" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/wander-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + } + } + Type { + name: "QtQuick3D.Particles3D.ParticleSystem3D" + icon: "images/particle-system-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Animated Sprite" + category: "Qt Quick 3D Particle System Templates" + libraryIcon: "images/particle-system-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + QmlSource { source: "./source/particlesystem_animatedsprite_template.qml" } + } + } + Type { + name: "QtQuick3D.Particles3D.ParticleSystem3D" + icon: "images/particle-system-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Attractor System" + category: "Qt Quick 3D Particle System Templates" + libraryIcon: "images/particle-system-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + QmlSource { source: "./source/particlesystem_attractor_template.qml" } + } + } + Type { + name: "QtQuick3D.Particles3D.ParticleSystem3D" + icon: "images/particle-system-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Burst" + category: "Qt Quick 3D Particle System Templates" + libraryIcon: "images/particle-system-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + QmlSource { source: "./source/particlesystem_burst_template.qml" } + } + } + Type { + name: "QtQuick3D.Particles3D.ParticleSystem3D" + icon: "images/particle-system-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Model Blend" + category: "Qt Quick 3D Particle System Templates" + libraryIcon: "images/particle-system-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + QmlSource { source: "./source/particlesystem_modelblend_template.qml" } + } + } + Type { + name: "QtQuick3D.Particles3D.ParticleSystem3D" + icon: "images/particle-system-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Model Shape" + category: "Qt Quick 3D Particle System Templates" + libraryIcon: "images/particle-system-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + QmlSource { source: "./source/particlesystem_modelshape_template.qml" } + } + } + Type { + name: "QtQuick3D.Particles3D.ParticleSystem3D" + icon: "images/particle-system-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Particle Trail" + category: "Qt Quick 3D Particle System Templates" + libraryIcon: "images/particle-system-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + QmlSource { source: "./source/particlesystem_particletrail_template.qml" } + } + } + Type { + name: "QtQuick3D.Particles3D.ParticleSystem3D" + icon: "images/particle-system-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Sprite" + category: "Qt Quick 3D Particle System Templates" + libraryIcon: "images/particle-system-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + QmlSource { source: "./source/particlesystem_sprite_template.qml" } + } + } + Type { + name: "QtQuick3D.Particles3D.ParticleSystem3D" + icon: "images/particle-system-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Wander" + category: "Qt Quick 3D Particle System Templates" + libraryIcon: "images/particle-system-24px.png" + version: "6.2" + requiredImport: "QtQuick3D.Particles3D" + QmlSource { source: "./source/particlesystem_wander_template.qml" } + } + } + Type { + name: "QtQuick3D.Particles3D.LineParticle3D" + icon: "images/line-particle-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Line Particle" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/line-particle-24px.png" + version: "6.4" + requiredImport: "QtQuick3D.Particles3D" + } + } + Type { + name: "QtQuick3D.Particles3D.Repeller3D" + icon: "images/repeller-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Repeller" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/repeller-24px.png" + version: "6.4" + requiredImport: "QtQuick3D.Particles3D" + } + } + Type { + name: "QtQuick3D.Particles3D.ScaleAffector3D" + icon: "images/scale-affector-16px.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Scale Affector" + category: "Qt Quick 3D Particles 3D" + libraryIcon: "images/scale-affector-24px.png" + version: "6.4" + requiredImport: "QtQuick3D.Particles3D" + } + } +} diff --git a/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/Physics/designer/physics.metainfo b/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/Physics/designer/physics.metainfo new file mode 100644 index 0000000000..874e209dc5 --- /dev/null +++ b/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/Physics/designer/physics.metainfo @@ -0,0 +1,261 @@ +MetaInfo { + Type { + name: "QtQuick3D.Physics.PhysicsWorld" + icon: "images/physicsworld16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Physics World" + category: "Components" + libraryIcon: "images/physicsworld.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.TriggerBody" + icon: "images/triggerbody16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Trigger Body" + category: "Collision Bodies" + libraryIcon: "images/triggerbody.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.StaticRigidBody" + icon: "images/staticrigidbody16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Static Rigid Body" + category: "Collision Bodies" + libraryIcon: "images/staticrigidbody.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.DynamicRigidBody" + icon: "images/dynamicrigidbody16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Dynamic Rigid Body" + category: "Collision Bodies" + libraryIcon: "images/dynamicrigidbody.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.PhysicsMaterial" + icon: "images/physicsmaterial16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Physics Material" + category: "Components" + libraryIcon: "images/physicsmaterial.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.BoxShape" + icon: "images/boxshape16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Box Shape" + category: "Collision Shapes" + libraryIcon: "images/boxshape.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.CapsuleShape" + icon: "images/capsuleshape16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Capsule Shape" + category: "Collision Shapes" + libraryIcon: "images/capsuleshape.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.ConvexMeshShape" + icon: "images/convexmeshshape16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Convex Mesh Shape" + category: "Collision Shapes" + libraryIcon: "images/convexmeshshape.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.HeightFieldShape" + icon: "images/heightfieldshape16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Height Field Shape" + category: "Collision Shapes" + libraryIcon: "images/heightfieldshape.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.PlaneShape" + icon: "images/planeshape16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Plane Shape" + category: "Collision Shapes" + libraryIcon: "images/planeshape.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.SphereShape" + icon: "images/sphereshape16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Sphere Shape" + category: "Collision Shapes" + libraryIcon: "images/sphereshape.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.TriangleMeshShape" + icon: "images/trianglemeshshape16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Triangle Mesh Shape" + category: "Collision Shapes" + libraryIcon: "images/trianglemeshshape.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } + + Type { + name: "QtQuick3D.Physics.CharacterController" + icon: "images/charactercontroller16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Character Controller" + category: "Collision Bodies" + libraryIcon: "images/charactercontroller.png" + version: "6.5" + requiredImport: "QtQuick3D.Physics" + } + } +} diff --git a/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/designer/quick3d.metainfo b/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/designer/quick3d.metainfo new file mode 100644 index 0000000000..852f908129 --- /dev/null +++ b/tests/unit/tests/unittests/projectstorage/data/qml/QtQuick3D/designer/quick3d.metainfo @@ -0,0 +1,861 @@ +MetaInfo { + Type { + name: "QtQuick3D.PerspectiveCamera" + icon: "images/camera16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Perspective Camera" + category: "Cameras" + libraryIcon: "images/camera.png" + version: "6.0" + requiredImport: "QtQuick3D" + Property { name: "z"; type: "int"; value: 500; } + toolTip: qsTr("A camera that uses perspective projection.") + } + } + Type { + name: "QtQuick3D.OrthographicCamera" + icon: "images/camera16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Orthographic Camera" + category: "Cameras" + libraryIcon: "images/camera.png" + version: "6.0" + requiredImport: "QtQuick3D" + Property { name: "z"; type: "int"; value: 500; } + toolTip: qsTr("A parallel projection Camera, in which an object's perceived scale is unaffected by its distance from the Camera.") + } + } + Type { + name: "QtQuick3D.FrustumCamera" + icon: "images/camera16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Frustum Camera" + category: "Cameras" + libraryIcon: "images/camera.png" + version: "6.0" + requiredImport: "QtQuick3D" + Property { name: "z"; type: "int"; value: 500; } + toolTip: qsTr("A perspective camera with a custom frustum.") + } + } + Type { + name: "QtQuick3D.CustomCamera" + icon: "images/camera16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Custom Camera" + category: "Cameras" + libraryIcon: "images/camera.png" + version: "6.0" + requiredImport: "QtQuick3D" + Property { name: "z"; type: "int"; value: 500; } + toolTip: qsTr("A camera with a custom projection matrix.") + } + } + Type { + name: "QtQuick3D.CustomMaterial" + icon: "images/custommaterial16.png" + + Hints { + visibleInNavigator: false + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + } + + ItemLibraryEntry { + name: "Custom Material" + category: "Materials" + libraryIcon: "images/custommaterial.png" + version: "6.0" + requiredImport: "QtQuick3D" + Property { name: "fragmentShader"; type: "QUrl"; value: "custom_material_default_shader.frag"; } + ExtraFile { source: "source/custom_material_default_shader.frag" } + toolTip: qsTr("A material with customizable vertex and fragment shaders.") + } + } + Type { + name: "QtQuick3D.DefaultMaterial" + icon: "images/material16.png" + + Hints { + visibleInNavigator: false + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + } + + ItemLibraryEntry { + name: "Default Material" + category: "Materials" + libraryIcon: "images/material.png" + version: "6.0" + requiredImport: "QtQuick3D" + Property { name: "diffuseColor"; type: "color"; value: "#4aee45"; } + toolTip: qsTr("A material with a specular/glossiness properties.") + } + } + Type { + name: "QtQuick3D.PrincipledMaterial" + icon: "images/material16.png" + + Hints { + visibleInNavigator: false + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + } + + ItemLibraryEntry { + name: "Principled Material" + category: "Materials" + libraryIcon: "images/material.png" + version: "6.0" + requiredImport: "QtQuick3D" + Property { name: "baseColor"; type: "color"; value: "#4aee45"; } + toolTip: qsTr("A material with a PBR metal/roughness properties.") + } + } + Type { + name: "QtQuick3D.SpecularGlossyMaterial" + icon: "images/material16.png" + + Hints { + visibleInNavigator: false + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + } + + ItemLibraryEntry { + name: "Specular Glossy" + category: "Materials" + libraryIcon: "images/material.png" + version: "6.4" + requiredImport: "QtQuick3D" + Property { name: "albedoColor"; type: "color"; value: "#4aee45"; } + Property { name: "specularColor"; type: "color"; value: "#000000"; } + toolTip: qsTr("A material with a PBR specular/glossiness properties.") + } + } + Type { + name: "QtQuick3D.Texture" + icon: "images/texture16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeContainer: false + } + + ItemLibraryEntry { + name: "Texture" + category: "Textures" + libraryIcon: "images/texture.png" + version: "6.0" + requiredImport: "QtQuick3D" + toolTip: qsTr("Defines a texture for 3D objects.") + } + } + Type { + name: "QtQuick3D.CubeMapTexture" + icon: "images/cubemaptexture16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeContainer: false + } + + ItemLibraryEntry { + name: "Cube Map Texture" + category: "Textures" + libraryIcon: "images/cubemaptexture.png" + version: "6.4" + requiredImport: "QtQuick3D" + toolTip: qsTr("Defines a cube map texture for 3D objects.") + } + } + Type { + name: "QtQuick3D.DirectionalLight" + icon: "images/lightdirectional16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Directional Light" + category: "Lights" + libraryIcon: "images/lightdirectional.png" + version: "6.0" + requiredImport: "QtQuick3D" + toolTip: qsTr("A light similar to sunlight. It emits light in one direction from an infinitely far away source.") + } + } + Type { + name: "QtQuick3D.PointLight" + icon: "images/lightpoint16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Point Light" + category: "Lights" + libraryIcon: "images/lightpoint.png" + version: "6.0" + requiredImport: "QtQuick3D" + toolTip: qsTr("A light similar to a light bulb. It emits light equally in all directions from a central source.") + } + } + Type { + name: "QtQuick3D.SpotLight" + icon: "images/lightspot16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Spotlight" + category: "Lights" + libraryIcon: "images/lightspot.png" + version: "6.0" + requiredImport: "QtQuick3D" + toolTip: qsTr("A spotlight emits light in one direction in a cone shape.") + } + } + Type { + name: "QtQuick3D.Model" + icon: "images/model16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + visibleNonDefaultProperties: "materials" + } + + ItemLibraryEntry { + name: "Model" + category: "Components" + libraryIcon: "images/group.png" + version: "6.0" + requiredImport: "QtQuick3D" + toolTip: qsTr("Allows you to load 3D mesh data.") + } + } + Type { + name: "QtQuick3D.Model" + icon: "images/model16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + visibleNonDefaultProperties: "materials" + } + + ItemLibraryEntry { + name: "Cube" + category: "Primitives" + libraryIcon: "images/cube.png" + version: "6.0" + requiredImport: "QtQuick3D" + Property { name: "source"; type: "QUrl"; value: "#Cube"; } + toolTip: qsTr("A cube model.") + } + } + Type { + name: "QtQuick3D.Model" + icon: "images/model16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + visibleNonDefaultProperties: "materials" + } + + ItemLibraryEntry { + name: "Sphere" + category: "Primitives" + libraryIcon: "images/sphere.png" + version: "6.0" + requiredImport: "QtQuick3D" + Property { name: "source"; type: "QUrl"; value: "#Sphere"; } + toolTip: qsTr("A sphere model.") + } + } + Type { + name: "QtQuick3D.Model" + icon: "images/model16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + visibleNonDefaultProperties: "materials" + } + + ItemLibraryEntry { + name: "Cylinder" + category: "Primitives" + libraryIcon: "images/cylinder.png" + version: "6.0" + requiredImport: "QtQuick3D" + Property { name: "source"; type: "QUrl"; value: "#Cylinder"; } + toolTip: qsTr("A cylinder model.") + } + } + Type { + name: "QtQuick3D.Model" + icon: "images/model16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + visibleNonDefaultProperties: "materials" + } + + ItemLibraryEntry { + name: "Plane" + category: "Primitives" + libraryIcon: "images/plane.png" + version: "6.0" + requiredImport: "QtQuick3D" + Property { name: "source"; type: "QUrl"; value: "#Rectangle"; } + toolTip: qsTr("A plane model.") + } + } + Type { + name: "QtQuick3D.Model" + icon: "images/model16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + visibleNonDefaultProperties: "materials" + } + + ItemLibraryEntry { + name: "Cone" + category: "Primitives" + libraryIcon: "images/cone.png" + version: "6.0" + requiredImport: "QtQuick3D" + Property { name: "source"; type: "QUrl"; value: "#Cone"; } + toolTip: qsTr("A cone model.") + } + } + Type { + name: "QtQuick3D.Node" + icon: "images/group16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Group" + category: "Components" + libraryIcon: "images/group.png" + version: "6.0" + requiredImport: "QtQuick3D" + toolTip: qsTr("A container to keep several QtQuick3D components or scenes together.") + } + } + Type { + name: "QtQuick3D.SceneEnvironment" + icon: "images/scene16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + } + + ItemLibraryEntry { + name: "Scene Environment" + category: "Components" + libraryIcon: "images/scene.png" + version: "6.0" + requiredImport: "QtQuick3D" + toolTip: qsTr("Configures the render settings for a scene.") + } + } + Type { + name: "QtQuick3D.View3D" + icon: "images/view3D16.png" + + ItemLibraryEntry { + name: "View3D" + category: "Items" + libraryIcon: "images/view3D.png" + version: "6.0" + requiredImport: "QtQuick3D" + QmlSource { source: "./source/view3D_template.qml" } + toolTip: qsTr("A 2D surface where a 3D scene can be rendered.") + } + } + Type { + name: "QtQuick3D.Shader" + icon: "images/shaderutil16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + } + + ItemLibraryEntry { + name: "Shader" + category: "Custom Shader Utils" + libraryIcon: "images/shaderutil.png" + version: "6.0" + requiredImport: "QtQuick3D" + toolTip: qsTr("A container for keeping the vertex or fragment shader codes to be used by post-processing effect.") + } + } + Type { + name: "QtQuick3D.TextureInput" + icon: "images/shaderutil16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + } + + ItemLibraryEntry { + name: "Texture Input" + category: "Custom Shader Utils" + libraryIcon: "images/shaderutil.png" + version: "6.0" + requiredImport: "QtQuick3D" + toolTip: qsTr("Specifies a texture that gets exposed to the shader.") + } + } + Type { + name: "QtQuick3D.Pass" + icon: "images/shaderutil16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + } + + ItemLibraryEntry { + name: "Pass" + category: "Custom Shader Utils" + libraryIcon: "images/shaderutil.png" + version: "6.0" + requiredImport: "QtQuick3D" + toolTip: qsTr("Holds a set of actions combining a list of executable render commands, an output buffer, and a list of shaders to use for rendering effects.") + } + } + Type { + name: "QtQuick3D.BufferInput" + icon: "images/shadercommand16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + } + + ItemLibraryEntry { + name: "Buffer Input" + category: "Custom Shader Utils" + libraryIcon: "images/shadercommand.png" + version: "6.0" + requiredImport: "QtQuick3D" + toolTip: qsTr("A command that gets added to the list of commands in the Pass of an Effect when executed.") + } + } + Type { + name: "QtQuick3D.Buffer" + icon: "images/shaderutil16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + } + + ItemLibraryEntry { + name: "Buffer" + category: "Custom Shader Utils" + libraryIcon: "images/shaderutil.png" + version: "6.0" + requiredImport: "QtQuick3D" + toolTip: qsTr("Creates or references a color buffer to be used for a pass of an Effect.") + } + } + Type { + name: "QtQuick3D.SetUniformValue" + icon: "images/shadercommand16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + } + + ItemLibraryEntry { + name: "Set Uniform Value" + category: "Custom Shader Utils" + libraryIcon: "images/shadercommand.png" + version: "6.0" + requiredImport: "QtQuick3D" + toolTip: qsTr("A value that would be set when a single pass actions takes place.") + } + } + Type { + name: "QtQuick3D.Effect" + icon: "images/effect16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + } + + ItemLibraryEntry { + name: "Effect" + category: "Components" + libraryIcon: "images/effect.png" + version: "6.0" + requiredImport: "QtQuick3D" + QmlSource { source: "./source/effect_template.qml" } + ExtraFile { source: "./source/effect_default_shader.frag" } + toolTip: qsTr("A method to allow the user to implement their post-processing effects on entire View3D.") + } + } + Type { + name: "QtQuick3D.Repeater3D" + icon: "images/repeater3d16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "3D Repeater" + category: "Components" + libraryIcon: "images/repeater3d.png" + version: "6.0" + requiredImport: "QtQuick3D" + toolTip: qsTr("Dynamically creates several copies of the same 3D object.") + } + } + Type { + name: "QtQuick3D.Loader3D" + icon: "images/loader3d16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Loader3D" + category: "Components" + libraryIcon: "images/loader3d.png" + version: "6.0" + requiredImport: "QtQuick3D" + toolTip: qsTr("Allows you to load 3D components dynamically.") + } + } + Type { + name: "QtQuick3D.Skeleton" + icon: "images/skeleton16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + } + + ItemLibraryEntry { + name: "Skeleton" + category: "Components" + libraryIcon: "images/skeleton.png" + version: "6.0" + requiredImport: "QtQuick3D" + toolTip: qsTr("Defines a skeletal animation hierarchy.") + } + } + Type { + name: "QtQuick3D.MorphTarget" + icon: "images/morphtarget16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + } + + ItemLibraryEntry { + name: "Morph Target" + category: "Components" + libraryIcon: "images/morphtarget.png" + version: "6.0" + requiredImport: "QtQuick3D" + toolTip: qsTr("Defines the properties of a morph target.") + } + } + Type { + name: "QtQuick3D.InstanceListEntry" + icon: "images/instancelistentry16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + } + + ItemLibraryEntry { + name: "Instance List Entry" + category: "Components" + libraryIcon: "images/instancelistentry.png" + version: "6.2" + requiredImport: "QtQuick3D" + toolTip: qsTr("One instance in an Instance List. The instance includes a set of property specifications.") + } + } + Type { + name: "QtQuick3D.InstanceList" + icon: "images/instancelist16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + } + + ItemLibraryEntry { + name: "Instance List" + category: "Components" + libraryIcon: "images/instancelist.png" + version: "6.2" + requiredImport: "QtQuick3D" + toolTip: qsTr("Enables 3D model instancing, a lightweight 3D object replication method.") + } + } + Type { + name: "QtQuick3D.FileInstancing" + icon: "images/fileinstancing16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + } + + ItemLibraryEntry { + name: "File Instancing" + category: "Components" + libraryIcon: "images/fileinstancing.png" + version: "6.2" + requiredImport: "QtQuick3D" + toolTip: qsTr("A method that allows reading instance tables from XML or Qt-specific binary files.") + } + } + Type { + name: "QtQuick3D.Joint" + icon: "images/joint16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + } + + ItemLibraryEntry { + name: "Joint" + category: "Components" + libraryIcon: "images/joint.png" + version: "6.0" + requiredImport: "QtQuick3D" + toolTip: qsTr("A transformable node that connects different parts in a skeletal animation.") + } + } + Type { + name: "QtQuick3D.ReflectionProbe" + icon: "images/reflectionProbe16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: true + } + + ItemLibraryEntry { + name: "Reflection Probe" + category: "Components" + libraryIcon: "images/reflectionProbe.png" + version: "6.3" + requiredImport: "QtQuick3D" + toolTip: qsTr("Reflects the current scene to the objects.") + } + } + Type { + name: "QtQuick3D.Fog" + icon: "images/fog16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Fog" + category: "Components" + libraryIcon: "images/fog.png" + version: "6.5" + requiredImport: "QtQuick3D" + } + } + Type { + name: "QtQuick3D.DebugSettings" + icon: "images/debugsettings16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Debug Settings" + category: "Components" + libraryIcon: "images/debugsettings.png" + version: "6.5" + requiredImport: "QtQuick3D" + } + } + + Type { + name: "QtQuick3D.Lightmapper" + icon: "images/lightmapper16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + // Split the name to avoid ellipsis in UI + name: "Light Mapper" + category: "Components" + libraryIcon: "images/lightmapper.png" + version: "6.5" + requiredImport: "QtQuick3D" + } + } + + Type { + name: "QtQuick3D.Skin" + icon: "images/skin16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Skin" + category: "Components" + libraryIcon: "images/skin.png" + version: "6.5" + requiredImport: "QtQuick3D" + } + } + + Type { + name: "QtQuick3D.ResourceLoader" + icon: "images/resourceLoader16.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: false + canBeDroppedInView3D: false + } + + ItemLibraryEntry { + name: "Resource Loader" + category: "Components" + libraryIcon: "images/resourceLoader.png" + version: "6.2" + requiredImport: "QtQuick3D" + toolTip: qsTr("Pre-load resources for 3D scene. It makes sure that large resources are available before rendering a frame.") + } + } +} diff --git a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp index 4b3f0a1869..fc806d73a9 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp @@ -5,7 +5,8 @@ #include <matchers/info_exportedtypenames-matcher.h> #include <matchers/projectstorage-matcher.h> -#include <mocks/projectstorageobservermock.h> +#include <projectstorageerrornotifiermock.h> +#include <projectstorageobservermock.h> #include <modelnode.h> #include <projectstorage/projectstorage.h> @@ -28,6 +29,7 @@ using QmlDesigner::PropertyDeclarationId; using QmlDesigner::SourceContextId; using QmlDesigner::SourceId; using QmlDesigner::SourceIds; +using QmlDesigner::Storage::ModuleKind; using QmlDesigner::Storage::Synchronization::SynchronizationPackage; using QmlDesigner::Storage::Synchronization::TypeAnnotations; using QmlDesigner::Storage::TypeTraits; @@ -48,6 +50,12 @@ Storage::Imports operator+(const Storage::Imports &first, return imports; } +auto IsModule(Utils::SmallStringView name, ModuleKind kind) +{ + return AllOf(Field(&QmlDesigner::Storage::Module::name, name), + Field(&QmlDesigner::Storage::Module::kind, kind)); +} + MATCHER_P2(IsSourceContext, id, value, @@ -197,12 +205,29 @@ MATCHER_P4(IsInfoPropertyDeclaration, && propertyDeclaration.traits == traits; } +auto IsUnresolvedTypeId() +{ + return Property(&QmlDesigner::TypeId::internalId, -1); +} + +template<typename Matcher> +auto IsPrototypeId(const Matcher &matcher) +{ + return Field(&Storage::Synchronization::Type::prototypeId, matcher); +} + +template<typename Matcher> +auto IsExtensionId(const Matcher &matcher) +{ + return Field(&Storage::Synchronization::Type::extensionId, matcher); +} + class HasNameMatcher { public: using is_gtest_matcher = void; - HasNameMatcher(const QmlDesigner::ProjectStorage<Sqlite::Database> &storage, + HasNameMatcher(const QmlDesigner::ProjectStorage &storage, Utils::SmallStringView name) : storage{storage} , name{name} @@ -231,7 +256,7 @@ public: void DescribeNegationTo(std::ostream *os) const { *os << "is not '" << name << "'"; } private: - const QmlDesigner::ProjectStorage<Sqlite::Database> &storage; + const QmlDesigner::ProjectStorage &storage; Utils::SmallStringView name; }; @@ -253,37 +278,34 @@ MATCHER(StringsAreSorted, std::string(negation ? "isn't sorted" : "is sorted")) }); } -MATCHER_P3(IsInfoType, - defaultPropertyId, +MATCHER_P2(IsInfoType, sourceId, traits, std::string(negation ? "isn't " : "is ") - + PrintToString(Storage::Info::Type{defaultPropertyId, sourceId, traits})) + + PrintToString(Storage::Info::Type{sourceId, traits})) { const Storage::Info::Type &type = arg; - return type.defaultPropertyId == defaultPropertyId && type.sourceId == sourceId - && type.traits == traits; + return type.sourceId == sourceId && type.traits == traits; } class ProjectStorage : public testing::Test { protected: - static void SetUpTestSuite() + struct StaticData { - static_database = std::make_unique<Sqlite::Database>(":memory:", Sqlite::JournalMode::Memory); + Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; + NiceMock<ProjectStorageErrorNotifierMock> errorNotifierMock; + QmlDesigner::ProjectStorage storage{database, errorNotifierMock, database.isInitialized()}; + }; - static_projectStorage = std::make_unique<QmlDesigner::ProjectStorage<Sqlite::Database>>( - *static_database, static_database->isInitialized()); - } + static void SetUpTestSuite() { staticData = std::make_unique<StaticData>(); } - static void TearDownTestSuite() - { - static_projectStorage.reset(); - static_database.reset(); - } + static void TearDownTestSuite() { staticData.reset(); } - ~ProjectStorage() { static_projectStorage->resetForTestsOnly(); } + ProjectStorage() { storage.setErrorNotifier(errorNotifierMock); } + + ~ProjectStorage() { storage.resetForTestsOnly(); } template<typename Range> static auto toValues(Range &&range) @@ -309,6 +331,32 @@ protected: storage.fetchSourceId(sourceContextId3, "bar"); } + auto createVerySimpleSynchronizationPackage() + { + SynchronizationPackage package; + + package.types.push_back(Storage::Synchronization::Type{ + "QQuickItem", + Storage::Synchronization::ImportedType{}, + Storage::Synchronization::ImportedType{}, + TypeTraitsKind::Reference, + sourceId1, + {Storage::Synchronization::ExportedType{qtQuickModuleId, "Item"}, + Storage::Synchronization::ExportedType{qtQuickNativeModuleId, "QQuickItem"}}}); + package.types.push_back(Storage::Synchronization::Type{ + "QObject", + Storage::Synchronization::ImportedType{}, + Storage::Synchronization::ImportedType{}, + TypeTraitsKind::Reference, + sourceId2, + {Storage::Synchronization::ExportedType{qmlModuleId, "Object"}, + Storage::Synchronization::ExportedType{qmlNativeModuleId, "QObject"}}}); + + package.updatedSourceIds = {sourceId1, sourceId2}; + + return package; + } + auto createSimpleSynchronizationPackage() { SynchronizationPackage package; @@ -998,10 +1046,10 @@ protected: package.updatedSourceIds = {sourceId1, sourceId2, sourceId3}; - package.propertyEditorQmlPaths.emplace_back(qtQuickModuleId, "QtObject", sourceId1, sourceIdPath); - package.propertyEditorQmlPaths.emplace_back(qtQuickModuleId, "Item", sourceId2, sourceIdPath); - package.propertyEditorQmlPaths.emplace_back(qtQuickModuleId, "Item3D", sourceId3, sourceIdPath); - package.updatedPropertyEditorQmlPathSourceIds.emplace_back(sourceIdPath); + package.propertyEditorQmlPaths.emplace_back(qtQuickModuleId, "QtObject", sourceId1, sourceIdPath6); + package.propertyEditorQmlPaths.emplace_back(qtQuickModuleId, "Item", sourceId2, sourceIdPath6); + package.propertyEditorQmlPaths.emplace_back(qtQuickModuleId, "Item3D", sourceId3, sourceIdPath6); + package.updatedPropertyEditorQmlPathSourceIds.emplace_back(sourceIdPath6); return package; } @@ -1015,6 +1063,7 @@ protected: traits.visibleInLibrary = FlagIs::True; annotations.emplace_back(sourceId4, + sourceIdPath6, "Object", qmlModuleId, "/path/to/icon.png", @@ -1036,6 +1085,32 @@ protected: "properties":[["color", "color", "#blue"]]}])xy"); annotations.emplace_back(sourceId5, + sourceIdPath6, + "Item", + qtQuickModuleId, + "/path/to/quick.png", + traits, + R"xy({"canBeContainer": "true", "forceClip": "false"})xy", + R"xy([{"name":"Item", + "iconPath":"/path/icon3", + "category":"Advanced Items", + "import":"QtQuick", + "toolTip":"Item is an Object", + "properties":[["x", "double", 1], ["y", "double", 2]]}])xy"); + + return annotations; + } + + auto createExtendedTypeAnnotations() const + { + auto annotations = createTypeAnnotions(); + annotations.pop_back(); + TypeTraits traits{TypeTraitsKind::Reference}; + traits.canBeContainer = FlagIs::True; + traits.visibleInLibrary = FlagIs::True; + + annotations.emplace_back(sourceId5, + sourceIdPath1, "Item", qtQuickModuleId, "/path/to/quick.png", @@ -1109,38 +1184,38 @@ protected: } protected: - inline static std::unique_ptr<Sqlite::Database> static_database; - Sqlite::Database &database = *static_database; - //Sqlite::Database database{"/tmp/aaaaa.db", Sqlite::JournalMode::Wal}; - inline static std::unique_ptr<QmlDesigner::ProjectStorage<Sqlite::Database>> static_projectStorage; - QmlDesigner::ProjectStorage<Sqlite::Database> &storage = *static_projectStorage; - QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage<Sqlite::Database>> sourcePathCache{ - storage}; + inline static std::unique_ptr<StaticData> staticData; + Sqlite::Database &database = staticData->database; + QmlDesigner::ProjectStorage &storage = staticData->storage; + NiceMock<ProjectStorageErrorNotifierMock> errorNotifierMock; + QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage> sourcePathCache{storage}; QmlDesigner::SourcePathView path1{"/path1/to"}; QmlDesigner::SourcePathView path2{"/path2/to"}; QmlDesigner::SourcePathView path3{"/path3/to"}; QmlDesigner::SourcePathView path4{"/path4/to"}; QmlDesigner::SourcePathView path5{"/path5/to"}; QmlDesigner::SourcePathView path6{"/path6/to"}; - QmlDesigner::SourcePathView pathPath{"/path6/."}; + QmlDesigner::SourcePathView pathPath1{"/path1/."}; + QmlDesigner::SourcePathView pathPath6{"/path6/."}; SourceId sourceId1{sourcePathCache.sourceId(path1)}; SourceId sourceId2{sourcePathCache.sourceId(path2)}; SourceId sourceId3{sourcePathCache.sourceId(path3)}; SourceId sourceId4{sourcePathCache.sourceId(path4)}; SourceId sourceId5{sourcePathCache.sourceId(path5)}; SourceId sourceId6{sourcePathCache.sourceId(path6)}; - SourceId sourceIdPath{sourcePathCache.sourceId(path6)}; + SourceId sourceIdPath1{sourcePathCache.sourceId(pathPath1)}; + SourceId sourceIdPath6{sourcePathCache.sourceId(pathPath6)}; SourceId qmlProjectSourceId{sourcePathCache.sourceId("/path1/qmldir")}; SourceId qtQuickProjectSourceId{sourcePathCache.sourceId("/path2/qmldir")}; - ModuleId qmlModuleId{storage.moduleId("Qml")}; - ModuleId qmlNativeModuleId{storage.moduleId("Qml-cppnative")}; - ModuleId qtQuickModuleId{storage.moduleId("QtQuick")}; - ModuleId qtQuickNativeModuleId{storage.moduleId("QtQuick-cppnative")}; - ModuleId pathToModuleId{storage.moduleId("/path/to")}; - ModuleId qtQuick3DModuleId{storage.moduleId("QtQuick3D")}; - ModuleId myModuleModuleId{storage.moduleId("MyModule")}; - ModuleId QMLModuleId{storage.moduleId("QML")}; - ModuleId QMLNativeModuleId{storage.moduleId("QML-cppnative")}; + ModuleId qmlModuleId{storage.moduleId("Qml", ModuleKind::QmlLibrary)}; + ModuleId qmlNativeModuleId{storage.moduleId("Qml", ModuleKind::CppLibrary)}; + ModuleId qtQuickModuleId{storage.moduleId("QtQuick", ModuleKind::QmlLibrary)}; + ModuleId qtQuickNativeModuleId{storage.moduleId("QtQuick", ModuleKind::CppLibrary)}; + ModuleId pathToModuleId{storage.moduleId("/path/to", ModuleKind::PathLibrary)}; + ModuleId qtQuick3DModuleId{storage.moduleId("QtQuick3D", ModuleKind::QmlLibrary)}; + ModuleId myModuleModuleId{storage.moduleId("MyModule", ModuleKind::QmlLibrary)}; + ModuleId QMLModuleId{storage.moduleId("QML", ModuleKind::QmlLibrary)}; + ModuleId QMLNativeModuleId{storage.moduleId("QML", ModuleKind::CppLibrary)}; Storage::Imports importsSourceId1; Storage::Imports importsSourceId2; Storage::Imports importsSourceId3; @@ -1456,22 +1531,193 @@ TEST_F(ProjectStorage, synchronize_types_adds_new_types_with_exported_extension_ "QQuickItem")))))); } -TEST_F(ProjectStorage, synchronize_types_adds_new_types_throws_with_wrong_prototype_name) +TEST_F(ProjectStorage, + synchronize_types_adds_unknown_prototype_which_notifies_about_unresolved_type_name) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types[0].prototype = Storage::Synchronization::ImportedType{"Objec"}; + + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Objec"), sourceId1)); + + storage.synchronize(std::move(package)); +} + +TEST_F(ProjectStorage, synchronize_types_adds_unknown_prototype_as_unresolved_type_id) { auto package{createSimpleSynchronizationPackage()}; package.types[0].prototype = Storage::Synchronization::ImportedType{"Objec"}; - ASSERT_THROW(storage.synchronize(std::move(package)), QmlDesigner::TypeNameDoesNotExists); + storage.synchronize(std::move(package)); + + ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), + IsPrototypeId(IsUnresolvedTypeId())); } -TEST_F(ProjectStorage, synchronize_types_adds_new_types_throws_with_wrong_extension_name) +TEST_F(ProjectStorage, synchronize_types_updates_unresolved_prototype_after_exported_type_name_is_added) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types[0].prototype = Storage::Synchronization::ImportedType{"Objec"}; + storage.synchronize(package); + package.types[1].exportedTypes.emplace_back(qmlNativeModuleId, "Objec"); + + storage.synchronize(std::move(package)); + + ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), + IsPrototypeId(fetchTypeId(sourceId2, "QObject"))); +} + +TEST_F(ProjectStorage, + synchronize_types_updates_prototype_to_unresolved_after_exported_type_name_is_removed) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types[0].prototype = Storage::Synchronization::ImportedType{"Objec"}; + package.types[1].exportedTypes.emplace_back(qmlNativeModuleId, "Objec"); + storage.synchronize(package); + package.types[1].exportedTypes.pop_back(); + + storage.synchronize(std::move(package)); + + ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), + IsPrototypeId(IsUnresolvedTypeId())); +} + +TEST_F(ProjectStorage, + synchronize_types_updates_unresolved_prototype_indirectly_after_exported_type_name_is_added) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types[0].prototype = Storage::Synchronization::ImportedType{"Objec"}; + storage.synchronize(package); + package.types[1].exportedTypes.emplace_back(qmlNativeModuleId, "Objec"); + package.types.erase(package.types.begin()); + package.updatedSourceIds = {sourceId2}; + + storage.synchronize(std::move(package)); + + ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), + IsPrototypeId(fetchTypeId(sourceId2, "QObject"))); +} + +TEST_F(ProjectStorage, + synchronize_types_updates_prototype_indirectly_to_unresolved_after_exported_type_name_is_removed) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types[0].prototype = Storage::Synchronization::ImportedType{"Objec"}; + package.types[1].exportedTypes.emplace_back(qmlNativeModuleId, "Objec"); + storage.synchronize(package); + package.types[1].exportedTypes.pop_back(); + package.types.erase(package.types.begin()); + package.updatedSourceIds = {sourceId2}; + + storage.synchronize(std::move(package)); + + ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), + IsPrototypeId(IsUnresolvedTypeId())); +} + +TEST_F(ProjectStorage, + synchronize_types_updates_prototype_indirectly_to_unresolved_after_exported_type_name_is_removed_notifies_type_name_cannot_be_resolved) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types[0].prototype = Storage::Synchronization::ImportedType{"Objec"}; + package.types[1].exportedTypes.emplace_back(qmlNativeModuleId, "Objec"); + storage.synchronize(package); + package.types[1].exportedTypes.pop_back(); + package.types.erase(package.types.begin()); + package.updatedSourceIds = {sourceId2}; + + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Objec"), sourceId1)); + + storage.synchronize(std::move(package)); +} + +TEST_F(ProjectStorage, synchronize_types_updates_unresolved_extension_after_exported_type_name_is_added) { auto package{createSimpleSynchronizationPackage()}; package.types[0].extension = Storage::Synchronization::ImportedType{"Objec"}; + storage.synchronize(package); + package.types[1].exportedTypes.emplace_back(qmlNativeModuleId, "Objec"); + + storage.synchronize(std::move(package)); - ASSERT_THROW(storage.synchronize(std::move(package)), QmlDesigner::TypeNameDoesNotExists); + ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), + IsExtensionId(fetchTypeId(sourceId2, "QObject"))); } +TEST_F(ProjectStorage, + synchronize_types_updates_extension_to_unresolved_after_exported_type_name_is_removed) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types[0].extension = Storage::Synchronization::ImportedType{"Objec"}; + package.types[1].exportedTypes.emplace_back(qmlNativeModuleId, "Objec"); + storage.synchronize(package); + package.types[1].exportedTypes.pop_back(); + + storage.synchronize(std::move(package)); + + ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), + IsExtensionId(IsUnresolvedTypeId())); +} + +TEST_F(ProjectStorage, + synchronize_types_updates_unresolved_extension_indirectly_after_exported_type_name_is_added) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types[0].extension = Storage::Synchronization::ImportedType{"Objec"}; + storage.synchronize(package); + package.types[1].exportedTypes.emplace_back(qmlNativeModuleId, "Objec"); + package.types.erase(package.types.begin()); + package.updatedSourceIds = {sourceId2}; + + storage.synchronize(std::move(package)); + + ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), + IsExtensionId(fetchTypeId(sourceId2, "QObject"))); +} + +TEST_F(ProjectStorage, + synchronize_types_updates_invalid_extension_indirectly_after_exported_type_name_is_removed) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types[0].extension = Storage::Synchronization::ImportedType{"Objec"}; + package.types[1].exportedTypes.emplace_back(qmlNativeModuleId, "Objec"); + storage.synchronize(package); + package.types[1].exportedTypes.pop_back(); + package.types.erase(package.types.begin()); + package.updatedSourceIds = {sourceId2}; + + storage.synchronize(std::move(package)); + + ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), + IsExtensionId(IsUnresolvedTypeId())); +} + +TEST_F(ProjectStorage, + synchronize_types_updates_extension_indirectly_to_unresolved_after_exported_type_name_is_removed_notifies_type_name_cannot_be_resolved) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types[0].extension = Storage::Synchronization::ImportedType{"Objec"}; + package.types[1].exportedTypes.emplace_back(qmlNativeModuleId, "Objec"); + storage.synchronize(package); + package.types[1].exportedTypes.pop_back(); + package.types.erase(package.types.begin()); + package.updatedSourceIds = {sourceId2}; + + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Objec"), sourceId1)); + + storage.synchronize(std::move(package)); +} + +TEST_F(ProjectStorage, synchronize_types_adds_extension_which_notifies_about_unresolved_type_name) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types[0].extension = Storage::Synchronization::ImportedType{"Objec"}; + + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Objec"), sourceId1)); + + storage.synchronize(std::move(package)); +} + + TEST_F(ProjectStorage, synchronize_types_adds_new_types_with_missing_module) { auto package{createSimpleSynchronizationPackage()}; @@ -1744,7 +1990,7 @@ TEST_F(ProjectStorage, synchronize_types_add_qualified_extension) IsExportedType(qtQuickNativeModuleId, "QQuickItem")))))); } -TEST_F(ProjectStorage, synchronize_types_throws_for_missing_prototype) +TEST_F(ProjectStorage, synchronize_types_notifies_cannot_resolve_for_missing_prototype) { auto package{createSimpleSynchronizationPackage()}; package.types = {Storage::Synchronization::Type{ @@ -1756,10 +2002,12 @@ TEST_F(ProjectStorage, synchronize_types_throws_for_missing_prototype) {Storage::Synchronization::ExportedType{qtQuickModuleId, "Item"}, Storage::Synchronization::ExportedType{qtQuickNativeModuleId, "QQuickItem"}}}}; - ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("QObject"), sourceId1)); + + storage.synchronize(package); } -TEST_F(ProjectStorage, synchronize_types_throws_for_missing_extension) +TEST_F(ProjectStorage, synchronize_types_notifies_cannot_resolve_for_missing_extension) { auto package{createSimpleSynchronizationPackage()}; package.types = {Storage::Synchronization::Type{ @@ -1771,7 +2019,9 @@ TEST_F(ProjectStorage, synchronize_types_throws_for_missing_extension) {Storage::Synchronization::ExportedType{qtQuickModuleId, "Item"}, Storage::Synchronization::ExportedType{qtQuickNativeModuleId, "QQuickItem"}}}}; - ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("QObject"), sourceId1)); + + storage.synchronize(package); } TEST_F(ProjectStorage, synchronize_types_throws_for_invalid_module) @@ -2889,7 +3139,7 @@ TEST_F(ProjectStorage, fetch_invalid_type_id_by_impor_ids_and_exported_name_if_n { auto package{createSimpleSynchronizationPackage()}; storage.synchronize(package); - auto qtQuickModuleId = storage.moduleId("QtQuick"); + auto qtQuickModuleId = storage.moduleId("QtQuick", ModuleKind::QmlLibrary); auto typeId = storage.fetchTypeIdByModuleIdsAndExportedName({qtQuickModuleId}, "Object"); @@ -3640,7 +3890,8 @@ TEST_F(ProjectStorage, change_extension_type_module_id) TypeTraitsKind::Reference))); } -TEST_F(ProjectStorage, change_qualified_prototype_type_module_id_throws) +TEST_F(ProjectStorage, + change_qualified_prototype_type_module_id_notifies_that_type_name_cannot_be_resolved) { auto package{createSimpleSynchronizationPackage()}; package.types[0].prototype = Storage::Synchronization::QualifiedImportedType{ @@ -3648,12 +3899,12 @@ TEST_F(ProjectStorage, change_qualified_prototype_type_module_id_throws) storage.synchronize(package); package.types[1].exportedTypes[0].moduleId = qtQuickModuleId; - ASSERT_THROW(storage.synchronize( - SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}}), - QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Object"), sourceId1)); + + storage.synchronize(SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}}); } -TEST_F(ProjectStorage, change_qualified_extension_type_module_id_throws) +TEST_F(ProjectStorage, change_qualified_extension_type_module_id_notifies_cannot_resolve) { auto package{createSimpleSynchronizationPackage()}; std::swap(package.types.front().extension, package.types.front().prototype); @@ -3662,9 +3913,9 @@ TEST_F(ProjectStorage, change_qualified_extension_type_module_id_throws) storage.synchronize(package); package.types[1].exportedTypes[0].moduleId = qtQuickModuleId; - ASSERT_THROW(storage.synchronize( - SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}}), - QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Object"), sourceId1)); + + storage.synchronize(SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}}); } TEST_F(ProjectStorage, change_qualified_prototype_type_module_id) @@ -3768,9 +4019,9 @@ TEST_F(ProjectStorage, change_prototype_type_name_throws_for_wrong_native_protot package.types[1].exportedTypes[2].name = "QObject3"; package.types[1].typeName = "QObject3"; - ASSERT_THROW(storage.synchronize( - SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}}), - QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("QObject"), sourceId1)); + + storage.synchronize(SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}}); } TEST_F(ProjectStorage, change_extension_type_name_throws_for_wrong_native_extension_type_name) @@ -3783,9 +4034,9 @@ TEST_F(ProjectStorage, change_extension_type_name_throws_for_wrong_native_extens package.types[1].exportedTypes[2].name = "QObject3"; package.types[1].typeName = "QObject3"; - ASSERT_THROW(storage.synchronize( - SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}}), - QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("QObject"), sourceId1)); + + storage.synchronize(SynchronizationPackage{importsSourceId2, {package.types[1]}, {sourceId2}}); } TEST_F(ProjectStorage, throw_for_prototype_chain_cycles) @@ -4087,23 +4338,29 @@ TEST_F(ProjectStorage, qualified_extension) TypeTraitsKind::Reference))); } -TEST_F(ProjectStorage, qualified_prototype_upper_down_the_module_chain_throws) +TEST_F(ProjectStorage, + qualified_prototype_upper_down_the_module_chain_notifies_type_name_cannot_be_resolved) { auto package{createSimpleSynchronizationPackage()}; package.types[0].prototype = Storage::Synchronization::QualifiedImportedType{ "Object", Storage::Import{qtQuickModuleId, Storage::Version{}, sourceId1}}; - ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Object"), sourceId1)); + + storage.synchronize(package); } -TEST_F(ProjectStorage, qualified_extension_upper_down_the_module_chain_throws) +TEST_F(ProjectStorage, + qualified_extension_upper_down_the_module_chain_notifies_type_name_cannot_be_resolved) { auto package{createSimpleSynchronizationPackage()}; std::swap(package.types.front().extension, package.types.front().prototype); package.types[0].extension = Storage::Synchronization::QualifiedImportedType{ "Object", Storage::Import{qtQuickModuleId, Storage::Version{}, sourceId1}}; - ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Object"), sourceId1)); + + storage.synchronize(package); } TEST_F(ProjectStorage, qualified_prototype_upper_in_the_module_chain) @@ -4159,7 +4416,7 @@ TEST_F(ProjectStorage, qualified_extension_upper_in_the_module_chain) TypeTraitsKind::Reference))); } -TEST_F(ProjectStorage, qualified_prototype_with_wrong_version_throws) +TEST_F(ProjectStorage, qualified_prototype_with_wrong_version_notifies_type_name_cannot_be_resolved) { auto package{createSimpleSynchronizationPackage()}; package.types[0].prototype = Storage::Synchronization::QualifiedImportedType{ @@ -4175,10 +4432,12 @@ TEST_F(ProjectStorage, qualified_prototype_with_wrong_version_throws) package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId3); package.updatedSourceIds.push_back(sourceId3); - ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Object"), sourceId1)); + + storage.synchronize(package); } -TEST_F(ProjectStorage, qualified_extension_with_wrong_version_throws) +TEST_F(ProjectStorage, qualified_extension_with_wrong_version_notifies_type_name_cannot_be_resolved) { auto package{createSimpleSynchronizationPackage()}; std::swap(package.types.front().extension, package.types.front().prototype); @@ -4195,7 +4454,9 @@ TEST_F(ProjectStorage, qualified_extension_with_wrong_version_throws) package.imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId3); package.updatedSourceIds.push_back(sourceId3); - ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Object"), sourceId1)); + + storage.synchronize(package); } TEST_F(ProjectStorage, qualified_prototype_with_version) @@ -4308,23 +4569,29 @@ TEST_F(ProjectStorage, qualified_extension_with_version_in_the_proto_type_chain) TypeTraitsKind::Reference))); } -TEST_F(ProjectStorage, qualified_prototype_with_version_down_the_proto_type_chain_throws) +TEST_F(ProjectStorage, + qualified_prototype_with_version_down_the_proto_type_chain_notifies_type_name_cannot_be_resolved) { auto package{createSimpleSynchronizationPackage()}; package.types[0].prototype = Storage::Synchronization::QualifiedImportedType{ "Object", Storage::Import{qtQuickModuleId, Storage::Version{2}, sourceId1}}; - ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Object"), sourceId1)); + + storage.synchronize(package); } -TEST_F(ProjectStorage, qualified_extension_with_version_down_the_proto_type_chain_throws) +TEST_F(ProjectStorage, + qualified_extension_with_version_down_the_proto_type_chain_notifies_type_name_cannot_be_resolved) { auto package{createSimpleSynchronizationPackage()}; std::swap(package.types.front().extension, package.types.front().prototype); package.types[0].extension = Storage::Synchronization::QualifiedImportedType{ "Object", Storage::Import{qtQuickModuleId, Storage::Version{2}, sourceId1}}; - ASSERT_THROW(storage.synchronize(package), QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Object"), sourceId1)); + + storage.synchronize(package); } TEST_F(ProjectStorage, qualified_property_declaration_type_name) @@ -4629,7 +4896,7 @@ TEST_F(ProjectStorage, fetch_by_major_version_and_minor_version_for_qualified_im } TEST_F(ProjectStorage, - fetch_by_major_version_and_minor_version_for_imported_type_if_minor_version_is_not_exported_throws) + fetch_by_major_version_and_minor_version_for_imported_type_if_minor_version_is_not_exported_notifies_type_name_cannot_be_resolved) { auto package{createSynchronizationPackageWithVersions()}; storage.synchronize(package); @@ -4643,12 +4910,13 @@ TEST_F(ProjectStorage, Storage::Version{}}}}; Storage::Import import{qmlModuleId, Storage::Version{1, 1}, sourceId2}; - ASSERT_THROW(storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}}), - QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Object"), sourceId2)); + + storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}}); } TEST_F(ProjectStorage, - fetch_by_major_version_and_minor_version_for_qualified_imported_type_if_minor_version_is_not_exported_throws) + fetch_by_major_version_and_minor_version_for_qualified_imported_type_if_minor_version_is_not_exported_notifies_type_name_cannot_be_resolved) { auto package{createSynchronizationPackageWithVersions()}; storage.synchronize(package); @@ -4661,11 +4929,12 @@ TEST_F(ProjectStorage, sourceId2, {Storage::Synchronization::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}}; - ASSERT_THROW(storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}}), - QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Object"), sourceId2)); + + storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}}); } -TEST_F(ProjectStorage, fetch_low_minor_version_for_imported_type_throws) +TEST_F(ProjectStorage, fetch_low_minor_version_for_imported_type_notifies_type_name_cannot_be_resolved) { auto package{createSynchronizationPackageWithVersions()}; storage.synchronize(package); @@ -4679,11 +4948,13 @@ TEST_F(ProjectStorage, fetch_low_minor_version_for_imported_type_throws) Storage::Version{}}}}; Storage::Import import{qmlModuleId, Storage::Version{1, 1}, sourceId2}; - ASSERT_THROW(storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}}), - QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Obj"), sourceId2)); + + storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}}); } -TEST_F(ProjectStorage, fetch_low_minor_version_for_qualified_imported_type_throws) +TEST_F(ProjectStorage, + fetch_low_minor_version_for_qualified_imported_type_notifies_type_name_cannot_be_resolved) { auto package{createSynchronizationPackageWithVersions()}; storage.synchronize(package); @@ -4696,8 +4967,9 @@ TEST_F(ProjectStorage, fetch_low_minor_version_for_qualified_imported_type_throw sourceId2, {Storage::Synchronization::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}}; - ASSERT_THROW(storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}}), - QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Obj"), sourceId2)); + + storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}}); } TEST_F(ProjectStorage, fetch_higher_minor_version_for_imported_type) @@ -4745,7 +5017,8 @@ TEST_F(ProjectStorage, fetch_higher_minor_version_for_qualified_imported_type) TypeTraitsKind::Reference))); } -TEST_F(ProjectStorage, fetch_different_major_version_for_imported_type_throws) +TEST_F(ProjectStorage, + fetch_different_major_version_for_imported_type_notifies_type_name_cannot_be_resolved) { auto package{createSynchronizationPackageWithVersions()}; storage.synchronize(package); @@ -4759,11 +5032,13 @@ TEST_F(ProjectStorage, fetch_different_major_version_for_imported_type_throws) Storage::Version{}}}}; Storage::Import import{qmlModuleId, Storage::Version{3, 1}, sourceId2}; - ASSERT_THROW(storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}}), - QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Obj"), sourceId2)); + + storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}}); } -TEST_F(ProjectStorage, fetch_different_major_version_for_qualified_imported_type_throws) +TEST_F(ProjectStorage, + fetch_different_major_version_for_qualified_imported_type_notifies_type_name_cannot_be_resolved) { auto package{createSynchronizationPackageWithVersions()}; storage.synchronize(package); @@ -4776,8 +5051,9 @@ TEST_F(ProjectStorage, fetch_different_major_version_for_qualified_imported_type sourceId2, {Storage::Synchronization::ExportedType{qtQuickModuleId, "Item", Storage::Version{}}}}; - ASSERT_THROW(storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}}), - QmlDesigner::TypeNameDoesNotExists); + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Obj"), sourceId2)); + + storage.synchronize(SynchronizationPackage{{import}, {type}, {sourceId2}}); } TEST_F(ProjectStorage, fetch_other_type_by_different_version_for_imported_type) @@ -5039,262 +5315,314 @@ TEST_F(ProjectStorage, minimal_updates) TEST_F(ProjectStorage, get_module_id) { - auto id = storage.moduleId("Qml"); + auto id = storage.moduleId("Qml", ModuleKind::QmlLibrary); ASSERT_TRUE(id); } TEST_F(ProjectStorage, get_same_module_id_again) { - auto initialId = storage.moduleId("Qml"); + auto initialId = storage.moduleId("Qml", ModuleKind::QmlLibrary); - auto id = storage.moduleId("Qml"); + auto id = storage.moduleId("Qml", ModuleKind::QmlLibrary); ASSERT_THAT(id, Eq(initialId)); } -TEST_F(ProjectStorage, module_name_throws_if_id_is_invalid) +TEST_F(ProjectStorage, different_module_kind_returns_different_id) +{ + auto qmlId = storage.moduleId("Qml", ModuleKind::QmlLibrary); + + auto cppId = storage.moduleId("Qml", ModuleKind::CppLibrary); + + ASSERT_THAT(cppId, Ne(qmlId)); +} + +TEST_F(ProjectStorage, module_throws_if_id_is_invalid) { - ASSERT_THROW(storage.moduleName(ModuleId{}), QmlDesigner::ModuleDoesNotExists); + ASSERT_THROW(storage.module(ModuleId{}), QmlDesigner::ModuleDoesNotExists); } -TEST_F(ProjectStorage, module_name_throws_if_id_does_not_exists) +TEST_F(ProjectStorage, module_throws_if_id_does_not_exists) { - ASSERT_THROW(storage.moduleName(ModuleId::create(222)), QmlDesigner::ModuleDoesNotExists); + ASSERT_THROW(storage.module(ModuleId::create(222)), QmlDesigner::ModuleDoesNotExists); } -TEST_F(ProjectStorage, get_module_name) +TEST_F(ProjectStorage, get_module) { - auto id = storage.moduleId("Qml"); + auto id = storage.moduleId("Qml", ModuleKind::QmlLibrary); - auto name = storage.moduleName(id); + auto module = storage.module(id); - ASSERT_THAT(name, Eq("Qml")); + ASSERT_THAT(module, IsModule("Qml", ModuleKind::QmlLibrary)); } TEST_F(ProjectStorage, populate_module_cache) { - auto id = storage.moduleId("Qml"); + auto id = storage.moduleId("Qml", ModuleKind::QmlLibrary); - QmlDesigner::ProjectStorage<Sqlite::Database> newStorage{database, database.isInitialized()}; + QmlDesigner::ProjectStorage newStorage{database, errorNotifierMock, database.isInitialized()}; - ASSERT_THAT(newStorage.moduleName(id), Eq("Qml")); + ASSERT_THAT(newStorage.module(id), IsModule("Qml", ModuleKind::QmlLibrary)); } -TEST_F(ProjectStorage, add_project_dataes) +TEST_F(ProjectStorage, add_directory_infoes) { - Storage::Synchronization::ProjectData projectData1{qmlProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::ProjectData projectData2{qmlProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectSourceId, sourceId2, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::ProjectData projectData3{qtQuickProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectSourceId, sourceId3, qtQuickModuleId, Storage::Synchronization::FileType::QmlTypes}; storage.synchronize(SynchronizationPackage{{qmlProjectSourceId, qtQuickProjectSourceId}, - {projectData1, projectData2, projectData3}}); + {directoryInfo1, directoryInfo2, directoryInfo3}}); - ASSERT_THAT(storage.fetchProjectDatas({qmlProjectSourceId, qtQuickProjectSourceId}), - UnorderedElementsAre(projectData1, projectData2, projectData3)); + ASSERT_THAT(storage.fetchDirectoryInfos({qmlProjectSourceId, qtQuickProjectSourceId}), + UnorderedElementsAre(directoryInfo1, directoryInfo2, directoryInfo3)); } -TEST_F(ProjectStorage, remove_project_data) +TEST_F(ProjectStorage, remove_directory_info) { - Storage::Synchronization::ProjectData projectData1{qmlProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::ProjectData projectData2{qmlProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectSourceId, sourceId2, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::ProjectData projectData3{qtQuickProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectSourceId, sourceId3, qtQuickModuleId, Storage::Synchronization::FileType::QmlTypes}; storage.synchronize(SynchronizationPackage{{qmlProjectSourceId, qtQuickProjectSourceId}, - {projectData1, projectData2, projectData3}}); + {directoryInfo1, directoryInfo2, directoryInfo3}}); storage.synchronize( - SynchronizationPackage{{qmlProjectSourceId, qtQuickProjectSourceId}, {projectData1}}); + SynchronizationPackage{{qmlProjectSourceId, qtQuickProjectSourceId}, {directoryInfo1}}); - ASSERT_THAT(storage.fetchProjectDatas({qmlProjectSourceId, qtQuickProjectSourceId}), - UnorderedElementsAre(projectData1)); + ASSERT_THAT(storage.fetchDirectoryInfos({qmlProjectSourceId, qtQuickProjectSourceId}), + UnorderedElementsAre(directoryInfo1)); } -TEST_F(ProjectStorage, update_project_data_file_type) +TEST_F(ProjectStorage, update_directory_info_file_type) { - Storage::Synchronization::ProjectData projectData1{qmlProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::ProjectData projectData2{qmlProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectSourceId, sourceId2, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::ProjectData projectData2b{qmlProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo2b{qmlProjectSourceId, sourceId2, qmlModuleId, Storage::Synchronization::FileType::QmlTypes}; - Storage::Synchronization::ProjectData projectData3{qtQuickProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectSourceId, sourceId3, qtQuickModuleId, Storage::Synchronization::FileType::QmlTypes}; storage.synchronize(SynchronizationPackage{{qmlProjectSourceId, qtQuickProjectSourceId}, - {projectData1, projectData2, projectData3}}); + {directoryInfo1, directoryInfo2, directoryInfo3}}); - storage.synchronize(SynchronizationPackage{{qmlProjectSourceId}, {projectData1, projectData2b}}); + storage.synchronize(SynchronizationPackage{{qmlProjectSourceId}, {directoryInfo1, directoryInfo2b}}); - ASSERT_THAT(storage.fetchProjectDatas({qmlProjectSourceId, qtQuickProjectSourceId}), - UnorderedElementsAre(projectData1, projectData2b, projectData3)); + ASSERT_THAT(storage.fetchDirectoryInfos({qmlProjectSourceId, qtQuickProjectSourceId}), + UnorderedElementsAre(directoryInfo1, directoryInfo2b, directoryInfo3)); } -TEST_F(ProjectStorage, update_project_data_module_id) +TEST_F(ProjectStorage, update_directory_info_module_id) { - Storage::Synchronization::ProjectData projectData1{qmlProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::ProjectData projectData2{qmlProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectSourceId, sourceId3, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::ProjectData projectData2b{qmlProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo2b{qmlProjectSourceId, sourceId3, qtQuickModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::ProjectData projectData3{qtQuickProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectSourceId, sourceId2, qtQuickModuleId, Storage::Synchronization::FileType::QmlTypes}; storage.synchronize(SynchronizationPackage{{qmlProjectSourceId, qtQuickProjectSourceId}, - {projectData1, projectData2, projectData3}}); + {directoryInfo1, directoryInfo2, directoryInfo3}}); - storage.synchronize(SynchronizationPackage{{qmlProjectSourceId}, {projectData1, projectData2b}}); + storage.synchronize(SynchronizationPackage{{qmlProjectSourceId}, {directoryInfo1, directoryInfo2b}}); - ASSERT_THAT(storage.fetchProjectDatas({qmlProjectSourceId, qtQuickProjectSourceId}), - UnorderedElementsAre(projectData1, projectData2b, projectData3)); + ASSERT_THAT(storage.fetchDirectoryInfos({qmlProjectSourceId, qtQuickProjectSourceId}), + UnorderedElementsAre(directoryInfo1, directoryInfo2b, directoryInfo3)); } -TEST_F(ProjectStorage, throw_for_invalid_source_id_in_project_data) +TEST_F(ProjectStorage, throw_for_invalid_source_id_in_directory_info) { - Storage::Synchronization::ProjectData projectData1{qmlProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceId, SourceId{}, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - ASSERT_THROW(storage.synchronize(SynchronizationPackage{{qmlProjectSourceId}, {projectData1}}), - QmlDesigner::ProjectDataHasInvalidSourceId); + ASSERT_THROW(storage.synchronize(SynchronizationPackage{{qmlProjectSourceId}, {directoryInfo1}}), + QmlDesigner::DirectoryInfoHasInvalidSourceId); } -TEST_F(ProjectStorage, insert_project_data_with_invalid_module_id) +TEST_F(ProjectStorage, insert_directory_info_with_invalid_module_id) { - Storage::Synchronization::ProjectData projectData1{qmlProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceId, sourceId1, ModuleId{}, Storage::Synchronization::FileType::QmlDocument}; - storage.synchronize(SynchronizationPackage{{qmlProjectSourceId}, {projectData1}}); + storage.synchronize(SynchronizationPackage{{qmlProjectSourceId}, {directoryInfo1}}); - ASSERT_THAT(storage.fetchProjectDatas({qmlProjectSourceId, qtQuickProjectSourceId}), - UnorderedElementsAre(projectData1)); + ASSERT_THAT(storage.fetchDirectoryInfos({qmlProjectSourceId, qtQuickProjectSourceId}), + UnorderedElementsAre(directoryInfo1)); } -TEST_F(ProjectStorage, update_project_data_with_invalid_module_id) +TEST_F(ProjectStorage, update_directory_info_with_invalid_module_id) { - Storage::Synchronization::ProjectData projectData1{qmlProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - storage.synchronize(SynchronizationPackage{{qmlProjectSourceId}, {projectData1}}); - projectData1.moduleId = ModuleId{}; + storage.synchronize(SynchronizationPackage{{qmlProjectSourceId}, {directoryInfo1}}); + directoryInfo1.moduleId = ModuleId{}; - storage.synchronize(SynchronizationPackage{{qmlProjectSourceId}, {projectData1}}); + storage.synchronize(SynchronizationPackage{{qmlProjectSourceId}, {directoryInfo1}}); - ASSERT_THAT(storage.fetchProjectDatas({qmlProjectSourceId, qtQuickProjectSourceId}), - UnorderedElementsAre(projectData1)); + ASSERT_THAT(storage.fetchDirectoryInfos({qmlProjectSourceId, qtQuickProjectSourceId}), + UnorderedElementsAre(directoryInfo1)); } -TEST_F(ProjectStorage, throw_for_updating_with_invalid_project_source_id_in_project_data) +TEST_F(ProjectStorage, throw_for_updating_with_invalid_project_source_id_in_directory_info) { - Storage::Synchronization::ProjectData projectData1{SourceId{}, + Storage::Synchronization::DirectoryInfo directoryInfo1{SourceId{}, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - ASSERT_THROW(storage.synchronize(SynchronizationPackage{{qmlProjectSourceId}, {projectData1}}), - QmlDesigner::ProjectDataHasInvalidProjectSourceId); + ASSERT_THROW(storage.synchronize(SynchronizationPackage{{qmlProjectSourceId}, {directoryInfo1}}), + QmlDesigner::DirectoryInfoHasInvalidProjectSourceId); } -TEST_F(ProjectStorage, fetch_project_datas_by_directory_source_ids) +TEST_F(ProjectStorage, fetch_directory_infos_by_directory_source_ids) { - Storage::Synchronization::ProjectData projectData1{qmlProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::ProjectData projectData2{qmlProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectSourceId, sourceId2, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::ProjectData projectData3{qtQuickProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectSourceId, sourceId3, qtQuickModuleId, Storage::Synchronization::FileType::QmlTypes}; storage.synchronize(SynchronizationPackage{{qmlProjectSourceId, qtQuickProjectSourceId}, - {projectData1, projectData2, projectData3}}); + {directoryInfo1, directoryInfo2, directoryInfo3}}); - auto projectDatas = storage.fetchProjectDatas({qmlProjectSourceId, qtQuickProjectSourceId}); + auto directoryInfos = storage.fetchDirectoryInfos({qmlProjectSourceId, qtQuickProjectSourceId}); - ASSERT_THAT(projectDatas, UnorderedElementsAre(projectData1, projectData2, projectData3)); + ASSERT_THAT(directoryInfos, UnorderedElementsAre(directoryInfo1, directoryInfo2, directoryInfo3)); } -TEST_F(ProjectStorage, fetch_project_datas_by_directory_source_id) +TEST_F(ProjectStorage, fetch_directory_infos_by_directory_source_id) { - Storage::Synchronization::ProjectData projectData1{qmlProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::ProjectData projectData2{qmlProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectSourceId, sourceId2, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::ProjectData projectData3{qtQuickProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectSourceId, sourceId3, qtQuickModuleId, Storage::Synchronization::FileType::QmlTypes}; storage.synchronize(SynchronizationPackage{{qmlProjectSourceId, qtQuickProjectSourceId}, - {projectData1, projectData2, projectData3}}); + {directoryInfo1, directoryInfo2, directoryInfo3}}); + + auto directoryInfo = storage.fetchDirectoryInfos(qmlProjectSourceId); + + ASSERT_THAT(directoryInfo, UnorderedElementsAre(directoryInfo1, directoryInfo2)); +} + +TEST_F(ProjectStorage, fetch_directory_infos_by_directory_source_id_and_file_type) +{ + Storage::Synchronization::DirectoryInfo directoryInfo1{ + qmlProjectSourceId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; + Storage::Synchronization::DirectoryInfo directoryInfo2{ + qmlProjectSourceId, sourceId2, ModuleId{}, Storage::Synchronization::FileType::Directory}; + Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectSourceId, + sourceId3, + qtQuickModuleId, + Storage::Synchronization::FileType::QmlTypes}; + Storage::Synchronization::DirectoryInfo directoryInfo4{ + qmlProjectSourceId, sourceId4, ModuleId{}, Storage::Synchronization::FileType::Directory}; + storage.synchronize( + SynchronizationPackage{{qmlProjectSourceId, qtQuickProjectSourceId}, + {directoryInfo1, directoryInfo2, directoryInfo3, directoryInfo4}}); - auto projectData = storage.fetchProjectDatas(qmlProjectSourceId); + auto directoryInfo = storage.fetchDirectoryInfos(qmlProjectSourceId, + Storage::Synchronization::FileType::Directory); - ASSERT_THAT(projectData, UnorderedElementsAre(projectData1, projectData2)); + ASSERT_THAT(directoryInfo, UnorderedElementsAre(directoryInfo2, directoryInfo4)); } -TEST_F(ProjectStorage, fetch_project_data_by_source_ids) +TEST_F(ProjectStorage, fetch_subdirectory_source_ids) { - Storage::Synchronization::ProjectData projectData1{qmlProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo1{ + qmlProjectSourceId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; + Storage::Synchronization::DirectoryInfo directoryInfo2{ + qmlProjectSourceId, sourceId2, ModuleId{}, Storage::Synchronization::FileType::Directory}; + Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectSourceId, + sourceId3, + qtQuickModuleId, + Storage::Synchronization::FileType::QmlTypes}; + Storage::Synchronization::DirectoryInfo directoryInfo4{ + qmlProjectSourceId, sourceId4, ModuleId{}, Storage::Synchronization::FileType::Directory}; + storage.synchronize( + SynchronizationPackage{{qmlProjectSourceId, qtQuickProjectSourceId}, + {directoryInfo1, directoryInfo2, directoryInfo3, directoryInfo4}}); + + auto directoryInfo = storage.fetchSubdirectorySourceIds(qmlProjectSourceId); + + ASSERT_THAT(directoryInfo, UnorderedElementsAre(sourceId2, sourceId4)); +} + +TEST_F(ProjectStorage, fetch_directory_info_by_source_ids) +{ + Storage::Synchronization::DirectoryInfo directoryInfo1{qmlProjectSourceId, sourceId1, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::ProjectData projectData2{qmlProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo2{qmlProjectSourceId, sourceId2, qmlModuleId, Storage::Synchronization::FileType::QmlDocument}; - Storage::Synchronization::ProjectData projectData3{qtQuickProjectSourceId, + Storage::Synchronization::DirectoryInfo directoryInfo3{qtQuickProjectSourceId, sourceId3, qtQuickModuleId, Storage::Synchronization::FileType::QmlTypes}; storage.synchronize(SynchronizationPackage{{qmlProjectSourceId, qtQuickProjectSourceId}, - {projectData1, projectData2, projectData3}}); + {directoryInfo1, directoryInfo2, directoryInfo3}}); - auto projectData = storage.fetchProjectData({sourceId2}); + auto directoryInfo = storage.fetchDirectoryInfo({sourceId2}); - ASSERT_THAT(projectData, Eq(projectData2)); + ASSERT_THAT(directoryInfo, Eq(directoryInfo2)); } TEST_F(ProjectStorage, exclude_exported_types) @@ -5442,7 +5770,7 @@ TEST_F(ProjectStorage, module_exported_import_with_indirect_different_versions) TEST_F(ProjectStorage, module_exported_import_prevent_collision_if_module_is_indirectly_reexported_multiple_times) { - ModuleId qtQuick4DModuleId{storage.moduleId("QtQuick4D")}; + ModuleId qtQuick4DModuleId{storage.moduleId("QtQuick4D", ModuleKind::QmlLibrary)}; auto package{createModuleExportedImportSynchronizationPackage()}; package.imports.emplace_back(qtQuickModuleId, Storage::Version{1}, sourceId5); package.moduleExportedImports.emplace_back(qtQuick4DModuleId, @@ -5498,8 +5826,8 @@ TEST_F(ProjectStorage, TEST_F(ProjectStorage, distinguish_between_import_kinds) { - ModuleId qml1ModuleId{storage.moduleId("Qml1")}; - ModuleId qml11ModuleId{storage.moduleId("Qml11")}; + ModuleId qml1ModuleId{storage.moduleId("Qml1", ModuleKind::QmlLibrary)}; + ModuleId qml11ModuleId{storage.moduleId("Qml11", ModuleKind::QmlLibrary)}; auto package{createSimpleSynchronizationPackage()}; package.moduleDependencies.emplace_back(qmlModuleId, Storage::Version{}, sourceId1); package.moduleDependencies.emplace_back(qml1ModuleId, Storage::Version{1}, sourceId1); @@ -6683,12 +7011,10 @@ TEST_F(ProjectStorage, get_type) auto package{createSimpleSynchronizationPackage()}; storage.synchronize(package); auto typeId = fetchTypeId(sourceId1, "QQuickItem"); - auto defaultPropertyName = storage.fetchTypeByTypeId(typeId).defaultPropertyName; - auto defaultPropertyId = storage.propertyDeclarationId(typeId, defaultPropertyName); auto type = storage.type(typeId); - ASSERT_THAT(type, Optional(IsInfoType(defaultPropertyId, sourceId1, TypeTraitsKind::Reference))); + ASSERT_THAT(type, Optional(IsInfoType(sourceId1, TypeTraitsKind::Reference))); } TEST_F(ProjectStorage, dont_get_type_for_invalid_id) @@ -6701,6 +7027,58 @@ TEST_F(ProjectStorage, dont_get_type_for_invalid_id) ASSERT_THAT(type, Eq(std::nullopt)); } +TEST_F(ProjectStorage, get_default_property_declarartion_id) +{ + auto package{createSimpleSynchronizationPackage()}; + storage.synchronize(package); + auto typeId = fetchTypeId(sourceId1, "QQuickItem"); + auto defaultPropertyName = storage.fetchTypeByTypeId(typeId).defaultPropertyName; + auto defaultPropertyId = storage.propertyDeclarationId(typeId, defaultPropertyName); + + auto propertyId = storage.defaultPropertyDeclarationId(typeId); + + ASSERT_THAT(propertyId, defaultPropertyId); +} + +TEST_F(ProjectStorage, get_default_property_declarartion_id_in_base_type) +{ + auto package{createSynchronizationPackageWithAliases()}; + storage.synchronize(package); + auto baseTypeId = fetchTypeId(sourceId1, "QQuickItem"); + auto defaultPropertyName = storage.fetchTypeByTypeId(baseTypeId).defaultPropertyName; + auto defaultPropertyId = storage.propertyDeclarationId(baseTypeId, defaultPropertyName); + auto typeId = fetchTypeId(sourceId3, "QAliasItem"); + + auto propertyId = storage.defaultPropertyDeclarationId(typeId); + + ASSERT_THAT(propertyId, defaultPropertyId); +} + +TEST_F(ProjectStorage, do_not_get_default_property_declarartion_id_wrong_type_in_property_chain) +{ + auto package{createSynchronizationPackageWithAliases()}; + package.types[1].defaultPropertyName = "objects"; + storage.synchronize(package); + auto baseTypeId = fetchTypeId(sourceId1, "QQuickItem"); + auto defaultPropertyName = storage.fetchTypeByTypeId(baseTypeId).defaultPropertyName; + auto defaultPropertyId = storage.propertyDeclarationId(baseTypeId, defaultPropertyName); + auto typeId = fetchTypeId(sourceId3, "QAliasItem"); + + auto propertyId = storage.defaultPropertyDeclarationId(typeId); + + ASSERT_THAT(propertyId, defaultPropertyId); +} + +TEST_F(ProjectStorage, get_invalid_default_property_declarartion_id_for_invalid_type) +{ + auto package{createSimpleSynchronizationPackage()}; + storage.synchronize(package); + + auto propertyId = storage.defaultPropertyDeclarationId(TypeId()); + + ASSERT_FALSE(propertyId); +} + TEST_F(ProjectStorage, get_common_type) { auto package{createSimpleSynchronizationPackage()}; @@ -7116,6 +7494,46 @@ TEST_F(ProjectStorage, synchronize_document_imports_adds_import) ASSERT_TRUE(storage.importId(imports.back())); } +TEST_F(ProjectStorage, + synchronize_document_imports_removes_import_notifies_that_type_name_cannot_be_resolved) +{ + auto package{createVerySimpleSynchronizationPackage()}; + package.imports.emplace_back(qmlModuleId, Storage::Version{}, sourceId1); + package.types[0].prototype = Storage::Synchronization::ImportedType{"Object"}; + storage.synchronize(package); + + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("Object"), sourceId1)); + + storage.synchronizeDocumentImports({}, sourceId1); +} + +TEST_F(ProjectStorage, synchronize_document_imports_removes_import_which_makes_prototype_unresolved) +{ + auto package{createVerySimpleSynchronizationPackage()}; + package.imports.emplace_back(qmlModuleId, Storage::Version{}, sourceId1); + package.types[0].prototype = Storage::Synchronization::ImportedType{"Object"}; + storage.synchronize(package); + + storage.synchronizeDocumentImports({}, sourceId1); + + ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), + IsPrototypeId(IsUnresolvedTypeId())); +} + +TEST_F(ProjectStorage, synchronize_document_imports_adds_import_which_makes_prototype_resolved) +{ + auto package{createVerySimpleSynchronizationPackage()}; + package.types[0].prototype = Storage::Synchronization::ImportedType{"Object"}; + storage.synchronize(package); + Storage::Imports imports; + imports.emplace_back(qmlModuleId, Storage::Version{}, sourceId1); + + storage.synchronizeDocumentImports(imports, sourceId1); + + ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), + IsPrototypeId(fetchTypeId(sourceId2, "QObject"))); +} + TEST_F(ProjectStorage, get_exported_type_names) { auto package{createSimpleSynchronizationPackage()}; @@ -7228,7 +7646,7 @@ TEST_F(ProjectStorage, synchronize_property_editor_adds_path) auto package{createPropertyEditorPathsSynchronizationPackage()}; package.propertyEditorQmlPaths.pop_back(); storage.synchronize(package); - package.propertyEditorQmlPaths.emplace_back(qtQuickModuleId, "Item3D", sourceId3, sourceIdPath); + package.propertyEditorQmlPaths.emplace_back(qtQuickModuleId, "Item3D", sourceId3, sourceIdPath6); storage.synchronize(package); @@ -7240,7 +7658,7 @@ TEST_F(ProjectStorage, synchronize_property_editor_adds_path) TEST_F(ProjectStorage, synchronize_property_editor_with_non_existing_type_name) { auto package{createPropertyEditorPathsSynchronizationPackage()}; - package.propertyEditorQmlPaths.emplace_back(qtQuickModuleId, "Item4D", sourceId4, sourceIdPath); + package.propertyEditorQmlPaths.emplace_back(qtQuickModuleId, "Item4D", sourceId4, sourceIdPath6); storage.synchronize(package); @@ -7260,6 +7678,18 @@ TEST_F(ProjectStorage, call_remove_type_ids_in_observer_after_synchronization) storage.synchronize(package); } +TEST_F(ProjectStorage, do_not_synchronize_type_annotations_without_type) +{ + SynchronizationPackage package; + package.typeAnnotations = createTypeAnnotions(); + package.updatedTypeAnnotationSourceIds = createUpdatedTypeAnnotionSourceIds( + package.typeAnnotations); + + storage.synchronize(package); + + ASSERT_THAT(storage.allItemLibraryEntries(), IsEmpty()); +} + TEST_F(ProjectStorage, synchronize_type_annotation_type_traits) { auto package{createSimpleSynchronizationPackage()}; @@ -7275,13 +7705,29 @@ TEST_F(ProjectStorage, synchronize_type_annotation_type_traits) ASSERT_THAT(storage.type(fetchTypeId(sourceId2, "QObject"))->traits, traits); } +TEST_F(ProjectStorage, synchronize_type_annotation_type_traits_for_prototype_heirs) +{ + auto package{createSimpleSynchronizationPackage()}; + package.typeAnnotations = createTypeAnnotions(); + package.typeAnnotations.pop_back(); + package.updatedTypeAnnotationSourceIds = createUpdatedTypeAnnotionSourceIds( + package.typeAnnotations); + TypeTraits traits{TypeTraitsKind::Reference}; + traits.canBeContainer = FlagIs::True; + traits.visibleInLibrary = FlagIs::True; + + storage.synchronize(package); + + ASSERT_THAT(storage.type(fetchTypeId(sourceId1, "QQuickItem"))->traits, traits); +} + TEST_F(ProjectStorage, synchronize_updates_type_annotation_type_traits) { auto package{createSimpleSynchronizationPackage()}; storage.synchronize(package); SynchronizationPackage annotationPackage; annotationPackage.typeAnnotations = createTypeAnnotions(); - package.updatedTypeAnnotationSourceIds = createUpdatedTypeAnnotionSourceIds( + annotationPackage.updatedTypeAnnotationSourceIds = createUpdatedTypeAnnotionSourceIds( package.typeAnnotations); TypeTraits traits{TypeTraitsKind::Reference}; traits.canBeContainer = FlagIs::True; @@ -7292,25 +7738,47 @@ TEST_F(ProjectStorage, synchronize_updates_type_annotation_type_traits) ASSERT_THAT(storage.type(fetchTypeId(sourceId2, "QObject"))->traits, traits); } +TEST_F(ProjectStorage, synchronize_updates_type_annotation_type_traits_for_prototype_heirs) +{ + auto package{createSimpleSynchronizationPackage()}; + storage.synchronize(package); + SynchronizationPackage annotationPackage; + annotationPackage.typeAnnotations = createTypeAnnotions(); + annotationPackage.typeAnnotations.pop_back(); + annotationPackage.updatedTypeAnnotationSourceIds = createUpdatedTypeAnnotionSourceIds( + package.typeAnnotations); + TypeTraits traits{TypeTraitsKind::Reference}; + traits.canBeContainer = FlagIs::True; + traits.visibleInLibrary = FlagIs::True; + + storage.synchronize(annotationPackage); + + ASSERT_THAT(storage.type(fetchTypeId(sourceId1, "QQuickItem"))->traits, traits); +} + TEST_F(ProjectStorage, synchronize_clears_annotation_type_traits_if_annotation_was_removed) { + +} + +TEST_F(ProjectStorage, + synchronize_clears_annotation_type_traits_if_annotation_was_removed_for_prototype_heirs) +{ auto package{createSimpleSynchronizationPackage()}; package.typeAnnotations = createTypeAnnotions(); package.updatedTypeAnnotationSourceIds = createUpdatedTypeAnnotionSourceIds( package.typeAnnotations); - storage.synchronize(package); package.typeAnnotations[0].traits.isStackedContainer = FlagIs::True; - TypeTraits traits{TypeTraitsKind::Reference}; - traits.canBeContainer = FlagIs::True; - traits.visibleInLibrary = FlagIs::True; - traits.isStackedContainer = FlagIs::True; + storage.synchronize(package); + package.typeAnnotations.pop_back(); storage.synchronize(package); - ASSERT_THAT(storage.type(fetchTypeId(sourceId2, "QObject"))->traits, traits); + ASSERT_THAT(storage.type(fetchTypeId(sourceId1, "QQuickItem"))->traits, + package.typeAnnotations[0].traits); } -TEST_F(ProjectStorage, synchronize_updatesannotation_type_traits) +TEST_F(ProjectStorage, synchronize_updates_annotation_type_traits) { auto package{createSimpleSynchronizationPackage()}; package.typeAnnotations = createTypeAnnotions(); @@ -7414,6 +7882,18 @@ TEST_F(ProjectStorage, synchronize_removes_type_hints) TEST_F(ProjectStorage, return_empty_type_hints_if_no_type_hints_exists) { auto package{createSimpleSynchronizationPackage()}; + package.typeAnnotations = createTypeAnnotions(); + package.typeAnnotations[0].hintsJson.clear(); + storage.synchronize(package); + + auto typeHints = storage.typeHints(fetchTypeId(sourceId2, "QObject")); + + ASSERT_THAT(typeHints, IsEmpty()); +} + +TEST_F(ProjectStorage, return_empty_type_hints_if_no_type_annotaion_exists) +{ + auto package{createSimpleSynchronizationPackage()}; storage.synchronize(package); auto typeHints = storage.typeHints(fetchTypeId(sourceId2, "QObject")); @@ -7441,6 +7921,7 @@ TEST_F(ProjectStorage, synchronize_item_library_entries) storage.allItemLibraryEntries(), UnorderedElementsAre( IsItemLibraryEntry(fetchTypeId(sourceId2, "QObject"), + "Object", "Foo", "/path/icon", "Basic Items", @@ -7452,6 +7933,7 @@ TEST_F(ProjectStorage, synchronize_item_library_entries) UnorderedElementsAre("/path/templates/frame.png", "/path/templates/frame.frag")), IsItemLibraryEntry(fetchTypeId(sourceId2, "QObject"), + "Object", "Bar", "/path/icon2", "Basic Items", @@ -7462,6 +7944,7 @@ TEST_F(ProjectStorage, synchronize_item_library_entries) IsEmpty()), IsItemLibraryEntry(fetchTypeId(sourceId1, "QQuickItem"), "Item", + "Item", "/path/icon3", "Advanced Items", "QtQuick", @@ -7486,7 +7969,7 @@ TEST_F(ProjectStorage, synchronize_removes_item_library_entries) ASSERT_THAT(storage.allItemLibraryEntries(), IsEmpty()); } -TEST_F(ProjectStorage, synchronize_udpates_item_library_entries) +TEST_F(ProjectStorage, synchronize_updates_item_library_entries) { auto package{createSimpleSynchronizationPackage()}; package.typeAnnotations = createTypeAnnotions(); @@ -7501,6 +7984,7 @@ TEST_F(ProjectStorage, synchronize_udpates_item_library_entries) ASSERT_THAT(storage.itemLibraryEntries(fetchTypeId(sourceId2, "QObject")), ElementsAre( IsItemLibraryEntry(fetchTypeId(sourceId2, "QObject"), + "Object", "Foo", "/path/icon", "Basic Items", @@ -7512,6 +7996,59 @@ TEST_F(ProjectStorage, synchronize_udpates_item_library_entries) IsEmpty()))); } +TEST_F(ProjectStorage, synchronize_updates_item_library_entries_with_empty_entries) +{ + auto package{createSimpleSynchronizationPackage()}; + package.typeAnnotations = createTypeAnnotions(); + package.updatedTypeAnnotationSourceIds = createUpdatedTypeAnnotionSourceIds( + package.typeAnnotations); + storage.synchronize(package); + package.typeAnnotations[0].itemLibraryJson.clear(); + + storage.synchronize(package); + + ASSERT_THAT(storage.itemLibraryEntries(fetchTypeId(sourceId2, "QObject")), IsEmpty()); +} + +TEST_F(ProjectStorage, synchronize_type_annotation_directory_source_id) +{ + auto package{createSimpleSynchronizationPackage()}; + package.typeAnnotations = createTypeAnnotions(); + package.updatedTypeAnnotationSourceIds = createUpdatedTypeAnnotionSourceIds( + package.typeAnnotations); + + storage.synchronize(package); + + ASSERT_THAT(storage.typeAnnotationSourceIds(sourceIdPath6), + UnorderedElementsAre(sourceId4, sourceId5)); +} + +TEST_F(ProjectStorage, get_type_annotation_source_ids) +{ + auto package{createSimpleSynchronizationPackage()}; + package.typeAnnotations = createTypeAnnotions(); + package.updatedTypeAnnotationSourceIds = createUpdatedTypeAnnotionSourceIds( + package.typeAnnotations); + storage.synchronize(package); + + auto sourceIds = storage.typeAnnotationSourceIds(sourceIdPath6); + + ASSERT_THAT(sourceIds, UnorderedElementsAre(sourceId4, sourceId5)); +} + +TEST_F(ProjectStorage, get_type_annotation_directory_source_ids) +{ + auto package{createSimpleSynchronizationPackage()}; + package.typeAnnotations = createExtendedTypeAnnotations(); + package.updatedTypeAnnotationSourceIds = createUpdatedTypeAnnotionSourceIds( + package.typeAnnotations); + storage.synchronize(package); + + auto sourceIds = storage.typeAnnotationDirectorySourceIds(); + + ASSERT_THAT(sourceIds, ElementsAre(sourceIdPath1, sourceIdPath6)); +} + TEST_F(ProjectStorage, get_all_item_library_entries) { auto package{createSimpleSynchronizationPackage()}; @@ -7526,6 +8063,7 @@ TEST_F(ProjectStorage, get_all_item_library_entries) entries, UnorderedElementsAre( IsItemLibraryEntry(fetchTypeId(sourceId2, "QObject"), + "Object", "Foo", "/path/icon", "Basic Items", @@ -7537,6 +8075,7 @@ TEST_F(ProjectStorage, get_all_item_library_entries) UnorderedElementsAre("/path/templates/frame.png", "/path/templates/frame.frag")), IsItemLibraryEntry(fetchTypeId(sourceId2, "QObject"), + "Object", "Bar", "/path/icon2", "Basic Items", @@ -7547,6 +8086,7 @@ TEST_F(ProjectStorage, get_all_item_library_entries) IsEmpty()), IsItemLibraryEntry(fetchTypeId(sourceId1, "QQuickItem"), "Item", + "Item", "/path/icon3", "Advanced Items", "QtQuick", @@ -7557,6 +8097,32 @@ TEST_F(ProjectStorage, get_all_item_library_entries) IsEmpty()))); } +TEST_F(ProjectStorage, get_all_item_library_entries_handles_no_entries) +{ + auto package{createSimpleSynchronizationPackage()}; + package.typeAnnotations = createTypeAnnotions(); + package.typeAnnotations[0].itemLibraryJson.clear(); + package.updatedTypeAnnotationSourceIds = createUpdatedTypeAnnotionSourceIds( + package.typeAnnotations); + storage.synchronize(package); + + auto entries = storage.allItemLibraryEntries(); + + ASSERT_THAT(entries, + UnorderedElementsAre( + IsItemLibraryEntry(fetchTypeId(sourceId1, "QQuickItem"), + "Item", + "Item", + "/path/icon3", + "Advanced Items", + "QtQuick", + "Item is an Object", + "", + UnorderedElementsAre(IsItemLibraryProperty("x", "double", 1), + IsItemLibraryProperty("y", "double", 2)), + IsEmpty()))); +} + TEST_F(ProjectStorage, get_item_library_entries_by_type_id) { auto package{createSimpleSynchronizationPackage()}; @@ -7572,6 +8138,7 @@ TEST_F(ProjectStorage, get_item_library_entries_by_type_id) entries, UnorderedElementsAre( IsItemLibraryEntry(fetchTypeId(sourceId2, "QObject"), + "Object", "Foo", "/path/icon", "Basic Items", @@ -7583,6 +8150,7 @@ TEST_F(ProjectStorage, get_item_library_entries_by_type_id) UnorderedElementsAre("/path/templates/frame.png", "/path/templates/frame.frag")), IsItemLibraryEntry(fetchTypeId(sourceId2, "QObject"), + "Object", "Bar", "/path/icon2", "Basic Items", @@ -7606,6 +8174,21 @@ TEST_F(ProjectStorage, get_no_item_library_entries_if_type_id_is_invalid) ASSERT_THAT(entries, IsEmpty()); } +TEST_F(ProjectStorage, get_no_item_library_entries_by_type_id_for_no_entries) +{ + auto package{createSimpleSynchronizationPackage()}; + package.typeAnnotations = createTypeAnnotions(); + package.typeAnnotations[0].itemLibraryJson.clear(); + package.updatedTypeAnnotationSourceIds = createUpdatedTypeAnnotionSourceIds( + package.typeAnnotations); + storage.synchronize(package); + auto typeId = fetchTypeId(sourceId2, "QObject"); + + auto entries = storage.itemLibraryEntries(typeId); + + ASSERT_THAT(entries, IsEmpty()); +} + TEST_F(ProjectStorage, get_item_library_entries_by_source_id) { auto package{createSimpleSynchronizationPackage()}; @@ -7620,6 +8203,7 @@ TEST_F(ProjectStorage, get_item_library_entries_by_source_id) entries, UnorderedElementsAre( IsItemLibraryEntry(fetchTypeId(sourceId2, "QObject"), + "Object", "Foo", "/path/icon", "Basic Items", @@ -7631,6 +8215,7 @@ TEST_F(ProjectStorage, get_item_library_entries_by_source_id) UnorderedElementsAre("/path/templates/frame.png", "/path/templates/frame.frag")), IsItemLibraryEntry(fetchTypeId(sourceId2, "QObject"), + "Object", "Bar", "/path/icon2", "Basic Items", @@ -7641,6 +8226,20 @@ TEST_F(ProjectStorage, get_item_library_entries_by_source_id) IsEmpty()))); } +TEST_F(ProjectStorage, get_no_item_library_entries_by_source_id_for_no_entries) +{ + auto package{createSimpleSynchronizationPackage()}; + package.typeAnnotations = createTypeAnnotions(); + package.typeAnnotations[0].itemLibraryJson.clear(); + package.updatedTypeAnnotationSourceIds = createUpdatedTypeAnnotionSourceIds( + package.typeAnnotations); + storage.synchronize(package); + + auto entries = storage.itemLibraryEntries(sourceId2); + + ASSERT_THAT(entries, IsEmpty()); +} + TEST_F(ProjectStorage, return_type_ids_for_module_id) { auto package{createBuiltinSynchronizationPackage()}; @@ -7683,4 +8282,105 @@ TEST_F(ProjectStorage, get_no_hair_ids_for_invalid_type_id) ASSERT_THAT(heirIds, IsEmpty()); } + +TEST_F(ProjectStorage, + removed_document_import_notifies_for_prototypes_that_type_name_cannot_be_resolved) +{ + auto package{createVerySimpleSynchronizationPackage()}; + package.moduleDependencies.emplace_back(qmlNativeModuleId, Storage::Version{}, sourceId1); + package.types[0].prototype = Storage::Synchronization::ImportedType{"QObject"}; + storage.synchronize(package); + package.moduleDependencies.clear(); + package.types.clear(); + package.updatedSourceIds.clear(); + package.updatedModuleDependencySourceIds = {sourceId1}; + + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("QObject"), sourceId1)); + + storage.synchronize(package); +} + +TEST_F(ProjectStorage, + removed_document_import_notifies_for_extensions_that_type_name_cannot_be_resolved) +{ + auto package{createVerySimpleSynchronizationPackage()}; + package.moduleDependencies.emplace_back(qmlNativeModuleId, Storage::Version{}, sourceId1); + package.types[0].extension = Storage::Synchronization::ImportedType{"QObject"}; + storage.synchronize(package); + package.moduleDependencies.clear(); + package.types.clear(); + package.updatedSourceIds.clear(); + package.updatedModuleDependencySourceIds = {sourceId1}; + + EXPECT_CALL(errorNotifierMock, typeNameCannotBeResolved(Eq("QObject"), sourceId1)); + + storage.synchronize(package); +} + +TEST_F(ProjectStorage, removed_document_import_changes_prototype_to_unresolved) +{ + auto package{createVerySimpleSynchronizationPackage()}; + package.moduleDependencies.emplace_back(qmlNativeModuleId, Storage::Version{}, sourceId1); + package.types[0].prototype = Storage::Synchronization::ImportedType{"QObject"}; + storage.synchronize(package); + package.moduleDependencies.clear(); + package.types.clear(); + package.updatedSourceIds.clear(); + package.updatedModuleDependencySourceIds = {sourceId1}; + + storage.synchronize(package); + + ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), + Field(&Storage::Synchronization::Type::prototypeId, IsUnresolvedTypeId())); +} + +TEST_F(ProjectStorage, removed_document_import_changes_extension_to_unresolved) +{ + auto package{createVerySimpleSynchronizationPackage()}; + package.moduleDependencies.emplace_back(qmlNativeModuleId, Storage::Version{}, sourceId1); + package.types[0].extension = Storage::Synchronization::ImportedType{"QObject"}; + storage.synchronize(package); + package.moduleDependencies.clear(); + package.types.clear(); + package.updatedSourceIds.clear(); + package.updatedModuleDependencySourceIds = {sourceId1}; + + storage.synchronize(package); + + ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), + Field(&Storage::Synchronization::Type::extensionId, IsUnresolvedTypeId())); +} + +TEST_F(ProjectStorage, added_document_import_fixes_unresolved_prototype) +{ + auto package{createVerySimpleSynchronizationPackage()}; + package.types[0].prototype = Storage::Synchronization::ImportedType{"QObject"}; + storage.synchronize(package); + package.moduleDependencies.emplace_back(qmlNativeModuleId, Storage::Version{}, sourceId1); + package.types.clear(); + package.updatedSourceIds.clear(); + package.updatedModuleDependencySourceIds = {sourceId1}; + + storage.synchronize(package); + + ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), + IsPrototypeId(fetchTypeId(sourceId2, "QObject"))); +} + +TEST_F(ProjectStorage, added_document_import_fixes_unresolved_extension) +{ + auto package{createVerySimpleSynchronizationPackage()}; + package.types[0].extension = Storage::Synchronization::ImportedType{"QObject"}; + storage.synchronize(package); + package.moduleDependencies.emplace_back(qmlNativeModuleId, Storage::Version{}, sourceId1); + package.types.clear(); + package.updatedSourceIds.clear(); + package.updatedModuleDependencySourceIds = {sourceId1}; + + storage.synchronize(package); + + ASSERT_THAT(storage.fetchTypeByTypeId(fetchTypeId(sourceId1, "QQuickItem")), + IsExtensionId(fetchTypeId(sourceId2, "QObject"))); +} + } // namespace diff --git a/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp index d6ed96d0cf..771107ece7 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp @@ -3,10 +3,11 @@ #include "../utils/googletest.h" -#include "../mocks/filesystemmock.h" -#include "../mocks/mockqfilesystemwatcher.h" -#include "../mocks/mocktimer.h" -#include "../mocks/projectstoragepathwatchernotifiermock.h" +#include <filesystemmock.h> +#include <mockqfilesystemwatcher.h> +#include <mocktimer.h> +#include <projectstorageerrornotifiermock.h> +#include <projectstoragepathwatchernotifiermock.h> #include <projectstorage/projectstorage.h> #include <projectstorage/projectstoragepathwatcher.h> @@ -16,7 +17,7 @@ #include <utils/smallstring.h> namespace { -using SourcePathCache = QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage<Sqlite::Database>>; +using SourcePathCache = QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage>; using Watcher = QmlDesigner::ProjectStoragePathWatcher<NiceMock<MockQFileSytemWatcher>, NiceMock<MockTimer>, SourcePathCache>; @@ -39,21 +40,18 @@ using QmlDesigner::WatcherEntry; class ProjectStoragePathWatcher : public testing::Test { protected: - static void SetUpTestSuite() + struct StaticData { - static_database = std::make_unique<Sqlite::Database>(":memory:", Sqlite::JournalMode::Memory); + Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; + ProjectStorageErrorNotifierMock errorNotifierMock; + QmlDesigner::ProjectStorage storage{database, errorNotifierMock, database.isInitialized()}; + }; - static_projectStorage = std::make_unique<QmlDesigner::ProjectStorage<Sqlite::Database>>( - *static_database, static_database->isInitialized()); - } + static void SetUpTestSuite() { staticData = std::make_unique<StaticData>(); } - static void TearDownTestSuite() - { - static_projectStorage.reset(); - static_database.reset(); - } + static void TearDownTestSuite() { staticData.reset(); } - ~ProjectStoragePathWatcher() { static_projectStorage->resetForTestsOnly(); } + ~ProjectStoragePathWatcher() { storage.resetForTestsOnly(); } ProjectStoragePathWatcher() { @@ -79,10 +77,9 @@ protected: protected: NiceMock<ProjectStoragePathWatcherNotifierMock> notifier; NiceMock<FileSystemMock> mockFileSystem; - inline static std::unique_ptr<Sqlite::Database> static_database; - Sqlite::Database &database = *static_database; - inline static std::unique_ptr<QmlDesigner::ProjectStorage<Sqlite::Database>> static_projectStorage; - QmlDesigner::ProjectStorage<Sqlite::Database> &storage = *static_projectStorage; + inline static std::unique_ptr<StaticData> staticData; + Sqlite::Database &database = staticData->database; + QmlDesigner::ProjectStorage &storage = staticData->storage; SourcePathCache pathCache{storage}; Watcher watcher{pathCache, mockFileSystem, ¬ifier}; NiceMock<MockQFileSytemWatcher> &mockQFileSytemWatcher = watcher.fileSystemWatcher(); diff --git a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp index d9578d2f1b..e38f05349b 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp @@ -3,11 +3,14 @@ #include "../utils/googletest.h" -#include "../mocks/filesystemmock.h" -#include "../mocks/projectstoragemock.h" -#include "../mocks/projectstoragepathwatchermock.h" -#include "../mocks/qmldocumentparsermock.h" -#include "../mocks/qmltypesparsermock.h" +#include <filesystemmock.h> +#include <projectstorageerrornotifiermock.h> +#include <projectstoragemock.h> +#include <projectstoragepathwatchermock.h> +#include <qmldocumentparsermock.h> +#include <qmltypesparsermock.h> + +#include <projectstorage-matcher.h> #include <projectstorage/filestatuscache.h> #include <projectstorage/projectstorage.h> @@ -25,10 +28,11 @@ using QmlDesigner::SourceId; namespace Storage = QmlDesigner::Storage; using QmlDesigner::IdPaths; using QmlDesigner::Storage::Import; +using QmlDesigner::Storage::ModuleKind; +using QmlDesigner::Storage::Synchronization::DirectoryInfo; using QmlDesigner::Storage::Synchronization::FileType; using QmlDesigner::Storage::Synchronization::IsAutoVersion; using QmlDesigner::Storage::Synchronization::ModuleExportedImport; -using QmlDesigner::Storage::Synchronization::ProjectData; using QmlDesigner::Storage::Synchronization::SynchronizationPackage; using QmlDesigner::Storage::TypeTraits; using QmlDesigner::Storage::TypeTraitsKind; @@ -93,21 +97,21 @@ MATCHER_P3(IsFileStatus, && fileStatus.lastModified == lastModified; } -MATCHER_P4(IsProjectData, - projectSourceId, +MATCHER_P4(IsDirectoryInfo, + directorySourceId, sourceId, moduleId, fileType, std::string(negation ? "isn't " : "is ") - + PrintToString(Storage::Synchronization::ProjectData{ - projectSourceId, sourceId, moduleId, fileType})) + + PrintToString(Storage::Synchronization::DirectoryInfo{ + directorySourceId, sourceId, moduleId, fileType})) { - const Storage::Synchronization::ProjectData &projectData = arg; + const Storage::Synchronization::DirectoryInfo &directoryInfo = arg; - return compareInvalidAreTrue(projectData.projectSourceId, projectSourceId) - && projectData.sourceId == sourceId - && compareInvalidAreTrue(projectData.moduleId, moduleId) - && projectData.fileType == fileType; + return compareInvalidAreTrue(directoryInfo.directorySourceId, directorySourceId) + && directoryInfo.sourceId == sourceId + && compareInvalidAreTrue(directoryInfo.moduleId, moduleId) + && directoryInfo.fileType == fileType; } MATCHER(PackageIsEmpty, std::string(negation ? "isn't empty" : "is empty")) @@ -115,12 +119,14 @@ MATCHER(PackageIsEmpty, std::string(negation ? "isn't empty" : "is empty")) const Storage::Synchronization::SynchronizationPackage &package = arg; return package.imports.empty() && package.types.empty() && package.fileStatuses.empty() - && package.updatedSourceIds.empty() && package.projectDatas.empty() - && package.updatedFileStatusSourceIds.empty() && package.updatedProjectSourceIds.empty() - && package.moduleDependencies.empty() && package.updatedModuleDependencySourceIds.empty() + && package.updatedSourceIds.empty() && package.directoryInfos.empty() + && package.updatedFileStatusSourceIds.empty() + && package.updatedDirectoryInfoSourceIds.empty() && package.moduleDependencies.empty() + && package.updatedModuleDependencySourceIds.empty() && package.moduleExportedImports.empty() && package.updatedModuleIds.empty() && package.propertyEditorQmlPaths.empty() - && package.updatedPropertyEditorQmlPathSourceIds.empty(); + && package.updatedPropertyEditorQmlPathSourceIds.empty() + && package.typeAnnotations.empty() && package.updatedTypeAnnotationSourceIds.empty(); } template<typename ModuleIdMatcher, typename TypeNameMatcher, typename SourceIdMatcher> @@ -137,19 +143,16 @@ auto IsPropertyEditorQmlPath(const ModuleIdMatcher &moduleIdMatcher, class ProjectStorageUpdater : public testing::Test { public: - static void SetUpTestSuite() + struct StaticData { - static_database = std::make_unique<Sqlite::Database>(":memory:", Sqlite::JournalMode::Memory); + Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; + NiceMock<ProjectStorageErrorNotifierMock> errorNotifierMock; + QmlDesigner::ProjectStorage storage{database, errorNotifierMock, database.isInitialized()}; + }; - static_projectStorage = std::make_unique<QmlDesigner::ProjectStorage<Sqlite::Database>>( - *static_database, static_database->isInitialized()); - } + static void SetUpTestSuite() { staticData = std::make_unique<StaticData>(); } - static void TearDownTestSuite() - { - static_projectStorage.reset(); - static_database.reset(); - } + static void TearDownTestSuite() { staticData.reset(); } ProjectStorageUpdater() { @@ -168,7 +171,8 @@ public: secondSourceId, thirdSourceId, qmltypes1SourceId, - qmltypes2SourceId}); + qmltypes2SourceId, + itemLibraryPathSourceId}); setFilesAdded({qmldir1SourceId, qmldir2SourceId, qmldir3SourceId}); @@ -176,8 +180,8 @@ public: setQmlFileNames(u"/path", {"First.qml", "First2.qml", "Second.qml"}); - ON_CALL(projectStorageMock, moduleId(_)).WillByDefault([&](const auto &name) { - return storage.moduleId(name); + ON_CALL(projectStorageMock, moduleId(_, _)).WillByDefault([&](const auto &name, const auto &kind) { + return storage.moduleId(name, kind); }); firstType.prototype = Storage::Synchronization::ImportedType{"Object"}; @@ -222,7 +226,7 @@ public: }); } - ~ProjectStorageUpdater() { static_projectStorage->resetForTestsOnly(); } + ~ProjectStorageUpdater() { storage.resetForTestsOnly(); } void setFilesDontChanged(const QmlDesigner::SourceIds &sourceIds) { @@ -277,14 +281,14 @@ public: ON_CALL(fileSystemMock, qmlFileNames(Eq(directoryPath))).WillByDefault(Return(qmlFileNames)); } - void setProjectDatas(SourceId directoryPathSourceId, - const QmlDesigner::Storage::Synchronization::ProjectDatas &projectDatas) + void setDirectoryInfos(SourceId directoryPathSourceId, + const QmlDesigner::Storage::Synchronization::DirectoryInfos &directoryInfos) { - ON_CALL(projectStorageMock, fetchProjectDatas(Eq(directoryPathSourceId))) - .WillByDefault(Return(projectDatas)); - for (const ProjectData &projectData : projectDatas) { - ON_CALL(projectStorageMock, fetchProjectData(Eq(projectData.sourceId))) - .WillByDefault(Return(std::optional{projectData})); + ON_CALL(projectStorageMock, fetchDirectoryInfos(Eq(directoryPathSourceId))) + .WillByDefault(Return(directoryInfos)); + for (const DirectoryInfo &directoryInfo : directoryInfos) { + ON_CALL(projectStorageMock, fetchDirectoryInfo(Eq(directoryInfo.sourceId))) + .WillByDefault(Return(std::optional{directoryInfo})); } } @@ -298,17 +302,33 @@ public: EXPECT_CALL(fileSystemMock, contentAsQString(Eq(path))).WillRepeatedly(Return(content)); } + void setSubdirectoryPaths(QStringView directoryPath, const QStringList &subdirectoryPaths) + { + ON_CALL(fileSystemMock, subdirectories(Eq(directoryPath))).WillByDefault(Return(subdirectoryPaths)); + } + + void setSubdirectorySourceIds(SourceId directorySourceId, + const QmlDesigner::SmallSourceIds<32> &subdirectorySourceId) + { + ON_CALL(projectStorageMock, fetchSubdirectorySourceIds(Eq(directorySourceId))) + .WillByDefault(Return(subdirectorySourceId)); + } + + auto moduleId(Utils::SmallStringView name, ModuleKind kind) const + { + return storage.moduleId(name, kind); + } + protected: NiceMock<FileSystemMock> fileSystemMock; NiceMock<ProjectStorageMock> projectStorageMock; NiceMock<QmlTypesParserMock> qmlTypesParserMock; NiceMock<QmlDocumentParserMock> qmlDocumentParserMock; QmlDesigner::FileStatusCache fileStatusCache{fileSystemMock}; - inline static std::unique_ptr<Sqlite::Database> static_database; - Sqlite::Database &database = *static_database; - inline static std::unique_ptr<QmlDesigner::ProjectStorage<Sqlite::Database>> static_projectStorage; - QmlDesigner::ProjectStorage<Sqlite::Database> &storage = *static_projectStorage; - QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage<Sqlite::Database>> sourcePathCache{ + inline static std::unique_ptr<StaticData> staticData; + Sqlite::Database &database = staticData->database; + QmlDesigner::ProjectStorage &storage = staticData->storage; + QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage> sourcePathCache{ storage}; NiceMock<ProjectStoragePathWatcherMock> patchWatcherMock; QmlDesigner::ProjectPartId projectPartId = QmlDesigner::ProjectPartId::create(1); @@ -328,16 +348,23 @@ protected: SourceId qmlDocumentSourceId1 = sourcePathCache.sourceId("/path/First.qml"); SourceId qmlDocumentSourceId2 = sourcePathCache.sourceId("/path/First2.qml"); SourceId qmlDocumentSourceId3 = sourcePathCache.sourceId("/path/Second.qml"); - ModuleId qmlModuleId{storage.moduleId("Qml")}; - ModuleId qmlCppNativeModuleId{storage.moduleId("Qml-cppnative")}; - ModuleId exampleModuleId{storage.moduleId("Example")}; - ModuleId exampleCppNativeModuleId{storage.moduleId("Example-cppnative")}; - ModuleId builtinModuleId{storage.moduleId("QML")}; - ModuleId builtinCppNativeModuleId{storage.moduleId("QML-cppnative")}; - ModuleId quickModuleId{storage.moduleId("Quick")}; - ModuleId quickCppNativeModuleId{storage.moduleId("Quick-cppnative")}; - ModuleId pathModuleId{storage.moduleId("/path")}; - ModuleId subPathQmlModuleId{storage.moduleId("/path/qml")}; + const QString itemLibraryPath = QDir::cleanPath( + UNITTEST_DIR "/../../../../share/qtcreator/qmldesigner/itemLibrary/"); + const QString qmlImportsPath = QDir::cleanPath(UNITTEST_DIR "/projectstorage/data/qml"); + SourceId itemLibraryPathSourceId = sourcePathCache.sourceId( + QmlDesigner::SourcePath{itemLibraryPath + "/."}); + SourceId qmlImportsPathSourceId = sourcePathCache.sourceId( + QmlDesigner::SourcePath{qmlImportsPath + "/."}); + ModuleId qmlModuleId{storage.moduleId("Qml", ModuleKind::QmlLibrary)}; + ModuleId qmlCppNativeModuleId{storage.moduleId("Qml", ModuleKind::CppLibrary)}; + ModuleId exampleModuleId{storage.moduleId("Example", ModuleKind::QmlLibrary)}; + ModuleId exampleCppNativeModuleId{storage.moduleId("Example", ModuleKind::CppLibrary)}; + ModuleId builtinModuleId{storage.moduleId("QML", ModuleKind::QmlLibrary)}; + ModuleId builtinCppNativeModuleId{storage.moduleId("QML", ModuleKind::CppLibrary)}; + ModuleId quickModuleId{storage.moduleId("Quick", ModuleKind::QmlLibrary)}; + ModuleId quickCppNativeModuleId{storage.moduleId("Quick", ModuleKind::CppLibrary)}; + ModuleId pathModuleId{storage.moduleId("/path", ModuleKind::PathLibrary)}; + ModuleId subPathQmlModuleId{storage.moduleId("/path/qml", ModuleKind::PathLibrary)}; Storage::Synchronization::Type objectType{ "QObject", Storage::Synchronization::ImportedType{}, @@ -410,7 +437,25 @@ TEST_F(ProjectStorageUpdater, get_content_for_qml_dir_paths_if_file_status_is_di EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/one/qmldir")))); EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/two/qmldir")))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); +} + +TEST_F(ProjectStorageUpdater, + get_content_for_qml_dir_paths_if_file_status_is_different_for_subdirectories) +{ + SourceId qmlDir1PathSourceId = sourcePathCache.sourceId("/path/one/qmldir"); + SourceId qmlDir2PathSourceId = sourcePathCache.sourceId("/path/two/qmldir"); + SourceId qmlDir3PathSourceId = sourcePathCache.sourceId("/path/three/qmldir"); + SourceId path3SourceId = sourcePathCache.sourceId("/path/three/."); + QStringList directories = {"/path/one"}; + setSubdirectoryPaths(u"/path/one", {"/path/two", "/path/three"}); + setFilesChanged({qmlDir1PathSourceId, qmlDir2PathSourceId}); + setFilesDontChanged({qmlDir3PathSourceId, path3SourceId}); + + EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/one/qmldir")))); + EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/two/qmldir")))); + + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, request_file_status_from_file_system) @@ -419,7 +464,21 @@ TEST_F(ProjectStorageUpdater, request_file_status_from_file_system) EXPECT_CALL(fileSystemMock, fileStatus(Eq(directoryPathSourceId))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); +} + +TEST_F(ProjectStorageUpdater, request_file_status_from_file_system_for_subdirectories) +{ + EXPECT_CALL(fileSystemMock, + fileStatus(AllOf(Ne(directoryPathSourceId), Ne(path1SourceId), Ne(path2SourceId)))) + .Times(AnyNumber()); + setSubdirectoryPaths(u"/path", {"/path/one", "/path/two"}); + + EXPECT_CALL(fileSystemMock, fileStatus(Eq(path1SourceId))); + EXPECT_CALL(fileSystemMock, fileStatus(Eq(path2SourceId))); + EXPECT_CALL(fileSystemMock, fileStatus(Eq(directoryPathSourceId))); + + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, get_content_for_qml_types) @@ -431,7 +490,7 @@ TEST_F(ProjectStorageUpdater, get_content_for_qml_types) EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/example.qmltypes")))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, get_content_for_qml_types_if_project_storage_file_status_is_invalid) @@ -444,7 +503,7 @@ TEST_F(ProjectStorageUpdater, get_content_for_qml_types_if_project_storage_file_ EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/example.qmltypes")))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, parse_qml_types) @@ -459,11 +518,32 @@ TEST_F(ProjectStorageUpdater, parse_qml_types) setContent(u"/path/example2.qmltypes", qmltypes2); EXPECT_CALL(qmlTypesParserMock, - parse(qmltypes, _, _, Field(&ProjectData::moduleId, exampleCppNativeModuleId))); + parse(qmltypes, _, _, Field(&DirectoryInfo::moduleId, exampleCppNativeModuleId))); EXPECT_CALL(qmlTypesParserMock, - parse(qmltypes2, _, _, Field(&ProjectData::moduleId, exampleCppNativeModuleId))); + parse(qmltypes2, _, _, Field(&DirectoryInfo::moduleId, exampleCppNativeModuleId))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); +} + +TEST_F(ProjectStorageUpdater, parse_qml_types_in_subdirectories) +{ + QString qmldir{R"(module Example + typeinfo example.qmltypes + typeinfo example2.qmltypes)"}; + setContent(u"/path/qmldir", qmldir); + QString qmltypes{"Module {\ndependencies: []}"}; + QString qmltypes2{"Module {\ndependencies: [foo]}"}; + setContent(u"/path/example.qmltypes", qmltypes); + setContent(u"/path/example2.qmltypes", qmltypes2); + QStringList directories = {"/root"}; + setSubdirectoryPaths(u"/root", {"/path"}); + + EXPECT_CALL(qmlTypesParserMock, + parse(qmltypes, _, _, Field(&DirectoryInfo::moduleId, exampleCppNativeModuleId))); + EXPECT_CALL(qmlTypesParserMock, + parse(qmltypes2, _, _, Field(&DirectoryInfo::moduleId, exampleCppNativeModuleId))); + + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_is_empty_for_no_change) @@ -472,7 +552,24 @@ TEST_F(ProjectStorageUpdater, synchronize_is_empty_for_no_change) EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty())); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); +} + +TEST_F(ProjectStorageUpdater, synchronize_is_empty_for_no_change_in_subdirectory) +{ + SourceId qmlDirRootPathSourceId = sourcePathCache.sourceId("/root/qmldir"); + SourceId rootPathSourceId = sourcePathCache.sourceId("/root/."); + setFilesDontChanged({qmltypesPathSourceId, + qmltypes2PathSourceId, + qmlDirPathSourceId, + qmlDirRootPathSourceId, + rootPathSourceId}); + QStringList directories = {"/root"}; + setSubdirectoryPaths(u"/root", {"/path"}); + + EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty())); + + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_qml_types) @@ -487,9 +584,9 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_types) imports.push_back(import); }); - EXPECT_CALL(projectStorageMock, moduleId(Eq("Example"))); - EXPECT_CALL(projectStorageMock, moduleId(Eq("Example-cppnative"))); - EXPECT_CALL(projectStorageMock, moduleId(Eq("/path"))); + EXPECT_CALL(projectStorageMock, moduleId(Eq("Example"), ModuleKind::QmlLibrary)); + EXPECT_CALL(projectStorageMock, moduleId(Eq("Example"), ModuleKind::CppLibrary)); + EXPECT_CALL(projectStorageMock, moduleId(Eq("/path"), ModuleKind::PathLibrary)); EXPECT_CALL(projectStorageMock, synchronize( AllOf(Field(&SynchronizationPackage::imports, ElementsAre(import)), @@ -499,15 +596,86 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_types) Field(&SynchronizationPackage::fileStatuses, UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 1, 21), IsFileStatus(qmltypesPathSourceId, 1, 21))), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmltypesPathSourceId, - exampleCppNativeModuleId, - FileType::QmlTypes))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmltypesPathSourceId, + exampleCppNativeModuleId, + FileType::QmlTypes))), + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId))))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); +} + +TEST_F(ProjectStorageUpdater, synchronize_subdircectories) +{ + QStringList directories = {"/root"}; + setSubdirectoryPaths(u"/root", {"/path/one", "/path/two"}); + setSubdirectoryPaths(u"/path/one", {"/path/three"}); + SourceId rootDirectoryPathSourceId = sourcePathCache.sourceId("/root/."); + setFilesChanged({rootDirectoryPathSourceId, path1SourceId, path2SourceId, path3SourceId}); + + EXPECT_CALL( + projectStorageMock, + synchronize(AllOf( + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre( + IsDirectoryInfo(rootDirectoryPathSourceId, path1SourceId, ModuleId{}, FileType::Directory), + IsDirectoryInfo(rootDirectoryPathSourceId, path2SourceId, ModuleId{}, FileType::Directory), + IsDirectoryInfo(path1SourceId, path3SourceId, ModuleId{}, FileType::Directory))), + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, + UnorderedElementsAre( + rootDirectoryPathSourceId, path1SourceId, path2SourceId, path3SourceId))))); + + updater.update(directories, {}, {}, {}); +} + +TEST_F(ProjectStorageUpdater, synchronize_subdircectories_even_for_no_changes) +{ + QStringList directories = {"/root"}; + setSubdirectoryPaths(u"/root", {"/path/one", "/path/two"}); + setSubdirectoryPaths(u"/path/one", {"/path/three"}); + SourceId rootDirectoryPathSourceId = sourcePathCache.sourceId("/root/."); + setFilesChanged({path1SourceId, path2SourceId, path3SourceId}); + setFilesDontChanged({rootDirectoryPathSourceId}); + + EXPECT_CALL(projectStorageMock, + synchronize( + AllOf(Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo( + path1SourceId, path3SourceId, ModuleId{}, FileType::Directory))), + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, + UnorderedElementsAre(path1SourceId, path2SourceId, path3SourceId))))); + + updater.update(directories, {}, {}, {}); +} + +TEST_F(ProjectStorageUpdater, synchronize_subdircectories_for_deleted_subdirecties) +{ + QStringList directories = {"/root"}; + setSubdirectoryPaths(u"/root", {"/path/two"}); + SourceId rootDirectoryPathSourceId = sourcePathCache.sourceId("/root/."); + setFilesChanged({rootDirectoryPathSourceId}); + setFilesDontExists({ + path1SourceId, + path3SourceId, + }); + setSubdirectorySourceIds(rootDirectoryPathSourceId, {path1SourceId, path2SourceId}); + setSubdirectorySourceIds(path1SourceId, {path3SourceId}); + + EXPECT_CALL(projectStorageMock, + synchronize(AllOf(Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(rootDirectoryPathSourceId, + path2SourceId, + ModuleId{}, + FileType::Directory))), + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, + UnorderedElementsAre(rootDirectoryPathSourceId, + path1SourceId, + path2SourceId, + path3SourceId))))); + + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_qml_types_throws_if_qmltpes_does_not_exists) @@ -515,7 +683,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_types_throws_if_qmltpes_does_not_e Storage::Import import{qmlModuleId, Storage::Version{2, 3}, qmltypesPathSourceId}; setFilesDontExists({qmltypesPathSourceId}); - ASSERT_THROW(updater.update(directories, {}, {}), QmlDesigner::CannotParseQmlTypesFile); + ASSERT_THROW(updater.update(directories, {}, {}, {}), QmlDesigner::CannotParseQmlTypesFile); } TEST_F(ProjectStorageUpdater, synchronize_qml_types_are_empty_if_file_does_not_changed) @@ -528,7 +696,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_types_are_empty_if_file_does_not_c EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty())); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, get_content_for_qml_documents) @@ -549,7 +717,7 @@ TEST_F(ProjectStorageUpdater, get_content_for_qml_documents) EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/OldSecond.qml")))); EXPECT_CALL(fileSystemMock, contentAsQString(Eq(QString("/path/Second.qml")))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, parse_qml_documents) @@ -570,7 +738,7 @@ TEST_F(ProjectStorageUpdater, parse_qml_documents) EXPECT_CALL(qmlDocumentParserMock, parse(qmlDocument2, _, _, _)); EXPECT_CALL(qmlDocumentParserMock, parse(qmlDocument3, _, _, _)); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, parse_qml_documents_with_non_existing_qml_document_throws) @@ -579,7 +747,7 @@ TEST_F(ProjectStorageUpdater, parse_qml_documents_with_non_existing_qml_document NonexitingType 1.0 NonexitingType.qml)"}; setContent(u"/path/qmldir", qmldir); - ASSERT_THROW(updater.update(directories, {}, {}), QmlDesigner::CannotParseQmlDocumentFile); + ASSERT_THROW(updater.update(directories, {}, {}, {}), QmlDesigner::CannotParseQmlDocumentFile); } TEST_F(ProjectStorageUpdater, synchronize_qml_documents) @@ -636,23 +804,23 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents) IsFileStatus(qmlDocumentSourceId1, 1, 21), IsFileStatus(qmlDocumentSourceId2, 1, 21), IsFileStatus(qmlDocumentSourceId3, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId3, - ModuleId{}, - FileType::QmlDocument)))))); - - updater.update(directories, {}, {}); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId3, + ModuleId{}, + FileType::QmlDocument)))))); + + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_add_only_qml_document_in_directory) @@ -663,8 +831,8 @@ TEST_F(ProjectStorageUpdater, synchronize_add_only_qml_document_in_directory) setFilesChanged({directoryPathSourceId}); setFilesDontChanged({qmlDirPathSourceId, qmlDocumentSourceId1}); setFilesAdded({qmlDocumentSourceId2}); - setProjectDatas(directoryPathSourceId, - {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}}); + setDirectoryInfos(directoryPathSourceId, + {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}}); setQmlFileNames(u"/path", {"First.qml", "First2.qml"}); EXPECT_CALL(projectStorageMock, @@ -696,19 +864,19 @@ TEST_F(ProjectStorageUpdater, synchronize_add_only_qml_document_in_directory) Field(&SynchronizationPackage::fileStatuses, UnorderedElementsAre(IsFileStatus(qmlDocumentSourceId2, 1, 21), IsFileStatus(directoryPathSourceId, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument)))))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_removes_qml_document) @@ -721,10 +889,11 @@ TEST_F(ProjectStorageUpdater, synchronize_removes_qml_document) setFilesChanged({qmlDirPathSourceId}); setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); setFilesRemoved({qmlDocumentSourceId3}); - setProjectDatas(directoryPathSourceId, - {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, - {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}, - {directoryPathSourceId, qmlDocumentSourceId3, ModuleId{}, FileType::QmlDocument}}); + setDirectoryInfos( + directoryPathSourceId, + {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, + {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}, + {directoryPathSourceId, qmlDocumentSourceId3, ModuleId{}, FileType::QmlDocument}}); setQmlFileNames(u"/path", {"First.qml", "First2.qml"}); EXPECT_CALL(projectStorageMock, @@ -759,19 +928,19 @@ TEST_F(ProjectStorageUpdater, synchronize_removes_qml_document) UnorderedElementsAre(qmlDirPathSourceId, qmlDocumentSourceId3)), Field(&SynchronizationPackage::fileStatuses, UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument)))))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_removes_qml_document_in_qmldir_only) @@ -782,9 +951,9 @@ TEST_F(ProjectStorageUpdater, synchronize_removes_qml_document_in_qmldir_only) setContent(u"/path/qmldir", qmldir); setFilesChanged({qmlDirPathSourceId}); setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); - setProjectDatas(directoryPathSourceId, - {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, - {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}}); + setDirectoryInfos(directoryPathSourceId, + {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, + {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}}); setQmlFileNames(u"/path", {"First.qml", "First2.qml"}); EXPECT_CALL( @@ -814,19 +983,19 @@ TEST_F(ProjectStorageUpdater, synchronize_removes_qml_document_in_qmldir_only) UnorderedElementsAre(qmlDirPathSourceId)), Field(&SynchronizationPackage::fileStatuses, UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument)))))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_add_qml_document_to_qmldir) @@ -838,9 +1007,9 @@ TEST_F(ProjectStorageUpdater, synchronize_add_qml_document_to_qmldir) setContent(u"/path/qmldir", qmldir); setFilesChanged({qmlDirPathSourceId}); setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); - setProjectDatas(directoryPathSourceId, - {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, - {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}}); + setDirectoryInfos(directoryPathSourceId, + {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, + {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}}); setQmlFileNames(u"/path", {"First.qml", "First2.qml"}); EXPECT_CALL( @@ -872,19 +1041,19 @@ TEST_F(ProjectStorageUpdater, synchronize_add_qml_document_to_qmldir) UnorderedElementsAre(qmlDirPathSourceId)), Field(&SynchronizationPackage::fileStatuses, UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument)))))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_remove_qml_document_from_qmldir) @@ -895,9 +1064,9 @@ TEST_F(ProjectStorageUpdater, synchronize_remove_qml_document_from_qmldir) setContent(u"/path/qmldir", qmldir); setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); setFilesChanged({qmlDirPathSourceId}); - setProjectDatas(directoryPathSourceId, - {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, - {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}}); + setDirectoryInfos(directoryPathSourceId, + {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, + {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}}); setQmlFileNames(u"/path", {"First.qml", "First2.qml"}); EXPECT_CALL( @@ -927,19 +1096,19 @@ TEST_F(ProjectStorageUpdater, synchronize_remove_qml_document_from_qmldir) UnorderedElementsAre(qmlDirPathSourceId)), Field(&SynchronizationPackage::fileStatuses, UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument)))))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_qml_documents_dont_update_if_up_to_date) @@ -993,28 +1162,28 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_dont_update_if_up_to_dat IsFileStatus(qmlDocumentSourceId2, 1, 21))), Field(&SynchronizationPackage::updatedFileStatusSourceIds, UnorderedElementsAre(qmlDirPathSourceId, qmlDocumentSourceId1, qmlDocumentSourceId2)), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId3, - ModuleId{}, - FileType::QmlDocument)))))); - - updater.update(directories, {}, {}); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId3, + ModuleId{}, + FileType::QmlDocument)))))); + + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_not_changed) { - setProjectDatas( + setDirectoryInfos( directoryPathSourceId, {{directoryPathSourceId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}, @@ -1058,14 +1227,14 @@ TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_not_changed) qmltypes2PathSourceId, qmlDocumentSourceId1, qmlDocumentSourceId2)), - Field(&SynchronizationPackage::projectDatas, IsEmpty())))); + Field(&SynchronizationPackage::directoryInfos, IsEmpty())))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_not_changed_and_some_updated_files) { - setProjectDatas( + setDirectoryInfos( directoryPathSourceId, {{directoryPathSourceId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}, @@ -1093,15 +1262,15 @@ TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_not_changed_and_some IsFileStatus(qmlDocumentSourceId1, 1, 21))), Field(&SynchronizationPackage::updatedFileStatusSourceIds, UnorderedElementsAre(qmltypesPathSourceId, qmlDocumentSourceId1)), - Field(&SynchronizationPackage::projectDatas, IsEmpty())))); + Field(&SynchronizationPackage::directoryInfos, IsEmpty())))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_not_changed_and_some_removed_files) { setQmlFileNames(u"/path", {"First2.qml"}); - setProjectDatas( + setDirectoryInfos( directoryPathSourceId, {{directoryPathSourceId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}, @@ -1110,7 +1279,7 @@ TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_not_changed_and_some_rem setFilesDontChanged({qmlDirPathSourceId, qmltypes2PathSourceId, qmlDocumentSourceId2}); setFilesRemoved({qmltypesPathSourceId, qmlDocumentSourceId1}); - ASSERT_THROW(updater.update(directories, {}, {}), QmlDesigner::CannotParseQmlTypesFile); + ASSERT_THROW(updater.update(directories, {}, {}, {}), QmlDesigner::CannotParseQmlTypesFile); } TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_changed_and_some_removed_files) @@ -1120,7 +1289,7 @@ TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_changed_and_some_rem typeinfo example2.qmltypes)"}; setContent(u"/path/qmldir", qmldir); setQmlFileNames(u"/path", {"First2.qml"}); - setProjectDatas( + setDirectoryInfos( directoryPathSourceId, {{directoryPathSourceId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}, @@ -1152,17 +1321,17 @@ TEST_F(ProjectStorageUpdater, synchroniz_if_qmldir_file_has_changed_and_some_rem UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 1, 21))), Field(&SynchronizationPackage::updatedFileStatusSourceIds, UnorderedElementsAre(qmlDirPathSourceId, qmltypesPathSourceId, qmlDocumentSourceId1)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmltypes2PathSourceId, - exampleCppNativeModuleId, - FileType::QmlTypes)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmltypes2PathSourceId, + exampleCppNativeModuleId, + FileType::QmlTypes)))))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, update_qml_types_files_is_empty) @@ -1174,10 +1343,10 @@ TEST_F(ProjectStorageUpdater, update_qml_types_files_is_empty) Field(&SynchronizationPackage::updatedSourceIds, IsEmpty()), Field(&SynchronizationPackage::fileStatuses, IsEmpty()), Field(&SynchronizationPackage::updatedFileStatusSourceIds, IsEmpty()), - Field(&SynchronizationPackage::projectDatas, IsEmpty()), - Field(&SynchronizationPackage::updatedProjectSourceIds, IsEmpty())))); + Field(&SynchronizationPackage::directoryInfos, IsEmpty()), + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, IsEmpty())))); - updater.update({}, {}, {}); + updater.update({}, {}, {}, {}); } TEST_F(ProjectStorageUpdater, update_qml_types_files) @@ -1193,19 +1362,19 @@ TEST_F(ProjectStorageUpdater, update_qml_types_files) IsFileStatus(qmltypes2PathSourceId, 1, 21))), Field(&SynchronizationPackage::updatedFileStatusSourceIds, UnorderedElementsAre(qmltypesPathSourceId, qmltypes2PathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(qmltypesPathSourceId, - qmltypesPathSourceId, - builtinCppNativeModuleId, - FileType::QmlTypes), - IsProjectData(qmltypes2PathSourceId, - qmltypes2PathSourceId, - builtinCppNativeModuleId, - FileType::QmlTypes))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(qmltypesPathSourceId, + qmltypesPathSourceId, + builtinCppNativeModuleId, + FileType::QmlTypes), + IsDirectoryInfo(qmltypes2PathSourceId, + qmltypes2PathSourceId, + builtinCppNativeModuleId, + FileType::QmlTypes))), + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(qmltypesPathSourceId, qmltypes2PathSourceId))))); - updater.update({}, {"/path/example.qmltypes", "/path/example2.qmltypes"}, {}); + updater.update({}, {"/path/example.qmltypes", "/path/example2.qmltypes"}, {}, {}); } TEST_F(ProjectStorageUpdater, dont_update_qml_types_files_if_unchanged) @@ -1222,15 +1391,15 @@ TEST_F(ProjectStorageUpdater, dont_update_qml_types_files_if_unchanged) UnorderedElementsAre(IsFileStatus(qmltypesPathSourceId, 1, 21))), Field(&SynchronizationPackage::updatedFileStatusSourceIds, UnorderedElementsAre(qmltypesPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(qmltypesPathSourceId, - qmltypesPathSourceId, - builtinCppNativeModuleId, - FileType::QmlTypes))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(qmltypesPathSourceId, + qmltypesPathSourceId, + builtinCppNativeModuleId, + FileType::QmlTypes))), + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(qmltypesPathSourceId))))); - updater.update({}, {"/path/example.qmltypes", "/path/example2.qmltypes"}, {}); + updater.update({}, {"/path/example.qmltypes", "/path/example2.qmltypes"}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_qml_documents_with_different_version_but_same_type_name_and_file_name) @@ -1265,15 +1434,15 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_with_different_version_b Field(&SynchronizationPackage::fileStatuses, UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 1, 21), IsFileStatus(qmlDocumentSourceId1, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument)))))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_qml_documents_with_different_type_name_but_same_version_and_file_name) @@ -1306,15 +1475,15 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_with_different_type_name Field(&SynchronizationPackage::fileStatuses, UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 1, 21), IsFileStatus(qmlDocumentSourceId1, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument)))))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, dont_synchronize_selectors) @@ -1332,7 +1501,7 @@ TEST_F(ProjectStorageUpdater, dont_synchronize_selectors) Contains(Field(&Storage::Synchronization::Type::exportedTypes, Contains(IsExportedType(exampleModuleId, "FirstType", 1, 0)))))))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_qmldir_dependencies) @@ -1357,7 +1526,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qmldir_dependencies) Field(&SynchronizationPackage::updatedModuleDependencySourceIds, UnorderedElementsAre(qmltypesPathSourceId, qmltypes2PathSourceId))))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_qmldir_dependencies_with_double_entries) @@ -1383,7 +1552,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qmldir_dependencies_with_double_entrie Field(&SynchronizationPackage::updatedModuleDependencySourceIds, UnorderedElementsAre(qmltypesPathSourceId, qmltypes2PathSourceId))))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_qmldir_dependencies_with_colliding_imports) @@ -1409,7 +1578,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qmldir_dependencies_with_colliding_imp Field(&SynchronizationPackage::updatedModuleDependencySourceIds, UnorderedElementsAre(qmltypesPathSourceId, qmltypes2PathSourceId))))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_qmldir_with_no_dependencies) @@ -1426,7 +1595,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qmldir_with_no_dependencies) Field(&SynchronizationPackage::updatedModuleDependencySourceIds, UnorderedElementsAre(qmltypesPathSourceId, qmltypes2PathSourceId))))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_qmldir_imports) @@ -1468,7 +1637,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qmldir_imports) Field(&SynchronizationPackage::updatedModuleIds, ElementsAre(exampleModuleId))))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_qmldir_with_no_imports) @@ -1482,7 +1651,7 @@ TEST_F(ProjectStorageUpdater, synchronize_qmldir_with_no_imports) Field(&SynchronizationPackage::updatedModuleIds, ElementsAre(exampleModuleId))))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_qmldir_imports_with_double_entries) @@ -1525,15 +1694,15 @@ TEST_F(ProjectStorageUpdater, synchronize_qmldir_imports_with_double_entries) Field(&SynchronizationPackage::updatedModuleIds, ElementsAre(exampleModuleId))))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } -TEST_F(ProjectStorageUpdater, synchronize_qmldir_optional_imports) +TEST_F(ProjectStorageUpdater, synchronize_qmldir_default_imports) { QString qmldir{R"(module Example import Qml auto import QML 2.1 - optional import Quick + default import Quick )"}; setContent(u"/path/qmldir", qmldir); @@ -1567,7 +1736,41 @@ TEST_F(ProjectStorageUpdater, synchronize_qmldir_optional_imports) Field(&SynchronizationPackage::updatedModuleIds, ElementsAre(exampleModuleId))))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); +} + +TEST_F(ProjectStorageUpdater, do_not_synchronize_qmldir_optional_imports) +{ + QString qmldir{R"(module Example + import Qml auto + import QML 2.1 + optional import Quick + )"}; + setContent(u"/path/qmldir", qmldir); + + EXPECT_CALL(projectStorageMock, + synchronize( + AllOf(Field(&SynchronizationPackage::moduleExportedImports, + UnorderedElementsAre(ModuleExportedImport{exampleModuleId, + qmlModuleId, + Storage::Version{}, + IsAutoVersion::Yes}, + ModuleExportedImport{exampleCppNativeModuleId, + qmlCppNativeModuleId, + Storage::Version{}, + IsAutoVersion::No}, + ModuleExportedImport{exampleModuleId, + builtinModuleId, + Storage::Version{2, 1}, + IsAutoVersion::No}, + ModuleExportedImport{exampleCppNativeModuleId, + builtinCppNativeModuleId, + Storage::Version{}, + IsAutoVersion::No})), + Field(&SynchronizationPackage::updatedModuleIds, + ElementsAre(exampleModuleId))))); + + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, update_path_watcher_directories) @@ -1577,7 +1780,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_directories) QmlDesigner::SourceType::Directory, {path1SourceId, path2SourceId, path3SourceId}}))); - updater.update(directories3, {}, {}); + updater.update(directories3, {}, {}, {}); } TEST_F(ProjectStorageUpdater, update_path_watcher_directory_does_not_exists) @@ -1589,7 +1792,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_directory_does_not_exists) QmlDesigner::SourceType::Directory, {path1SourceId, path3SourceId}}))); - updater.update(directories3, {}, {}); + updater.update(directories3, {}, {}, {}); } TEST_F(ProjectStorageUpdater, update_path_watcher_directory_does_not_changed) @@ -1601,7 +1804,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_directory_does_not_changed) QmlDesigner::SourceType::Directory, {path1SourceId, path2SourceId}}))); - updater.update(directories2, {}, {}); + updater.update(directories2, {}, {}, {}); } TEST_F(ProjectStorageUpdater, update_path_watcher_directory_removed) @@ -1612,7 +1815,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_directory_removed) updateIdPaths(Contains( IdPaths{projectPartId, QmlDesigner::SourceType::Directory, {path2SourceId}}))); - updater.update(directories2, {}, {}); + updater.update(directories2, {}, {}, {}); } TEST_F(ProjectStorageUpdater, update_path_watcher_qmldirs) @@ -1622,7 +1825,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qmldirs) QmlDesigner::SourceType::QmlDir, {qmldir1SourceId, qmldir2SourceId, qmldir3SourceId}}))); - updater.update(directories3, {}, {}); + updater.update(directories3, {}, {}, {}); } TEST_F(ProjectStorageUpdater, update_path_watcher_qmldir_does_not_exists) @@ -1634,7 +1837,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qmldir_does_not_exists) QmlDesigner::SourceType::QmlDir, {qmldir1SourceId, qmldir3SourceId}}))); - updater.update(directories3, {}, {}); + updater.update(directories3, {}, {}, {}); } TEST_F(ProjectStorageUpdater, update_path_watcher_qmldir_does_not_changed) @@ -1646,7 +1849,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qmldir_does_not_changed) QmlDesigner::SourceType::QmlDir, {qmldir1SourceId, qmldir2SourceId}}))); - updater.update(directories2, {}, {}); + updater.update(directories2, {}, {}, {}); } TEST_F(ProjectStorageUpdater, update_path_watcher_qmldir_removed) @@ -1657,7 +1860,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qmldir_removed) updateIdPaths(Contains( IdPaths{projectPartId, QmlDesigner::SourceType::QmlDir, {qmldir2SourceId}}))); - updater.update(directories2, {}, {}); + updater.update(directories2, {}, {}, {}); } TEST_F(ProjectStorageUpdater, update_path_watcher_qml_files) @@ -1674,7 +1877,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qml_files) QmlDesigner::SourceType::Qml, {firstSourceId, secondSourceId, thirdSourceId}}))); - updater.update(directories2, {}, {}); + updater.update(directories2, {}, {}, {}); } TEST_F(ProjectStorageUpdater, update_path_watcher_only_qml_files_dont_changed) @@ -1692,25 +1895,25 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_only_qml_files_dont_changed) QmlDesigner::SourceType::Qml, {firstSourceId, secondSourceId, thirdSourceId}}))); - updater.update(directories2, {}, {}); + updater.update(directories2, {}, {}, {}); } TEST_F(ProjectStorageUpdater, update_path_watcher_only_qml_files_changed) { setFilesDontChanged({qmldir1SourceId, qmldir2SourceId, path1SourceId, path2SourceId}); setFilesChanged({firstSourceId, secondSourceId, thirdSourceId}); - setProjectDatas(path1SourceId, - {{path1SourceId, firstSourceId, exampleModuleId, FileType::QmlDocument}, - {path1SourceId, secondSourceId, exampleModuleId, FileType::QmlDocument}}); - setProjectDatas(path2SourceId, - {{path2SourceId, thirdSourceId, ModuleId{}, FileType::QmlDocument}}); + setDirectoryInfos(path1SourceId, + {{path1SourceId, firstSourceId, exampleModuleId, FileType::QmlDocument}, + {path1SourceId, secondSourceId, exampleModuleId, FileType::QmlDocument}}); + setDirectoryInfos(path2SourceId, + {{path2SourceId, thirdSourceId, ModuleId{}, FileType::QmlDocument}}); EXPECT_CALL(patchWatcherMock, updateIdPaths(Contains(IdPaths{projectPartId, QmlDesigner::SourceType::Qml, {firstSourceId, secondSourceId, thirdSourceId}}))); - updater.update(directories2, {}, {}); + updater.update(directories2, {}, {}, {}); } TEST_F(ProjectStorageUpdater, update_path_watcher_qml_files_and_directories_dont_changed) @@ -1722,18 +1925,18 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qml_files_and_directories_dont firstSourceId, secondSourceId, thirdSourceId}); - setProjectDatas(path1SourceId, - {{path1SourceId, firstSourceId, exampleModuleId, FileType::QmlDocument}, - {path1SourceId, secondSourceId, exampleModuleId, FileType::QmlDocument}}); - setProjectDatas(path2SourceId, - {{path2SourceId, thirdSourceId, ModuleId{}, FileType::QmlDocument}}); + setDirectoryInfos(path1SourceId, + {{path1SourceId, firstSourceId, exampleModuleId, FileType::QmlDocument}, + {path1SourceId, secondSourceId, exampleModuleId, FileType::QmlDocument}}); + setDirectoryInfos(path2SourceId, + {{path2SourceId, thirdSourceId, ModuleId{}, FileType::QmlDocument}}); EXPECT_CALL(patchWatcherMock, updateIdPaths(Contains(IdPaths{projectPartId, QmlDesigner::SourceType::Qml, {firstSourceId, secondSourceId, thirdSourceId}}))); - updater.update(directories2, {}, {}); + updater.update(directories2, {}, {}, {}); } TEST_F(ProjectStorageUpdater, update_path_watcher_qmltypes_files_in_qmldir) @@ -1752,7 +1955,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qmltypes_files_in_qmldir) QmlDesigner::SourceType::QmlTypes, {qmltypes1SourceId, qmltypes2SourceId}}))); - updater.update(directories2, {}, {}); + updater.update(directories2, {}, {}, {}); } TEST_F(ProjectStorageUpdater, update_path_watcher_only_qmltypes_files_in_qmldir_dont_changed) @@ -1770,24 +1973,24 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_only_qmltypes_files_in_qmldir_ QmlDesigner::SourceType::QmlTypes, {qmltypes1SourceId, qmltypes2SourceId}}))); - updater.update(directories2, {}, {}); + updater.update(directories2, {}, {}, {}); } TEST_F(ProjectStorageUpdater, update_path_watcher_only_qmltypes_files_changed) { setFilesDontChanged({qmldir1SourceId, qmldir2SourceId, path1SourceId, path2SourceId}); setFilesChanged({qmltypes1SourceId, qmltypes2SourceId}); - setProjectDatas(path1SourceId, - {{path1SourceId, qmltypes1SourceId, exampleModuleId, FileType::QmlTypes}}); - setProjectDatas(path2SourceId, - {{path2SourceId, qmltypes2SourceId, exampleModuleId, FileType::QmlTypes}}); + setDirectoryInfos(path1SourceId, + {{path1SourceId, qmltypes1SourceId, exampleModuleId, FileType::QmlTypes}}); + setDirectoryInfos(path2SourceId, + {{path2SourceId, qmltypes2SourceId, exampleModuleId, FileType::QmlTypes}}); EXPECT_CALL(patchWatcherMock, updateIdPaths(Contains(IdPaths{projectPartId, QmlDesigner::SourceType::QmlTypes, {qmltypes1SourceId, qmltypes2SourceId}}))); - updater.update(directories2, {}, {}); + updater.update(directories2, {}, {}, {}); } TEST_F(ProjectStorageUpdater, update_path_watcher_qmltypes_files_and_directories_dont_changed) @@ -1798,17 +2001,17 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_qmltypes_files_and_directories path2SourceId, qmltypes1SourceId, qmltypes2SourceId}); - setProjectDatas(path1SourceId, - {{path1SourceId, qmltypes1SourceId, exampleModuleId, FileType::QmlTypes}}); - setProjectDatas(path2SourceId, - {{path2SourceId, qmltypes2SourceId, exampleModuleId, FileType::QmlTypes}}); + setDirectoryInfos(path1SourceId, + {{path1SourceId, qmltypes1SourceId, exampleModuleId, FileType::QmlTypes}}); + setDirectoryInfos(path2SourceId, + {{path2SourceId, qmltypes2SourceId, exampleModuleId, FileType::QmlTypes}}); EXPECT_CALL(patchWatcherMock, updateIdPaths(Contains(IdPaths{projectPartId, QmlDesigner::SourceType::QmlTypes, {qmltypes1SourceId, qmltypes2SourceId}}))); - updater.update(directories2, {}, {}); + updater.update(directories2, {}, {}, {}); } TEST_F(ProjectStorageUpdater, update_path_watcher_builtin_qmltypes_files) @@ -1823,7 +2026,7 @@ TEST_F(ProjectStorageUpdater, update_path_watcher_builtin_qmltypes_files) QmlDesigner::SourceType::QmlTypes, {qmltypes1SourceId, qmltypes2SourceId}}))); - updater.update({}, {builtinQmltyplesPath1, builtinQmltyplesPath2}, {}); + updater.update({}, {builtinQmltyplesPath1, builtinQmltyplesPath2}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir) @@ -1874,23 +2077,23 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir) IsFileStatus(qmlDocumentSourceId1, 1, 21), IsFileStatus(qmlDocumentSourceId2, 1, 21), IsFileStatus(qmlDocumentSourceId3, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId3, - ModuleId{}, - FileType::QmlDocument)))))); - - updater.update(directories, {}, {}); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId3, + ModuleId{}, + FileType::QmlDocument)))))); + + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_throws_if_qml_document_does_not_exists) @@ -1898,16 +2101,17 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_throws_if setFilesDontExists({qmlDirPathSourceId, qmlDocumentSourceId1}); setFilesAdded({directoryPathSourceId}); - ASSERT_THROW(updater.update(directories, {}, {}), QmlDesigner::CannotParseQmlDocumentFile); + ASSERT_THROW(updater.update(directories, {}, {}, {}), QmlDesigner::CannotParseQmlDocumentFile); } TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_throws_if_directory_does_not_exists) { setFilesDontExists({qmlDirPathSourceId, directoryPathSourceId}); - setProjectDatas(directoryPathSourceId, - {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, - {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}, - {directoryPathSourceId, qmlDocumentSourceId3, ModuleId{}, FileType::QmlDocument}}); + setDirectoryInfos( + directoryPathSourceId, + {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, + {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}, + {directoryPathSourceId, qmlDocumentSourceId3, ModuleId{}, FileType::QmlDocument}}); EXPECT_CALL(projectStorageMock, synchronize(AllOf(Field(&SynchronizationPackage::imports, IsEmpty()), @@ -1924,11 +2128,11 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_throws_if qmlDocumentSourceId2, qmlDocumentSourceId3)), Field(&SynchronizationPackage::fileStatuses, IsEmpty()), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, IsEmpty())))); + Field(&SynchronizationPackage::directoryInfos, IsEmpty())))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_add_qml_document) @@ -1937,9 +2141,9 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_add_qml_d setFilesChanged({directoryPathSourceId}); setFilesAdded({qmlDocumentSourceId3}); setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); - setProjectDatas(directoryPathSourceId, - {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, - {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}}); + setDirectoryInfos(directoryPathSourceId, + {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, + {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}}); EXPECT_CALL( projectStorageMock, @@ -1961,23 +2165,23 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_add_qml_d Field(&SynchronizationPackage::fileStatuses, UnorderedElementsAre(IsFileStatus(directoryPathSourceId, 1, 21), IsFileStatus(qmlDocumentSourceId3, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId3, - ModuleId{}, - FileType::QmlDocument)))))); - - updater.update(directories, {}, {}); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId3, + ModuleId{}, + FileType::QmlDocument)))))); + + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_removes_qml_document) @@ -1987,10 +2191,11 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_removes_q setFilesRemoved({qmlDocumentSourceId3}); setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); setQmlFileNames(u"/path", {"First.qml", "First2.qml"}); - setProjectDatas(directoryPathSourceId, - {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, - {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}, - {directoryPathSourceId, qmlDocumentSourceId3, ModuleId{}, FileType::QmlDocument}}); + setDirectoryInfos( + directoryPathSourceId, + {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, + {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}, + {directoryPathSourceId, qmlDocumentSourceId3, ModuleId{}, FileType::QmlDocument}}); EXPECT_CALL(projectStorageMock, synchronize( @@ -2004,19 +2209,19 @@ TEST_F(ProjectStorageUpdater, synchronize_qml_documents_without_qmldir_removes_q qmlDocumentSourceId3)), Field(&SynchronizationPackage::fileStatuses, UnorderedElementsAre(IsFileStatus(directoryPathSourceId, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument)))))); - updater.update(directories, {}, {}); + updater.update(directories, {}, {}, {}); } TEST_F(ProjectStorageUpdater, watcher_updates_directories) @@ -2072,25 +2277,93 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directories) IsFileStatus(qmlDocumentSourceId1, 1, 21), IsFileStatus(qmlDocumentSourceId2, 1, 21), IsFileStatus(qmlDocumentSourceId3, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId3, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId3, + ModuleId{}, + FileType::QmlDocument)))))); updater.pathsWithIdsChanged({{directoryProjectChunkId, {directoryPathSourceId}}}); } +TEST_F(ProjectStorageUpdater, watcher_updates_subdirectories) +{ + QString qmldir{R"(module Example + FirstType 1.0 First.qml + FirstType 2.2 First2.qml + SecondType 2.2 Second.qml)"}; + setContent(u"/path/qmldir", qmldir); + SourceId rootPathSourceId = sourcePathCache.sourceId("/root/."); + SourceId rootQmldirPathSourceId = sourcePathCache.sourceId("/root/qmldir"); + setFilesChanged({directoryPathSourceId, rootPathSourceId}); + setFilesDontChanged({qmlDirPathSourceId, rootQmldirPathSourceId}); + setSubdirectoryPaths(u"/root", {"/path"}); + setSubdirectorySourceIds(rootPathSourceId, {directoryPathSourceId}); + + EXPECT_CALL( + projectStorageMock, + synchronize(AllOf( + Field(&SynchronizationPackage::imports, UnorderedElementsAre(import1, import2, import3)), + Field( + &SynchronizationPackage::types, + UnorderedElementsAre( + AllOf(IsStorageType("First.qml", + Storage::Synchronization::ImportedType{"Object"}, + TypeTraitsKind::Reference, + qmlDocumentSourceId1, + Storage::Synchronization::ChangeLevel::Full), + Field(&Storage::Synchronization::Type::exportedTypes, + UnorderedElementsAre(IsExportedType(exampleModuleId, "FirstType", 1, 0), + IsExportedType(pathModuleId, "First", -1, -1)))), + AllOf(IsStorageType("First2.qml", + Storage::Synchronization::ImportedType{"Object2"}, + TypeTraitsKind::Reference, + qmlDocumentSourceId2, + Storage::Synchronization::ChangeLevel::Full), + Field(&Storage::Synchronization::Type::exportedTypes, + UnorderedElementsAre(IsExportedType(exampleModuleId, "FirstType", 2, 2), + IsExportedType(pathModuleId, "First2", -1, -1)))), + AllOf(IsStorageType("Second.qml", + Storage::Synchronization::ImportedType{"Object3"}, + TypeTraitsKind::Reference, + qmlDocumentSourceId3, + Storage::Synchronization::ChangeLevel::Full), + Field(&Storage::Synchronization::Type::exportedTypes, + UnorderedElementsAre(IsExportedType(exampleModuleId, "SecondType", 2, 2), + IsExportedType(pathModuleId, "Second", -1, -1)))))), + Field(&SynchronizationPackage::updatedSourceIds, + UnorderedElementsAre(qmlDocumentSourceId1, qmlDocumentSourceId2, qmlDocumentSourceId3)), + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId3, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(rootPathSourceId, + directoryPathSourceId, + ModuleId{}, + FileType::Directory)))))); + + updater.pathsWithIdsChanged({{directoryProjectChunkId, {rootPathSourceId, directoryPathSourceId}}}); +} + TEST_F(ProjectStorageUpdater, watcher_updates_removed_directory) { setFilesRemoved({directoryPathSourceId, @@ -2098,10 +2371,11 @@ TEST_F(ProjectStorageUpdater, watcher_updates_removed_directory) qmlDocumentSourceId1, qmlDocumentSourceId2, qmlDocumentSourceId3}); - setProjectDatas(directoryPathSourceId, - {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, - {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}, - {directoryPathSourceId, qmlDocumentSourceId3, ModuleId{}, FileType::QmlDocument}}); + setDirectoryInfos( + directoryPathSourceId, + {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, + {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}, + {directoryPathSourceId, qmlDocumentSourceId3, ModuleId{}, FileType::QmlDocument}}); EXPECT_CALL(projectStorageMock, synchronize(AllOf(Field(&SynchronizationPackage::imports, IsEmpty()), @@ -2118,9 +2392,9 @@ TEST_F(ProjectStorageUpdater, watcher_updates_removed_directory) qmlDocumentSourceId2, qmlDocumentSourceId3)), Field(&SynchronizationPackage::fileStatuses, UnorderedElementsAre()), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, IsEmpty())))); + Field(&SynchronizationPackage::directoryInfos, IsEmpty())))); updater.pathsWithIdsChanged({{directoryProjectChunkId, {directoryPathSourceId}}}); } @@ -2220,21 +2494,21 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directories_and_qmldir) IsFileStatus(qmlDocumentSourceId1, 1, 21), IsFileStatus(qmlDocumentSourceId2, 1, 21), IsFileStatus(qmlDocumentSourceId3, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId3, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId3, + ModuleId{}, + FileType::QmlDocument)))))); updater.pathsWithIdsChanged({{directoryProjectChunkId, {directoryPathSourceId}}, {qmldirProjectChunkId, {qmlDirPathSourceId}}}); @@ -2284,8 +2558,8 @@ TEST_F(ProjectStorageUpdater, watcher_updates_add_only_qml_document_in_directory setFilesChanged({directoryPathSourceId}); setFilesDontChanged({qmlDirPathSourceId, qmlDocumentSourceId1}); setFilesAdded({qmlDocumentSourceId2}); - setProjectDatas(directoryPathSourceId, - {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}}); + setDirectoryInfos(directoryPathSourceId, + {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}}); setQmlFileNames(u"/path", {"First.qml", "First2.qml"}); EXPECT_CALL(projectStorageMock, @@ -2317,17 +2591,17 @@ TEST_F(ProjectStorageUpdater, watcher_updates_add_only_qml_document_in_directory Field(&SynchronizationPackage::fileStatuses, UnorderedElementsAre(IsFileStatus(qmlDocumentSourceId2, 1, 21), IsFileStatus(directoryPathSourceId, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument)))))); updater.pathsWithIdsChanged({{directoryProjectChunkId, {directoryPathSourceId}}}); } @@ -2342,10 +2616,11 @@ TEST_F(ProjectStorageUpdater, watcher_updates_removes_qml_document) setFilesChanged({qmlDirPathSourceId}); setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); setFilesRemoved({qmlDocumentSourceId3}); - setProjectDatas(directoryPathSourceId, - {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, - {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}, - {directoryPathSourceId, qmlDocumentSourceId3, ModuleId{}, FileType::QmlDocument}}); + setDirectoryInfos( + directoryPathSourceId, + {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, + {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}, + {directoryPathSourceId, qmlDocumentSourceId3, ModuleId{}, FileType::QmlDocument}}); setQmlFileNames(u"/path", {"First.qml", "First2.qml"}); EXPECT_CALL(projectStorageMock, @@ -2380,17 +2655,17 @@ TEST_F(ProjectStorageUpdater, watcher_updates_removes_qml_document) UnorderedElementsAre(qmlDirPathSourceId, qmlDocumentSourceId3)), Field(&SynchronizationPackage::fileStatuses, UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument)))))); updater.pathsWithIdsChanged({{directoryProjectChunkId, {directoryPathSourceId}}}); } @@ -2403,9 +2678,9 @@ TEST_F(ProjectStorageUpdater, watcher_updates_removes_qml_document_in_qmldir_onl setContent(u"/path/qmldir", qmldir); setFilesChanged({qmlDirPathSourceId}); setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); - setProjectDatas(directoryPathSourceId, - {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, - {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}}); + setDirectoryInfos(directoryPathSourceId, + {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, + {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}}); setQmlFileNames(u"/path", {"First.qml", "First2.qml"}); EXPECT_CALL( @@ -2435,17 +2710,17 @@ TEST_F(ProjectStorageUpdater, watcher_updates_removes_qml_document_in_qmldir_onl UnorderedElementsAre(qmlDirPathSourceId)), Field(&SynchronizationPackage::fileStatuses, UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument)))))); updater.pathsWithIdsChanged({{qmldirProjectChunkId, {qmlDirPathSourceId}}}); } @@ -2459,9 +2734,9 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directories_add_qml_document_to_qm setContent(u"/path/qmldir", qmldir); setFilesChanged({qmlDirPathSourceId}); setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); - setProjectDatas(directoryPathSourceId, - {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, - {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}}); + setDirectoryInfos(directoryPathSourceId, + {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, + {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}}); setQmlFileNames(u"/path", {"First.qml", "First2.qml"}); EXPECT_CALL( @@ -2493,17 +2768,17 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directories_add_qml_document_to_qm UnorderedElementsAre(qmlDirPathSourceId)), Field(&SynchronizationPackage::fileStatuses, UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument)))))); updater.pathsWithIdsChanged({{qmldirProjectChunkId, {qmlDirPathSourceId}}}); } @@ -2516,9 +2791,9 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directories_remove_qml_document_fr setContent(u"/path/qmldir", qmldir); setFilesDontChanged({qmlDocumentSourceId1, qmlDocumentSourceId2}); setFilesChanged({qmlDirPathSourceId}); - setProjectDatas(directoryPathSourceId, - {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, - {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}}); + setDirectoryInfos(directoryPathSourceId, + {{directoryPathSourceId, qmlDocumentSourceId1, ModuleId{}, FileType::QmlDocument}, + {directoryPathSourceId, qmlDocumentSourceId2, ModuleId{}, FileType::QmlDocument}}); setQmlFileNames(u"/path", {"First.qml", "First2.qml"}); EXPECT_CALL( @@ -2548,17 +2823,17 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directories_remove_qml_document_fr UnorderedElementsAre(qmlDirPathSourceId)), Field(&SynchronizationPackage::fileStatuses, UnorderedElementsAre(IsFileStatus(qmlDirPathSourceId, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument)))))); updater.pathsWithIdsChanged({{qmldirProjectChunkId, {qmlDirPathSourceId}}}); } @@ -2614,21 +2889,21 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directories_dont_update_qml_docume IsFileStatus(qmlDocumentSourceId2, 1, 21))), Field(&SynchronizationPackage::updatedFileStatusSourceIds, UnorderedElementsAre(qmlDirPathSourceId, qmlDocumentSourceId1, qmlDocumentSourceId2)), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId3, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId3, + ModuleId{}, + FileType::QmlDocument)))))); updater.pathsWithIdsChanged({{directoryProjectChunkId, {directoryPathSourceId}}}); } @@ -2684,28 +2959,28 @@ TEST_F(ProjectStorageUpdater, watcher_updates_qmldirs_dont_update_qml_documents_ IsFileStatus(qmlDocumentSourceId2, 1, 21))), Field(&SynchronizationPackage::updatedFileStatusSourceIds, UnorderedElementsAre(qmlDirPathSourceId, qmlDocumentSourceId1, qmlDocumentSourceId2)), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId3, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId3, + ModuleId{}, + FileType::QmlDocument)))))); updater.pathsWithIdsChanged({{qmldirProjectChunkId, {qmlDirPathSourceId}}}); } TEST_F(ProjectStorageUpdater, watcher_updates_directory_but_not_qmldir) { - setProjectDatas( + setDirectoryInfos( directoryPathSourceId, {{directoryPathSourceId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}, @@ -2749,7 +3024,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directory_but_not_qmldir) qmltypes2PathSourceId, qmlDocumentSourceId1, qmlDocumentSourceId2)), - Field(&SynchronizationPackage::projectDatas, IsEmpty())))); + Field(&SynchronizationPackage::directoryInfos, IsEmpty())))); updater.pathsWithIdsChanged({{directoryProjectChunkId, {directoryPathSourceId}}}); } @@ -2781,7 +3056,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_qml_documents) IsFileStatus(qmlDocumentSourceId2, 1, 21))), Field(&SynchronizationPackage::updatedFileStatusSourceIds, UnorderedElementsAre(qmlDocumentSourceId1, qmlDocumentSourceId2)), - Field(&SynchronizationPackage::projectDatas, IsEmpty())))); + Field(&SynchronizationPackage::directoryInfos, IsEmpty())))); updater.pathsWithIdsChanged( {{qmlDocumentProjectChunkId, {qmlDocumentSourceId1, qmlDocumentSourceId2}}}); @@ -2808,7 +3083,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_removed_qml_documents) UnorderedElementsAre(IsFileStatus(qmlDocumentSourceId1, 1, 21))), Field(&SynchronizationPackage::updatedFileStatusSourceIds, UnorderedElementsAre(qmlDocumentSourceId1, qmlDocumentSourceId2)), - Field(&SynchronizationPackage::projectDatas, IsEmpty())))); + Field(&SynchronizationPackage::directoryInfos, IsEmpty())))); updater.pathsWithIdsChanged( {{qmlDocumentProjectChunkId, {qmlDocumentSourceId1, qmlDocumentSourceId2}}}); @@ -2831,7 +3106,7 @@ TEST_F(ProjectStorageUpdater, watcher_dont_updates_qml_documents_for_other_proje TEST_F(ProjectStorageUpdater, watcher_updates_qmltypes) { - setProjectDatas( + setDirectoryInfos( directoryPathSourceId, {{directoryPathSourceId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}}); @@ -2851,7 +3126,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_qmltypes) IsFileStatus(qmltypes2PathSourceId, 1, 21))), Field(&SynchronizationPackage::updatedFileStatusSourceIds, UnorderedElementsAre(qmltypesPathSourceId, qmltypes2PathSourceId)), - Field(&SynchronizationPackage::projectDatas, IsEmpty())))); + Field(&SynchronizationPackage::directoryInfos, IsEmpty())))); updater.pathsWithIdsChanged( {{qmltypesProjectChunkId, {qmltypesPathSourceId, qmltypes2PathSourceId}}}); @@ -2859,7 +3134,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_qmltypes) TEST_F(ProjectStorageUpdater, watcher_updates_removed_qmltypes_without_updated_qmldir) { - setProjectDatas( + setDirectoryInfos( directoryPathSourceId, {{directoryPathSourceId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}}); @@ -2875,7 +3150,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_removed_qmltypes_without_updated_q TEST_F(ProjectStorageUpdater, watcher_updates_removed_qmltypes_with_updated_qmldir) { - setProjectDatas( + setDirectoryInfos( directoryPathSourceId, {{directoryPathSourceId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}}); @@ -2905,18 +3180,18 @@ TEST_F(ProjectStorageUpdater, watcher_updates_removed_qmltypes_with_updated_qmld UnorderedElementsAre(qmlDirPathSourceId, qmltypesPathSourceId, qmltypes2PathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmltypes2PathSourceId, - exampleCppNativeModuleId, - FileType::QmlTypes)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmltypes2PathSourceId, + exampleCppNativeModuleId, + FileType::QmlTypes)))))); updater.pathsWithIdsChanged({{qmldirProjectChunkId, {qmlDirPathSourceId}}}); } TEST_F(ProjectStorageUpdater, watcher_dont_watches_directories_after_qmltypes_changes) { - setProjectDatas( + setDirectoryInfos( directoryPathSourceId, {{directoryPathSourceId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}}); @@ -2931,7 +3206,7 @@ TEST_F(ProjectStorageUpdater, watcher_dont_watches_directories_after_qmltypes_ch TEST_F(ProjectStorageUpdater, watcher_dont_updates_qmltypes_for_other_projects) { - setProjectDatas( + setDirectoryInfos( directoryPathSourceId, {{directoryPathSourceId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}}); @@ -2997,21 +3272,21 @@ TEST_F(ProjectStorageUpdater, watcher_updates_directories_and_but_not_included_q IsFileStatus(qmlDocumentSourceId1, 1, 21), IsFileStatus(qmlDocumentSourceId2, 1, 21), IsFileStatus(qmlDocumentSourceId3, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId3, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId3, + ModuleId{}, + FileType::QmlDocument)))))); updater.pathsWithIdsChanged({{directoryProjectChunkId, {directoryPathSourceId}}, {qmlDocumentProjectChunkId, @@ -3074,21 +3349,21 @@ TEST_F(ProjectStorageUpdater, watcher_updates_qmldir_and_but_not_included_qml_do IsFileStatus(qmlDocumentSourceId1, 1, 21), IsFileStatus(qmlDocumentSourceId2, 1, 21), IsFileStatus(qmlDocumentSourceId3, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId3, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId3, + ModuleId{}, + FileType::QmlDocument)))))); updater.pathsWithIdsChanged({{qmldirProjectChunkId, {qmlDirPathSourceId}}, {qmlDocumentProjectChunkId, @@ -3097,7 +3372,7 @@ TEST_F(ProjectStorageUpdater, watcher_updates_qmldir_and_but_not_included_qml_do TEST_F(ProjectStorageUpdater, watcher_updates_qmldir_and_but_not_included_qmltypes) { - setProjectDatas( + setDirectoryInfos( directoryPathSourceId, {{directoryPathSourceId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}, @@ -3173,29 +3448,29 @@ TEST_F(ProjectStorageUpdater, watcher_updates_qmldir_and_but_not_included_qmltyp IsFileStatus(qmlDocumentSourceId1, 1, 21), IsFileStatus(qmlDocumentSourceId2, 1, 21), IsFileStatus(qmlDocumentSourceId3, 1, 21))), - Field(&SynchronizationPackage::updatedProjectSourceIds, + Field(&SynchronizationPackage::updatedDirectoryInfoSourceIds, UnorderedElementsAre(directoryPathSourceId)), - Field(&SynchronizationPackage::projectDatas, - UnorderedElementsAre(IsProjectData(directoryPathSourceId, - qmltypesPathSourceId, - exampleCppNativeModuleId, - FileType::QmlTypes), - IsProjectData(directoryPathSourceId, - qmltypes2PathSourceId, - exampleCppNativeModuleId, - FileType::QmlTypes), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId1, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId2, - ModuleId{}, - FileType::QmlDocument), - IsProjectData(directoryPathSourceId, - qmlDocumentSourceId3, - ModuleId{}, - FileType::QmlDocument)))))); + Field(&SynchronizationPackage::directoryInfos, + UnorderedElementsAre(IsDirectoryInfo(directoryPathSourceId, + qmltypesPathSourceId, + exampleCppNativeModuleId, + FileType::QmlTypes), + IsDirectoryInfo(directoryPathSourceId, + qmltypes2PathSourceId, + exampleCppNativeModuleId, + FileType::QmlTypes), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId1, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId2, + ModuleId{}, + FileType::QmlDocument), + IsDirectoryInfo(directoryPathSourceId, + qmlDocumentSourceId3, + ModuleId{}, + FileType::QmlDocument)))))); updater.pathsWithIdsChanged( {{qmldirProjectChunkId, {qmlDirPathSourceId}}, @@ -3210,7 +3485,8 @@ TEST_F(ProjectStorageUpdater, errors_for_watcher_updates_are_handled) SecondType 2.2 Second.qml)"}; setContent(u"/path/qmldir", qmldir); - ON_CALL(projectStorageMock, synchronize(_)).WillByDefault(Throw(QmlDesigner::ProjectStorageError{})); + ON_CALL(projectStorageMock, synchronize(_)) + .WillByDefault(Throw(QmlDesigner::NoSourcePathForInvalidSourceId{})); ASSERT_NO_THROW(updater.pathsWithIdsChanged({{directoryProjectChunkId, {directoryPathSourceId}}})); } @@ -3222,12 +3498,13 @@ TEST_F(ProjectStorageUpdater, input_is_reused_next_call_if_an_error_happens) FirstType 2.2 First2.qml SecondType 2.2 Second.qml)"}; setContent(u"/path/qmldir", qmldir); - setProjectDatas( + setDirectoryInfos( directoryPathSourceId, {{directoryPathSourceId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}}); setFilesDontChanged({directoryPathSourceId, qmlDirPathSourceId}); - ON_CALL(projectStorageMock, synchronize(_)).WillByDefault(Throw(QmlDesigner::ProjectStorageError{})); + ON_CALL(projectStorageMock, synchronize(_)) + .WillByDefault(Throw(QmlDesigner::NoSourcePathForInvalidSourceId{})); updater.pathsWithIdsChanged( {{qmltypesProjectChunkId, {qmltypesPathSourceId, qmltypes2PathSourceId}}}); ON_CALL(projectStorageMock, synchronize(_)).WillByDefault(Return()); @@ -3268,7 +3545,7 @@ TEST_F(ProjectStorageUpdater, input_is_reused_next_call_if_an_error_happens) qmlDocumentSourceId2, qmltypesPathSourceId, qmltypes2PathSourceId)), - Field(&SynchronizationPackage::projectDatas, IsEmpty())))); + Field(&SynchronizationPackage::directoryInfos, IsEmpty())))); updater.pathsWithIdsChanged( {{qmlDocumentProjectChunkId, {qmlDocumentSourceId1, qmlDocumentSourceId2}}}); @@ -3281,12 +3558,13 @@ TEST_F(ProjectStorageUpdater, input_is_reused_next_call_if_an_error_happens_and_ FirstType 2.2 First2.qml SecondType 2.2 Second.qml)"}; setContent(u"/path/qmldir", qmldir); - setProjectDatas( + setDirectoryInfos( directoryPathSourceId, {{directoryPathSourceId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}}); setFilesDontChanged({directoryPathSourceId, qmlDirPathSourceId}); - ON_CALL(projectStorageMock, synchronize(_)).WillByDefault(Throw(QmlDesigner::ProjectStorageError{})); + ON_CALL(projectStorageMock, synchronize(_)) + .WillByDefault(Throw(QmlDesigner::NoSourcePathForInvalidSourceId{})); updater.pathsWithIdsChanged( {{qmltypesProjectChunkId, {qmltypesPathSourceId, qmltypes2PathSourceId}}}); ON_CALL(projectStorageMock, synchronize(_)).WillByDefault(Return()); @@ -3327,7 +3605,7 @@ TEST_F(ProjectStorageUpdater, input_is_reused_next_call_if_an_error_happens_and_ qmlDocumentSourceId2, qmltypesPathSourceId, qmltypes2PathSourceId)), - Field(&SynchronizationPackage::projectDatas, IsEmpty())))); + Field(&SynchronizationPackage::directoryInfos, IsEmpty())))); updater.pathsWithIdsChanged( {{qmltypesProjectChunkId, {qmltypesPathSourceId, qmltypes2PathSourceId}}, @@ -3341,14 +3619,15 @@ TEST_F(ProjectStorageUpdater, input_is_reused_next_call_if_an_error_happens_and_ FirstType 2.2 First2.qml SecondType 2.2 Second.qml)"}; setContent(u"/path/qmldir", qmldir); - setProjectDatas( + setDirectoryInfos( directoryPathSourceId, {{directoryPathSourceId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathSourceId, qmlDocumentSourceId1, QmlDesigner::ModuleId{}, FileType::QmlDocument}, {directoryPathSourceId, qmlDocumentSourceId1, QmlDesigner::ModuleId{}, FileType::QmlDocument}}); setFilesDontChanged({directoryPathSourceId, qmlDirPathSourceId}); - ON_CALL(projectStorageMock, synchronize(_)).WillByDefault(Throw(QmlDesigner::ProjectStorageError{})); + ON_CALL(projectStorageMock, synchronize(_)) + .WillByDefault(Throw(QmlDesigner::NoSourcePathForInvalidSourceId{})); updater.pathsWithIdsChanged( {{qmlDocumentProjectChunkId, {qmlDocumentSourceId1, qmlDocumentSourceId2}}}); ON_CALL(projectStorageMock, synchronize(_)).WillByDefault(Return()); @@ -3389,7 +3668,7 @@ TEST_F(ProjectStorageUpdater, input_is_reused_next_call_if_an_error_happens_and_ qmlDocumentSourceId2, qmltypesPathSourceId, qmltypes2PathSourceId)), - Field(&SynchronizationPackage::projectDatas, IsEmpty())))); + Field(&SynchronizationPackage::directoryInfos, IsEmpty())))); updater.pathsWithIdsChanged( {{qmltypesProjectChunkId, {qmltypesPathSourceId, qmltypes2PathSourceId}}, @@ -3403,7 +3682,7 @@ TEST_F(ProjectStorageUpdater, input_is_cleared_after_successful_update) FirstType 2.2 First2.qml SecondType 2.2 Second.qml)"}; setContent(u"/path/qmldir", qmldir); - setProjectDatas( + setDirectoryInfos( directoryPathSourceId, {{directoryPathSourceId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes}, {directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}}); @@ -3436,7 +3715,7 @@ TEST_F(ProjectStorageUpdater, input_is_cleared_after_successful_update) IsFileStatus(qmlDocumentSourceId2, 1, 21))), Field(&SynchronizationPackage::updatedFileStatusSourceIds, UnorderedElementsAre(qmlDocumentSourceId1, qmlDocumentSourceId2)), - Field(&SynchronizationPackage::projectDatas, IsEmpty())))); + Field(&SynchronizationPackage::directoryInfos, IsEmpty())))); updater.pathsWithIdsChanged( {{qmlDocumentProjectChunkId, {qmlDocumentSourceId1, qmlDocumentSourceId2}}}); @@ -3458,7 +3737,7 @@ TEST_F(ProjectStorageUpdater, update_property_editor_panes) auto directoryId = sourcePathCache.sourceId( QmlDesigner::SourcePath{propertyEditorQmlPath + "/QML/."}); setFilesChanged({directoryId}); - auto qmlModuleId = storage.moduleId("QML"); + auto qmlModuleId = storage.moduleId("QML", ModuleKind::QmlLibrary); EXPECT_CALL(projectStorageMock, synchronize( @@ -3471,7 +3750,7 @@ TEST_F(ProjectStorageUpdater, update_property_editor_panes) Field(&SynchronizationPackage::updatedPropertyEditorQmlPathSourceIds, ElementsAre(directoryId))))); - updater.update({}, {}, propertyEditorQmlPath); + updater.update({}, {}, propertyEditorQmlPath, {}); } TEST_F(ProjectStorageUpdater, update_property_editor_specifics) @@ -3482,26 +3761,33 @@ TEST_F(ProjectStorageUpdater, update_property_editor_specifics) ON_CALL(projectStorageMock, fetchFileStatus(_)).WillByDefault([](SourceId sourceId) { return FileStatus{sourceId, 1, 21}; }); - auto sourceId = sourcePathCache.sourceId( + auto textSourceId = sourcePathCache.sourceId( QmlDesigner::SourcePath{propertyEditorQmlPath + "/QtQuick/TextSpecifics.qml"}); - auto directoryId = sourcePathCache.sourceId( + auto qtQuickDirectoryId = sourcePathCache.sourceId( QmlDesigner::SourcePath{propertyEditorQmlPath + "/QtQuick/."}); - setFilesChanged({directoryId}); - auto qtQuickModuleId = storage.moduleId("QtQuick"); + auto buttonSourceId = sourcePathCache.sourceId( + QmlDesigner::SourcePath{propertyEditorQmlPath + "/QtQuick/Controls/ButtonSpecifics.qml"}); + auto controlsDirectoryId = sourcePathCache.sourceId( + QmlDesigner::SourcePath{propertyEditorQmlPath + "/QtQuick/Controls/."}); + setFilesChanged({qtQuickDirectoryId, controlsDirectoryId}); + auto qtQuickModuleId = storage.moduleId("QtQuick", ModuleKind::QmlLibrary); + auto controlsModuleId = storage.moduleId("QtQuick.Controls", ModuleKind::QmlLibrary); EXPECT_CALL(projectStorageMock, - synchronize( - AllOf(Field(&SynchronizationPackage::propertyEditorQmlPaths, - Contains(IsPropertyEditorQmlPath(qtQuickModuleId, "Text", sourceId))), - Field(&SynchronizationPackage::updatedPropertyEditorQmlPathSourceIds, - ElementsAre(directoryId))))); + synchronize(AllOf( + Field(&SynchronizationPackage::propertyEditorQmlPaths, + IsSupersetOf( + {IsPropertyEditorQmlPath(qtQuickModuleId, "Text", textSourceId), + IsPropertyEditorQmlPath(controlsModuleId, "Button", buttonSourceId)})), + Field(&SynchronizationPackage::updatedPropertyEditorQmlPathSourceIds, + ElementsAre(qtQuickDirectoryId, controlsDirectoryId))))); - updater.update({}, {}, propertyEditorQmlPath); + updater.update({}, {}, propertyEditorQmlPath, {}); } TEST_F(ProjectStorageUpdater, update_property_editor_panes_is_empty_if_directory_has_not_changed) { - updater.update({}, {}, propertyEditorQmlPath); + updater.update({}, {}, propertyEditorQmlPath, {}); ON_CALL(fileSystemMock, fileStatus(_)).WillByDefault([](SourceId sourceId) { return FileStatus{sourceId, 1, 21}; }); @@ -3511,7 +3797,135 @@ TEST_F(ProjectStorageUpdater, update_property_editor_panes_is_empty_if_directory EXPECT_CALL(projectStorageMock, synchronize(PackageIsEmpty())); - updater.update({}, {}, propertyEditorQmlPath); + updater.update({}, {}, propertyEditorQmlPath, {}); +} + +TEST_F(ProjectStorageUpdater, update_type_annotations) +{ + auto itemSourceId = sourcePathCache.sourceId( + QmlDesigner::SourcePath{itemLibraryPath + "/quick.metainfo"}); + auto buttonSourceId = sourcePathCache.sourceId( + QmlDesigner::SourcePath{itemLibraryPath + "/qtquickcontrols2.metainfo"}); + setFilesChanged({itemLibraryPathSourceId, itemSourceId, buttonSourceId}); + auto qtQuickModuleId = moduleId("QtQuick", ModuleKind::QmlLibrary); + auto qtQuickControlsModuleId = moduleId("QtQuick.Controls.Basic", ModuleKind::QmlLibrary); + QmlDesigner::Storage::TypeTraits itemTraits; + itemTraits.canBeContainer = QmlDesigner::FlagIs::True; + + EXPECT_CALL(projectStorageMock, + synchronize(AllOf(Field(&SynchronizationPackage::typeAnnotations, + IsSupersetOf({IsTypeAnnotation(itemSourceId, + itemLibraryPathSourceId, + "Item", + qtQuickModuleId, + StartsWith(itemLibraryPath), + _, + _, + _), + IsTypeAnnotation(buttonSourceId, + itemLibraryPathSourceId, + "Button", + qtQuickControlsModuleId, + StartsWith(itemLibraryPath), + _, + _, + _)})), + Field(&SynchronizationPackage::updatedTypeAnnotationSourceIds, + IsSupersetOf({itemSourceId, buttonSourceId}))))); + + updater.update({}, {}, {}, {itemLibraryPath}); +} + +TEST_F(ProjectStorageUpdater, update_changed_type_annotation) +{ + auto itemSourceId = sourcePathCache.sourceId( + QmlDesigner::SourcePath{itemLibraryPath + "/quick.metainfo"}); + auto buttonSourceId = sourcePathCache.sourceId( + QmlDesigner::SourcePath{itemLibraryPath + "/qtquickcontrols2.metainfo"}); + setFilesDontChanged({itemLibraryPathSourceId}); + setFilesChanged({itemSourceId, buttonSourceId}); + auto qtQuickModuleId = moduleId("QtQuick", ModuleKind::QmlLibrary); + auto qtQuickControlsModuleId = moduleId("QtQuick.Controls.Basic", ModuleKind::QmlLibrary); + QmlDesigner::Storage::TypeTraits itemTraits; + itemTraits.canBeContainer = QmlDesigner::FlagIs::True; + + EXPECT_CALL(projectStorageMock, + synchronize(AllOf(Field(&SynchronizationPackage::typeAnnotations, + IsSupersetOf({IsTypeAnnotation(itemSourceId, + itemLibraryPathSourceId, + "Item", + qtQuickModuleId, + StartsWith(itemLibraryPath), + _, + _, + _), + IsTypeAnnotation(buttonSourceId, + itemLibraryPathSourceId, + "Button", + qtQuickControlsModuleId, + StartsWith(itemLibraryPath), + _, + _, + _)})), + Field(&SynchronizationPackage::updatedTypeAnnotationSourceIds, + IsSupersetOf({itemSourceId, buttonSourceId}))))); + + updater.update({}, {}, {}, {itemLibraryPath}); +} + +TEST_F(ProjectStorageUpdater, update_type_annotations_removed_meta_info_file) +{ + ON_CALL(fileSystemMock, fileStatus(_)).WillByDefault([](SourceId sourceId) { + return FileStatus{sourceId, 1, 21}; + }); + ON_CALL(projectStorageMock, fetchFileStatus(_)).WillByDefault([](SourceId sourceId) { + return FileStatus{sourceId, 1, 21}; + }); + auto itemSourceId = sourcePathCache.sourceId( + QmlDesigner::SourcePath{itemLibraryPath + "/quick.metainfo"}); + auto buttonSourceId = sourcePathCache.sourceId( + QmlDesigner::SourcePath{itemLibraryPath + "/qtquickcontrols2.metainfo"}); + ON_CALL(projectStorageMock, typeAnnotationDirectorySourceIds()) + .WillByDefault(Return(QmlDesigner::SmallSourceIds<64>{itemLibraryPathSourceId})); + ON_CALL(projectStorageMock, typeAnnotationSourceIds(itemLibraryPathSourceId)) + .WillByDefault(Return(QmlDesigner::SmallSourceIds<4>{itemSourceId, buttonSourceId})); + setFilesChanged({itemLibraryPathSourceId}); + setFilesDontChanged({itemSourceId, buttonSourceId}); + + EXPECT_CALL(projectStorageMock, + synchronize(AllOf(Field(&SynchronizationPackage::typeAnnotations, IsEmpty()), + Field(&SynchronizationPackage::updatedTypeAnnotationSourceIds, + IsSupersetOf({itemSourceId, buttonSourceId}))))); + + updater.update({}, {}, {}, {itemLibraryPath}); +} + +TEST_F(ProjectStorageUpdater, update_type_annotations_removed_directory) +{ + ON_CALL(fileSystemMock, fileStatus(_)).WillByDefault([](SourceId sourceId) { + return FileStatus{sourceId, 1, 21}; + }); + ON_CALL(projectStorageMock, fetchFileStatus(_)).WillByDefault([](SourceId sourceId) { + return FileStatus{sourceId, 1, 21}; + }); + auto itemSourceId = sourcePathCache.sourceId( + QmlDesigner::SourcePath{itemLibraryPath + "/quick.metainfo"}); + auto buttonSourceId = sourcePathCache.sourceId( + QmlDesigner::SourcePath{itemLibraryPath + "/qtquickcontrols2.metainfo"}); + ON_CALL(projectStorageMock, typeAnnotationDirectorySourceIds()) + .WillByDefault(Return(QmlDesigner::SmallSourceIds<64>{ + itemLibraryPathSourceId, + })); + ON_CALL(projectStorageMock, typeAnnotationSourceIds(itemLibraryPathSourceId)) + .WillByDefault(Return(QmlDesigner::SmallSourceIds<4>{itemSourceId, buttonSourceId})); + setFilesDontExists({itemLibraryPathSourceId, buttonSourceId, itemSourceId}); + + EXPECT_CALL(projectStorageMock, + synchronize(AllOf(Field(&SynchronizationPackage::typeAnnotations, IsEmpty()), + Field(&SynchronizationPackage::updatedTypeAnnotationSourceIds, + IsSupersetOf({buttonSourceId, itemSourceId}))))); + + updater.update({}, {}, {}, {itemLibraryPath}); } } // namespace diff --git a/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp b/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp index f39dec121c..e135bb27bd 100644 --- a/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp @@ -3,6 +3,8 @@ #include "../utils/googletest.h" +#include <projectstorageerrornotifiermock.h> + #include <sqlitedatabase.h> #include <projectstorage/projectstorage.h> @@ -16,6 +18,7 @@ namespace Synchronization = Storage::Synchronization; using QmlDesigner::ModuleId; using QmlDesigner::SourceContextId; using QmlDesigner::SourceId; +using QmlDesigner::Storage::ModuleKind; MATCHER_P(HasPrototype, prototype, std::string(negation ? "isn't " : "is ") + PrintToString(prototype)) { @@ -143,15 +146,16 @@ class QmlDocumentParser : public ::testing::Test public: protected: Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; - QmlDesigner::ProjectStorage<Sqlite::Database> storage{database, database.isInitialized()}; - QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage<Sqlite::Database>> sourcePathCache{ + ProjectStorageErrorNotifierMock errorNotifierMock; + QmlDesigner::ProjectStorage storage{database, errorNotifierMock, database.isInitialized()}; + QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage> sourcePathCache{ storage}; QmlDesigner::QmlDocumentParser parser{storage, sourcePathCache}; Storage::Imports imports; SourceId qmlFileSourceId{sourcePathCache.sourceId("/path/to/qmlfile.qml")}; SourceContextId qmlFileSourceContextId{sourcePathCache.sourceContextId(qmlFileSourceId)}; Utils::PathString directoryPath{sourcePathCache.sourceContextPath(qmlFileSourceContextId)}; - ModuleId directoryModuleId{storage.moduleId(directoryPath)}; + ModuleId directoryModuleId{storage.moduleId(directoryPath, ModuleKind::PathLibrary)}; }; TEST_F(QmlDocumentParser, prototype) @@ -163,7 +167,7 @@ TEST_F(QmlDocumentParser, prototype) TEST_F(QmlDocumentParser, qualified_prototype) { - auto exampleModuleId = storage.moduleId("Example"); + auto exampleModuleId = storage.moduleId("Example", ModuleKind::QmlLibrary); QString text = R"(import Example 2.1 as Example Example.Item{})"; @@ -187,7 +191,7 @@ TEST_F(QmlDocumentParser, properties) TEST_F(QmlDocumentParser, qualified_properties) { - auto exampleModuleId = storage.moduleId("Example"); + auto exampleModuleId = storage.moduleId("Example", ModuleKind::QmlLibrary); auto type = parser.parse(R"(import Example 2.1 as Example Item{ property Example.Foo foo})", @@ -222,7 +226,7 @@ TEST_F(QmlDocumentParser, enumeration_in_properties) TEST_F(QmlDocumentParser, qualified_enumeration_in_properties) { - auto exampleModuleId = storage.moduleId("Example"); + auto exampleModuleId = storage.moduleId("Example", ModuleKind::QmlLibrary); auto type = parser.parse(R"(import Example 2.1 as Example Item{ property Example.Enumeration.Foo foo})", @@ -242,9 +246,9 @@ TEST_F(QmlDocumentParser, qualified_enumeration_in_properties) TEST_F(QmlDocumentParser, imports) { - ModuleId fooDirectoryModuleId = storage.moduleId("/path/foo"); - ModuleId qmlModuleId = storage.moduleId("QML"); - ModuleId qtQuickModuleId = storage.moduleId("QtQuick"); + ModuleId fooDirectoryModuleId = storage.moduleId("/path/foo", ModuleKind::PathLibrary); + ModuleId qmlModuleId = storage.moduleId("QML", ModuleKind::QmlLibrary); + ModuleId qtQuickModuleId = storage.moduleId("QtQuick", ModuleKind::QmlLibrary); auto type = parser.parse(R"(import QtQuick import "../foo" @@ -263,9 +267,9 @@ TEST_F(QmlDocumentParser, imports) TEST_F(QmlDocumentParser, imports_with_version) { - ModuleId fooDirectoryModuleId = storage.moduleId("/path/foo"); - ModuleId qmlModuleId = storage.moduleId("QML"); - ModuleId qtQuickModuleId = storage.moduleId("QtQuick"); + ModuleId fooDirectoryModuleId = storage.moduleId("/path/foo", ModuleKind::PathLibrary); + ModuleId qmlModuleId = storage.moduleId("QML", ModuleKind::QmlLibrary); + ModuleId qtQuickModuleId = storage.moduleId("QtQuick", ModuleKind::QmlLibrary); auto type = parser.parse(R"(import QtQuick 2.1 import "../foo" @@ -284,8 +288,8 @@ TEST_F(QmlDocumentParser, imports_with_version) TEST_F(QmlDocumentParser, imports_with_explict_directory) { - ModuleId qmlModuleId = storage.moduleId("QML"); - ModuleId qtQuickModuleId = storage.moduleId("QtQuick"); + ModuleId qmlModuleId = storage.moduleId("QML", ModuleKind::QmlLibrary); + ModuleId qtQuickModuleId = storage.moduleId("QtQuick", ModuleKind::QmlLibrary); auto type = parser.parse(R"(import QtQuick import "../to" @@ -358,10 +362,10 @@ TEST_F(QmlDocumentParser, enumeration) TEST_F(QmlDocumentParser, DISABLED_duplicate_imports_are_removed) { - ModuleId fooDirectoryModuleId = storage.moduleId("/path/foo"); - ModuleId qmlModuleId = storage.moduleId("QML"); - ModuleId qtQmlModuleId = storage.moduleId("QtQml"); - ModuleId qtQuickModuleId = storage.moduleId("QtQuick"); + ModuleId fooDirectoryModuleId = storage.moduleId("/path/foo", ModuleKind::PathLibrary); + ModuleId qmlModuleId = storage.moduleId("QML", ModuleKind::QmlLibrary); + ModuleId qtQmlModuleId = storage.moduleId("QtQml", ModuleKind::QmlLibrary); + ModuleId qtQuickModuleId = storage.moduleId("QtQuick", ModuleKind::QmlLibrary); auto type = parser.parse(R"(import QtQuick import "../foo" @@ -497,7 +501,7 @@ TEST_F(QmlDocumentParser, alias_on_list_property) TEST_F(QmlDocumentParser, qualified_list_property) { - auto exampleModuleId = storage.moduleId("Example"); + auto exampleModuleId = storage.moduleId("Example", ModuleKind::QmlLibrary); auto type = parser.parse(R"(import Example 2.1 as Example Item{ property list<Example.Foo> foos @@ -516,4 +520,16 @@ TEST_F(QmlDocumentParser, qualified_list_property) Storage::PropertyDeclarationTraits::IsList))); } +TEST_F(QmlDocumentParser, default_property) +{ + auto type = parser.parse(R"(import Example 2.1 as Example + Item{ + default property list<Example.Foo> foos + })", + imports, + qmlFileSourceId, + directoryPath); + + ASSERT_THAT(type.defaultPropertyName, Eq("foos")); +} } // namespace diff --git a/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp b/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp index 78f8f41d6c..e75f7bf3a9 100644 --- a/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp @@ -3,6 +3,8 @@ #include "../utils/googletest.h" +#include <projectstorageerrornotifiermock.h> + #include <sqlitedatabase.h> #include <projectstorage/projectstorage.h> @@ -17,6 +19,7 @@ namespace Synchronization = QmlDesigner::Storage::Synchronization; using QmlDesigner::ModuleId; using QmlDesigner::SourceContextId; using QmlDesigner::SourceId; +using QmlDesigner::Storage::ModuleKind; MATCHER_P3(IsImport, moduleId, @@ -168,20 +171,20 @@ class QmlTypesParser : public ::testing::Test public: protected: Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; - QmlDesigner::ProjectStorage<Sqlite::Database> storage{database, database.isInitialized()}; - QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage<Sqlite::Database>> sourcePathCache{ + ProjectStorageErrorNotifierMock errorNotifierMock; + QmlDesigner::ProjectStorage storage{database, errorNotifierMock, database.isInitialized()}; + QmlDesigner::SourcePathCache<QmlDesigner::ProjectStorage> sourcePathCache{ storage}; QmlDesigner::QmlTypesParser parser{storage}; Storage::Imports imports; Synchronization::Types types; SourceId qmltypesFileSourceId{sourcePathCache.sourceId("path/to/types.qmltypes")}; - ModuleId qtQmlNativeModuleId = storage.moduleId("QtQml-cppnative"); - Synchronization::ProjectData projectData{qmltypesFileSourceId, + ModuleId qtQmlNativeModuleId = storage.moduleId("QtQml", ModuleKind::CppLibrary); + Synchronization::DirectoryInfo directoryInfo{qmltypesFileSourceId, qmltypesFileSourceId, qtQmlNativeModuleId, Synchronization::FileType::QmlTypes}; SourceContextId qmltypesFileSourceContextId{sourcePathCache.sourceContextId(qmltypesFileSourceId)}; - ModuleId directoryModuleId{storage.moduleId("path/to/")}; }; TEST_F(QmlTypesParser, imports) @@ -191,22 +194,22 @@ TEST_F(QmlTypesParser, imports) dependencies: ["QtQuick 2.15", "QtQuick.Window 2.1", "QtFoo 6"]})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(imports, - UnorderedElementsAre(IsImport(storage.moduleId("QML-cppnative"), + UnorderedElementsAre(IsImport(storage.moduleId("QML", ModuleKind::CppLibrary), QmlDesigner::Storage::Version{}, qmltypesFileSourceId), - IsImport(storage.moduleId("QtQml-cppnative"), + IsImport(storage.moduleId("QtQml", ModuleKind::CppLibrary), QmlDesigner::Storage::Version{}, qmltypesFileSourceId), - IsImport(storage.moduleId("QtQuick-cppnative"), + IsImport(storage.moduleId("QtQuick", ModuleKind::CppLibrary), QmlDesigner::Storage::Version{}, qmltypesFileSourceId), - IsImport(storage.moduleId("QtQuick.Window-cppnative"), + IsImport(storage.moduleId("QtQuick.Window", ModuleKind::CppLibrary), QmlDesigner::Storage::Version{}, qmltypesFileSourceId), - IsImport(storage.moduleId("QtFoo-cppnative"), + IsImport(storage.moduleId("QtFoo", ModuleKind::CppLibrary), QmlDesigner::Storage::Version{}, qmltypesFileSourceId))); } @@ -218,7 +221,7 @@ TEST_F(QmlTypesParser, types) Component { name: "QObject"} Component { name: "QQmlComponent"}})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, UnorderedElementsAre(IsType("QObject", @@ -241,7 +244,7 @@ TEST_F(QmlTypesParser, prototype) Component { name: "QQmlComponent" prototype: "QObject"}})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, UnorderedElementsAre(IsType("QObject", @@ -264,7 +267,7 @@ TEST_F(QmlTypesParser, extension) Component { name: "QQmlComponent" extension: "QObject"}})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, UnorderedElementsAre(IsType("QObject", @@ -286,10 +289,10 @@ TEST_F(QmlTypesParser, exported_types) Component { name: "QObject" exports: ["QML/QtObject 1.0", "QtQml/QtObject 2.1"] }})"}; - ModuleId qmlModuleId = storage.moduleId("QML"); - ModuleId qtQmlModuleId = storage.moduleId("QtQml"); + ModuleId qmlModuleId = storage.moduleId("QML", ModuleKind::QmlLibrary); + ModuleId qtQmlModuleId = storage.moduleId("QtQml", ModuleKind::QmlLibrary); - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT( types, @@ -312,7 +315,7 @@ TEST_F(QmlTypesParser, properties) Property { name: "targets"; type: "QQuickItem"; isList: true; isReadonly: true; isPointer: true } }})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, ElementsAre(Field( @@ -346,7 +349,7 @@ TEST_F(QmlTypesParser, properties_with_qualified_types) Property { name: "values2"; type: "Qt::Vector" } }})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, Contains( @@ -372,7 +375,7 @@ TEST_F(QmlTypesParser, properties_without_type) Property { name: "target"; type: "QObject"; isPointer: true } }})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, ElementsAre( @@ -405,7 +408,7 @@ TEST_F(QmlTypesParser, functions) } }})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, ElementsAre(Field( @@ -436,7 +439,7 @@ TEST_F(QmlTypesParser, skip_java_script_functions) } }})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, ElementsAre(Field(&Synchronization::Type::functionDeclarations, IsEmpty()))); } @@ -456,7 +459,7 @@ TEST_F(QmlTypesParser, functions_with_qualified_types) } }})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, Contains( @@ -491,7 +494,7 @@ TEST_F(QmlTypesParser, signals) } }})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, ElementsAre(Field(&Synchronization::Type::signalDeclarations, @@ -524,7 +527,7 @@ TEST_F(QmlTypesParser, signals_with_qualified_types) } }})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, Contains( @@ -557,7 +560,7 @@ TEST_F(QmlTypesParser, enumerations) } }})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, Contains(Field( @@ -596,7 +599,7 @@ TEST_F(QmlTypesParser, enumeration_is_exported_as_type) exports: ["QML/QtObject 1.0", "QtQml/QtObject 2.1"] }})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); QmlDesigner::Storage::TypeTraits traits{QmlDesigner::Storage::TypeTraitsKind::Value}; traits.isEnum = true; @@ -642,7 +645,7 @@ TEST_F(QmlTypesParser, enumeration_is_exported_as_type_with_alias) exports: ["QML/QtObject 1.0", "QtQml/QtObject 2.1"] }})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); QmlDesigner::Storage::TypeTraits traits{QmlDesigner::Storage::TypeTraitsKind::Value}; traits.isEnum = true; @@ -690,7 +693,7 @@ TEST_F(QmlTypesParser, enumeration_is_exported_as_type_with_alias_too) exports: ["QML/QtObject 1.0", "QtQml/QtObject 2.1"] }})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); QmlDesigner::Storage::TypeTraits traits{QmlDesigner::Storage::TypeTraitsKind::Value}; traits.isEnum = true; @@ -728,7 +731,7 @@ TEST_F(QmlTypesParser, enumeration_is_referenced_by_qualified_name) } }})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, Contains(Field(&Synchronization::Type::propertyDeclarations, @@ -756,7 +759,7 @@ TEST_F(QmlTypesParser, alias_enumeration_is_referenced_by_qualified_name) } }})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, Contains(Field(&Synchronization::Type::propertyDeclarations, @@ -773,7 +776,7 @@ TEST_F(QmlTypesParser, access_type_is_reference) Component { name: "QObject" accessSemantics: "reference"}})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, ElementsAre(IsTypeTrait(Storage::TypeTraitsKind::Reference))); } @@ -785,7 +788,7 @@ TEST_F(QmlTypesParser, access_type_is_value) Component { name: "QObject" accessSemantics: "value"}})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, ElementsAre(IsTypeTrait(Storage::TypeTraitsKind::Value))); } @@ -797,7 +800,7 @@ TEST_F(QmlTypesParser, access_type_is_sequence) Component { name: "QObject" accessSemantics: "sequence"}})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, ElementsAre(IsTypeTrait(Storage::TypeTraitsKind::Sequence))); } @@ -809,7 +812,7 @@ TEST_F(QmlTypesParser, access_type_is_none) Component { name: "QObject" accessSemantics: "none"}})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, ElementsAre(IsTypeTrait(Storage::TypeTraitsKind::None))); } @@ -821,7 +824,7 @@ TEST_F(QmlTypesParser, uses_custom_parser) Component { name: "QObject" hasCustomParser: true }})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, ElementsAre(IsTypeTrait(UsesCustomParser(true)))); } @@ -833,9 +836,44 @@ TEST_F(QmlTypesParser, uses_no_custom_parser) Component { name: "QObject" hasCustomParser: false }})"}; - parser.parse(source, imports, types, projectData); + parser.parse(source, imports, types, directoryInfo); ASSERT_THAT(types, ElementsAre(IsTypeTrait(UsesCustomParser(false)))); } +TEST_F(QmlTypesParser, default_property) +{ + QString source{R"(import QtQuick.tooling 1.2 + Module{ + Component { name: "QObject" + defaultProperty: "children" }})"}; + + parser.parse(source, imports, types, directoryInfo); + + ASSERT_THAT(types, + ElementsAre(Field(&Synchronization::Type::defaultPropertyName, Eq("children")))); +} + +TEST_F(QmlTypesParser, skip_template_item) +{ + ModuleId moduleId = storage.moduleId("QtQuick.Templates", ModuleKind::CppLibrary); + Synchronization::DirectoryInfo directoryInfo{qmltypesFileSourceId, + qmltypesFileSourceId, + moduleId, + Synchronization::FileType::QmlTypes}; + QString source{R"(import QtQuick.tooling 1.2 + Module{ + Component { name: "QQuickItem"} + Component { name: "QQmlComponent"}})"}; + + parser.parse(source, imports, types, directoryInfo); + + ASSERT_THAT(types, + UnorderedElementsAre(IsType("QQmlComponent", + Synchronization::ImportedType{}, + Synchronization::ImportedType{}, + Storage::TypeTraitsKind::Reference, + qmltypesFileSourceId))); +} + } // namespace diff --git a/tests/unit/tests/unittests/projectstorage/typeannotationreader-test.cpp b/tests/unit/tests/unittests/projectstorage/typeannotationreader-test.cpp index ed5c1a0778..d55c368f6e 100644 --- a/tests/unit/tests/unittests/projectstorage/typeannotationreader-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/typeannotationreader-test.cpp @@ -3,6 +3,8 @@ #include "../utils/googletest.h" +#include <projectstorage-matcher.h> +#include <projectstorageerrornotifiermock.h> #include <strippedstring-matcher.h> #include <projectstorage/projectstorage.h> @@ -11,51 +13,47 @@ namespace { -template<typename HintsJsonMatcher, typename ItemLibraryJsonMatcher> -auto IsTypeAnnotation(QmlDesigner::SourceId sourceId, - Utils::SmallStringView typeName, - QmlDesigner::ModuleId moduleId, - Utils::SmallStringView iconPath, - QmlDesigner::Storage::TypeTraits traits, - HintsJsonMatcher hintsJsonMatcher, - ItemLibraryJsonMatcher itemLibraryJsonMatcher) -{ - using QmlDesigner::Storage::Synchronization::TypeAnnotation; - return AllOf(Field("sourceId", &TypeAnnotation::sourceId, sourceId), - Field("typeName", &TypeAnnotation::typeName, typeName), - Field("moduleId", &TypeAnnotation::moduleId, moduleId), - Field("iconPath", &TypeAnnotation::iconPath, iconPath), - Field("traits", &TypeAnnotation::traits, traits), - Field("hintsJson", &TypeAnnotation::hintsJson, hintsJsonMatcher), - Field("itemLibraryJson", &TypeAnnotation::itemLibraryJson, itemLibraryJsonMatcher)); -} +using QmlDesigner::FlagIs; class TypeAnnotationReader : public testing::Test { protected: - static void SetUpTestSuite() + TypeAnnotationReader() { - static_database = std::make_unique<Sqlite::Database>(":memory:", Sqlite::JournalMode::Memory); - - static_projectStorage = std::make_unique<QmlDesigner::ProjectStorage<Sqlite::Database>>( - *static_database, static_database->isInitialized()); + traits.canBeDroppedInFormEditor = FlagIs::True; + traits.canBeDroppedInNavigator = FlagIs::True; + traits.isMovable = FlagIs::True; + traits.isResizable = FlagIs::True; + traits.hasFormEditorItem = FlagIs::True; + traits.visibleInLibrary = FlagIs::True; } - static void TearDownTestSuite() + ~TypeAnnotationReader() { storage.resetForTestsOnly(); } + + struct StaticData { - static_projectStorage.reset(); - static_database.reset(); - } + Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; + ProjectStorageErrorNotifierMock errorNotifierMock; + QmlDesigner::ProjectStorage storage{database, errorNotifierMock, database.isInitialized()}; + }; - auto moduleId(Utils::SmallStringView name) const { return storage.moduleId(name); } + static void SetUpTestSuite() { staticData = std::make_unique<StaticData>(); } + + static void TearDownTestSuite() { staticData.reset(); } + + auto moduleId(Utils::SmallStringView name) const + { + return storage.moduleId(name, QmlDesigner::Storage::ModuleKind::QmlLibrary); + } protected: - inline static std::unique_ptr<Sqlite::Database> static_database; - Sqlite::Database &database = *static_database; - inline static std::unique_ptr<QmlDesigner::ProjectStorage<Sqlite::Database>> static_projectStorage; - QmlDesigner::ProjectStorage<Sqlite::Database> &storage = *static_projectStorage; + inline static std::unique_ptr<StaticData> staticData; + Sqlite::Database &database = staticData->database; + QmlDesigner::ProjectStorage &storage = staticData->storage; QmlDesigner::Storage::TypeAnnotationReader reader{storage}; QmlDesigner::SourceId sourceId = QmlDesigner::SourceId::create(33); + QmlDesigner::SourceId directorySourceId = QmlDesigner::SourceId::create(77); + QmlDesigner::Storage::TypeTraits traits; }; TEST_F(TypeAnnotationReader, parse_type) @@ -71,12 +69,12 @@ TEST_F(TypeAnnotationReader, parse_type) icon: "images/item-icon16.png" } })xy"}; - QmlDesigner::Storage::TypeTraits traits; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, UnorderedElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), "/path/images/frame-icon16.png", @@ -84,6 +82,7 @@ TEST_F(TypeAnnotationReader, parse_type) IsEmpty(), IsEmpty()), IsTypeAnnotation(sourceId, + directorySourceId, "Item", moduleId("QtQuick"), "/path/images/item-icon16.png", @@ -106,13 +105,13 @@ TEST_F(TypeAnnotationReader, parse_true_canBeContainer) } } })xy"}; - QmlDesigner::Storage::TypeTraits traits; traits.canBeContainer = FlagIs::True; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, ElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), "/path/images/frame-icon16.png", @@ -135,13 +134,13 @@ TEST_F(TypeAnnotationReader, parse_true_forceClip) } } })xy"}; - QmlDesigner::Storage::TypeTraits traits; traits.forceClip = FlagIs::True; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, ElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), "/path/images/frame-icon16.png", @@ -164,13 +163,13 @@ TEST_F(TypeAnnotationReader, parse_true_doesLayoutChildren) } } })xy"}; - QmlDesigner::Storage::TypeTraits traits; traits.doesLayoutChildren = FlagIs::True; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, ElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), "/path/images/frame-icon16.png", @@ -179,7 +178,7 @@ TEST_F(TypeAnnotationReader, parse_true_doesLayoutChildren) IsEmpty()))); } -TEST_F(TypeAnnotationReader, parse_true_canBeDroppedInFormEditor) +TEST_F(TypeAnnotationReader, parse_false_canBeDroppedInFormEditor) { using QmlDesigner::FlagIs; auto content = QString{R"xy( @@ -189,17 +188,17 @@ TEST_F(TypeAnnotationReader, parse_true_canBeDroppedInFormEditor) icon: "images/frame-icon16.png" Hints { - canBeDroppedInFormEditor: true + canBeDroppedInFormEditor: false } } })xy"}; - QmlDesigner::Storage::TypeTraits traits; - traits.canBeDroppedInFormEditor = FlagIs::True; + traits.canBeDroppedInFormEditor = FlagIs::False; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, ElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), "/path/images/frame-icon16.png", @@ -208,7 +207,7 @@ TEST_F(TypeAnnotationReader, parse_true_canBeDroppedInFormEditor) IsEmpty()))); } -TEST_F(TypeAnnotationReader, parse_true_canBeDroppedInNavigator) +TEST_F(TypeAnnotationReader, parse_false_canBeDroppedInNavigator) { using QmlDesigner::FlagIs; auto content = QString{R"xy( @@ -218,17 +217,17 @@ TEST_F(TypeAnnotationReader, parse_true_canBeDroppedInNavigator) icon: "images/frame-icon16.png" Hints { - canBeDroppedInNavigator: true + canBeDroppedInNavigator: false } } })xy"}; - QmlDesigner::Storage::TypeTraits traits; - traits.canBeDroppedInNavigator = FlagIs::True; + traits.canBeDroppedInNavigator = FlagIs::False; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, ElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), "/path/images/frame-icon16.png", @@ -251,13 +250,13 @@ TEST_F(TypeAnnotationReader, parse_true_canBeDroppedInView3D) } } })xy"}; - QmlDesigner::Storage::TypeTraits traits; traits.canBeDroppedInView3D = FlagIs::True; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, ElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), "/path/images/frame-icon16.png", @@ -266,7 +265,7 @@ TEST_F(TypeAnnotationReader, parse_true_canBeDroppedInView3D) IsEmpty()))); } -TEST_F(TypeAnnotationReader, parse_true_isMovable) +TEST_F(TypeAnnotationReader, parse_false_isMovable) { using QmlDesigner::FlagIs; auto content = QString{R"xy( @@ -276,17 +275,17 @@ TEST_F(TypeAnnotationReader, parse_true_isMovable) icon: "images/frame-icon16.png" Hints { - isMovable: true + isMovable: false } } })xy"}; - QmlDesigner::Storage::TypeTraits traits; - traits.isMovable = FlagIs::True; + traits.isMovable = FlagIs::False; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, ElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), "/path/images/frame-icon16.png", @@ -295,7 +294,7 @@ TEST_F(TypeAnnotationReader, parse_true_isMovable) IsEmpty()))); } -TEST_F(TypeAnnotationReader, parse_true_isResizable) +TEST_F(TypeAnnotationReader, parse_false_isResizable) { using QmlDesigner::FlagIs; auto content = QString{R"xy( @@ -305,17 +304,17 @@ TEST_F(TypeAnnotationReader, parse_true_isResizable) icon: "images/frame-icon16.png" Hints { - isResizable: true + isResizable: false } } })xy"}; - QmlDesigner::Storage::TypeTraits traits; - traits.isResizable = FlagIs::True; + traits.isResizable = FlagIs::False; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, ElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), "/path/images/frame-icon16.png", @@ -324,7 +323,7 @@ TEST_F(TypeAnnotationReader, parse_true_isResizable) IsEmpty()))); } -TEST_F(TypeAnnotationReader, parse_true_hasFormEditorItem) +TEST_F(TypeAnnotationReader, parse_false_hasFormEditorItem) { using QmlDesigner::FlagIs; auto content = QString{R"xy( @@ -334,17 +333,17 @@ TEST_F(TypeAnnotationReader, parse_true_hasFormEditorItem) icon: "images/frame-icon16.png" Hints { - hasFormEditorItem: true + hasFormEditorItem: false } } })xy"}; - QmlDesigner::Storage::TypeTraits traits; - traits.hasFormEditorItem = FlagIs::True; + traits.hasFormEditorItem = FlagIs::False; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, ElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), "/path/images/frame-icon16.png", @@ -367,13 +366,13 @@ TEST_F(TypeAnnotationReader, parse_true_isStackedContainer) } } })xy"}; - QmlDesigner::Storage::TypeTraits traits; traits.isStackedContainer = FlagIs::True; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, ElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), "/path/images/frame-icon16.png", @@ -396,13 +395,13 @@ TEST_F(TypeAnnotationReader, parse_true_takesOverRenderingOfChildren) } } })xy"}; - QmlDesigner::Storage::TypeTraits traits; traits.takesOverRenderingOfChildren = FlagIs::True; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, ElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), "/path/images/frame-icon16.png", @@ -425,13 +424,13 @@ TEST_F(TypeAnnotationReader, parse_true_visibleInNavigator) } } })xy"}; - QmlDesigner::Storage::TypeTraits traits; traits.visibleInNavigator = FlagIs::True; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, ElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), "/path/images/frame-icon16.png", @@ -440,7 +439,7 @@ TEST_F(TypeAnnotationReader, parse_true_visibleInNavigator) IsEmpty()))); } -TEST_F(TypeAnnotationReader, parse_true_visibleInLibrary) +TEST_F(TypeAnnotationReader, parse_false_visibleInLibrary) { using QmlDesigner::FlagIs; auto content = QString{R"xy( @@ -450,17 +449,17 @@ TEST_F(TypeAnnotationReader, parse_true_visibleInLibrary) icon: "images/frame-icon16.png" Hints { - visibleInLibrary: true + visibleInLibrary: false } } })xy"}; - QmlDesigner::Storage::TypeTraits traits; - traits.visibleInLibrary = FlagIs::True; + traits.visibleInLibrary = FlagIs::False; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, ElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), "/path/images/frame-icon16.png", @@ -479,16 +478,16 @@ TEST_F(TypeAnnotationReader, parse_false) icon: "images/frame-icon16.png" Hints { - isMovable: false + isMovable: true } } })xy"}; - QmlDesigner::Storage::TypeTraits traits; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, ElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), "/path/images/frame-icon16.png", @@ -521,15 +520,16 @@ TEST_F(TypeAnnotationReader, parse_complex_expression) } } })xy"}; - QmlDesigner::Storage::TypeTraits frameTraits; + QmlDesigner::Storage::TypeTraits frameTraits = traits; frameTraits.isMovable = QmlDesigner::FlagIs::Set; - QmlDesigner::Storage::TypeTraits itemTraits; + QmlDesigner::Storage::TypeTraits itemTraits = traits; itemTraits.canBeContainer = QmlDesigner::FlagIs::True; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, UnorderedElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), "/path/images/frame-icon16.png", @@ -538,6 +538,7 @@ TEST_F(TypeAnnotationReader, parse_complex_expression) "visibleNonDefaultProperties":"layer.effect"})xy"), IsEmpty()), IsTypeAnnotation(sourceId, + directorySourceId, "Item", moduleId("QtQuick"), "/path/images/item-icon16.png", @@ -571,12 +572,12 @@ TEST_F(TypeAnnotationReader, parse_item_library_entry) } } })xy"}; - QmlDesigner::Storage::TypeTraits traits; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, ElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), "/path/images/frame-icon16.png", @@ -584,12 +585,12 @@ TEST_F(TypeAnnotationReader, parse_item_library_entry) IsEmpty(), StrippedStringEq(R"xy([ {"category":"Qt Quick - Controls 2", - "iconPath":"images/frame-icon.png", + "iconPath":"/path/images/frame-icon.png", "import":"QtQuick.Controls", "name":"Frame", "toolTip":"qsTr(\"An untitled container for a group of controls.\")"}, {"category":"Qt Quick - Controls 2", - "iconPath":"images/frame-icon.png", + "iconPath":"/path/images/frame-icon.png", "import":"QtQuick.Controls", "name":"Large Frame", "toolTip":"qsTr(\"An large container for a group of controls.\")"}] @@ -627,12 +628,12 @@ TEST_F(TypeAnnotationReader, parse_item_library_entry_with_properties) } } })xy"}; - QmlDesigner::Storage::TypeTraits traits; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, ElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), "/path/images/frame-icon16.png", @@ -640,13 +641,13 @@ TEST_F(TypeAnnotationReader, parse_item_library_entry_with_properties) IsEmpty(), StrippedStringEq(R"xy([ {"category":"Qt Quick - Controls 2", - "iconPath":"images/frame-icon.png", + "iconPath":"/path/images/frame-icon.png", "import":"QtQuick.Controls", "name":"Frame", "properties":[["width","int",200.0],["height","int",100.0]], "toolTip":"qsTr(\"An untitled container for a group of controls.\")"}, {"category":"Qt Quick - Controls 2", - "iconPath":"images/frame-icon.png", + "iconPath":"/path/images/frame-icon.png", "import":"QtQuick.Controls", "name":"Large Frame", "properties":[["width","int",2000.0],["height","int",1000.0]], @@ -677,15 +678,15 @@ TEST_F(TypeAnnotationReader, parse_item_library_entry_template_path) } } })xy"}; - QmlDesigner::Storage::TypeTraits traits; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, ElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), - {}, + Utils::SmallStringView{}, traits, IsEmpty(), StrippedStringEq(R"xy([ @@ -693,9 +694,10 @@ TEST_F(TypeAnnotationReader, parse_item_library_entry_template_path) "templatePath":"/path/templates/frame.qml"}] )xy")), IsTypeAnnotation(sourceId, + directorySourceId, "Item", moduleId("QtQuick"), - {}, + Utils::SmallStringView{}, traits, IsEmpty(), StrippedStringEq(R"xy([ @@ -728,15 +730,15 @@ TEST_F(TypeAnnotationReader, parse_item_library_entry_extra_file_paths) } } })xy"}; - QmlDesigner::Storage::TypeTraits traits; - auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId); + auto annotations = reader.parseTypeAnnotation(content, "/path", sourceId, directorySourceId); ASSERT_THAT(annotations, ElementsAre(IsTypeAnnotation(sourceId, + directorySourceId, "Frame", moduleId("QtQuick.Controls"), - {}, + Utils::SmallStringView{}, traits, IsEmpty(), StrippedStringEq(R"xy([ @@ -744,9 +746,10 @@ TEST_F(TypeAnnotationReader, parse_item_library_entry_extra_file_paths) "name":"Frame"}] )xy")), IsTypeAnnotation(sourceId, + directorySourceId, "Item", moduleId("QtQuick"), - {}, + Utils::SmallStringView{}, traits, IsEmpty(), StrippedStringEq(R"xy([ diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.jsontoqml b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.jsontoqml index 2a67b12d50..90c980cda1 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.jsontoqml +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.jsontoqml @@ -7,6 +7,7 @@ Project { mainFile: "content/App.qml" mainUiFile: "content/Screen01.ui.qml" targetDirectory: "/opt/UntitledProject13" + enableCMakeGeneration: false widgetApp: true importPaths: [ "imports","asset_imports" ] diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.qmlproject b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.qmlproject index 260938164a..cb0ca5f9e1 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.qmlproject +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.qmlproject @@ -90,6 +90,8 @@ Project { /* Required for deployment */ targetDirectory: "/opt/UntitledProject13" + enableCMakeGeneration: false + qdsVersion: "4.0" quickVersion: "6.2" diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.qmltojson b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.qmltojson index c4475af39c..e362cdf886 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.qmltojson +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.qmltojson @@ -1,5 +1,6 @@ { "deployment": { + "enableCMakeGeneration": false, "targetDirectory": "/opt/UntitledProject13" }, "environment": { @@ -74,7 +75,12 @@ "*.png", "*.svg", "*.hdr", - "*.ktx" + "*.ktx", + "*.bmp", + "*.ttf", + "*.tiff", + "*.webp", + "*.gif" ], "mcuProperties": { }, @@ -92,7 +98,12 @@ "*.png", "*.svg", "*.hdr", - "*.ktx" + "*.ktx", + "*.bmp", + "*.ttf", + "*.tiff", + "*.webp", + "*.gif" ], "mcuProperties": { }, diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.jsontoqml b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.jsontoqml index 5878bdafc7..16617e015d 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.jsontoqml +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.jsontoqml @@ -6,6 +6,7 @@ import QmlProject Project { mainFile: "fileSelectors.qml" targetDirectory: "/opt/fileSelectors" + enableCMakeGeneration: false widgetApp: false importPaths: [ "imports" ] diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.qmlproject b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.qmlproject index 3ceeda651a..29bc108e68 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.qmlproject +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.qmlproject @@ -44,4 +44,6 @@ Project { /* Required for deployment */ targetDirectory: "/opt/fileSelectors" + + enableCMakeGeneration: false } diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.qmltojson b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.qmltojson index a26e0fc160..80eaf6fefa 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.qmltojson +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.qmltojson @@ -1,5 +1,6 @@ { "deployment": { + "enableCMakeGeneration": false, "targetDirectory": "/opt/fileSelectors" }, "environment": { @@ -44,7 +45,12 @@ "*.png", "*.svg", "*.hdr", - "*.ktx" + "*.ktx", + "*.bmp", + "*.ttf", + "*.tiff", + "*.webp", + "*.gif" ], "mcuProperties": { }, diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.jsontoqml b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.jsontoqml index 2a67b12d50..90c980cda1 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.jsontoqml +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.jsontoqml @@ -7,6 +7,7 @@ Project { mainFile: "content/App.qml" mainUiFile: "content/Screen01.ui.qml" targetDirectory: "/opt/UntitledProject13" + enableCMakeGeneration: false widgetApp: true importPaths: [ "imports","asset_imports" ] diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.qmlproject b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.qmlproject index 1ec43b95d5..faf115d609 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.qmlproject +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.qmlproject @@ -90,6 +90,8 @@ Project { /* Required for deployment */ QDS.targetDirectory: "/opt/UntitledProject13" + QDS.enableCMakeGeneration: false + QDS.qdsVersion: "4.0" QDS.quickVersion: "6.2" diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.qmltojson b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.qmltojson index c4475af39c..e362cdf886 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.qmltojson +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.qmltojson @@ -1,5 +1,6 @@ { "deployment": { + "enableCMakeGeneration": false, "targetDirectory": "/opt/UntitledProject13" }, "environment": { @@ -74,7 +75,12 @@ "*.png", "*.svg", "*.hdr", - "*.ktx" + "*.ktx", + "*.bmp", + "*.ttf", + "*.tiff", + "*.webp", + "*.gif" ], "mcuProperties": { }, @@ -92,7 +98,12 @@ "*.png", "*.svg", "*.hdr", - "*.ktx" + "*.ktx", + "*.bmp", + "*.ttf", + "*.tiff", + "*.webp", + "*.gif" ], "mcuProperties": { }, diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.jsontoqml b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.jsontoqml index 99e4f60bb3..04911c40f8 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.jsontoqml +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.jsontoqml @@ -6,6 +6,7 @@ import QmlProject Project { mainFile: "Main.qml" targetDirectory: "/opt/UntitledProject13" + enableCMakeGeneration: false widgetApp: true importPaths: [ "imports","asset_imports" ] diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.qmltojson b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.qmltojson index 303bfc3899..634623c9cf 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.qmltojson +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.qmltojson @@ -48,7 +48,12 @@ "*.png", "*.svg", "*.hdr", - "*.ktx" + "*.ktx", + "*.bmp", + "*.ttf", + "*.tiff", + "*.webp", + "*.gif" ], "mcuProperties": { }, diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-2/testfile.jsontoqml b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-2/testfile.jsontoqml index 2e73146cda..ad0102201f 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-2/testfile.jsontoqml +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-2/testfile.jsontoqml @@ -4,6 +4,7 @@ import QmlProject Project { + enableCMakeGeneration: false widgetApp: false qt6Project: false diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/getter-setter/empty.qmlproject b/tests/unit/tests/unittests/qmlprojectmanager/data/getter-setter/empty.qmlproject index 66adaaa7d9..bcf8995b7a 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/getter-setter/empty.qmlproject +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/getter-setter/empty.qmlproject @@ -11,6 +11,7 @@ Project { importPaths: [ ] targetDirectory: "" + enableCMakeGeneration: false fileSelectors: [ ] qdsVersion: "" diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/getter-setter/with_qds_prefix.qmlproject b/tests/unit/tests/unittests/qmlprojectmanager/data/getter-setter/with_qds_prefix.qmlproject index a8b5b459d6..6422179e66 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/getter-setter/with_qds_prefix.qmlproject +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/getter-setter/with_qds_prefix.qmlproject @@ -11,6 +11,7 @@ Project { QDS.importPaths: [ "imports", "asset_imports" ] QDS.targetDirectory: "/opt/targetDirectory" + QDS.enableCMakeGeneration: true QDS.fileSelectors: [ "WXGA", "darkTheme", "ShowIndicator"] QDS.qdsVersion: "3.9" diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/getter-setter/without_qds_prefix.qmlproject b/tests/unit/tests/unittests/qmlprojectmanager/data/getter-setter/without_qds_prefix.qmlproject index 6bee599955..77b5556893 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/getter-setter/without_qds_prefix.qmlproject +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/getter-setter/without_qds_prefix.qmlproject @@ -11,6 +11,7 @@ Project { importPaths: [ "imports", "asset_imports" ] targetDirectory: "/opt/targetDirectory" + enableCMakeGeneration: true fileSelectors: [ "WXGA", "darkTheme", "ShowIndicator"] qdsVersion: "3.9" diff --git a/tests/unit/tests/unittests/qmlprojectmanager/projectitem-test.cpp b/tests/unit/tests/unittests/qmlprojectmanager/projectitem-test.cpp index 49caf96074..1e1d7d1189 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/projectitem-test.cpp +++ b/tests/unit/tests/unittests/qmlprojectmanager/projectitem-test.cpp @@ -121,6 +121,13 @@ TEST_F(QmlProjectItem, get_with_qds_prefix_tar_get_with_qds_prefix_directory) ASSERT_THAT(targetDirectory, Eq("/opt/targetDirectory")); } +TEST_F(QmlProjectItem, get_with_qds_prefix_enable_cmake_generation) +{ + auto enable = projectItemWithQdsPrefix->enableCMakeGeneration(); + + ASSERT_TRUE(enable); +} + TEST_F(QmlProjectItem, get_with_qds_prefix_import_paths) { auto importPaths = projectItemWithQdsPrefix->importPaths(); @@ -266,6 +273,13 @@ TEST_F(QmlProjectItem, get_without_qds_prefix_tar_get_without_qds_prefix_directo ASSERT_THAT(targetDirectory, Eq("/opt/targetDirectory")); } +TEST_F(QmlProjectItem, get_without_qds_prefix_enable_cmake_generation) +{ + auto enable = projectItemWithoutQdsPrefix->enableCMakeGeneration(); + + ASSERT_TRUE(enable); +} + TEST_F(QmlProjectItem, get_without_qds_prefix_import_paths) { auto importPaths = projectItemWithoutQdsPrefix->importPaths(); @@ -413,6 +427,13 @@ TEST_F(QmlProjectItem, get_empty_tar_get_empty_directory) ASSERT_THAT(targetDirectory, IsEmpty()); } +TEST_F(QmlProjectItem, get_empty_enable_cmake_generation) +{ + auto enable = projectItemEmpty->enableCMakeGeneration(); + + ASSERT_FALSE(enable); +} + TEST_F(QmlProjectItem, get_empty_import_paths) { auto importPaths = projectItemEmpty->importPaths(); @@ -677,6 +698,13 @@ TEST_F(QmlProjectItem, set_design_studio_version) ASSERT_EQ(projectItemSetters->versionDesignStudio(), "6"); } +TEST_F(QmlProjectItem, set_enable_cmake_generation) +{ + projectItemSetters->setEnableCMakeGeneration(true); + + ASSERT_EQ(projectItemSetters->enableCMakeGeneration(), true); +} + // TODO: We should move these 2 tests into the integration tests TEST_F(QmlProjectItem, test_file_filters) { diff --git a/tests/unit/tests/unittests/sqlite/sqliteindex-test.cpp b/tests/unit/tests/unittests/sqlite/sqliteindex-test.cpp index 9d3fca88ff..b065c0ab9a 100644 --- a/tests/unit/tests/unittests/sqlite/sqliteindex-test.cpp +++ b/tests/unit/tests/unittests/sqlite/sqliteindex-test.cpp @@ -17,7 +17,9 @@ TEST(Index, one_column) auto sqlStatement = index.sqlStatement(); - ASSERT_THAT(sqlStatement, Eq("CREATE INDEX IF NOT EXISTS index_tableName_column1 ON tableName(column1)")); + ASSERT_THAT( + sqlStatement, + Eq("CREATE INDEX IF NOT EXISTS index_normal_tableName_column1 ON tableName(column1)")); } TEST(Index, two_column) @@ -26,7 +28,9 @@ TEST(Index, two_column) auto sqlStatement = index.sqlStatement(); - ASSERT_THAT(sqlStatement, Eq("CREATE INDEX IF NOT EXISTS index_tableName_column1_column2 ON tableName(column1, column2)")); + ASSERT_THAT(sqlStatement, + Eq("CREATE INDEX IF NOT EXISTS index_normal_tableName_column1_column2 ON " + "tableName(column1, column2)")); } TEST(Index, empty_table_name) @@ -49,7 +53,8 @@ TEST(Index, unique_index) auto sqlStatement = index.sqlStatement(); - ASSERT_THAT(sqlStatement, Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_tableName_column1 ON tableName(column1)")); + ASSERT_THAT( + sqlStatement, Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_unique_tableName_column1 ON tableName(column1)")); } TEST(Index, condition) @@ -58,8 +63,20 @@ TEST(Index, condition) auto sqlStatement = index.sqlStatement(); + ASSERT_THAT( + sqlStatement, + Eq("CREATE INDEX IF NOT EXISTS index_partial_tableName_column1 ON tableName(column1) WHERE " + "column1 IS NOT NULL")); +} + +TEST(Index, unique_index_with_condition) +{ + Index index{"tableName", {"column1"}, IndexType::Unique, "column1 IS NOT NULL"}; + + auto sqlStatement = index.sqlStatement(); + ASSERT_THAT(sqlStatement, - Eq("CREATE INDEX IF NOT EXISTS index_tableName_column1 ON tableName(column1) WHERE " - "column1 IS NOT NULL")); + Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_unique_partial_tableName_column1 ON " + "tableName(column1) WHERE column1 IS NOT NULL")); } } diff --git a/tests/unit/tests/unittests/sqlite/sqlitestatement-test.cpp b/tests/unit/tests/unittests/sqlite/sqlitestatement-test.cpp index f533c651e9..24b20176ea 100644 --- a/tests/unit/tests/unittests/sqlite/sqlitestatement-test.cpp +++ b/tests/unit/tests/unittests/sqlite/sqlitestatement-test.cpp @@ -269,6 +269,21 @@ TEST_F(SqliteStatement, bind_int_id) ASSERT_THAT(readStatement.fetchIntValue(0), 42); } +TEST_F(SqliteStatement, bind_special_state_id) +{ + enum class SpecialIdState { Unresolved = -1 }; + constexpr TestIntId unresolvedTypeId = TestIntId::createSpecialState(SpecialIdState::Unresolved); + SqliteTestStatement<0, 1> statement("INSERT INTO test VALUES ('id', 323, ?)", database); + + statement.bind(1, unresolvedTypeId); + statement.next(); + + SqliteTestStatement<1, 1> readStatement("SELECT value FROM test WHERE name='id'", database); + readStatement.next(); + ASSERT_THAT(readStatement.fetchType(0), Sqlite::Type::Integer); + ASSERT_THAT(readStatement.fetchIntValue(0), -1); +} + TEST_F(SqliteStatement, bind_invalid_long_long_id_to_null) { TestLongLongId id; diff --git a/tests/unit/tests/unittests/sqlite/sqlitetable-test.cpp b/tests/unit/tests/unittests/sqlite/sqlitetable-test.cpp index 7b8189b51e..e1b0427f3c 100644 --- a/tests/unit/tests/unittests/sqlite/sqlitetable-test.cpp +++ b/tests/unit/tests/unittests/sqlite/sqlitetable-test.cpp @@ -60,9 +60,9 @@ TEST_F(SqliteTable, add_index) auto index = table.addIndex({column, column2}); - ASSERT_THAT( - Utils::SmallStringView(index.sqlStatement()), - Eq("CREATE INDEX IF NOT EXISTS index_testTable_name_value ON testTable(name, value)")); + ASSERT_THAT(Utils::SmallStringView(index.sqlStatement()), + Eq("CREATE INDEX IF NOT EXISTS index_normal_testTable_name_value ON " + "testTable(name, value)")); } TEST_F(SqliteTable, initialize_table) @@ -92,10 +92,11 @@ TEST_F(SqliteTable, initialize_table_with_index) EXPECT_CALL(databaseMock, execute(Eq("CREATE TABLE testTable(name, value)"))); EXPECT_CALL(databaseMock, - execute(Eq("CREATE INDEX IF NOT EXISTS index_testTable_name ON testTable(name)"))); + execute(Eq( + "CREATE INDEX IF NOT EXISTS index_normal_testTable_name ON testTable(name)"))); EXPECT_CALL(databaseMock, - execute(Eq("CREATE INDEX IF NOT EXISTS index_testTable_value ON testTable(value) " - "WHERE value IS NOT NULL"))); + execute(Eq("CREATE INDEX IF NOT EXISTS index_partial_testTable_value ON " + "testTable(value) WHERE value IS NOT NULL"))); table.initialize(databaseMock); } @@ -110,13 +111,13 @@ TEST_F(SqliteTable, initialize_table_with_unique_index) table.addUniqueIndex({column2}, "value IS NOT NULL"); EXPECT_CALL(databaseMock, execute(Eq("CREATE TABLE testTable(name, value)"))); + EXPECT_CALL( + databaseMock, + execute(Eq( + "CREATE UNIQUE INDEX IF NOT EXISTS index_unique_testTable_name ON testTable(name)"))); EXPECT_CALL(databaseMock, - execute(Eq( - "CREATE UNIQUE INDEX IF NOT EXISTS index_testTable_name ON testTable(name)"))); - EXPECT_CALL(databaseMock, - execute(Eq( - "CREATE UNIQUE INDEX IF NOT EXISTS index_testTable_value ON testTable(value) " - "WHERE value IS NOT NULL"))); + execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_unique_partial_testTable_value " + "ON testTable(value) WHERE value IS NOT NULL"))); table.initialize(databaseMock); } @@ -351,8 +352,8 @@ TEST_F(StrictSqliteTable, add_index) auto index = table.addIndex({column, column2}); ASSERT_THAT(Utils::SmallStringView(index.sqlStatement()), - Eq("CREATE INDEX IF NOT EXISTS index_testTable_name_value ON testTable(name, " - "value)")); + Eq("CREATE INDEX IF NOT EXISTS index_normal_testTable_name_value ON " + "testTable(name, value)")); } TEST_F(StrictSqliteTable, initialize_table) @@ -382,10 +383,11 @@ TEST_F(StrictSqliteTable, initialize_table_with_index) EXPECT_CALL(databaseMock, execute(Eq("CREATE TABLE testTable(name ANY, value ANY) STRICT"))); EXPECT_CALL(databaseMock, - execute(Eq("CREATE INDEX IF NOT EXISTS index_testTable_name ON testTable(name)"))); + execute(Eq( + "CREATE INDEX IF NOT EXISTS index_normal_testTable_name ON testTable(name)"))); EXPECT_CALL(databaseMock, - execute(Eq("CREATE INDEX IF NOT EXISTS index_testTable_value ON testTable(value) " - "WHERE value IS NOT NULL"))); + execute(Eq("CREATE INDEX IF NOT EXISTS index_partial_testTable_value ON " + "testTable(value) WHERE value IS NOT NULL"))); table.initialize(databaseMock); } @@ -400,13 +402,13 @@ TEST_F(StrictSqliteTable, initialize_table_with_unique_index) table.addUniqueIndex({column2}, "value IS NOT NULL"); EXPECT_CALL(databaseMock, execute(Eq("CREATE TABLE testTable(name ANY, value ANY) STRICT"))); + EXPECT_CALL( + databaseMock, + execute(Eq( + "CREATE UNIQUE INDEX IF NOT EXISTS index_unique_testTable_name ON testTable(name)"))); EXPECT_CALL(databaseMock, - execute(Eq( - "CREATE UNIQUE INDEX IF NOT EXISTS index_testTable_name ON testTable(name)"))); - EXPECT_CALL(databaseMock, - execute(Eq( - "CREATE UNIQUE INDEX IF NOT EXISTS index_testTable_value ON testTable(value) " - "WHERE value IS NOT NULL"))); + execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_unique_partial_testTable_value " + "ON testTable(value) WHERE value IS NOT NULL"))); table.initialize(databaseMock); } diff --git a/tests/unit/tests/unittests/utils/smallstring-test.cpp b/tests/unit/tests/unittests/utils/smallstring-test.cpp index bdcdb44019..71090f8760 100644 --- a/tests/unit/tests/unittests/utils/smallstring-test.cpp +++ b/tests/unit/tests/unittests/utils/smallstring-test.cpp @@ -941,6 +941,33 @@ TEST(SmallString, append_empty_initializer_list) ASSERT_THAT(text, Eq("some text")); } +TEST(SmallString, append_int) +{ + SmallString text("some text"); + + text += 123; + + ASSERT_THAT(text, Eq("some text123")); +} + +TEST(SmallString, append_float) +{ + SmallString text("some text"); + + text += 123.456; + + ASSERT_THAT(text, Eq("some text123.456")); +} + +TEST(SmallString, append_character) +{ + SmallString text("some text"); + + text += 'x'; + + ASSERT_THAT(text, Eq("some textx")); +} + TEST(SmallString, to_byte_array) { SmallString text("some text"); @@ -1299,6 +1326,19 @@ TEST(SmallString, starts_with_string_view) ASSERT_FALSE(text.startsWith('@')); } +TEST(SmallString, starts_with_qstringview) +{ + using namespace Qt::StringLiterals; + SmallString text("$column"); + + ASSERT_FALSE(text.startsWith(u"$columnxxx"_s)); + ASSERT_TRUE(text.startsWith(u"$column"_s)); + ASSERT_TRUE(text.startsWith(u"$col"_s)); + ASSERT_FALSE(text.startsWith(u"col"_s)); + ASSERT_TRUE(text.startsWith(u"$"_s)); + ASSERT_FALSE(text.startsWith(u"@"_s)); +} + TEST(SmallString, ends_with) { SmallString text("/my/path"); @@ -1839,6 +1879,8 @@ TEST(SmallString, number_to_string) ASSERT_THAT(SmallString::number(std::numeric_limits<long long int>::min()), "-9223372036854775808"); ASSERT_THAT(SmallString::number(1.2), "1.2"); ASSERT_THAT(SmallString::number(-1.2), "-1.2"); + ASSERT_THAT(SmallString::number(1.2f), "1.2"); + ASSERT_THAT(SmallString::number(-1.2f), "-1.2"); } TEST(SmallString, string_view_plus_operator) |