diff options
Diffstat (limited to 'tests/auto')
48 files changed, 687 insertions, 424 deletions
diff --git a/tests/auto/api/tst_api.cpp b/tests/auto/api/tst_api.cpp index 28bbe4638..d85b2502a 100644 --- a/tests/auto/api/tst_api.cpp +++ b/tests/auto/api/tst_api.cpp @@ -1434,7 +1434,7 @@ void TestApi::infiniteLoopResolving() m_logSink, nullptr)); QTimer::singleShot(1000, setupJob.get(), &qbs::AbstractJob::cancel); QVERIFY(waitForFinished(setupJob.get(), testTimeoutInMsecs())); - QVERIFY2(setupJob->error().toString().toLower().contains("interrupted"), + QVERIFY2(setupJob->error().toString().toLower().contains("cancel"), qPrintable(setupJob->error().toString())); } @@ -2711,12 +2711,13 @@ void TestApi::restoredWarnings() waitForFinished(job.get()); QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString())); job.reset(nullptr); - QCOMPARE(toSet(m_logSink->warnings).size(), 2); + QCOMPARE(toSet(m_logSink->warnings).size(), 3); const auto beforeErrors = m_logSink->warnings; for (const qbs::ErrorInfo &e : beforeErrors) { const QString msg = e.toString(); QVERIFY2(msg.contains("Superfluous version") - || msg.contains("Property 'blubb' is not declared"), + || msg.contains("Property 'blubb' is not declared") + || msg.contains("Product 'theProduct' had errors and was disabled"), qPrintable(msg)); } m_logSink->warnings.clear(); @@ -2726,7 +2727,7 @@ void TestApi::restoredWarnings() waitForFinished(job.get()); QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString())); job.reset(nullptr); - QCOMPARE(toSet(m_logSink->warnings).size(), 2); + QCOMPARE(toSet(m_logSink->warnings).size(), 3); m_logSink->warnings.clear(); // Re-resolving with changes: Errors come from the re-resolving, stored ones must be suppressed. @@ -2737,13 +2738,14 @@ void TestApi::restoredWarnings() waitForFinished(job.get()); QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString())); job.reset(nullptr); - QCOMPARE(toSet(m_logSink->warnings).size(), 3); // One more for the additional group + QCOMPARE(toSet(m_logSink->warnings).size(), 4); // One more for the additional group const auto afterErrors = m_logSink->warnings; for (const qbs::ErrorInfo &e : afterErrors) { const QString msg = e.toString(); QVERIFY2(msg.contains("Superfluous version") || msg.contains("Property 'blubb' is not declared") - || msg.contains("blubb.cpp' does not exist"), + || msg.contains("blubb.cpp' does not exist") + || msg.contains("Product 'theProduct' had errors and was disabled"), qPrintable(msg)); } m_logSink->warnings.clear(); diff --git a/tests/auto/auto.qbs b/tests/auto/auto.qbs index a4c4beedd..bf6b3d219 100644 --- a/tests/auto/auto.qbs +++ b/tests/auto/auto.qbs @@ -9,6 +9,7 @@ Project { "blackbox/blackbox-examples.qbs", "blackbox/blackbox-java.qbs", "blackbox/blackbox-joblimits.qbs", + "blackbox/blackbox-providers.qbs", "blackbox/blackbox-qt.qbs", "blackbox/blackbox-windows.qbs", "blackbox/blackbox.qbs", diff --git a/tests/auto/blackbox/CMakeLists.txt b/tests/auto/blackbox/CMakeLists.txt index 5b5376064..1d90ec95b 100644 --- a/tests/auto/blackbox/CMakeLists.txt +++ b/tests/auto/blackbox/CMakeLists.txt @@ -63,6 +63,14 @@ add_qbs_test(blackbox-joblimits tst_blackboxjoblimits.cpp ) +add_qbs_test(blackbox-providers + SOURCES + ../shared.h + tst_blackboxbase.cpp + tst_blackboxbase.h + tst_blackboxproviders.cpp + ) + add_qbs_test(blackbox-qt SOURCES ../shared.h diff --git a/tests/auto/blackbox/blackbox-providers.qbs b/tests/auto/blackbox/blackbox-providers.qbs new file mode 100644 index 000000000..95ebaa423 --- /dev/null +++ b/tests/auto/blackbox/blackbox-providers.qbs @@ -0,0 +1,21 @@ +import qbs.Utilities + +QbsAutotest { + testName: "blackbox-providers" + Depends { name: "qbs_app" } + Depends { name: "qbs-setup-toolchains" } + Group { + name: "testdata" + prefix: "testdata-providers/" + files: ["**/*"] + fileTags: [] + } + files: [ + "../shared.h", + "tst_blackboxbase.cpp", + "tst_blackboxbase.h", + "tst_blackboxproviders.cpp", + "tst_blackboxproviders.h", + ] + cpp.defines: base.concat(["SRCDIR=" + Utilities.cStringQuote(path)]) +} diff --git a/tests/auto/blackbox/testdata/fallback-module-provider/fallback-module-provider.qbs b/tests/auto/blackbox/testdata-providers/fallback-module-provider/fallback-module-provider.qbs index a798e15b3..a798e15b3 100644 --- a/tests/auto/blackbox/testdata/fallback-module-provider/fallback-module-provider.qbs +++ b/tests/auto/blackbox/testdata-providers/fallback-module-provider/fallback-module-provider.qbs diff --git a/tests/auto/blackbox/testdata/fallback-module-provider/libdir/qbsmetatestmodule.pc b/tests/auto/blackbox/testdata-providers/fallback-module-provider/libdir/qbsmetatestmodule.pc index ae4daba89..ae4daba89 100644 --- a/tests/auto/blackbox/testdata/fallback-module-provider/libdir/qbsmetatestmodule.pc +++ b/tests/auto/blackbox/testdata-providers/fallback-module-provider/libdir/qbsmetatestmodule.pc diff --git a/tests/auto/blackbox/testdata/fallback-module-provider/main.cpp b/tests/auto/blackbox/testdata-providers/fallback-module-provider/main.cpp index 442b755bf..442b755bf 100644 --- a/tests/auto/blackbox/testdata/fallback-module-provider/main.cpp +++ b/tests/auto/blackbox/testdata-providers/fallback-module-provider/main.cpp diff --git a/tests/auto/blackbox/testdata-providers/module-providers-cache/module-providers-cache.qbs b/tests/auto/blackbox/testdata-providers/module-providers-cache/module-providers-cache.qbs new file mode 100644 index 000000000..508ed84d2 --- /dev/null +++ b/tests/auto/blackbox/testdata-providers/module-providers-cache/module-providers-cache.qbs @@ -0,0 +1,11 @@ +Project { + qbsModuleProviders: ["provider_a"] + name: "project" + property string dummyProp + + Product { + name: "p1" + Depends { name: "qbsothermodule" } + Depends { name: "qbsmetatestmodule" } + } +} diff --git a/tests/auto/blackbox/testdata-providers/module-providers-cache/module-providers/provider_a.qbs b/tests/auto/blackbox/testdata-providers/module-providers-cache/module-providers/provider_a.qbs new file mode 100644 index 000000000..782cf7d25 --- /dev/null +++ b/tests/auto/blackbox/testdata-providers/module-providers-cache/module-providers/provider_a.qbs @@ -0,0 +1,9 @@ +import "../../qbs-module-providers-helpers.js" as Helpers + +ModuleProvider { + relativeSearchPaths: { + Helpers.writeModule(outputBaseDir, "qbsmetatestmodule", "from_provider_a"); + Helpers.writeModule(outputBaseDir, "qbsothermodule", "from_provider_a"); + return ""; + } +} diff --git a/tests/auto/blackbox/testdata/module-providers/main.cpp b/tests/auto/blackbox/testdata-providers/module-providers/main.cpp index 85a4f551c..85a4f551c 100644 --- a/tests/auto/blackbox/testdata/module-providers/main.cpp +++ b/tests/auto/blackbox/testdata-providers/module-providers/main.cpp diff --git a/tests/auto/blackbox/testdata/module-providers/module-providers.qbs b/tests/auto/blackbox/testdata-providers/module-providers/module-providers.qbs index e83c80bb1..e83c80bb1 100644 --- a/tests/auto/blackbox/testdata/module-providers/module-providers.qbs +++ b/tests/auto/blackbox/testdata-providers/module-providers/module-providers.qbs diff --git a/tests/auto/blackbox/testdata/module-providers/module-providers/mygenerator/provider.qbs b/tests/auto/blackbox/testdata-providers/module-providers/module-providers/mygenerator/provider.qbs index dae02c03a..dae02c03a 100644 --- a/tests/auto/blackbox/testdata/module-providers/module-providers/mygenerator/provider.qbs +++ b/tests/auto/blackbox/testdata-providers/module-providers/module-providers/mygenerator/provider.qbs diff --git a/tests/auto/blackbox/testdata/module-providers/module-providers/othergenerator/provider.qbs b/tests/auto/blackbox/testdata-providers/module-providers/module-providers/othergenerator/provider.qbs index 66557037c..66557037c 100644 --- a/tests/auto/blackbox/testdata/module-providers/module-providers/othergenerator/provider.qbs +++ b/tests/auto/blackbox/testdata-providers/module-providers/module-providers/othergenerator/provider.qbs diff --git a/tests/auto/blackbox/testdata/probe-in-module-provider/module-providers/provider_a.qbs b/tests/auto/blackbox/testdata-providers/probe-in-module-provider/module-providers/provider_a.qbs index 8a7c7d6ed..8a7c7d6ed 100644 --- a/tests/auto/blackbox/testdata/probe-in-module-provider/module-providers/provider_a.qbs +++ b/tests/auto/blackbox/testdata-providers/probe-in-module-provider/module-providers/provider_a.qbs diff --git a/tests/auto/blackbox/testdata/probe-in-module-provider/probe-in-module-provider.qbs b/tests/auto/blackbox/testdata-providers/probe-in-module-provider/probe-in-module-provider.qbs index cb346beeb..cb346beeb 100644 --- a/tests/auto/blackbox/testdata/probe-in-module-provider/probe-in-module-provider.qbs +++ b/tests/auto/blackbox/testdata-providers/probe-in-module-provider/probe-in-module-provider.qbs diff --git a/tests/auto/blackbox/testdata/providers-properties/module-providers/provider_a.qbs b/tests/auto/blackbox/testdata-providers/providers-properties/module-providers/provider_a.qbs index ab9d475d8..ab9d475d8 100644 --- a/tests/auto/blackbox/testdata/providers-properties/module-providers/provider_a.qbs +++ b/tests/auto/blackbox/testdata-providers/providers-properties/module-providers/provider_a.qbs diff --git a/tests/auto/blackbox/testdata/providers-properties/module-providers/provider_b.qbs b/tests/auto/blackbox/testdata-providers/providers-properties/module-providers/provider_b.qbs index 1b2a79979..1b2a79979 100644 --- a/tests/auto/blackbox/testdata/providers-properties/module-providers/provider_b.qbs +++ b/tests/auto/blackbox/testdata-providers/providers-properties/module-providers/provider_b.qbs diff --git a/tests/auto/blackbox/testdata/providers-properties/providers-properties.qbs b/tests/auto/blackbox/testdata-providers/providers-properties/providers-properties.qbs index 258a973fa..258a973fa 100644 --- a/tests/auto/blackbox/testdata/providers-properties/providers-properties.qbs +++ b/tests/auto/blackbox/testdata-providers/providers-properties/providers-properties.qbs diff --git a/tests/auto/blackbox/testdata/qbs-module-properties-in-providers/module-providers/provider_a.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-properties-in-providers/module-providers/provider_a.qbs index 95c89cd1c..95c89cd1c 100644 --- a/tests/auto/blackbox/testdata/qbs-module-properties-in-providers/module-providers/provider_a.qbs +++ b/tests/auto/blackbox/testdata-providers/qbs-module-properties-in-providers/module-providers/provider_a.qbs diff --git a/tests/auto/blackbox/testdata/qbs-module-properties-in-providers/qbs-module-properties-in-providers.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-properties-in-providers/qbs-module-properties-in-providers.qbs index a338a220d..c2fc58299 100644 --- a/tests/auto/blackbox/testdata/qbs-module-properties-in-providers/qbs-module-properties-in-providers.qbs +++ b/tests/auto/blackbox/testdata-providers/qbs-module-properties-in-providers/qbs-module-properties-in-providers.qbs @@ -4,12 +4,12 @@ Project { Profile { name: "profile1" - qbs.sysroot: "sysroot1" + qbs.sysroot: "/sysroot1" } Profile { name: "profile2" - qbs.sysroot: "sysroot2" + qbs.sysroot: "/sysroot2" } Product { diff --git a/tests/auto/blackbox/testdata/qbs-module-providers-cli-override/module-providers/provider_a.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-providers-cli-override/module-providers/provider_a.qbs index d34d1cac5..d34d1cac5 100644 --- a/tests/auto/blackbox/testdata/qbs-module-providers-cli-override/module-providers/provider_a.qbs +++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers-cli-override/module-providers/provider_a.qbs diff --git a/tests/auto/blackbox/testdata/qbs-module-providers-cli-override/module-providers/provider_b.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-providers-cli-override/module-providers/provider_b.qbs index 767e30923..767e30923 100644 --- a/tests/auto/blackbox/testdata/qbs-module-providers-cli-override/module-providers/provider_b.qbs +++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers-cli-override/module-providers/provider_b.qbs diff --git a/tests/auto/blackbox/testdata/qbs-module-providers-cli-override/qbs-module-providers-cli-override.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-providers-cli-override/qbs-module-providers-cli-override.qbs index 6f94ab207..6f94ab207 100644 --- a/tests/auto/blackbox/testdata/qbs-module-providers-cli-override/qbs-module-providers-cli-override.qbs +++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers-cli-override/qbs-module-providers-cli-override.qbs diff --git a/tests/auto/blackbox/testdata/qbs-module-providers-compatibility/module-providers/named_provider.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-providers-compatibility/module-providers/named_provider.qbs index 07114b5ef..07114b5ef 100644 --- a/tests/auto/blackbox/testdata/qbs-module-providers-compatibility/module-providers/named_provider.qbs +++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers-compatibility/module-providers/named_provider.qbs diff --git a/tests/auto/blackbox/testdata/qbs-module-providers-compatibility/module-providers/qbsmetatestmodule/provider.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-providers-compatibility/module-providers/qbsmetatestmodule/provider.qbs index b04a52261..b04a52261 100644 --- a/tests/auto/blackbox/testdata/qbs-module-providers-compatibility/module-providers/qbsmetatestmodule/provider.qbs +++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers-compatibility/module-providers/qbsmetatestmodule/provider.qbs diff --git a/tests/auto/blackbox/testdata/qbs-module-providers-compatibility/qbs-module-providers-compatibility.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-providers-compatibility/qbs-module-providers-compatibility.qbs index 7885b540a..7885b540a 100644 --- a/tests/auto/blackbox/testdata/qbs-module-providers-compatibility/qbs-module-providers-compatibility.qbs +++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers-compatibility/qbs-module-providers-compatibility.qbs diff --git a/tests/auto/blackbox/testdata/qbs-module-providers-helpers.js b/tests/auto/blackbox/testdata-providers/qbs-module-providers-helpers.js index 8b6d9e275..8b6d9e275 100644 --- a/tests/auto/blackbox/testdata/qbs-module-providers-helpers.js +++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers-helpers.js diff --git a/tests/auto/blackbox/testdata/qbs-module-providers/module-providers/provider_a.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-providers/module-providers/provider_a.qbs index d34d1cac5..d34d1cac5 100644 --- a/tests/auto/blackbox/testdata/qbs-module-providers/module-providers/provider_a.qbs +++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers/module-providers/provider_a.qbs diff --git a/tests/auto/blackbox/testdata/qbs-module-providers/module-providers/provider_b.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-providers/module-providers/provider_b.qbs index 767e30923..767e30923 100644 --- a/tests/auto/blackbox/testdata/qbs-module-providers/module-providers/provider_b.qbs +++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers/module-providers/provider_b.qbs diff --git a/tests/auto/blackbox/testdata/qbs-module-providers/qbs-module-providers.qbs b/tests/auto/blackbox/testdata-providers/qbs-module-providers/qbs-module-providers.qbs index 00776a62e..00776a62e 100644 --- a/tests/auto/blackbox/testdata/qbs-module-providers/qbs-module-providers.qbs +++ b/tests/auto/blackbox/testdata-providers/qbs-module-providers/qbs-module-providers.qbs diff --git a/tests/auto/blackbox/testdata/qbspkgconfig-module-provider/libs/libA.cpp b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/libs/libA.cpp index 0c5274415..0c5274415 100644 --- a/tests/auto/blackbox/testdata/qbspkgconfig-module-provider/libs/libA.cpp +++ b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/libs/libA.cpp diff --git a/tests/auto/blackbox/testdata/qbspkgconfig-module-provider/libs/libA.h b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/libs/libA.h index ddaaf1609..ddaaf1609 100644 --- a/tests/auto/blackbox/testdata/qbspkgconfig-module-provider/libs/libA.h +++ b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/libs/libA.h diff --git a/tests/auto/blackbox/testdata/qbspkgconfig-module-provider/libs/libs.qbs b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/libs/libs.qbs index b473083c6..b473083c6 100644 --- a/tests/auto/blackbox/testdata/qbspkgconfig-module-provider/libs/libs.qbs +++ b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/libs/libs.qbs diff --git a/tests/auto/blackbox/testdata/qbspkgconfig-module-provider/main.cpp b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/main.cpp index 5fa0f7eed..5fa0f7eed 100644 --- a/tests/auto/blackbox/testdata/qbspkgconfig-module-provider/main.cpp +++ b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/main.cpp diff --git a/tests/auto/blackbox/testdata/qbspkgconfig-module-provider/qbspkgconfig-module-provider.qbs b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/qbspkgconfig-module-provider.qbs index d2b3654ae..d2b3654ae 100644 --- a/tests/auto/blackbox/testdata/qbspkgconfig-module-provider/qbspkgconfig-module-provider.qbs +++ b/tests/auto/blackbox/testdata-providers/qbspkgconfig-module-provider/qbspkgconfig-module-provider.qbs diff --git a/tests/auto/blackbox/testdata/conflicting-property-values/conflicting-property-values.qbs b/tests/auto/blackbox/testdata/conflicting-property-values/conflicting-property-values.qbs new file mode 100644 index 000000000..23b6ee5a3 --- /dev/null +++ b/tests/auto/blackbox/testdata/conflicting-property-values/conflicting-property-values.qbs @@ -0,0 +1,41 @@ +Project { + Product { + name: "low" + Export { property string prop: "low"; property string prop2: "low" } + } + Product { + name: "higher1" + Export { Depends { name: "low" } low.prop: "higher1" } + } + Product { + name: "higher2" + Export { Depends { name: "low" } low.prop: "higher2" } + } + Product { + name: "highest1" + Export { + Depends { name: "low" } + Depends { name: "higher1" } + Depends { name: "higher2" } + low.prop: "highest1" + low.prop2: "highest" + } + } + Product { + name: "highest2" + Export { + Depends { name: "low" } + Depends { name: "higher1" } + Depends { name: "higher2" } + low.prop: "highest2" + low.prop2: "highest" + } + } + Product { + name: "toplevel" + Depends { name: "highest1" } + Depends { name: "highest2" } + low.prop: name + property bool dummy: { console.info("final prop value: " + low.prop); } + } +} diff --git a/tests/auto/blackbox/testdata/deprecated-property/deprecated-property.qbs b/tests/auto/blackbox/testdata/deprecated-property/deprecated-property.qbs index e699672a8..7d1550312 100644 --- a/tests/auto/blackbox/testdata/deprecated-property/deprecated-property.qbs +++ b/tests/auto/blackbox/testdata/deprecated-property/deprecated-property.qbs @@ -1,5 +1,3 @@ -import qbs // FIXME: Don't remove this import because then the test fails! - Product { Depends { name: "themodule" } themodule.newProp: true diff --git a/tests/auto/blackbox/testdata/exports-qbs/lib.qbs b/tests/auto/blackbox/testdata/exports-qbs/lib.qbs index 951b0fa74..01f89a221 100644 --- a/tests/auto/blackbox/testdata/exports-qbs/lib.qbs +++ b/tests/auto/blackbox/testdata/exports-qbs/lib.qbs @@ -52,7 +52,7 @@ DynamicLibrary { condition: true prefixMapping: [{ prefix: includeDir, - replacement: FileInfo.joinPaths(qbs.installPrefix, exportingProduct.headersInstallDir) + replacement: FileInfo.joinPaths(exportingProduct.qbs.installPrefix, exportingProduct.headersInstallDir) }] } } diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index fd81dd494..e8934c403 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -1070,11 +1070,11 @@ void TestBlackbox::deprecatedProperty() QVERIFY(runQbs(params) != 0); m_qbsStderr = QDir::fromNativeSeparators(QString::fromLocal8Bit(m_qbsStderr)).toLocal8Bit(); const bool hasExpiringWarning = m_qbsStderr.contains(QByteArray( - "deprecated-property.qbs:6:29 The property 'expiringProp' is " + "deprecated-property.qbs:4:29 The property 'expiringProp' is " "deprecated and will be removed in Qbs ") + version.toLocal8Bit()); QVERIFY2(expiringWarning == hasExpiringWarning, m_qbsStderr.constData()); const bool hasRemovedOutput = m_qbsStderr.contains( - "deprecated-property.qbs:7:28 The property 'veryOldProp' can no " + "deprecated-property.qbs:5:28 The property 'veryOldProp' can no " "longer be used. It was removed in Qbs 1.3.0."); QVERIFY2(hasRemovedOutput == !expiringError, m_qbsStderr.constData()); QVERIFY2(m_qbsStderr.contains("Property 'forgottenProp' was scheduled for removal in version " @@ -1961,6 +1961,42 @@ void TestBlackbox::conanfileProbe() QCOMPARE(actualResults, expectedResults); } +void TestBlackbox::conflictingPropertyValues_data() +{ + QTest::addColumn<bool>("overrideInProduct"); + QTest::newRow("don't override in product") << false; + QTest::newRow("override in product") << true; +} + +void TestBlackbox::conflictingPropertyValues() +{ + QFETCH(bool, overrideInProduct); + + QDir::setCurrent(testDataDir + "/conflicting-property-values"); + if (overrideInProduct) + REPLACE_IN_FILE("conflicting-property-values.qbs", "// low.prop: name", "low.prop: name"); + else + REPLACE_IN_FILE("conflicting-property-values.qbs", "low.prop: name", "// low.prop: name"); + WAIT_FOR_NEW_TIMESTAMP(); + QCOMPARE(runQbs(QString("resolve")), 0); + if (overrideInProduct) { + // Binding in product itself overrides everything else, module-level conflicts + // are irrelevant. + QVERIFY2(m_qbsStdout.contains("final prop value: toplevel"), m_qbsStdout.constData()); + QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData()); + } else { + // Only the conflicts in the highest-level modules are reported, lower-level conflicts + // are irrelevant. + // prop2 does not cause a conflict, because the values are the same. + QVERIFY2(m_qbsStdout.contains("final prop value: highest"), m_qbsStdout.constData()); + QVERIFY2(m_qbsStderr.contains("Conflicting scalar values for property 'prop'"), + m_qbsStderr.constData()); + QVERIFY2(m_qbsStderr.count("values.qbs") == 2, m_qbsStderr.constData()); + QVERIFY2(m_qbsStderr.contains("values.qbs:20:23"), m_qbsStderr.constData()); + QVERIFY2(m_qbsStderr.contains("values.qbs:30:23"), m_qbsStderr.constData()); + } +} + void TestBlackbox::cpuFeatures() { QDir::setCurrent(testDataDir + "/cpu-features"); @@ -3395,23 +3431,6 @@ void TestBlackbox::probeInExportedModule() QVERIFY2(m_qbsStdout.contains("listProp: myother,my"), m_qbsStdout.constData()); } -void TestBlackbox::probeInModuleProvider() -{ - QDir::setCurrent(testDataDir + "/probe-in-module-provider"); - - QbsRunParameters params; - params.command = "build"; - params.arguments << "--force-probe-execution"; - QCOMPARE(runQbs(params), 0); - QVERIFY2(m_qbsStdout.contains("Running probe"), m_qbsStdout); - QVERIFY2(m_qbsStdout.contains("p.qbsmetatestmodule.boolProp: true"), m_qbsStdout); - WAIT_FOR_NEW_TIMESTAMP(); - touch("probe-in-module-provider.qbs"); - QCOMPARE(runQbs(), 0); - QVERIFY2(m_qbsStdout.contains("p.qbsmetatestmodule.boolProp: true"), m_qbsStdout); - QVERIFY2(!m_qbsStdout.contains("Running probe"), m_qbsStdout); -} - void TestBlackbox::probesAndArrayProperties() { QDir::setCurrent(testDataDir + "/probes-and-array-properties"); @@ -3447,7 +3466,7 @@ void TestBlackbox::propertyAssignmentInFailedModule() QVERIFY(runQbs(failParams) != 0); QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("modules.m.doFail:true"))), 0); QVERIFY2(m_qbsStdout.contains("Resolving"), m_qbsStdout.constData()); - QEXPECT_FAIL(nullptr, "circular dependency between module merging and validation", Continue); + failParams.expectFailure = false; QCOMPARE(runQbs(failParams), 0); } @@ -5574,11 +5593,7 @@ void TestBlackbox::propertyPrecedence() switchProfileContents(profile.p, s.get(), false); switchFileContents(nonleafFile, true); QCOMPARE(runQbs(resolveParams), 0); - QVERIFY2(m_qbsStderr.contains("WARNING: Conflicting scalar values at") - && m_qbsStderr.contains("nonleaf.qbs:4:22") - && m_qbsStderr.contains("dep.qbs:6:26"), - m_qbsStderr.constData()); - QCOMPARE(runQbs(params), 0); + QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData()); QCOMPARE(runQbs(params), 0); QVERIFY2(m_qbsStdout.contains("scalar prop: export\n") && m_qbsStdout.contains("list prop: [\"export\",\"nonleaf\",\"leaf\"]\n"), m_qbsStdout.constData()); @@ -5586,10 +5601,7 @@ void TestBlackbox::propertyPrecedence() // Case 8: [cmdline=0,prod=0,export=1,nonleaf=1,profile=1] switchProfileContents(profile.p, s.get(), true); QCOMPARE(runQbs(resolveParams), 0); - QVERIFY2(m_qbsStderr.contains("WARNING: Conflicting scalar values at") - && m_qbsStderr.contains("nonleaf.qbs:4:22") - && m_qbsStderr.contains("dep.qbs:6:26"), - m_qbsStderr.constData()); + QVERIFY2(m_qbsStderr.isEmpty(), m_qbsStderr.constData()); QCOMPARE(runQbs(params), 0); QVERIFY2(m_qbsStdout.contains("scalar prop: export\n") && m_qbsStdout.contains("list prop: [\"export\",\"nonleaf\",\"profile\"]\n"), @@ -5977,19 +5989,6 @@ void TestBlackbox::protobufLibraryInstall() QFileInfo::exists(installRootInclude + "/hello/world.pb.h")); } -// Tests whether it is possible to set providers properties in a Product or from command-line -void TestBlackbox::providersProperties() -{ - QDir::setCurrent(testDataDir + "/providers-properties"); - - QbsRunParameters params("build"); - params.arguments = QStringList("moduleProviders.provider_b.someProp: \"first,second\""); - QCOMPARE(runQbs(params), 0); - QVERIFY2(m_qbsStdout.contains("p.qbsmetatestmodule.listProp: [\"someValue\"]"), m_qbsStdout); - QVERIFY2(m_qbsStdout.contains( - "p.qbsothermodule.listProp: [\"first\",\"second\"]"), m_qbsStdout); -} - void TestBlackbox::pseudoMultiplexing() { // This is "pseudo-multiplexing" on all platforms that initialize qbs.architectures @@ -6163,162 +6162,6 @@ void TestBlackbox::qbsConfigAddProfile_data() << QString("Profile properties must be key/value pairs"); } -// checks that we can set qbs module properties in providers and provider cache works corectly -void TestBlackbox::qbsModulePropertiesInProviders() -{ - QDir::setCurrent(testDataDir + "/qbs-module-properties-in-providers"); - - QbsRunParameters params("resolve"); - - QCOMPARE(runQbs(params), 0); - - // We have 2 products in 2 configurations, but second product should use the cached value - // so we should have only 2 copies of the module, not 4. - QCOMPARE(m_qbsStdout.count("Running setup script for qbsmetatestmodule"), 2); - - // Check that products get correct values from modules - QVERIFY2(m_qbsStdout.contains(("product1.qbsmetatestmodule.prop: sysroot1")), m_qbsStdout); - QVERIFY2(m_qbsStdout.contains(("product1.qbsmetatestmodule.prop: sysroot2")), m_qbsStdout); - - QVERIFY2(m_qbsStdout.contains(("product2.qbsmetatestmodule.prop: sysroot1")), m_qbsStdout); - QVERIFY2(m_qbsStdout.contains(("product2.qbsmetatestmodule.prop: sysroot2")), m_qbsStdout); -} - -// Tests whether it is possible to set qbsModuleProviders in Product and Project items -// and that the order of providers results in correct priority -void TestBlackbox::qbsModuleProviders() -{ - QFETCH(QStringList, arguments); - QFETCH(QString, firstProp); - QFETCH(QString, secondProp); - - QDir::setCurrent(testDataDir + "/qbs-module-providers"); - - QbsRunParameters params("resolve"); - params.arguments = arguments; - QCOMPARE(runQbs(params), 0); - QVERIFY2(m_qbsStdout.contains(("p1.qbsmetatestmodule.prop: " + firstProp).toUtf8()), - m_qbsStdout); - QVERIFY2(m_qbsStdout.contains(("p1.qbsothermodule.prop: " + secondProp).toUtf8()), - m_qbsStdout); - QVERIFY2(m_qbsStdout.contains(("p2.qbsmetatestmodule.prop: " + firstProp).toUtf8()), - m_qbsStdout); - QVERIFY2(m_qbsStdout.contains(("p2.qbsothermodule.prop: " + secondProp).toUtf8()), - m_qbsStdout); -} - -void TestBlackbox::qbsModuleProviders_data() -{ - QTest::addColumn<QStringList>("arguments"); - QTest::addColumn<QString>("firstProp"); - QTest::addColumn<QString>("secondProp"); - - QTest::newRow("default") << QStringList() << "from_provider_a" << "undefined"; - QTest::newRow("override") - << QStringList("projects.project.qbsModuleProviders:provider_b") - << "from_provider_b" - << "from_provider_b"; - QTest::newRow("override list a") - << QStringList("projects.project.qbsModuleProviders:provider_a,provider_b") - << "from_provider_a" - << "from_provider_b"; - QTest::newRow("override list b") - << QStringList("projects.project.qbsModuleProviders:provider_b,provider_a") - << "from_provider_b" - << "from_provider_b"; -} - -// Tests possible use-cases how to override providers from command-line -void TestBlackbox::qbsModuleProvidersCliOverride() -{ - QFETCH(QStringList, arguments); - QFETCH(QString, propertyValue); - - QDir::setCurrent(testDataDir + "/qbs-module-providers-cli-override"); - - QbsRunParameters params("resolve"); - params.arguments = arguments; - QCOMPARE(runQbs(params), 0); - QVERIFY2(m_qbsStdout.contains(("qbsmetatestmodule.prop: " + propertyValue).toUtf8()), - m_qbsStdout); -} - -void TestBlackbox::qbsModuleProvidersCliOverride_data() -{ - QTest::addColumn<QStringList>("arguments"); - QTest::addColumn<QString>("propertyValue"); - - QTest::newRow("default") << QStringList() << "undefined"; - QTest::newRow("project-wide") - << QStringList("project.qbsModuleProviders:provider_a") - << "from_provider_a"; - QTest::newRow("concrete project") - << QStringList("projects.innerProject.qbsModuleProviders:provider_a") - << "from_provider_a"; - QTest::newRow("concrete product") - << QStringList("products.product.qbsModuleProviders:provider_a") - << "from_provider_a"; - QTest::newRow("concrete project override project-wide") - << QStringList({ - "project.qbsModuleProviders:provider_a", - "projects.innerProject.qbsModuleProviders:provider_b"}) - << "from_provider_b"; - QTest::newRow("concrete product override project-wide") - << QStringList({ - "project.qbsModuleProviders:provider_a", - "products.product.qbsModuleProviders:provider_b"}) - << "from_provider_b"; -} - -// Tests whether scoped providers can be used as named, i.e. new provider machinery -// is compatible with the old one -void TestBlackbox::qbsModuleProvidersCompatibility() -{ - QFETCH(QStringList, arguments); - QFETCH(QString, propertyValue); - - QDir::setCurrent(testDataDir + "/qbs-module-providers-compatibility"); - - QbsRunParameters params("resolve"); - params.arguments = arguments; - QCOMPARE(runQbs(params), 0); - QVERIFY2(m_qbsStdout.contains(("qbsmetatestmodule.prop: " + propertyValue).toUtf8()), - m_qbsStdout); -} - -void TestBlackbox::qbsModuleProvidersCompatibility_data() -{ - QTest::addColumn<QStringList>("arguments"); - QTest::addColumn<QString>("propertyValue"); - - QTest::newRow("default") << QStringList() << "from_scoped_provider"; - QTest::newRow("scoped by name") << QStringList("project.qbsModuleProviders:qbsmetatestmodule") << "from_scoped_provider"; - QTest::newRow("named") << QStringList("project.qbsModuleProviders:named_provider") << "from_named_provider"; -} - -void TestBlackbox::qbspkgconfigModuleProvider() -{ - QDir::setCurrent(testDataDir + "/qbspkgconfig-module-provider/libs"); - rmDirR(relativeBuildDir()); - - const auto commonParams = QbsRunParameters(QStringLiteral("install"), { - QStringLiteral("--install-root"), - QStringLiteral("install-root") - }); - auto dynamicParams = commonParams; - dynamicParams.arguments << "config:library" << "projects.libs.isBundle:false"; - QCOMPARE(runQbs(dynamicParams), 0); - - QDir::setCurrent(testDataDir + "/qbspkgconfig-module-provider"); - rmDirR(relativeBuildDir()); - - const auto sysroot = testDataDir + "/qbspkgconfig-module-provider/libs/install-root"; - - QbsRunParameters params; - params.arguments << "moduleProviders.qbspkgconfig.sysroot:" + sysroot; - QCOMPARE(runQbs(params), 0); -} - static QJsonObject getNextSessionPacket(QProcess &session, QByteArray &data) { int totalSize = -1; @@ -8024,112 +7867,6 @@ void TestBlackbox::maximumCxxLanguageVersion() m_qbsStdout.constData()); } -void TestBlackbox::moduleProviders() -{ - QDir::setCurrent(testDataDir + "/module-providers"); - - // Resolving in dry-run mode must not leave any data behind. - QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("-n"))), 0); - if (m_qbsStdout.contains("targetPlatform differs from hostPlatform")) - QSKIP("Cannot run binaries in cross-compiled build"); - QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 2); - QVERIFY(!QFile::exists(relativeBuildDir())); - - // Initial build. - QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0); - QVERIFY(QFile::exists(relativeBuildDir())); - QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 2); - QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData()); - QVERIFY2(m_qbsStdout.contains("The MY_DEFINE is app1"), m_qbsStdout.constData()); - QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0); - QVERIFY2(m_qbsStdout.contains("The letters are Z and Y"), m_qbsStdout.constData()); - QVERIFY2(m_qbsStdout.contains("The MY_DEFINE is app2"), m_qbsStdout.constData()); - - // Rebuild with overridden module provider config. The output for product 2 must change, - // but no setup script must be re-run, because both config values have already been - // handled in the first run. - const QStringList resolveArgs("moduleProviders.mygenerator.chooseLettersFrom:beginning"); - QCOMPARE(runQbs(QbsRunParameters("resolve", resolveArgs)), 0); - QVERIFY2(!m_qbsStdout.contains("Running setup script"), m_qbsStdout.constData()); - QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0); - QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData()); - QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0); - QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData()); - - // Forcing Probe execution triggers a re-run of the setup script. But only once, - // because the module provider config is the same now. - QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList(resolveArgs) - << "--force-probe-execution")), 0); - QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 1); - QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0); - QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData()); - QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0); - QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData()); - - // Now re-run without the module provider config override. Again, the setup script must - // run once, for the config value that was not present in the last run. - QCOMPARE(runQbs(QbsRunParameters("resolve")), 0); - QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 1); - QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0); - QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData()); - QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0); - QVERIFY2(m_qbsStdout.contains("The letters are Z and Y"), m_qbsStdout.constData()); -} - -void TestBlackbox::fallbackModuleProvider_data() -{ - QTest::addColumn<bool>("fallbacksEnabledGlobally"); - QTest::addColumn<bool>("fallbacksEnabledInProduct"); - QTest::addColumn<QStringList>("pkgConfigLibDirs"); - QTest::addColumn<bool>("successExpected"); - QTest::newRow("without custom lib dir, fallbacks disabled globally and in product") - << false << false << QStringList() << false; - QTest::newRow("without custom lib dir, fallbacks disabled globally, enabled in product") - << false << true << QStringList() << false; - QTest::newRow("without custom lib dir, fallbacks enabled globally, disabled in product") - << true << false << QStringList() << false; - QTest::newRow("without custom lib dir, fallbacks enabled globally and in product") - << true << true << QStringList() << false; - QTest::newRow("with custom lib dir, fallbacks disabled globally and in product") - << false << false << QStringList(testDataDir + "/fallback-module-provider/libdir") - << false; - QTest::newRow("with custom lib dir, fallbacks disabled globally, enabled in product") - << false << true << QStringList(testDataDir + "/fallback-module-provider/libdir") - << false; - QTest::newRow("with custom lib dir, fallbacks enabled globally, disabled in product") - << true << false << QStringList(testDataDir + "/fallback-module-provider/libdir") - << false; - QTest::newRow("with custom lib dir, fallbacks enabled globally and in product") - << true << true << QStringList(testDataDir + "/fallback-module-provider/libdir") - << true; -} - -void TestBlackbox::fallbackModuleProvider() -{ - QFETCH(bool, fallbacksEnabledInProduct); - QFETCH(bool, fallbacksEnabledGlobally); - QFETCH(QStringList, pkgConfigLibDirs); - QFETCH(bool, successExpected); - - QDir::setCurrent(testDataDir + "/fallback-module-provider"); - static const auto b2s = [](bool b) { return QString(b ? "true" : "false"); }; - QbsRunParameters resolveParams("resolve", - QStringList{"modules.pkgconfig.libDirs:" + pkgConfigLibDirs.join(','), - "products.p.fallbacksEnabled:" + b2s(fallbacksEnabledInProduct), - "--force-probe-execution"}); - if (!fallbacksEnabledGlobally) - resolveParams.arguments << "--no-fallback-module-provider"; - QCOMPARE(runQbs(resolveParams), 0); - const bool pkgConfigPresent = m_qbsStdout.contains("pkg-config present: true"); - const bool pkgConfigNotPresent = m_qbsStdout.contains("pkg-config present: false"); - QVERIFY(pkgConfigPresent != pkgConfigNotPresent); - if (pkgConfigNotPresent) - successExpected = false; - QbsRunParameters buildParams; - buildParams.expectFailure = !successExpected; - QCOMPARE(runQbs(buildParams) == 0, successExpected); -} - void TestBlackbox::minimumSystemVersion() { rmDirR(relativeBuildDir()); diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h index 8f9bfc984..9abc84897 100644 --- a/tests/auto/blackbox/tst_blackbox.h +++ b/tests/auto/blackbox/tst_blackbox.h @@ -90,6 +90,8 @@ private slots: void cxxLanguageVersion_data(); void conanfileProbe_data(); void conanfileProbe(); + void conflictingPropertyValues_data(); + void conflictingPropertyValues(); void cpuFeatures(); void dependenciesProperty(); void dependencyScanningLoop(); @@ -195,9 +197,6 @@ private slots: void makefileGenerator(); void maximumCLanguageVersion(); void maximumCxxLanguageVersion(); - void moduleProviders(); - void fallbackModuleProvider_data(); - void fallbackModuleProvider(); void minimumSystemVersion(); void minimumSystemVersion_data(); void missingBuildGraph(); @@ -242,7 +241,6 @@ private slots: void probeProperties(); void probesAndShadowProducts(); void probeInExportedModule(); - void probeInModuleProvider(); void probesAndArrayProperties(); void probesInNestedModules(); void productDependenciesByType(); @@ -258,19 +256,10 @@ private slots: void protobuf_data(); void protobuf(); void protobufLibraryInstall(); - void providersProperties(); void pseudoMultiplexing(); void qbsConfig(); void qbsConfigAddProfile(); void qbsConfigAddProfile_data(); - void qbsModulePropertiesInProviders(); - void qbsModuleProviders(); - void qbsModuleProviders_data(); - void qbsModuleProvidersCliOverride(); - void qbsModuleProvidersCliOverride_data(); - void qbsModuleProvidersCompatibility(); - void qbsModuleProvidersCompatibility_data(); - void qbspkgconfigModuleProvider(); void qbsSession(); void qbsVersion(); void qtBug51237(); diff --git a/tests/auto/blackbox/tst_blackboxproviders.cpp b/tests/auto/blackbox/tst_blackboxproviders.cpp new file mode 100644 index 000000000..ceb413510 --- /dev/null +++ b/tests/auto/blackbox/tst_blackboxproviders.cpp @@ -0,0 +1,368 @@ +/**************************************************************************** +** +** Copyright (C) 2023 Ivan Komissarov (abbapoh@gmail.com) +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qbs. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "tst_blackboxproviders.h" + +#include "../shared.h" + +// #include <tools/hostosinfo.h> +// #include <tools/profile.h> +// #include <tools/qttools.h> + +// #include <QtCore/qdir.h> +// #include <QtCore/qregularexpression.h> + +// using qbs::Internal::HostOsInfo; +// using qbs::Profile; + +#define WAIT_FOR_NEW_TIMESTAMP() waitForNewTimestamp(testDataDir) + +TestBlackboxProviders::TestBlackboxProviders() + : TestBlackboxBase(SRCDIR "/testdata-providers", "blackbox-providers") +{ +} + +void TestBlackboxProviders::fallbackModuleProvider_data() +{ + QTest::addColumn<bool>("fallbacksEnabledGlobally"); + QTest::addColumn<bool>("fallbacksEnabledInProduct"); + QTest::addColumn<QStringList>("pkgConfigLibDirs"); + QTest::addColumn<bool>("successExpected"); + QTest::newRow("without custom lib dir, fallbacks disabled globally and in product") + << false << false << QStringList() << false; + QTest::newRow("without custom lib dir, fallbacks disabled globally, enabled in product") + << false << true << QStringList() << false; + QTest::newRow("without custom lib dir, fallbacks enabled globally, disabled in product") + << true << false << QStringList() << false; + QTest::newRow("without custom lib dir, fallbacks enabled globally and in product") + << true << true << QStringList() << false; + QTest::newRow("with custom lib dir, fallbacks disabled globally and in product") + << false << false << QStringList(testDataDir + "/fallback-module-provider/libdir") + << false; + QTest::newRow("with custom lib dir, fallbacks disabled globally, enabled in product") + << false << true << QStringList(testDataDir + "/fallback-module-provider/libdir") + << false; + QTest::newRow("with custom lib dir, fallbacks enabled globally, disabled in product") + << true << false << QStringList(testDataDir + "/fallback-module-provider/libdir") + << false; + QTest::newRow("with custom lib dir, fallbacks enabled globally and in product") + << true << true << QStringList(testDataDir + "/fallback-module-provider/libdir") + << true; +} + +void TestBlackboxProviders::fallbackModuleProvider() +{ + QFETCH(bool, fallbacksEnabledInProduct); + QFETCH(bool, fallbacksEnabledGlobally); + QFETCH(QStringList, pkgConfigLibDirs); + QFETCH(bool, successExpected); + + QDir::setCurrent(testDataDir + "/fallback-module-provider"); + static const auto b2s = [](bool b) { return QString(b ? "true" : "false"); }; + QbsRunParameters resolveParams("resolve", + QStringList{"modules.pkgconfig.libDirs:" + pkgConfigLibDirs.join(','), + "products.p.fallbacksEnabled:" + b2s(fallbacksEnabledInProduct), + "--force-probe-execution"}); + if (!fallbacksEnabledGlobally) + resolveParams.arguments << "--no-fallback-module-provider"; + QCOMPARE(runQbs(resolveParams), 0); + const bool pkgConfigPresent = m_qbsStdout.contains("pkg-config present: true"); + const bool pkgConfigNotPresent = m_qbsStdout.contains("pkg-config present: false"); + QVERIFY(pkgConfigPresent != pkgConfigNotPresent); + if (pkgConfigNotPresent) + successExpected = false; + QbsRunParameters buildParams; + buildParams.expectFailure = !successExpected; + QCOMPARE(runQbs(buildParams) == 0, successExpected); +} + +void TestBlackboxProviders::moduleProviders() +{ + QDir::setCurrent(testDataDir + "/module-providers"); + + // Resolving in dry-run mode must not leave any data behind. + QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList("-n"))), 0); + if (m_qbsStdout.contains("targetPlatform differs from hostPlatform")) + QSKIP("Cannot run binaries in cross-compiled build"); + QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 2); + QVERIFY(!QFile::exists(relativeBuildDir())); + + // Initial build. + QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0); + QVERIFY(QFile::exists(relativeBuildDir())); + QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 2); + QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData()); + QVERIFY2(m_qbsStdout.contains("The MY_DEFINE is app1"), m_qbsStdout.constData()); + QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0); + QVERIFY2(m_qbsStdout.contains("The letters are Z and Y"), m_qbsStdout.constData()); + QVERIFY2(m_qbsStdout.contains("The MY_DEFINE is app2"), m_qbsStdout.constData()); + + // Rebuild with overridden module provider config. The output for product 2 must change, + // but no setup script must be re-run, because both config values have already been + // handled in the first run. + const QStringList resolveArgs("moduleProviders.mygenerator.chooseLettersFrom:beginning"); + QCOMPARE(runQbs(QbsRunParameters("resolve", resolveArgs)), 0); + QVERIFY2(!m_qbsStdout.contains("Running setup script"), m_qbsStdout.constData()); + QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0); + QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData()); + QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0); + QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData()); + + // Forcing Probe execution triggers a re-run of the setup script. But only once, + // because the module provider config is the same now. + QCOMPARE(runQbs(QbsRunParameters("resolve", QStringList(resolveArgs) + << "--force-probe-execution")), 0); + QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 1); + QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0); + QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData()); + QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0); + QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData()); + + // Now re-run without the module provider config override. Again, the setup script must + // run once, for the config value that was not present in the last run. + QCOMPARE(runQbs(QbsRunParameters("resolve")), 0); + QCOMPARE(m_qbsStdout.count("Running setup script for mygenerator"), 1); + QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app1"})), 0); + QVERIFY2(m_qbsStdout.contains("The letters are A and B"), m_qbsStdout.constData()); + QCOMPARE(runQbs(QbsRunParameters("run", QStringList{"-p", "app2"})), 0); + QVERIFY2(m_qbsStdout.contains("The letters are Z and Y"), m_qbsStdout.constData()); +} + +// Checks regression - when loading 2 modules from the same provider, the second module should +// come from provider cache +void TestBlackboxProviders::moduleProvidersCache() +{ + QDir::setCurrent(testDataDir + "/module-providers-cache"); + + QbsRunParameters params("resolve", {"-v"}); + QCOMPARE(runQbs(params), 0); + const auto qbsmetatestmoduleMessage = "Re-checking for module \"qbsmetatestmodule\" with " + "newly added search paths from module provider"; + const auto qbsothermoduleMessage = "Re-checking for module \"qbsothermodule\" with " + "newly added search paths from module provider"; + QCOMPARE(m_qbsStderr.count(qbsmetatestmoduleMessage), 1); + QCOMPARE(m_qbsStderr.count(qbsothermoduleMessage), 1); + QCOMPARE(m_qbsStderr.count("Re-using provider \"provider_a\" from cache"), 1); + + // We didn't change providers, so both modules should come from cache. + params.arguments << "project.dummyProp:value"; + QCOMPARE(runQbs(params), 0); + QCOMPARE(m_qbsStderr.count(qbsmetatestmoduleMessage), 1); + QCOMPARE(m_qbsStderr.count(qbsothermoduleMessage), 1); + QCOMPARE(m_qbsStderr.count("Re-using provider \"provider_a\" from cache"), 2); +} + +void TestBlackboxProviders::probeInModuleProvider() +{ + QDir::setCurrent(testDataDir + "/probe-in-module-provider"); + + QbsRunParameters params; + params.command = "build"; + params.arguments << "--force-probe-execution"; + QCOMPARE(runQbs(params), 0); + QVERIFY2(m_qbsStdout.contains("Running probe"), m_qbsStdout); + QVERIFY2(m_qbsStdout.contains("p.qbsmetatestmodule.boolProp: true"), m_qbsStdout); + WAIT_FOR_NEW_TIMESTAMP(); + touch("probe-in-module-provider.qbs"); + QCOMPARE(runQbs(), 0); + QVERIFY2(m_qbsStdout.contains("p.qbsmetatestmodule.boolProp: true"), m_qbsStdout); + QVERIFY2(!m_qbsStdout.contains("Running probe"), m_qbsStdout); +} + +// Tests whether it is possible to set providers properties in a Product or from command-line +void TestBlackboxProviders::providersProperties() +{ + QDir::setCurrent(testDataDir + "/providers-properties"); + + QbsRunParameters params("build"); + params.arguments = QStringList("moduleProviders.provider_b.someProp: \"first,second\""); + QCOMPARE(runQbs(params), 0); + QVERIFY2(m_qbsStdout.contains("p.qbsmetatestmodule.listProp: [\"someValue\"]"), m_qbsStdout); + QVERIFY2(m_qbsStdout.contains( + "p.qbsothermodule.listProp: [\"first\",\"second\"]"), m_qbsStdout); +} + +// checks that we can set qbs module properties in providers and provider cache works corectly +void TestBlackboxProviders::qbsModulePropertiesInProviders() +{ + QDir::setCurrent(testDataDir + "/qbs-module-properties-in-providers"); + + QbsRunParameters params("resolve"); + + QCOMPARE(runQbs(params), 0); + + // We have 2 products in 2 configurations, but second product should use the cached value + // so we should have only 2 copies of the module, not 4. + QCOMPARE(m_qbsStdout.count("Running setup script for qbsmetatestmodule"), 2); + + // Check that products get correct values from modules + QVERIFY2(m_qbsStdout.contains(("product1.qbsmetatestmodule.prop: /sysroot1")), m_qbsStdout); + QVERIFY2(m_qbsStdout.contains(("product1.qbsmetatestmodule.prop: /sysroot2")), m_qbsStdout); + + QVERIFY2(m_qbsStdout.contains(("product2.qbsmetatestmodule.prop: /sysroot1")), m_qbsStdout); + QVERIFY2(m_qbsStdout.contains(("product2.qbsmetatestmodule.prop: /sysroot2")), m_qbsStdout); +} + +void TestBlackboxProviders::qbsModuleProviders_data() +{ + QTest::addColumn<QStringList>("arguments"); + QTest::addColumn<QString>("firstProp"); + QTest::addColumn<QString>("secondProp"); + + QTest::newRow("default") << QStringList() << "from_provider_a" << "undefined"; + QTest::newRow("override") + << QStringList("projects.project.qbsModuleProviders:provider_b") + << "from_provider_b" + << "from_provider_b"; + QTest::newRow("override list a") + << QStringList("projects.project.qbsModuleProviders:provider_a,provider_b") + << "from_provider_a" + << "from_provider_b"; + QTest::newRow("override list b") + << QStringList("projects.project.qbsModuleProviders:provider_b,provider_a") + << "from_provider_b" + << "from_provider_b"; +} + +// Tests whether it is possible to set qbsModuleProviders in Product and Project items +// and that the order of providers results in correct priority +void TestBlackboxProviders::qbsModuleProviders() +{ + QFETCH(QStringList, arguments); + QFETCH(QString, firstProp); + QFETCH(QString, secondProp); + + QDir::setCurrent(testDataDir + "/qbs-module-providers"); + + QbsRunParameters params("resolve"); + params.arguments = arguments; + QCOMPARE(runQbs(params), 0); + QVERIFY2(m_qbsStdout.contains(("p1.qbsmetatestmodule.prop: " + firstProp).toUtf8()), + m_qbsStdout); + QVERIFY2(m_qbsStdout.contains(("p1.qbsothermodule.prop: " + secondProp).toUtf8()), + m_qbsStdout); + QVERIFY2(m_qbsStdout.contains(("p2.qbsmetatestmodule.prop: " + firstProp).toUtf8()), + m_qbsStdout); + QVERIFY2(m_qbsStdout.contains(("p2.qbsothermodule.prop: " + secondProp).toUtf8()), + m_qbsStdout); +} + +void TestBlackboxProviders::qbsModuleProvidersCliOverride_data() +{ + QTest::addColumn<QStringList>("arguments"); + QTest::addColumn<QString>("propertyValue"); + + QTest::newRow("default") << QStringList() << "undefined"; + QTest::newRow("project-wide") + << QStringList("project.qbsModuleProviders:provider_a") + << "from_provider_a"; + QTest::newRow("concrete project") + << QStringList("projects.innerProject.qbsModuleProviders:provider_a") + << "from_provider_a"; + QTest::newRow("concrete product") + << QStringList("products.product.qbsModuleProviders:provider_a") + << "from_provider_a"; + QTest::newRow("concrete project override project-wide") + << QStringList({ + "project.qbsModuleProviders:provider_a", + "projects.innerProject.qbsModuleProviders:provider_b"}) + << "from_provider_b"; + QTest::newRow("concrete product override project-wide") + << QStringList({ + "project.qbsModuleProviders:provider_a", + "products.product.qbsModuleProviders:provider_b"}) + << "from_provider_b"; +} + +// Tests possible use-cases how to override providers from command-line +void TestBlackboxProviders::qbsModuleProvidersCliOverride() +{ + QFETCH(QStringList, arguments); + QFETCH(QString, propertyValue); + + QDir::setCurrent(testDataDir + "/qbs-module-providers-cli-override"); + + QbsRunParameters params("resolve"); + params.arguments = arguments; + QCOMPARE(runQbs(params), 0); + QVERIFY2(m_qbsStdout.contains(("qbsmetatestmodule.prop: " + propertyValue).toUtf8()), + m_qbsStdout); +} + +void TestBlackboxProviders::qbsModuleProvidersCompatibility_data() +{ + QTest::addColumn<QStringList>("arguments"); + QTest::addColumn<QString>("propertyValue"); + + QTest::newRow("default") << QStringList() << "from_scoped_provider"; + QTest::newRow("scoped by name") << QStringList("project.qbsModuleProviders:qbsmetatestmodule") << "from_scoped_provider"; + QTest::newRow("named") << QStringList("project.qbsModuleProviders:named_provider") << "from_named_provider"; +} + +// Tests whether scoped providers can be used as named, i.e. new provider machinery +// is compatible with the old one +void TestBlackboxProviders::qbsModuleProvidersCompatibility() +{ + QFETCH(QStringList, arguments); + QFETCH(QString, propertyValue); + + QDir::setCurrent(testDataDir + "/qbs-module-providers-compatibility"); + + QbsRunParameters params("resolve"); + params.arguments = arguments; + QCOMPARE(runQbs(params), 0); + QVERIFY2(m_qbsStdout.contains(("qbsmetatestmodule.prop: " + propertyValue).toUtf8()), + m_qbsStdout); +} + +void TestBlackboxProviders::qbspkgconfigModuleProvider() +{ + QDir::setCurrent(testDataDir + "/qbspkgconfig-module-provider/libs"); + rmDirR(relativeBuildDir()); + + const auto commonParams = QbsRunParameters(QStringLiteral("install"), { + QStringLiteral("--install-root"), + QStringLiteral("install-root") + }); + auto dynamicParams = commonParams; + dynamicParams.arguments << "config:library" << "projects.libs.isBundle:false"; + QCOMPARE(runQbs(dynamicParams), 0); + + QDir::setCurrent(testDataDir + "/qbspkgconfig-module-provider"); + rmDirR(relativeBuildDir()); + + const auto sysroot = testDataDir + "/qbspkgconfig-module-provider/libs/install-root"; + + QbsRunParameters params; + params.arguments << "moduleProviders.qbspkgconfig.sysroot:" + sysroot; + QCOMPARE(runQbs(params), 0); +} + +QTEST_MAIN(TestBlackboxProviders) diff --git a/tests/auto/blackbox/tst_blackboxproviders.h b/tests/auto/blackbox/tst_blackboxproviders.h new file mode 100644 index 000000000..017cc1c5e --- /dev/null +++ b/tests/auto/blackbox/tst_blackboxproviders.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2023 Ivan Komissarov (abbapoh@gmail.com) +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qbs. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef TST_BLACKBOXPROVIDERS_H +#define TST_BLACKBOXPROVIDERS_H + +#include "tst_blackboxbase.h" + +class TestBlackboxProviders : public TestBlackboxBase +{ + Q_OBJECT + +public: + TestBlackboxProviders(); + +private slots: + void fallbackModuleProvider_data(); + void fallbackModuleProvider(); + void moduleProviders(); + void moduleProvidersCache(); + void probeInModuleProvider(); + void providersProperties(); + void qbsModulePropertiesInProviders(); + void qbsModuleProviders_data(); + void qbsModuleProviders(); + void qbsModuleProvidersCliOverride(); + void qbsModuleProvidersCliOverride_data(); + void qbsModuleProvidersCompatibility(); + void qbsModuleProvidersCompatibility_data(); + void qbspkgconfigModuleProvider(); +}; + +#endif // TST_BLACKBOXPROVIDERS_H diff --git a/tests/auto/language/testdata/erroneous/module-depends-on-product.qbs b/tests/auto/language/testdata/module-depends-on-product.qbs index a7db9e036..a7db9e036 100644 --- a/tests/auto/language/testdata/erroneous/module-depends-on-product.qbs +++ b/tests/auto/language/testdata/module-depends-on-product.qbs diff --git a/tests/auto/language/testdata/modulepropertiesingroups.qbs b/tests/auto/language/testdata/modulepropertiesingroups.qbs index e3857bdf4..49f24c0ca 100644 --- a/tests/auto/language/testdata/modulepropertiesingroups.qbs +++ b/tests/auto/language/testdata/modulepropertiesingroups.qbs @@ -80,4 +80,13 @@ Project { } } } + + Product { + name: "module-property-in-group-condition" + Depends { name: "cpp" } + Group { + condition: qbs.architecture === "x86_64" + cpp.includePaths: "." + } + } } diff --git a/tests/auto/language/testdata/modules/broken/broken.qbs b/tests/auto/language/testdata/modules/broken/broken.qbs index 302573bbf..a80547340 100644 --- a/tests/auto/language/testdata/modules/broken/broken.qbs +++ b/tests/auto/language/testdata/modules/broken/broken.qbs @@ -1,5 +1,3 @@ -import qbs // FIXME: Don't remove this import because then the test fails! - Module { Probe { id: theProbe diff --git a/tests/auto/language/testdata/erroneous/modules/module-with-product-dependency/module-with-product-dependency.qbs b/tests/auto/language/testdata/modules/module-with-product-dependency/module-with-product-dependency.qbs index 5781bd6de..5781bd6de 100644 --- a/tests/auto/language/testdata/erroneous/modules/module-with-product-dependency/module-with-product-dependency.qbs +++ b/tests/auto/language/testdata/modules/module-with-product-dependency/module-with-product-dependency.qbs diff --git a/tests/auto/language/tst_language.cpp b/tests/auto/language/tst_language.cpp index 50269a7d7..eda7bf566 100644 --- a/tests/auto/language/tst_language.cpp +++ b/tests/auto/language/tst_language.cpp @@ -143,7 +143,7 @@ void TestLanguage::handleInitCleanupDataTags(const char *projectFileName, bool * bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject(projectFileName)); - project = loader->loadProject(defaultParameters); + project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); } catch (const ErrorInfo &e) { exceptionCaught = true; @@ -160,10 +160,16 @@ void TestLanguage::handleInitCleanupDataTags(const char *projectFileName, bool * void TestLanguage::init() { + m_resolver = new ProjectResolver(m_engine.get(), m_logger); m_logSink->setLogLevel(LoggerInfo); QVERIFY(m_tempDir.isValid()); } +void TestLanguage::cleanup() +{ + delete m_resolver; +} + #define HANDLE_INIT_CLEANUP_DATATAGS(fn) {\ bool handled;\ handleInitCleanupDataTags(fn, &handled);\ @@ -176,27 +182,20 @@ void TestLanguage::initTestCase() { m_logger = Logger(m_logSink); m_engine = ScriptEngine::create(m_logger, EvalContext::PropertyEvaluation); - loader = new Loader(m_engine.get(), m_logger); - loader->setSearchPaths(QStringList() - << (testDataDir() + "/../../../../share/qbs")); defaultParameters.setTopLevelProfile(profileName()); defaultParameters.setConfigurationName("default"); defaultParameters.expandBuildConfiguration(); defaultParameters.setEnvironment(QProcessEnvironment::systemEnvironment()); + defaultParameters.setSearchPaths({testDataDir() + "/../../../../share/qbs"}); QVERIFY(QFileInfo(m_wildcardsTestDirPath).isAbsolute()); } -void TestLanguage::cleanupTestCase() -{ - delete loader; -} - void TestLanguage::additionalProductTypes() { bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("additional-product-types.qbs")); - project = loader->loadProject(defaultParameters); + project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); const QHash<QString, ResolvedProductPtr> products = productsFromProject(project); const ResolvedProductConstPtr product = products.value("p"); @@ -218,7 +217,7 @@ void TestLanguage::baseProperty() bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("baseproperty.qbs")); - project = loader->loadProject(defaultParameters); + project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); ResolvedProductPtr product = products.value("product1"); @@ -238,7 +237,7 @@ void TestLanguage::baseValidation() qbs::SetupProjectParameters params = defaultParameters; params.setProjectFilePath(testProject("base-validate/base-validate.qbs")); try { - project = loader->loadProject(params); + project = m_resolver->resolve(params); QVERIFY2(false, "exception expected"); } catch (const qbs::ErrorInfo &e) { QVERIFY2(e.toString().contains("Parent succeeded, child failed."), @@ -252,7 +251,7 @@ void TestLanguage::brokenDependencyCycle() QFETCH(QString, projectFileName); params.setProjectFilePath(testProject(qPrintable(projectFileName))); try { - project = loader->loadProject(params); + project = m_resolver->resolve(params); } catch (const qbs::ErrorInfo &e) { QVERIFY2(false, qPrintable(e.toString())); } @@ -274,7 +273,7 @@ void TestLanguage::buildConfigStringListSyntax() overriddenValues.insert("project.someStrings", "foo,bar,baz"); parameters.setOverriddenValues(overriddenValues); parameters.setProjectFilePath(testProject("buildconfigstringlistsyntax.qbs")); - project = loader->loadProject(parameters); + project = m_resolver->resolve(parameters); QVERIFY(!!project); QCOMPARE(project->projectProperties().value("someStrings").toStringList(), QStringList() << "foo" << "bar" << "baz"); @@ -291,7 +290,7 @@ void TestLanguage::builtinFunctionInSearchPathsProperty() try { SetupProjectParameters parameters = defaultParameters; parameters.setProjectFilePath(testProject("builtinFunctionInSearchPathsProperty.qbs")); - QVERIFY(!!loader->loadProject(parameters)); + QVERIFY(!!m_resolver->resolve(parameters)); } catch (const ErrorInfo &e) { exceptionCaught = true; qDebug() << e.toString(); @@ -305,7 +304,7 @@ void TestLanguage::chainedProbes() try { SetupProjectParameters parameters = defaultParameters; parameters.setProjectFilePath(testProject("chained-probes/chained-probes.qbs")); - const TopLevelProjectConstPtr project = loader->loadProject(parameters); + const TopLevelProjectConstPtr project = m_resolver->resolve(parameters); QVERIFY(!!project); QCOMPARE(project->products.size(), size_t(1)); const QString prop1Val = project->products.front()->moduleProperties @@ -328,7 +327,7 @@ void TestLanguage::versionCompare() try { SetupProjectParameters parameters = defaultParameters; parameters.setProjectFilePath(testProject("versionCompare.qbs")); - QVERIFY(!!loader->loadProject(parameters)); + QVERIFY(!!m_resolver->resolve(parameters)); } catch (const ErrorInfo &e) { exceptionCaught = true; qDebug() << e.toString(); @@ -341,7 +340,7 @@ void TestLanguage::canonicalArchitecture() bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("canonicalArchitecture.qbs")); - project = loader->loadProject(defaultParameters); + project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); ResolvedProductPtr product = products.value(QStringLiteral("x86")); @@ -358,7 +357,7 @@ void TestLanguage::rfc1034Identifier() bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("rfc1034identifier.qbs")); - project = loader->loadProject(defaultParameters); + project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); ResolvedProductPtr product = products.value(QStringLiteral("this-has-special-characters-" @@ -381,7 +380,7 @@ void TestLanguage::conditionalDepends() params.setProjectFilePath(testProject("conditionaldepends.qbs")); params.setOverriddenValues({std::make_pair(QString("products." "multilevel_module_props_overridden.dummy3.loadDummy"), true)}); - project = loader->loadProject(params); + project = m_resolver->resolve(params); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); @@ -490,7 +489,7 @@ void TestLanguage::delayedError() QVariantMap overriddenValues; overriddenValues.insert("project.enableProduct", productEnabled); params.setOverriddenValues(overriddenValues); - project = loader->loadProject(params); + project = m_resolver->resolve(params); QCOMPARE(productEnabled, false); QVERIFY(!!project); QCOMPARE(project->products.size(), size_t(1)); @@ -532,7 +531,7 @@ void TestLanguage::dependencyOnAllProfiles() overriddenValues.insert("project.profile1", "p1"); overriddenValues.insert("project.profile2", "p2"); params.setOverriddenValues(overriddenValues); - project = loader->loadProject(params); + project = m_resolver->resolve(params); QVERIFY(!!project); QCOMPARE(project->products.size(), size_t(3)); const ResolvedProductConstPtr mainProduct = productsFromProject(project).value("main"); @@ -555,7 +554,7 @@ void TestLanguage::derivedSubProject() try { SetupProjectParameters params = defaultParameters; params.setProjectFilePath(testProject("derived-sub-project/project.qbs")); - const TopLevelProjectPtr project = loader->loadProject(params); + const TopLevelProjectPtr project = m_resolver->resolve(params); QVERIFY(!!project); const QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 1); @@ -572,7 +571,7 @@ void TestLanguage::disabledSubProject() try { SetupProjectParameters params = defaultParameters; params.setProjectFilePath(testProject("disabled-subproject.qbs")); - const TopLevelProjectPtr project = loader->loadProject(params); + const TopLevelProjectPtr project = m_resolver->resolve(params); QVERIFY(!!project); const QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 0); @@ -610,7 +609,7 @@ void TestLanguage::dottedNames() std::make_pair("projects.theProject.includeDottedModule", useModule) }; params.setOverriddenValues(overridden); - TopLevelProjectPtr project = loader->loadProject(params); + TopLevelProjectPtr project = m_resolver->resolve(params); QVERIFY(expectSuccess); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); @@ -633,7 +632,7 @@ void TestLanguage::emptyJsFile() try { SetupProjectParameters params = defaultParameters; params.setProjectFilePath(testProject("empty-js-file.qbs")); - const TopLevelProjectPtr project = loader->loadProject(params); + const TopLevelProjectPtr project = m_resolver->resolve(params); QVERIFY(!!project); const QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 1); @@ -650,7 +649,7 @@ void TestLanguage::enumerateProjectProperties() try { SetupProjectParameters params = defaultParameters; params.setProjectFilePath(testProject("enum-project-props.qbs")); - auto project = loader->loadProject(params); + auto project = m_resolver->resolve(params); QVERIFY(!!project); auto products = productsFromProject(project); QCOMPARE(products.size(), 1); @@ -673,7 +672,7 @@ void TestLanguage::evalErrorInNonPresentModule_data() QTest::addColumn<QString>("errorMessage"); QTest::newRow("module required") - << true << "broken.qbs:4:5 Element at index 0 of list property 'broken' " + << true << "broken.qbs:2:5 Element at index 0 of list property 'broken' " "does not have string type"; QTest::newRow("module not required") << false << QString(); } @@ -687,7 +686,7 @@ void TestLanguage::evalErrorInNonPresentModule() params.setProjectFilePath(testProject("eval-error-in-non-present-module.qbs")); QVariantMap overridden{std::make_pair("products.p.moduleRequired", moduleRequired)}; params.setOverriddenValues(overridden); - TopLevelProjectPtr project = loader->loadProject(params); + TopLevelProjectPtr project = m_resolver->resolve(params); QVERIFY(errorMessage.isEmpty()); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); @@ -712,7 +711,7 @@ void TestLanguage::defaultValue() if (!prop1Value.isEmpty()) overridden.insert("modules.lower.prop1", prop1Value); params.setOverriddenValues(overridden); - TopLevelProjectPtr project = loader->loadProject(params); + TopLevelProjectPtr project = m_resolver->resolve(params); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 2); @@ -763,7 +762,7 @@ void TestLanguage::environmentVariable() defaultParameters.setEnvironment(env); defaultParameters.setProjectFilePath(testProject("environmentvariable.qbs")); - project = loader->loadProject(defaultParameters); + project = m_resolver->resolve(defaultParameters); defaultParameters.setEnvironment(origEnv); // reset environment @@ -784,7 +783,7 @@ void TestLanguage::errorInDisabledProduct() try { SetupProjectParameters params = defaultParameters; params.setProjectFilePath(testProject("error-in-disabled-product.qbs")); - auto project = loader->loadProject(params); + auto project = m_resolver->resolve(params); QVERIFY(!!project); auto products = productsFromProject(project); QCOMPARE(products.size(), 5); @@ -899,8 +898,6 @@ void TestLanguage::erroneousFiles_data() QTest::newRow("conflicting-module-instances") << "There is more than one equally prioritized candidate for module " "'conflicting-instances'."; - QTest::newRow("module-depends-on-product") - << "module-with-product-dependency.qbs:2:5.*Modules cannot depend on products."; QTest::newRow("overwrite-inherited-readonly-property") << "overwrite-inherited-readonly-property.qbs" ":2:21.*Cannot set read-only property 'readOnlyString'."; @@ -957,7 +954,7 @@ void TestLanguage::erroneousFiles() QString fileName = QString::fromLocal8Bit(QTest::currentDataTag()) + QLatin1String(".qbs"); try { defaultParameters.setProjectFilePath(testProject("/erroneous/") + fileName); - loader->loadProject(defaultParameters); + m_resolver->resolve(defaultParameters); } catch (const ErrorInfo &e) { const QRegularExpression reg(errorMessage, QRegularExpression::DotMatchesEverythingOption); if (!e.toString().contains(reg)) { @@ -977,7 +974,7 @@ void TestLanguage::exports() bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("exports.qbs")); - TopLevelProjectPtr project = loader->loadProject(defaultParameters); + TopLevelProjectPtr project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 22); @@ -1103,7 +1100,7 @@ void TestLanguage::fileContextProperties() bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("filecontextproperties.qbs")); - project = loader->loadProject(defaultParameters); + project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); ResolvedProductPtr product = products.value("product1"); @@ -1156,7 +1153,7 @@ void TestLanguage::fileInProductAndModule() std::make_pair("modules.module_with_file.file2IsTarget", file2IsTarget), std::make_pair("products.p.addFileToProduct", addFileToProduct), }); - project = loader->loadProject(params); + project = m_resolver->resolve(params); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 1); @@ -1172,7 +1169,7 @@ void TestLanguage::getNativeSetting() bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("getNativeSetting.qbs")); - project = loader->loadProject(defaultParameters); + project = m_resolver->resolve(defaultParameters); QString expectedTargetName; if (HostOsInfo::isMacosHost()) { @@ -1248,7 +1245,7 @@ void TestLanguage::groupName() bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("groupname.qbs")); - TopLevelProjectPtr project = loader->loadProject(defaultParameters); + TopLevelProjectPtr project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 2); @@ -1287,7 +1284,7 @@ void TestLanguage::homeDirectory() { try { defaultParameters.setProjectFilePath(testProject("homeDirectory.qbs")); - ResolvedProjectPtr project = loader->loadProject(defaultParameters); + ResolvedProjectPtr project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 1); @@ -1393,7 +1390,7 @@ void TestLanguage::idUsage() bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("idusage.qbs")); - TopLevelProjectPtr project = loader->loadProject(defaultParameters); + TopLevelProjectPtr project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 5); @@ -1430,7 +1427,7 @@ void TestLanguage::idUniqueness() bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("id-uniqueness.qbs")); - loader->loadProject(defaultParameters); + m_resolver->resolve(defaultParameters); } catch (const ErrorInfo &e) { exceptionCaught = true; @@ -1448,7 +1445,7 @@ void TestLanguage::importCollection() bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("import-collection/project.qbs")); - const TopLevelProjectPtr project = loader->loadProject(defaultParameters); + const TopLevelProjectPtr project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); const ResolvedProductConstPtr product = products.value("da product"); @@ -1480,7 +1477,7 @@ void TestLanguage::inheritedPropertiesItems() params.setProjectFilePath (testProject("inherited-properties-items/inherited-properties-items.qbs")); params.setOverriddenValues(QVariantMap{std::make_pair("qbs.buildVariant", buildVariant)}); - TopLevelProjectPtr project = loader->loadProject(params); + TopLevelProjectPtr project = m_resolver->resolve(params); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 1); @@ -1498,7 +1495,7 @@ void TestLanguage::invalidBindingInDisabledItem() bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("invalidBindingInDisabledItem.qbs")); - TopLevelProjectPtr project = loader->loadProject(defaultParameters); + TopLevelProjectPtr project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 2); @@ -1520,7 +1517,7 @@ void TestLanguage::invalidOverrides() qbs::SetupProjectParameters params = defaultParameters; params.setProjectFilePath(testProject("invalid-overrides.qbs")); params.setOverriddenValues(QVariantMap{std::make_pair(key, true)}); - const TopLevelProjectPtr project = loader->loadProject(params); + const TopLevelProjectPtr project = m_resolver->resolve(params); QVERIFY(!!project); } catch (const ErrorInfo &e) { @@ -1570,25 +1567,20 @@ void TestLanguage::invalidOverrides_data() class JSSourceValueCreator { FileContextPtr m_fileContext; - QList<QString *> m_strings; + std::vector<std::unique_ptr<QString>> m_strings; public: JSSourceValueCreator(const FileContextPtr &fileContext) : m_fileContext(fileContext) { } - ~JSSourceValueCreator() - { - qDeleteAll(m_strings); - } - JSSourceValuePtr create(const QString &sourceCode) { JSSourceValuePtr value = JSSourceValue::create(); value->setFile(m_fileContext); - const auto str = new QString(sourceCode); - m_strings.push_back(str); - value->setSourceCode(QStringRef(str)); + auto str = std::make_unique<QString>(sourceCode); + value->setSourceCode(*str.get()); + m_strings.push_back(std::move(str)); return value; } }; @@ -1674,7 +1666,7 @@ void TestLanguage::jsImportUsedInMultipleScopes() params.setOverriddenValues({std::make_pair(QStringLiteral("qbs.buildVariant"), buildVariant)}); params.expandBuildConfiguration(); - TopLevelProjectPtr project = loader->loadProject(params); + TopLevelProjectPtr project = m_resolver->resolve(params); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 1); @@ -1697,7 +1689,7 @@ void TestLanguage::moduleMergingVariantValues() params.setProjectFilePath (testProject("module-merging-variant-values/module-merging-variant-values.qbs")); params.expandBuildConfiguration(); - const TopLevelProjectPtr project = loader->loadProject(params); + const TopLevelProjectPtr project = m_resolver->resolve(params); QVERIFY(!!project); QCOMPARE(int(project->products.size()), 2); } catch (const ErrorInfo &e) { @@ -1727,7 +1719,7 @@ void TestLanguage::modulePrioritizationBySearchPath() params.setOverriddenValues({std::make_pair(QStringLiteral("project.qbsSearchPaths"), searchPaths)}); params.expandBuildConfiguration(); - TopLevelProjectPtr project = loader->loadProject(params); + TopLevelProjectPtr project = m_resolver->resolve(params); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 1); @@ -1803,7 +1795,7 @@ void TestLanguage::modulePropertiesInGroups() defaultParameters.setProjectFilePath(testProject("modulepropertiesingroups.qbs")); bool exceptionCaught = false; try { - TopLevelProjectPtr project = loader->loadProject(defaultParameters); + TopLevelProjectPtr project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); const QHash<QString, ResolvedProductPtr> products = productsFromProject(project); ResolvedProductPtr product = products.value("grouptest"); @@ -1931,7 +1923,7 @@ void TestLanguage::modulePropertiesInGroups() QCOMPARE(g2Gmod1List1, QStringList() << "gmod1_list1_proto" << "g2"); const auto &g2Gmod1List2 = moduleProperty(g2Props, "gmod.gmod1", "gmod1_list2") .toStringList(); - QCOMPARE(g2Gmod1List2, QStringList() << "grouptest" << "g2" << "gmod1_list2_proto"); + QCOMPARE(g2Gmod1List2, QStringList() << "grouptest" << "gmod1_string_proto" << "gmod1_list2_proto"); const int g2P0 = moduleProperty(g2Props, "gmod.gmod1", "p0").toInt(); QCOMPARE(g2P0, 6); const int g2DepProp = moduleProperty(g2Props, "gmod.gmod1", "depProp").toInt(); @@ -2025,7 +2017,7 @@ void TestLanguage::modulePropertyOverridesPerProduct() }); params.setProjectFilePath( testProject("module-property-overrides-per-product.qbs")); - const TopLevelProjectPtr project = loader->loadProject(params); + const TopLevelProjectPtr project = m_resolver->resolve(params); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 3); @@ -2071,7 +2063,7 @@ void TestLanguage::moduleScope() bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("modulescope.qbs")); - TopLevelProjectPtr project = loader->loadProject(defaultParameters); + TopLevelProjectPtr project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 1); @@ -2097,7 +2089,25 @@ void TestLanguage::moduleScope() qDebug() << e.toString(); } QCOMPARE(exceptionCaught, false); +} +void TestLanguage::moduleWithProductDependency() +{ + bool exceptionCaught = false; + try { + defaultParameters.setProjectFilePath(testProject("module-depends-on-product.qbs")); + TopLevelProjectPtr project = m_resolver->resolve(defaultParameters); + QVERIFY(project); + QHash<QString, ResolvedProductPtr> products = productsFromProject(project); + QCOMPARE(products.size(), 2); + ResolvedProductPtr product = products.value("p1"); + QVERIFY(product); + QCOMPARE(int(product->dependencies.size()), 1); + } catch (const ErrorInfo &e) { + exceptionCaught = true; + qDebug() << e.toString(); + } + QCOMPARE(exceptionCaught, false); } void TestLanguage::modules_data() @@ -2158,7 +2168,7 @@ void TestLanguage::multiplexedExports() try { SetupProjectParameters params = defaultParameters; params.setProjectFilePath(testProject("multiplexed-exports.qbs")); - const TopLevelProjectPtr project = loader->loadProject(params); + const TopLevelProjectPtr project = m_resolver->resolve(params); QVERIFY(!!project); const auto products = project->allProducts(); QCOMPARE(products.size(), size_t(4)); @@ -2196,7 +2206,7 @@ void TestLanguage::multiplexingByProfile() params.setProjectFilePath(testDataDir() + "/multiplexing-by-profile/" + projectFileName); try { params.setDryRun(true); - const TopLevelProjectPtr project = loader->loadProject(params); + const TopLevelProjectPtr project = m_resolver->resolve(params); QVERIFY(successExpected); QVERIFY(!!project); } catch (const ErrorInfo &e) { @@ -2224,7 +2234,7 @@ void TestLanguage::nonApplicableModulePropertyInProfile() params.setProjectFilePath(testProject("non-applicable-module-property-in-profile.qbs")); params.setOverriddenValues(QVariantMap{std::make_pair("project.targetOS", targetOS), std::make_pair("project.toolchain", toolchain)}); - const TopLevelProjectPtr project = loader->loadProject(params); + const TopLevelProjectPtr project = m_resolver->resolve(params); QVERIFY(!!project); QVERIFY(successExpected); } catch (const ErrorInfo &e) { @@ -2264,7 +2274,7 @@ void TestLanguage::nonRequiredProducts() else if (!dependeeEnabled) overriddenValues.insert("products.dependee.condition", false); params.setOverriddenValues(overriddenValues); - const TopLevelProjectPtr project = loader->loadProject(params); + const TopLevelProjectPtr project = m_resolver->resolve(params); QVERIFY(!!project); const auto products = productsFromProject(project); QCOMPARE(products.size(), 4 + !!subProjectEnabled); @@ -2305,7 +2315,7 @@ void TestLanguage::outerInGroup() bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("outerInGroup.qbs")); - TopLevelProjectPtr project = loader->loadProject(defaultParameters); + TopLevelProjectPtr project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 1); @@ -2343,7 +2353,7 @@ void TestLanguage::overriddenPropertiesAndPrototypes() SetupProjectParameters params = defaultParameters; params.setProjectFilePath(testProject("overridden-properties-and-prototypes.qbs")); params.setOverriddenValues({std::make_pair("modules.qbs.targetPlatform", osName)}); - TopLevelProjectConstPtr project = loader->loadProject(params); + TopLevelProjectConstPtr project = m_resolver->resolve(params); QVERIFY(!!project); QCOMPARE(project->products.size(), size_t(1)); QCOMPARE(project->products.front()->moduleProperties->moduleProperty( @@ -2372,7 +2382,7 @@ void TestLanguage::overriddenVariantProperty() const QVariantMap objectValue{std::make_pair("x", 1), std::make_pair("y", 2)}; params.setOverriddenValues({std::make_pair("products.p.myObject", objectValue)}); params.setProjectFilePath(testProject("overridden-variant-property.qbs")); - TopLevelProjectConstPtr project = loader->loadProject(params); + TopLevelProjectConstPtr project = m_resolver->resolve(params); QVERIFY(!!project); QCOMPARE(project->products.size(), size_t(1)); QCOMPARE(project->products.front()->productProperties.value("myObject").toMap(), @@ -2389,7 +2399,7 @@ void TestLanguage::parameterTypes() bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("parameter-types.qbs")); - loader->loadProject(defaultParameters); + m_resolver->resolve(defaultParameters); } catch (const ErrorInfo &e) { exceptionCaught = true; @@ -2403,7 +2413,7 @@ void TestLanguage::pathProperties() bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("pathproperties.qbs")); - project = loader->loadProject(defaultParameters); + project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); ResolvedProductPtr product = products.value("product1"); @@ -2446,7 +2456,7 @@ void TestLanguage::profileValuesAndOverriddenValues() parameters.setOverriddenValues(overriddenValues); parameters.setProjectFilePath(testProject("profilevaluesandoverriddenvalues.qbs")); parameters.expandBuildConfiguration(); - project = loader->loadProject(parameters); + project = m_resolver->resolve(parameters); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); ResolvedProductPtr product = products.value("product1"); @@ -2476,7 +2486,7 @@ void TestLanguage::projectFileLookup() try { SetupProjectParameters params; params.setProjectFilePath(projectFileInput); - Loader::setupProjectFilePath(params); + params.finalizeProjectFilePath(); QVERIFY(!failureExpected); QCOMPARE(params.projectFilePath(), projectFileOutput); } catch (const ErrorInfo &) { @@ -2508,7 +2518,7 @@ void TestLanguage::productConditions() bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("productconditions.qbs")); - TopLevelProjectPtr project = loader->loadProject(defaultParameters); + TopLevelProjectPtr project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 6); @@ -2549,7 +2559,7 @@ void TestLanguage::productDirectories() bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("productdirectories.qbs")); - ResolvedProjectPtr project = loader->loadProject(defaultParameters); + ResolvedProjectPtr project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 1); @@ -2708,7 +2718,7 @@ void TestLanguage::propertiesBlockInGroup() bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("properties-block-in-group.qbs")); - const TopLevelProjectPtr project = loader->loadProject(defaultParameters); + const TopLevelProjectPtr project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); QCOMPARE(project->allProducts().size(), size_t(1)); const ResolvedProductConstPtr product = project->allProducts().front(); @@ -2734,7 +2744,7 @@ void TestLanguage::propertiesItemInModule() try { defaultParameters.setProjectFilePath( testProject("properties-item-in-module.qbs")); - const TopLevelProjectPtr project = loader->loadProject(defaultParameters); + const TopLevelProjectPtr project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); const QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 2); @@ -2755,7 +2765,7 @@ void TestLanguage::propertyAssignmentInExportedGroup() try { defaultParameters.setProjectFilePath( testProject("property-assignment-in-exported-group.qbs")); - const TopLevelProjectPtr project = loader->loadProject(defaultParameters); + const TopLevelProjectPtr project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); const QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 2); @@ -2783,7 +2793,7 @@ void TestLanguage::qbs1275() bool exceptionCaught = false; try { defaultParameters.setProjectFilePath(testProject("qbs1275.qbs")); - const TopLevelProjectPtr project = loader->loadProject(defaultParameters); + const TopLevelProjectPtr project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); const QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.count(), 5); @@ -2800,7 +2810,7 @@ void TestLanguage::qbsPropertiesInProjectCondition() try { defaultParameters.setProjectFilePath( testProject("qbs-properties-in-project-condition.qbs")); - const TopLevelProjectPtr project = loader->loadProject(defaultParameters); + const TopLevelProjectPtr project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); const QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 0); @@ -2818,13 +2828,13 @@ void TestLanguage::qbsPropertyConvenienceOverride() SetupProjectParameters params = defaultParameters; params.setProjectFilePath(testProject("qbs-property-convenience-override.qbs")); params.setOverriddenValues({std::make_pair("qbs.installPrefix", "/opt")}); - TopLevelProjectConstPtr project = loader->loadProject(params); + TopLevelProjectConstPtr project = m_resolver->resolve(params); QVERIFY(!!project); QCOMPARE(project->products.size(), size_t(1)); QCOMPARE(project->products.front()->moduleProperties->qbsPropertyValue("installPrefix") .toString(), QString("/opt")); - } - catch (const ErrorInfo &e) { + } catch (const ErrorInfo &e) { + exceptionCaught = true; qDebug() << e.toString(); } QCOMPARE(exceptionCaught, false); @@ -2839,7 +2849,7 @@ void TestLanguage::relaxedErrorMode() params.setProjectFilePath(testProject("relaxed-error-mode/relaxed-error-mode.qbs")); params.setProductErrorMode(strictMode ? ErrorHandlingMode::Strict : ErrorHandlingMode::Relaxed); - const TopLevelProjectPtr project = loader->loadProject(params); + const TopLevelProjectPtr project = m_resolver->resolve(params); QVERIFY(!strictMode); const auto productMap = productsFromProject(project); const ResolvedProductConstPtr brokenProduct = productMap.value("broken"); @@ -2887,7 +2897,7 @@ void TestLanguage::requiredAndNonRequiredDependencies() SetupProjectParameters params = defaultParameters; const QString projectFilePath = "required-and-nonrequired-dependencies/" + projectFile; params.setProjectFilePath(testProject(projectFilePath.toLocal8Bit())); - const TopLevelProjectConstPtr project = loader->loadProject(params); + const TopLevelProjectConstPtr project = m_resolver->resolve(params); QVERIFY(!!project); QVERIFY(!exceptionExpected); } catch (const ErrorInfo &e) { @@ -2917,7 +2927,7 @@ void TestLanguage::suppressedAndNonSuppressedErrors() SetupProjectParameters params = defaultParameters; const QString projectFilePath = "suppressed-and-non-suppressed-errors.qbs"; params.setProjectFilePath(testProject(projectFilePath.toLocal8Bit())); - const TopLevelProjectConstPtr project = loader->loadProject(params); + const TopLevelProjectConstPtr project = m_resolver->resolve(params); QFAIL("failure expected"); } catch (const ErrorInfo &e) { QVERIFY2(e.toString().contains("easter bunny"), qPrintable(e.toString())); @@ -2934,7 +2944,7 @@ void TestLanguage::throwingProbe() QVariantMap properties; properties.insert(QStringLiteral("products.theProduct.enableProbe"), enableProbe); params.setOverriddenValues(properties); - const TopLevelProjectPtr project = loader->loadProject(params); + const TopLevelProjectPtr project = m_resolver->resolve(params); QVERIFY(!!project); QVERIFY(!enableProbe); } catch (const ErrorInfo &e) { @@ -2978,7 +2988,7 @@ void TestLanguage::recursiveProductDependencies() try { defaultParameters.setProjectFilePath( testProject("recursive-dependencies/recursive-dependencies.qbs")); - const TopLevelProjectPtr project = loader->loadProject(defaultParameters); + const TopLevelProjectPtr project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); const QHash<QString, ResolvedProductPtr> products = productsFromProject(project); QCOMPARE(products.size(), 4); @@ -3041,7 +3051,7 @@ void TestLanguage::useInternalProfile() SetupProjectParameters params = defaultParameters; params.setProjectFilePath(testProject("use-internal-profile.qbs")); params.setTopLevelProfile(profile); - TopLevelProjectConstPtr project = loader->loadProject(params); + TopLevelProjectConstPtr project = m_resolver->resolve(params); QVERIFY(!!project); QCOMPARE(project->profile(), profile); QCOMPARE(project->products.size(), size_t(1)); @@ -3251,7 +3261,7 @@ void TestLanguage::wildcards() ResolvedProductPtr product; try { defaultParameters.setProjectFilePath(projectFilePath); - project = loader->loadProject(defaultParameters); + project = m_resolver->resolve(defaultParameters); QVERIFY(!!project); const QHash<QString, ResolvedProductPtr> products = productsFromProject(project); product = products.value("MyProduct"); diff --git a/tests/auto/language/tst_language.h b/tests/auto/language/tst_language.h index 4fe2752e4..0a59c48b1 100644 --- a/tests/auto/language/tst_language.h +++ b/tests/auto/language/tst_language.h @@ -41,7 +41,7 @@ #define TST_LANGUAGE_H #include <language/forward_decls.h> -#include <language/loader.h> +#include <loader/projectresolver.h> #include <logging/ilogsink.h> #include <tools/setupprojectparameters.h> @@ -61,7 +61,7 @@ private: qbs::Settings * const m_settings; qbs::Internal::Logger m_logger; std::unique_ptr<qbs::Internal::ScriptEngine> m_engine; - qbs::Internal::Loader *loader; + qbs::Internal::ProjectResolver *m_resolver; qbs::Internal::TopLevelProjectPtr project; qbs::SetupProjectParameters defaultParameters; const QString m_wildcardsTestDirPath; @@ -75,8 +75,8 @@ private: private slots: void init(); + void cleanup(); void initTestCase(); - void cleanupTestCase(); void additionalProductTypes(); void baseProperty(); @@ -137,6 +137,7 @@ private slots: void modulePropertiesInGroups(); void modulePropertyOverridesPerProduct(); void moduleScope(); + void moduleWithProductDependency(); void modules_data(); void modules(); void multiplexedExports(); |