diff options
Diffstat (limited to 'tests/auto/blackbox')
21 files changed, 499 insertions, 117 deletions
diff --git a/tests/auto/blackbox/testdata/appWithoutSources/a.c b/tests/auto/blackbox/testdata/appWithoutSources/a.c new file mode 100644 index 000000000..bf7759e11 --- /dev/null +++ b/tests/auto/blackbox/testdata/appWithoutSources/a.c @@ -0,0 +1 @@ +int foo() { return 42; } diff --git a/tests/auto/blackbox/testdata/appWithoutSources/b.c b/tests/auto/blackbox/testdata/appWithoutSources/b.c new file mode 100644 index 000000000..e3841fa32 --- /dev/null +++ b/tests/auto/blackbox/testdata/appWithoutSources/b.c @@ -0,0 +1,10 @@ +#include <stdio.h> + +int foo(); // defined in a.cpp + +int main() +{ + printf("The answer is %d.\n", foo()); + return 0; +} + diff --git a/tests/auto/blackbox/testdata/appWithoutSources/project.qbs b/tests/auto/blackbox/testdata/appWithoutSources/project.qbs new file mode 100644 index 000000000..3e587bd5c --- /dev/null +++ b/tests/auto/blackbox/testdata/appWithoutSources/project.qbs @@ -0,0 +1,32 @@ +import qbs 1.0 + +Project { + StaticLibrary { + name: "a" + + Depends { name: "cpp" } + + files: [ + "a.c", + ] + } + + StaticLibrary { + name: "b" + + Depends { name: "a" } + Depends { name: "cpp" } + + files: [ + "b.c", + ] + } + + CppApplication { + name: "appWithoutSources" + cpp.entryPoint: "main" + + Depends { name: "a" } + Depends { name: "b" } + } +} diff --git a/tests/auto/blackbox/testdata/build-directories/project.qbs b/tests/auto/blackbox/testdata/build-directories/project.qbs new file mode 100644 index 000000000..cb83999e2 --- /dev/null +++ b/tests/auto/blackbox/testdata/build-directories/project.qbs @@ -0,0 +1,44 @@ +import qbs + +Project { + Product { + name: "p1" + type: "blubb1" + Transformer { + Artifact { + fileName: "dummy1.txt" + fileTags: product.type + } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.silent = true; + cmd.sourceCode = function() { + print(product.buildDirectory); + } + return cmd; + } + } + } + Product { + name: "p2" + type: "blubb2" + Depends { name: "p1" } + Rule { + usings: "blubb1" + Artifact { + fileName: "dummy2.txt" + fileTags: product.type + } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.silent = true; + cmd.sourceCode = function() { + print(product.buildDirectory); + print(project.buildDirectory); + print(project.sourceDirectory); + } + return cmd; + } + } + } +} diff --git a/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/genlexer.qbs b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/genlexer.qbs index 61504573f..2c145682a 100644 --- a/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/genlexer.qbs +++ b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/genlexer.qbs @@ -64,12 +64,12 @@ Project { var sourceFileName = options["outfile"] || "lex.yy.c"; var headerFileName = options["header-file"]; var result = [{ - filePath: "GeneratedFiles/" + product.name + "/" + sourceFileName, + filePath: "GeneratedFiles/" + sourceFileName, fileTags: ["c"] }]; if (headerFileName) { result.push({ - filePath: "GeneratedFiles/" + product.name + "/" + headerFileName, + filePath: "GeneratedFiles/" + headerFileName, fileTags: ["hpp"] }); } @@ -80,7 +80,7 @@ Project { if (product.isFlexAvailable) { // flex is available. Let's call it. cmd = new Command("flex", [input.filePath]); - cmd.workingDirectory = product.buildDirectory + "/GeneratedFiles/" + product.name; + cmd.workingDirectory = product.buildDirectory + "/GeneratedFiles"; } else { // No flex available here, generate some C source and header. cmd = new JavaScriptCommand(); diff --git a/tests/auto/blackbox/testdata/nodejs/hello.js b/tests/auto/blackbox/testdata/nodejs/hello.js new file mode 100644 index 000000000..43f1e2ffd --- /dev/null +++ b/tests/auto/blackbox/testdata/nodejs/hello.js @@ -0,0 +1,3 @@ +if (console) { + console.log("hello world"); +} diff --git a/tests/auto/blackbox/testdata/nodejs/hello.qbs b/tests/auto/blackbox/testdata/nodejs/hello.qbs new file mode 100644 index 000000000..e11b1a599 --- /dev/null +++ b/tests/auto/blackbox/testdata/nodejs/hello.qbs @@ -0,0 +1,7 @@ +import qbs + +NodeJSApplication { + nodejs.applicationFile: "hello.js" + name: "hello" + files: "hello.js" +} diff --git a/tests/auto/blackbox/testdata/simpleProbe/main.cpp b/tests/auto/blackbox/testdata/simpleProbe/main.cpp new file mode 100644 index 000000000..76e819701 --- /dev/null +++ b/tests/auto/blackbox/testdata/simpleProbe/main.cpp @@ -0,0 +1 @@ +int main() { return 0; } diff --git a/tests/auto/blackbox/testdata/simpleProbe/simpleProbe.qbs b/tests/auto/blackbox/testdata/simpleProbe/simpleProbe.qbs new file mode 100644 index 000000000..b409c7cc6 --- /dev/null +++ b/tests/auto/blackbox/testdata/simpleProbe/simpleProbe.qbs @@ -0,0 +1,31 @@ +import qbs 1.0 +import qbs.Probes + +CppApplication { + Probe { + id: probe1 + property string someString + configure: { + someString = "one"; + found = true; + } + } + Probe { + id: probe2 + configure: { + found = false; + } + } + name: "MyApp" + type: { + if (!probe1.found) + throw "probe1 not found"; + if (probe2.found) + throw "probe2 unexpectedly found"; + if (probe1.someString !== "one") + throw "probe1.someString expected to be \"one\"." + return "application" + } + files: ["main.cpp"] +} + diff --git a/tests/auto/blackbox/testdata/typescript/animals.ts b/tests/auto/blackbox/testdata/typescript/animals.ts new file mode 100644 index 000000000..a33ae5c11 --- /dev/null +++ b/tests/auto/blackbox/testdata/typescript/animals.ts @@ -0,0 +1,21 @@ +export interface Mammal { + speak(): string; +} + +export class Cat implements Mammal { + public speak() { + return "Meow"; // a cat says meow + } +} + +export class Dog implements Mammal { + public speak() { + return "Woof"; // a dog says woof + } +} + +export class Human implements Mammal { + public speak() { + return "Hello"; + } +} diff --git a/tests/auto/blackbox/testdata/typescript/extra.js b/tests/auto/blackbox/testdata/typescript/extra.js new file mode 100644 index 000000000..5500e4688 --- /dev/null +++ b/tests/auto/blackbox/testdata/typescript/extra.js @@ -0,0 +1,3 @@ +if (console) { + console.log("This doesn't do anything useful!"); +} diff --git a/tests/auto/blackbox/testdata/typescript/foo.ts b/tests/auto/blackbox/testdata/typescript/foo.ts new file mode 100644 index 000000000..3554d317a --- /dev/null +++ b/tests/auto/blackbox/testdata/typescript/foo.ts @@ -0,0 +1,5 @@ +export class Greeter { + public getGreeting(): string { + return "guten Tag!"; + } +} diff --git a/tests/auto/blackbox/testdata/typescript/main.ts b/tests/auto/blackbox/testdata/typescript/main.ts new file mode 100644 index 000000000..c41eebea5 --- /dev/null +++ b/tests/auto/blackbox/testdata/typescript/main.ts @@ -0,0 +1,19 @@ +import Animals = require("animals"); +import Foo = require("foo"); + +function main() { + var mammals: Animals.Mammal[] = []; + mammals.push(new Animals.Human()); + mammals.push(new Animals.Dog()); + mammals.push(new Animals.Cat()); + + // Make everyone speak + for (var i = 0; i < mammals.length; ++i) { + console.log(mammals[i].speak()); + } + + var greeting: string = (new Foo.Greeter()).getGreeting(); + console.log(greeting); +} + +main(); diff --git a/tests/auto/blackbox/testdata/typescript/typescript.qbs b/tests/auto/blackbox/testdata/typescript/typescript.qbs new file mode 100644 index 000000000..8407d1203 --- /dev/null +++ b/tests/auto/blackbox/testdata/typescript/typescript.qbs @@ -0,0 +1,34 @@ +import qbs + +Project { + NodeJSApplication { + Depends { name: "typescript" } + Depends { name: "lib" } + + typescript.warningLevel: ["pedantic"] + typescript.generateDeclarations: true + typescript.moduleLoader: "commonjs" + nodejs.applicationFile: "main.ts" + + name: "animals" + + files: [ + "animals.ts", + "extra.js", + "main.ts" + ] + } + + Product { + Depends { name: "typescript" } + + typescript.generateDeclarations: true + typescript.moduleLoader: "commonjs" + + name: "lib" + + files: [ + "foo.ts" + ] + } +} diff --git a/tests/auto/blackbox/testdata/usings-as-sole-inputs-non-multiplexed/custom1.in b/tests/auto/blackbox/testdata/usings-as-sole-inputs-non-multiplexed/custom1.in new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/auto/blackbox/testdata/usings-as-sole-inputs-non-multiplexed/custom1.in diff --git a/tests/auto/blackbox/testdata/usings-as-sole-inputs-non-multiplexed/custom2.in b/tests/auto/blackbox/testdata/usings-as-sole-inputs-non-multiplexed/custom2.in new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/auto/blackbox/testdata/usings-as-sole-inputs-non-multiplexed/custom2.in diff --git a/tests/auto/blackbox/testdata/usings-as-sole-inputs-non-multiplexed/project.qbs b/tests/auto/blackbox/testdata/usings-as-sole-inputs-non-multiplexed/project.qbs new file mode 100644 index 000000000..80644232e --- /dev/null +++ b/tests/auto/blackbox/testdata/usings-as-sole-inputs-non-multiplexed/project.qbs @@ -0,0 +1,62 @@ +import qbs +import qbs.FileInfo +import qbs.TextFile + +Project { + Product { + name: "p1" + type: "custom" + Group { + files: "custom1.in" + fileTags: "custom.in" + } + } + Product { + name: "p2" + type: "custom" + Group { + files: "custom2.in" + fileTags: "custom.in" + } + } + + Rule { + inputs: "custom.in" + Artifact { + fileName: FileInfo.baseName(input.filePath) + ".out" + fileTags: "custom" + } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "generating " + output.fileName; + cmd.sourceCode = function() { + var f = new TextFile(output.filePath, TextFile.WriteOnly); + f.close(); + } + return cmd; + } + } + + Product { + name: "p3" + type: "custom-plus" + Depends { name: "p1" } + Depends { name: "p2" } + Rule { + usings: "custom" + Artifact { + fileName: FileInfo.fileName(input.filePath) + ".plus" + fileTags: "custom-plus" + } + prepare: { + var cmd = new JavaScriptCommand(); + cmd.description = "generating " + output.fileName; + cmd.sourceCode = function() { + var f = new TextFile(output.filePath, TextFile.WriteOnly); + f.close(); + } + return cmd; + } + } + } +} diff --git a/tests/auto/blackbox/testdata/wix/WiXInstallers.qbs b/tests/auto/blackbox/testdata/wix/WiXInstallers.qbs index 718901675..88f50733d 100644 --- a/tests/auto/blackbox/testdata/wix/WiXInstallers.qbs +++ b/tests/auto/blackbox/testdata/wix/WiXInstallers.qbs @@ -13,12 +13,12 @@ Project { name: "QbsBootstrapper" targetName: "qbs-setup-" + qbs.architecture files: ["QbsBootstrapper.wxs"] - wix.defines: ["msiName=qbs-" + qbs.architecture + ".msi"] + wix.defines: ["msiName=" + project.buildDirectory + "/QbsSetup/qbs-" + qbs.architecture + ".msi"] } WindowsInstallerPackage { name: "RegressionBuster9000" - files: ["QbsSetup.wxs", "Qt.wxs"] + files: ["QbsSetup.wxs", "Qt.wxs", "de.wxl"] wix.defines: ["scriptName=ExampleScript.bat"] wix.cultures: [] } diff --git a/tests/auto/blackbox/testdata/wix/de.wxl b/tests/auto/blackbox/testdata/wix/de.wxl new file mode 100644 index 000000000..75394cfdd --- /dev/null +++ b/tests/auto/blackbox/testdata/wix/de.wxl @@ -0,0 +1 @@ +<WixLocalization xmlns="http://schemas.microsoft.com/wix/2006/localization"/> diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index d185dbdde..5ffb43961 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -47,6 +47,12 @@ using qbs::Internal::HostOsInfo; using qbs::Internal::removeDirectoryWithContents; using qbs::Profile; +static bool regularFileExists(const QString &filePath) +{ + const QFileInfo fi(filePath); + return fi.exists() && fi.isFile(); +} + static QString initQbsExecutableFilePath() { QString filePath = QCoreApplication::applicationDirPath() + QLatin1String("/qbs"); @@ -173,7 +179,7 @@ QByteArray TestBlackbox::unifiedLineEndings(const QByteArray &ba) void TestBlackbox::initTestCase() { - QVERIFY(QFile::exists(qbsExecutableFilePath)); + QVERIFY(regularFileExists(qbsExecutableFilePath)); SettingsPtr settings = qbsSettings(QString()); if (!settings->profiles().contains(buildProfileName)) @@ -259,49 +265,68 @@ void TestBlackbox::baseProperties() QCOMPARE(runQbs(), 0); } +void TestBlackbox::buildDirectories() +{ + const QString projectDir + = QDir::cleanPath(testDataDir + QLatin1String("/build-directories")); + const QString projectBuildDir = projectDir + '/' + buildDir; + QDir::setCurrent(projectDir); + QCOMPARE(runQbs(QStringList("-qq")), 0); + const QStringList outputLines + = QString::fromLocal8Bit(m_qbsStderr.trimmed()).split('\n', QString::SkipEmptyParts); + QCOMPARE(outputLines.count(), 4); + QCOMPARE(outputLines.at(0).trimmed(), projectDir + '/' + productBuildDir("p1")); + QCOMPARE(outputLines.at(1).trimmed(), projectDir + '/' + productBuildDir("p2")); + QCOMPARE(outputLines.at(2).trimmed(), projectBuildDir); + QCOMPARE(outputLines.at(3).trimmed(), projectDir); +} + void TestBlackbox::build_project_data() { QTest::addColumn<QString>("projectSubDir"); QTest::addColumn<QString>("productFileName"); QTest::newRow("BPs in Sources") << QString("buildproperties_source") - << QString(HostOsInfo::appendExecutableSuffix(buildDir + "/HelloWorld")); + << executableFilePath("HelloWorld"); QTest::newRow("code generator") << QString("codegen") - << QString(HostOsInfo::appendExecutableSuffix(buildDir + "/codegen")); + << executableFilePath("codegen"); QTest::newRow("link static libs") << QString("link_staticlib") - << QString(buildDir + QLatin1String("/") - + HostOsInfo::appendExecutableSuffix("HelloWorld")); + << executableFilePath("HelloWorld"); QTest::newRow("precompiled header") << QString("precompiledHeader") - << QString(buildDir + QLatin1String("/") - + HostOsInfo::appendExecutableSuffix("MyApp")); + << executableFilePath("MyApp"); QTest::newRow("lots of dots") << QString("lotsofdots") - << QString(buildDir + QLatin1String("/") - + HostOsInfo::appendExecutableSuffix("lots.of.dots")); + << executableFilePath("lots.of.dots"); QTest::newRow("Qt5 plugin") << QString("qt5plugin") - << QString(buildDir + QLatin1String("/") + HostOsInfo::dynamicLibraryName("echoplugin")); + << productBuildDir("echoplugin") + '/' + HostOsInfo::dynamicLibraryName("echoplugin"); QTest::newRow("Q_OBJECT in source") << QString("moc_cpp") - << QString(HostOsInfo::appendExecutableSuffix(buildDir + "/moc_cpp")); + << executableFilePath("moc_cpp"); QTest::newRow("Q_OBJECT in header") << QString("moc_hpp") - << QString(HostOsInfo::appendExecutableSuffix(buildDir + "/moc_hpp")); + << executableFilePath("moc_hpp"); QTest::newRow("Q_OBJECT in header, moc_XXX.cpp included") << QString("moc_hpp_included") - << QString(HostOsInfo::appendExecutableSuffix(buildDir + "/moc_hpp_included")); + << executableFilePath("moc_hpp_included"); QTest::newRow("app and lib with same source file") << QString("lib_samesource") - << QString(HostOsInfo::appendExecutableSuffix(buildDir + "/HelloWorldApp")); + << executableFilePath("HelloWorldApp"); QTest::newRow("source files with the same base name but different extensions") << QString("sameBaseName") - << QString(HostOsInfo::appendExecutableSuffix(buildDir + "/basename")); + << executableFilePath("basename"); QTest::newRow("static library dependencies") << QString("staticLibDeps") - << QString(HostOsInfo::appendExecutableSuffix(buildDir + "/staticLibDeps")); + << executableFilePath("staticLibDeps"); + QTest::newRow("simple probes") + << QString("simpleProbe") + << executableFilePath("MyApp"); + QTest::newRow("application without sources") + << QString("appWithoutSources") + << executableFilePath("appWithoutSources"); } void TestBlackbox::build_project() @@ -315,13 +340,13 @@ void TestBlackbox::build_project() rmDirR(buildDir); QCOMPARE(runQbs(), 0); - QVERIFY2(QFile::exists(productFileName), qPrintable(productFileName)); - QVERIFY(QFile::exists(buildGraphPath)); + QVERIFY2(regularFileExists(productFileName), qPrintable(productFileName)); + QVERIFY(regularFileExists(buildGraphPath)); QVERIFY2(QFile::remove(productFileName), qPrintable(productFileName)); waitForNewTimestamp(); QCOMPARE(runQbs(QbsRunParameters(QStringList("--check-timestamps"))), 0); - QVERIFY2(QFile::exists(productFileName), qPrintable(productFileName)); - QVERIFY(QFile::exists(buildGraphPath)); + QVERIFY2(regularFileExists(productFileName), qPrintable(productFileName)); + QVERIFY(regularFileExists(buildGraphPath)); } void TestBlackbox::build_project_dry_run_data() @@ -387,7 +412,7 @@ void TestBlackbox::dependenciesProperty() { QDir::setCurrent(testDataDir + QLatin1String("/dependenciesProperty")); QCOMPARE(runQbs(), 0); - QFile depsFile(buildDir + QLatin1String("/product1.deps")); + QFile depsFile(productBuildDir("product1") + QLatin1String("/product1.deps")); QVERIFY(depsFile.open(QFile::ReadOnly)); QString deps = QString::fromLatin1(depsFile.readAll()); QVERIFY(!deps.isEmpty()); @@ -445,7 +470,7 @@ void TestBlackbox::resolve_project() QCOMPARE(runQbs(QbsRunParameters("resolve")), 0); QVERIFY2(!QFile::exists(productFileName), qPrintable(productFileName)); - QVERIFY(QFile::exists(buildGraphPath)); + QVERIFY(regularFileExists(buildGraphPath)); } void TestBlackbox::resolve_project_dry_run_data() @@ -468,6 +493,15 @@ void TestBlackbox::resolve_project_dry_run() QVERIFY2(!QFile::exists(buildGraphPath), qPrintable(buildGraphPath)); } +void TestBlackbox::usingsAsSoleInputsNonMultiplexed() +{ + QDir::setCurrent(testDataDir + QLatin1String("/usings-as-sole-inputs-non-multiplexed")); + QCOMPARE(runQbs(), 0); + const QString p3BuildDir = productBuildDir("p3"); + QVERIFY(regularFileExists(p3BuildDir + "/custom1.out.plus")); + QVERIFY(regularFileExists(p3BuildDir + "/custom2.out.plus")); +} + static bool symlinkExists(const QString &linkFilePath) { return QFileInfo(linkFilePath).isSymLink(); @@ -475,10 +509,10 @@ static bool symlinkExists(const QString &linkFilePath) void TestBlackbox::clean() { - const QString appObjectFilePath = buildDir + "/.obj/app/main.cpp" + QTC_HOST_OBJECT_SUFFIX; - const QString appExeFilePath = buildDir + "/app" + QTC_HOST_EXE_SUFFIX; - const QString depObjectFilePath = buildDir + "/.obj/dep/dep.cpp" + QTC_HOST_OBJECT_SUFFIX; - const QString depLibBase = buildDir + '/' + QTC_HOST_DYNAMICLIB_PREFIX + "dep"; + const QString appObjectFilePath = productBuildDir("app") + "/.obj/main.cpp" + QTC_HOST_OBJECT_SUFFIX; + const QString appExeFilePath = executableFilePath("app"); + const QString depObjectFilePath = productBuildDir("dep") + "/.obj/dep.cpp" + QTC_HOST_OBJECT_SUFFIX; + const QString depLibBase = productBuildDir("dep") + '/' + QTC_HOST_DYNAMICLIB_PREFIX + "dep"; QString depLibFilePath; QStringList symlinks; if (qbs::Internal::HostOsInfo::isOsxHost()) { @@ -499,24 +533,24 @@ void TestBlackbox::clean() // Default behavior: Remove only temporaries. QCOMPARE(runQbs(), 0); - QVERIFY(QFile(appObjectFilePath).exists()); - QVERIFY(QFile(appExeFilePath).exists()); - QVERIFY(QFile(depObjectFilePath).exists()); - QVERIFY(QFile(depLibFilePath).exists()); + QVERIFY(regularFileExists(appObjectFilePath)); + QVERIFY(regularFileExists(appExeFilePath)); + QVERIFY(regularFileExists(depObjectFilePath)); + QVERIFY(regularFileExists(depLibFilePath)); foreach (const QString &symLink, symlinks) - QVERIFY2(QFile(symLink).exists(), qPrintable(symLink)); + QVERIFY2(regularFileExists(symLink), qPrintable(symLink)); QCOMPARE(runQbs(QbsRunParameters("clean")), 0); QVERIFY(!QFile(appObjectFilePath).exists()); - QVERIFY(QFile(appExeFilePath).exists()); + QVERIFY(regularFileExists(appExeFilePath)); QVERIFY(!QFile(depObjectFilePath).exists()); - QVERIFY(QFile(depLibFilePath).exists()); + QVERIFY(regularFileExists(depLibFilePath)); foreach (const QString &symLink, symlinks) QVERIFY2(symlinkExists(symLink), qPrintable(symLink)); // Remove all. QCOMPARE(runQbs(), 0); - QVERIFY(QFile(appObjectFilePath).exists()); - QVERIFY(QFile(appExeFilePath).exists()); + QVERIFY(regularFileExists(appObjectFilePath)); + QVERIFY(regularFileExists(appExeFilePath)); QCOMPARE(runQbs(QbsRunParameters(QLatin1String("clean"), QStringList("--all-artifacts"))), 0); QVERIFY(!QFile(appObjectFilePath).exists()); QVERIFY(!QFile(appExeFilePath).exists()); @@ -527,28 +561,28 @@ void TestBlackbox::clean() // Dry run. QCOMPARE(runQbs(), 0); - QVERIFY(QFile(appObjectFilePath).exists()); - QVERIFY(QFile(appExeFilePath).exists()); + QVERIFY(regularFileExists(appObjectFilePath)); + QVERIFY(regularFileExists(appExeFilePath)); QCOMPARE(runQbs(QbsRunParameters(QLatin1String("clean"), QStringList("--all-artifacts") << "-n")), 0); - QVERIFY(QFile(appObjectFilePath).exists()); - QVERIFY(QFile(appExeFilePath).exists()); - QVERIFY(QFile(depObjectFilePath).exists()); - QVERIFY(QFile(depLibFilePath).exists()); + QVERIFY(regularFileExists(appObjectFilePath)); + QVERIFY(regularFileExists(appExeFilePath)); + QVERIFY(regularFileExists(depObjectFilePath)); + QVERIFY(regularFileExists(depLibFilePath)); foreach (const QString &symLink, symlinks) QVERIFY2(symlinkExists(symLink), qPrintable(symLink)); // Product-wise, dependency only. QCOMPARE(runQbs(), 0); - QVERIFY(QFile(appObjectFilePath).exists()); - QVERIFY(QFile(appExeFilePath).exists()); - QVERIFY(QFile(depObjectFilePath).exists()); - QVERIFY(QFile(depLibFilePath).exists()); + QVERIFY(regularFileExists(appObjectFilePath)); + QVERIFY(regularFileExists(appExeFilePath)); + QVERIFY(regularFileExists(depObjectFilePath)); + QVERIFY(regularFileExists(depLibFilePath)); QCOMPARE(runQbs(QbsRunParameters(QLatin1String("clean"), QStringList("--all-artifacts") << "-p" << "dep")), 0); - QVERIFY(QFile(appObjectFilePath).exists()); - QVERIFY(QFile(appExeFilePath).exists()); + QVERIFY(regularFileExists(appObjectFilePath)); + QVERIFY(regularFileExists(appExeFilePath)); QVERIFY(!QFile(depObjectFilePath).exists()); QVERIFY(!QFile(depLibFilePath).exists()); foreach (const QString &symLink, symlinks) @@ -556,17 +590,17 @@ void TestBlackbox::clean() // Product-wise, dependent product only. QCOMPARE(runQbs(), 0); - QVERIFY(QFile(appObjectFilePath).exists()); - QVERIFY(QFile(appExeFilePath).exists()); - QVERIFY(QFile(depObjectFilePath).exists()); - QVERIFY(QFile(depLibFilePath).exists()); + QVERIFY(regularFileExists(appObjectFilePath)); + QVERIFY(regularFileExists(appExeFilePath)); + QVERIFY(regularFileExists(depObjectFilePath)); + QVERIFY(regularFileExists(depLibFilePath)); QCOMPARE(runQbs(QbsRunParameters(QLatin1String("clean"), QStringList("--all-artifacts") << "-p" << "app")), 0); QVERIFY(!QFile(appObjectFilePath).exists()); QVERIFY(!QFile(appExeFilePath).exists()); - QVERIFY(QFile(depObjectFilePath).exists()); - QVERIFY(QFile(depLibFilePath).exists()); + QVERIFY(regularFileExists(depObjectFilePath)); + QVERIFY(regularFileExists(depLibFilePath)); foreach (const QString &symLink, symlinks) QVERIFY2(symlinkExists(symLink), qPrintable(symLink)); } @@ -708,8 +742,8 @@ void TestBlackbox::track_qrc() { QDir::setCurrent(testDataDir + "/qrc"); QCOMPARE(runQbs(), 0); - const QString fileName = HostOsInfo::appendExecutableSuffix(buildDir + "/i"); - QVERIFY2(QFile(fileName).exists(), qPrintable(fileName)); + const QString fileName = executableFilePath("i"); + QVERIFY2(regularFileExists(fileName), qPrintable(fileName)); QDateTime dt = QFileInfo(fileName).lastModified(); QTest::qSleep(2020); { @@ -720,7 +754,7 @@ void TestBlackbox::track_qrc() f.close(); } QCOMPARE(runQbs(), 0); - QVERIFY(QFile(fileName).exists()); + QVERIFY(regularFileExists(fileName)); QVERIFY(dt < QFileInfo(fileName).lastModified()); } @@ -731,18 +765,18 @@ void TestBlackbox::track_qobject_change() QVERIFY(QFile("bla_qobject.h").copy("bla.h")); touch("bla.h"); QCOMPARE(runQbs(), 0); - const QString productFilePath = HostOsInfo::appendExecutableSuffix(buildDir + "/i"); - QVERIFY2(QFile(productFilePath).exists(), qPrintable(productFilePath)); + const QString productFilePath = executableFilePath("i"); + QVERIFY2(regularFileExists(productFilePath), qPrintable(productFilePath)); QString moc_bla_objectFileName - = buildDir + "/.obj/i/GeneratedFiles/i/moc_bla.cpp" QTC_HOST_OBJECT_SUFFIX; - QVERIFY(QFile(moc_bla_objectFileName).exists()); + = buildDir + "/i/.obj/i/GeneratedFiles/moc_bla.cpp" QTC_HOST_OBJECT_SUFFIX; + QVERIFY2(regularFileExists(moc_bla_objectFileName), qPrintable(moc_bla_objectFileName)); QTest::qSleep(1000); QFile("bla.h").remove(); QVERIFY(QFile("bla_noqobject.h").copy("bla.h")); touch("bla.h"); QCOMPARE(runQbs(), 0); - QVERIFY(QFile(productFilePath).exists()); + QVERIFY(regularFileExists(productFilePath)); QVERIFY(!QFile(moc_bla_objectFileName).exists()); } @@ -758,7 +792,7 @@ void TestBlackbox::trackAddFile() QDir::setCurrent(testDataDir + "/trackAddFile/work"); QCOMPARE(runQbs(), 0); - process.start(buildDir + "/someapp"); + process.start(executableFilePath("someapp")); QVERIFY2(process.waitForStarted(), qPrintable(process.errorString())); QVERIFY2(process.waitForFinished(), qPrintable(process.errorString())); QCOMPARE(process.exitCode(), 0); @@ -774,7 +808,7 @@ void TestBlackbox::trackAddFile() touch("main.cpp"); QCOMPARE(runQbs(), 0); - process.start(buildDir + "/someapp"); + process.start(executableFilePath("someapp")); QVERIFY(process.waitForStarted()); QVERIFY(process.waitForFinished()); QCOMPARE(process.exitCode(), 0); @@ -863,7 +897,7 @@ void TestBlackbox::trackRemoveFile() QDir::setCurrent(testDataDir + "/trackAddFile/work"); QCOMPARE(runQbs(), 0); - process.start(buildDir + "/someapp"); + process.start(executableFilePath("someapp")); QVERIFY2(process.waitForStarted(), qPrintable(process.errorString())); QVERIFY2(process.waitForFinished(), qPrintable(process.errorString())); QCOMPARE(process.exitCode(), 0); @@ -887,7 +921,7 @@ void TestBlackbox::trackRemoveFile() touch("project.qbs"); QCOMPARE(runQbs(), 0); - process.start(buildDir + "/someapp"); + process.start(executableFilePath("someapp")); QVERIFY(process.waitForStarted()); QVERIFY(process.waitForFinished()); QCOMPARE(process.exitCode(), 0); @@ -900,7 +934,7 @@ void TestBlackbox::trackRemoveFile() QCOMPARE(unchangedObjectFileTime1, unchangedObjectFileTime2); // the object file for the removed cpp file should have vanished too - QCOMPARE(QFile::exists(buildDir + "/someapp/zort.cpp" QTC_HOST_OBJECT_SUFFIX), false); + QCOMPARE(regularFileExists(buildDir + "/someapp/zort.cpp" QTC_HOST_OBJECT_SUFFIX), false); } void TestBlackbox::trackAddFileTag() @@ -915,7 +949,7 @@ void TestBlackbox::trackAddFileTag() QDir::setCurrent(testDataDir + "/trackFileTags/work"); QCOMPARE(runQbs(), 0); - process.start(buildDir + "/someapp"); + process.start(executableFilePath("someapp")); QVERIFY2(process.waitForStarted(), qPrintable(process.errorString())); QVERIFY2(process.waitForFinished(), qPrintable(process.errorString())); QCOMPARE(process.exitCode(), 0); @@ -928,7 +962,7 @@ void TestBlackbox::trackAddFileTag() touch("project.qbs"); QCOMPARE(runQbs(), 0); - process.start(buildDir + "/someapp"); + process.start(executableFilePath("someapp")); QVERIFY(process.waitForStarted()); QVERIFY(process.waitForFinished()); QCOMPARE(process.exitCode(), 0); @@ -949,12 +983,11 @@ void TestBlackbox::trackRemoveFileTag() QCOMPARE(runQbs(), 0); // check if the artifacts are here that will become stale in the 2nd step - QVERIFY2(QFile::exists(buildDir + "/.obj/someapp/main_foo.cpp" QTC_HOST_OBJECT_SUFFIX), - qPrintable(buildDir + "/.obj/someapp/main_foo.cpp" QTC_HOST_OBJECT_SUFFIX)); - QVERIFY2(QFile::exists(buildDir + "/main_foo.cpp"), qPrintable(buildDir + "/main_foo.cpp")); - QVERIFY2(QFile::exists(buildDir + "/main.foo"), qPrintable(buildDir + "/main.foo")); + QVERIFY(regularFileExists(buildDir + "/someapp/.obj/someapp/main_foo.cpp" QTC_HOST_OBJECT_SUFFIX)); + QVERIFY(regularFileExists(productBuildDir("someapp") + "/main_foo.cpp")); + QVERIFY(regularFileExists(productBuildDir("someapp") + "/main.foo")); - process.start(buildDir + "/someapp"); + process.start(executableFilePath("someapp")); QVERIFY(process.waitForStarted()); QVERIFY(process.waitForFinished()); QCOMPARE(process.exitCode(), 0); @@ -967,7 +1000,7 @@ void TestBlackbox::trackRemoveFileTag() touch("project.qbs"); QCOMPARE(runQbs(), 0); - process.start(buildDir + "/someapp"); + process.start(executableFilePath("someapp")); QVERIFY(process.waitForStarted()); QVERIFY(process.waitForFinished()); QCOMPARE(process.exitCode(), 0); @@ -975,9 +1008,9 @@ void TestBlackbox::trackRemoveFileTag() QCOMPARE(output.takeFirst().trimmed().constData(), "there's no foo here"); // check if stale artifacts have been removed - QCOMPARE(QFile::exists(buildDir + "/someapp/main_foo.cpp" QTC_HOST_OBJECT_SUFFIX), false); - QCOMPARE(QFile::exists(buildDir + "/someapp/main_foo.cpp"), false); - QCOMPARE(QFile::exists(buildDir + "/someapp/main.foo"), false); + QCOMPARE(regularFileExists(productBuildDir("someapp") + "/.obj/main_foo.cpp" QTC_HOST_OBJECT_SUFFIX), false); + QCOMPARE(regularFileExists(productBuildDir("someapp") + "/main_foo.cpp"), false); + QCOMPARE(regularFileExists(productBuildDir("someapp") + "/main.foo"), false); } void TestBlackbox::trackAddMocInclude() @@ -1108,10 +1141,10 @@ void TestBlackbox::ruleConditions() { QDir::setCurrent(testDataDir + "/ruleConditions"); QCOMPARE(runQbs(), 0); - QVERIFY(QFileInfo(buildDir + HostOsInfo::appendExecutableSuffix("/zorted")).exists()); - QVERIFY(QFileInfo(buildDir + HostOsInfo::appendExecutableSuffix("/unzorted")).exists()); - QVERIFY(QFileInfo(buildDir + "/zorted.foo.narf.zort").exists()); - QVERIFY(!QFileInfo(buildDir + "/unzorted.foo.narf.zort").exists()); + QVERIFY(QFileInfo(executableFilePath("zorted")).exists()); + QVERIFY(QFileInfo(executableFilePath("unzorted")).exists()); + QVERIFY(QFileInfo(productBuildDir("zorted") + "/zorted.foo.narf.zort").exists()); + QVERIFY(!QFileInfo(productBuildDir("unzorted") + "/unzorted.foo.narf.zort").exists()); } void TestBlackbox::ruleCycle() @@ -1175,8 +1208,7 @@ void TestBlackbox::overrideProjectProperties() << QLatin1String("project.someInt:156") << QLatin1String("project.someStringList:one") << QLatin1String("MyAppForYou.mainFile:main.cpp"))), 0); - QVERIFY(QFile::exists(buildDir + HostOsInfo::appendExecutableSuffix("/MyAppForYou"))); - + QVERIFY(regularFileExists(executableFilePath("MyAppForYou"))); QVERIFY(QFile::remove(buildGraphPath)); QbsRunParameters params; params.arguments << QLatin1String("-f") << QLatin1String("project_using_helper_lib.qbs"); @@ -1196,7 +1228,7 @@ void TestBlackbox::productProperties() QDir::setCurrent(testDataDir + "/productproperties"); QCOMPARE(runQbs(QbsRunParameters(QStringList() << QLatin1String("-f") << QLatin1String("project.qbs"))), 0); - QVERIFY(QFile::exists(buildDir + HostOsInfo::appendExecutableSuffix("/blubb_user"))); + QVERIFY(regularFileExists(executableFilePath("blubb_user"))); } void TestBlackbox::propertyChanges() @@ -1214,7 +1246,7 @@ void TestBlackbox::propertyChanges() QVERIFY(m_qbsStdout.contains("linking product 1.debug")); QVERIFY(m_qbsStdout.contains("generated.txt")); QVERIFY(m_qbsStdout.contains("Making output from input")); - QFile generatedFile(buildDir + QLatin1String("/generated.txt")); + QFile generatedFile(productBuildDir("generated text file") + "/generated.txt"); QVERIFY(generatedFile.open(QIODevice::ReadOnly)); QCOMPARE(generatedFile.readAll(), QByteArray("prefix 1contents 1suffix 1")); generatedFile.close(); @@ -1480,15 +1512,15 @@ void TestBlackbox::dynamicRuleOutputs() QDir::setCurrent(testDir + "/work"); QCOMPARE(runQbs(), 0); - const QString appFile = buildDir + "/genlexer" + QTC_HOST_EXE_SUFFIX; - const QString headerFile1 = buildDir + "/GeneratedFiles/genlexer/numberscanner.h"; - const QString sourceFile1 = buildDir + "/GeneratedFiles/genlexer/numberscanner.c"; - const QString sourceFile2 = buildDir + "/GeneratedFiles/genlexer/lex.yy.c"; + const QString appFile = executableFilePath("genlexer"); + const QString headerFile1 = productBuildDir("genlexer") + "/GeneratedFiles/numberscanner.h"; + const QString sourceFile1 = productBuildDir("genlexer") + "/GeneratedFiles/numberscanner.c"; + const QString sourceFile2 = productBuildDir("genlexer") + "/GeneratedFiles/lex.yy.c"; // Check build #1: source and header file name are specified in numbers.l - QVERIFY(QFile::exists(appFile)); - QVERIFY(QFile::exists(headerFile1)); - QVERIFY(QFile::exists(sourceFile1)); + QVERIFY(regularFileExists(appFile)); + QVERIFY(regularFileExists(headerFile1)); + QVERIFY(regularFileExists(sourceFile1)); QVERIFY(!QFile::exists(sourceFile2)); QDateTime appFileTimeStamp1 = QFileInfo(appFile).lastModified(); @@ -1504,7 +1536,7 @@ void TestBlackbox::dynamicRuleOutputs() QVERIFY(appFileTimeStamp1 < appFileTimeStamp2); QVERIFY(!QFile::exists(headerFile1)); QVERIFY(!QFile::exists(sourceFile1)); - QVERIFY(QFile::exists(sourceFile2)); + QVERIFY(regularFileExists(sourceFile2)); waitForNewTimestamp(); QFile::remove("numbers.l"); @@ -1515,9 +1547,9 @@ void TestBlackbox::dynamicRuleOutputs() // Check build #3: source and header file name are specified in numbers.l QDateTime appFileTimeStamp3 = QFileInfo(appFile).lastModified(); QVERIFY(appFileTimeStamp2 < appFileTimeStamp3); - QVERIFY(QFile::exists(appFile)); - QVERIFY(QFile::exists(headerFile1)); - QVERIFY(QFile::exists(sourceFile1)); + QVERIFY(regularFileExists(appFile)); + QVERIFY(regularFileExists(headerFile1)); + QVERIFY(regularFileExists(sourceFile1)); QVERIFY(!QFile::exists(sourceFile2)); } @@ -1563,8 +1595,8 @@ void TestBlackbox::fileDependencies() QCOMPARE(runQbs(), 0); QVERIFY(m_qbsStdout.contains("compiling narf.cpp")); QVERIFY(m_qbsStdout.contains("compiling zort.cpp")); - const QString productFileName = HostOsInfo::appendExecutableSuffix(buildDir + "/myapp"); - QVERIFY2(QFile::exists(productFileName), qPrintable(productFileName)); + const QString productFileName = executableFilePath("myapp"); + QVERIFY2(regularFileExists(productFileName), qPrintable(productFileName)); // Incremental build without changes. QCOMPARE(runQbs(), 0); @@ -1742,7 +1774,7 @@ void TestBlackbox::qmlDebugging() QDir::setCurrent(testDataDir + "/qml-debugging"); QCOMPARE(runQbs(), 0); QProcess nm; - nm.start("nm", QStringList(HostOsInfo::appendExecutableSuffix(buildDir + "/debuggable-app"))); + nm.start("nm", QStringList(executableFilePath("debuggable-app"))); if (nm.waitForStarted()) { // Let's ignore hosts without nm. QVERIFY2(nm.waitForFinished(), qPrintable(nm.errorString())); QVERIFY2(nm.exitCode() == 0, nm.readAllStandardError().constData()); @@ -1780,12 +1812,12 @@ void TestBlackbox::installedApp() QDir::setCurrent(testDataDir + "/installed_artifact"); QCOMPARE(runQbs(QbsRunParameters("install")), 0); - QVERIFY(QFile::exists(defaultInstallRoot + QVERIFY(regularFileExists(defaultInstallRoot + HostOsInfo::appendExecutableSuffix(QLatin1String("/usr/bin/installedApp")))); QCOMPARE(runQbs(QbsRunParameters(QLatin1String("install"), QStringList("--install-root") << (testDataDir + "/installed-app"))), 0); - QVERIFY(QFile::exists(testDataDir + QVERIFY(regularFileExists(testDataDir + HostOsInfo::appendExecutableSuffix("/installed-app/usr/bin/installedApp"))); QFile addedFile(defaultInstallRoot + QLatin1String("/blubb.txt")); @@ -1793,9 +1825,9 @@ void TestBlackbox::installedApp() addedFile.close(); QVERIFY(addedFile.exists()); QCOMPARE(runQbs(QbsRunParameters(QLatin1String("install"), QStringList("--remove-first"))), 0); - QVERIFY(QFile::exists(defaultInstallRoot + QVERIFY(regularFileExists(defaultInstallRoot + HostOsInfo::appendExecutableSuffix(QLatin1String("/usr/bin/installedApp")))); - QVERIFY(QFile::exists(defaultInstallRoot + QLatin1String("/usr/src/main.cpp"))); + QVERIFY(regularFileExists(defaultInstallRoot + QLatin1String("/usr/src/main.cpp"))); QVERIFY(!addedFile.exists()); // Check whether changing install parameters on the product causes re-installation. @@ -1808,9 +1840,9 @@ void TestBlackbox::installedApp() projectFile.write(content); QVERIFY(projectFile.flush()); QCOMPARE(runQbs(QbsRunParameters(QLatin1String("install"))), 0); - QVERIFY(QFile::exists(defaultInstallRoot + QVERIFY(regularFileExists(defaultInstallRoot + HostOsInfo::appendExecutableSuffix(QLatin1String("/usr/local/bin/installedApp")))); - QVERIFY(QFile::exists(defaultInstallRoot + QLatin1String("/usr/local/src/main.cpp"))); + QVERIFY(regularFileExists(defaultInstallRoot + QLatin1String("/usr/local/src/main.cpp"))); // Check whether changing install parameters on the artifact causes re-installation. content.replace("qbs.installDir: \"bin\"", "qbs.installDir: 'custom'"); @@ -1819,7 +1851,7 @@ void TestBlackbox::installedApp() projectFile.write(content); QVERIFY(projectFile.flush()); QCOMPARE(runQbs(QbsRunParameters(QLatin1String("install"))), 0); - QVERIFY(QFile::exists(defaultInstallRoot + QVERIFY(regularFileExists(defaultInstallRoot + HostOsInfo::appendExecutableSuffix(QLatin1String("/usr/local/custom/installedApp")))); // Check whether changing install parameters on a source file causes re-installation. @@ -1829,7 +1861,7 @@ void TestBlackbox::installedApp() projectFile.write(content); projectFile.close(); QCOMPARE(runQbs(QbsRunParameters(QLatin1String("install"))), 0); - QVERIFY(QFile::exists(defaultInstallRoot + QLatin1String("/usr/local/source/main.cpp"))); + QVERIFY(regularFileExists(defaultInstallRoot + QLatin1String("/usr/local/source/main.cpp"))); rmDirR(buildDir); QbsRunParameters params; @@ -1932,7 +1964,7 @@ void TestBlackbox::testNsis() bool haveMakeNsis = false; foreach (const QString &path, paths) { - if (QFile::exists(QDir::fromNativeSeparators(path) + + if (regularFileExists(QDir::fromNativeSeparators(path) + HostOsInfo::appendExecutableSuffix(QLatin1String("/makensis")))) { haveMakeNsis = true; break; @@ -1992,9 +2024,9 @@ static bool haveWiX() } foreach (const QString &path, paths) { - if (QFile::exists(QDir::fromNativeSeparators(path) + + if (regularFileExists(QDir::fromNativeSeparators(path) + HostOsInfo::appendExecutableSuffix(QLatin1String("/candle"))) && - QFile::exists(QDir::fromNativeSeparators(path) + + regularFileExists(QDir::fromNativeSeparators(path) + HostOsInfo::appendExecutableSuffix(QLatin1String("/light")))) { return true; } @@ -2025,8 +2057,77 @@ void TestBlackbox::testWiX() QVERIFY(m_qbsStdout.contains("compiling QbsBootstrapper.wxs")); QVERIFY(m_qbsStdout.contains("linking qbs-" + arch + ".msi")); QVERIFY(m_qbsStdout.contains("linking qbs-setup-" + arch + ".exe")); - QVERIFY(QFile::exists(buildDir + "/qbs-" + arch + ".msi")); - QVERIFY(QFile::exists(buildDir + "/qbs-setup-" + arch + ".exe")); + QVERIFY(regularFileExists(buildDir + "/QbsSetup/qbs-" + arch + ".msi")); + QVERIFY(regularFileExists(buildDir + "/QbsBootstrapper/qbs-setup-" + arch + ".exe")); +} + +static QString findExecutable(const QStringList &fileNames) +{ + const QStringList path = QString::fromLocal8Bit(qgetenv("PATH")) + .split(HostOsInfo::pathListSeparator(), QString::SkipEmptyParts); + + foreach (const QString &fileName, fileNames) { + foreach (const QString &ppath, path) { + const QString fullPath = ppath + QLatin1Char('/') + fileName; + if (QFileInfo(fullPath).exists()) + return QDir::cleanPath(fullPath); + } + } + return QString(); +} + +static bool haveNodeJs() +{ + // The Node.js binary is called nodejs on Debian/Ubuntu-family operating systems due to a + // conflict with another package containing a binary named node + return !findExecutable(QStringList() + << QLatin1String("nodejs") + << QLatin1String("node")).isEmpty(); +} + +void TestBlackbox::testNodeJs() +{ + if (!haveNodeJs()) { + SKIP_TEST("Node.js is not installed"); + return; + } + + QDir::setCurrent(testDataDir + QLatin1String("/nodejs")); + + QbsRunParameters params; + params.command = QLatin1String("run"); + QCOMPARE(runQbs(params), 0); + QVERIFY((bool)m_qbsStdout.contains("hello world")); + QVERIFY(regularFileExists(buildDir + "/hello/hello.js")); +} + +void TestBlackbox::testTypeScript() +{ + if (!haveNodeJs()) { + SKIP_TEST("node.js is not installed"); + return; + } + + QDir::setCurrent(testDataDir + QLatin1String("/typescript")); + + QbsRunParameters params; + params.command = QLatin1String("run"); + params.arguments = QStringList() << "-p" << "animals"; + QCOMPARE(runQbs(params), 0); + + QVERIFY(regularFileExists(buildDir + "/animals/animals.js")); + QVERIFY(regularFileExists(buildDir + "/animals/extra.js")); + QVERIFY(regularFileExists(buildDir + "/animals/main.js")); +} + +QString TestBlackbox::productBuildDir(const QString &productName) const +{ + return buildDir + '/' + productName; +} + +QString TestBlackbox::executableFilePath(const QString &productName) const +{ + return productBuildDir(productName) + '/' + HostOsInfo::appendExecutableSuffix(productName); } QTEST_MAIN(TestBlackbox) diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h index 7a52a9bd3..fc9ae76b5 100644 --- a/tests/auto/blackbox/tst_blackbox.h +++ b/tests/auto/blackbox/tst_blackbox.h @@ -99,6 +99,7 @@ private slots: void addedFilePersistent(); void addQObjectMacroToCppFile(); void baseProperties(); + void buildDirectories(); void build_project_data(); void build_project(); void build_project_dry_run_data(); @@ -133,6 +134,7 @@ private slots: void resolve_project(); void resolve_project_dry_run_data(); void resolve_project_dry_run(); + void usingsAsSoleInputsNonMultiplexed(); void clean(); void exportSimple(); void exportWithRecursiveDepends(); @@ -172,8 +174,13 @@ private slots: void testNsis(); void testEmbedInfoPlist(); void testWiX(); + void testNodeJs(); + void testTypeScript(); private: + QString productBuildDir(const QString &productName) const; + QString executableFilePath(const QString &productName) const; + QByteArray m_qbsStderr; QByteArray m_qbsStdout; }; |