aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/blackbox
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@digia.com>2014-01-16 16:50:00 +0100
committerChristian Kandeler <christian.kandeler@digia.com>2014-01-20 16:58:49 +0100
commitfe3941568f11ea02996af489453bc5606b6988fd (patch)
tree8b410caad9ddfce47e13347b9b4509d3cf1ea2b0 /tests/auto/blackbox
parentf64c7492a3ba5cd73994be810be7ff529a19f37e (diff)
add autotest for dynamic rule outputs
Task-number: QBS-370 Change-Id: Ib70597d8eeed711842cfb86f8d1ecb434f6b40bd Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
Diffstat (limited to 'tests/auto/blackbox')
-rw-r--r--tests/auto/blackbox/testdata/dynamicRuleOutputs/after/numbers.l77
-rw-r--r--tests/auto/blackbox/testdata/dynamicRuleOutputs/before/flexoptionsreader.js103
-rw-r--r--tests/auto/blackbox/testdata/dynamicRuleOutputs/before/genlexer.qbs103
-rw-r--r--tests/auto/blackbox/testdata/dynamicRuleOutputs/before/numbers.l78
-rw-r--r--tests/auto/blackbox/tst_blackbox.cpp53
-rw-r--r--tests/auto/blackbox/tst_blackbox.h1
6 files changed, 415 insertions, 0 deletions
diff --git a/tests/auto/blackbox/testdata/dynamicRuleOutputs/after/numbers.l b/tests/auto/blackbox/testdata/dynamicRuleOutputs/after/numbers.l
new file mode 100644
index 000000000..b29f8798f
--- /dev/null
+++ b/tests/auto/blackbox/testdata/dynamicRuleOutputs/after/numbers.l
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Build Suite.
+**
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+****************************************************************************/
+
+/* scanner for integer and float numbers */
+
+%option noyywrap
+
+%{
+/* need this for the call to atof() below */
+#include <math.h>
+%}
+
+DIGIT [0-9]
+
+%%
+
+{DIGIT}+ {
+ printf("integer: %s (%d)\n", yytext, atoi(yytext));
+ }
+
+{DIGIT}+"."{DIGIT}* {
+ printf("float: %s (%g)\n", yytext, atof(yytext));
+ }
+
+"{"[\^{}}\n]*"}" /* eat up one-line comments */
+
+[ \t\n]+ /* eat up whitespace */
+
+. printf("Unexpected character: %s\n", yytext);
+
+%%
+
+int main(int argc, char **argv)
+{
+ if (argc > 1)
+ yyin = fopen(argv[1], "r");
+ else
+ yyin = stdin;
+
+ yylex();
+ return 0;
+}
+
diff --git a/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/flexoptionsreader.js b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/flexoptionsreader.js
new file mode 100644
index 000000000..232e8338f
--- /dev/null
+++ b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/flexoptionsreader.js
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Build Suite.
+**
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+****************************************************************************/
+
+// needs import qbs.TextFile
+
+function readFlexOptions(filePath)
+{
+ function splitOptions(str)
+ {
+ var options = [];
+ var opt = "";
+ var inquote = false;
+ for (var i = 0; i < str.length; ++i) {
+ if (str[i] === '"') {
+ opt += '"';
+ inquote = !inquote;
+ } else if (str[i] === ' ' && !inquote) {
+ options.push(opt);
+ opt = "";
+ } else {
+ opt += str[i];
+ }
+ }
+ if (opt.length)
+ options.push(opt);
+ return options;
+ }
+
+ function unquote(str)
+ {
+ var l = str.length;
+ if (l > 2 && str[0] === '"' && str[l - 1] === '"')
+ return str.substr(1, l - 2);
+ return str;
+ }
+
+ function parseOptionLine(result, str)
+ {
+ var options = splitOptions(str);
+ var re = /^(outfile|header-file)=(.*)$/;
+ var reres;
+ for (var k in options) {
+ re.lastIndex = 0;
+ reres = re.exec(options[k]);
+ if (reres === null)
+ continue;
+ result[reres[1]] = unquote(reres[2]);
+ }
+ }
+
+ var tf = new TextFile(input.fileName);
+ var line;
+ var optrex = /^%option\s+(.*$)/;
+ var res;
+ var options = {};
+ while (!tf.atEof()) {
+ line = tf.readLine();
+ if (line === "%%")
+ break;
+ optrex.lastIndex = 0;
+ res = optrex.exec(line);
+ if (res === null)
+ continue;
+ parseOptionLine(options, res[1]);
+ }
+ tf.close();
+ return options;
+}
+
diff --git a/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/genlexer.qbs b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/genlexer.qbs
new file mode 100644
index 000000000..b822e852e
--- /dev/null
+++ b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/genlexer.qbs
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Build Suite.
+**
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+****************************************************************************/
+
+import qbs 1.0
+import qbs.File
+import qbs.FileInfo
+import qbs.TextFile
+import "flexoptionsreader.js" as FlexOptionsReader
+
+Project {
+ Product {
+ name: "genlexer"
+ type: "application"
+ Depends { name: "cpp" }
+ Group {
+ files: ["numbers.l"]
+ fileTags: ["flex"]
+ }
+ property bool isFlexAvailable: File.exists("/usr/bin/flex") // ### replace with PathProbe
+ Rule {
+ inputs: ["flex"]
+ outputFileTags: ["c", "hpp"]
+ outputArtifacts: {
+ var options = FlexOptionsReader.readFlexOptions(input.fileName);
+ var sourceFileName = options["outfile"] || "lex.yy.c";
+ var headerFileName = options["header-file"];
+ var result = [{
+ filePath: "GeneratedFiles/" + product.name + "/" + sourceFileName,
+ fileTags: ["c"]
+ }];
+ if (headerFileName) {
+ result.push({
+ filePath: "GeneratedFiles/" + product.name + "/" + headerFileName,
+ fileTags: ["hpp"]
+ });
+ }
+ return result;
+ }
+ prepare: {
+ var cmd;
+ if (product.isFlexAvailable) {
+ // flex is available. Let's call it.
+ cmd = new Command("flex", [input.fileName]);
+ cmd.workingDirectory = product.buildDirectory + "/GeneratedFiles/" + product.name;
+ } else {
+ // No flex available here, generate some C source and header.
+ cmd = new JavaScriptCommand();
+ cmd.sourceFileName = outputs["c"][0].fileName;
+ cmd.headerFileName = outputs["hpp"] ? outputs["hpp"][0].fileName : "";
+ cmd.sourceCode = function() {
+ var fsrc = new TextFile(sourceFileName, TextFile.WriteOnly);
+ if (headerFileName) {
+ fsrc.write("#include \"" + FileInfo.fileName(headerFileName)
+ + "\"\n\n");
+ var fhdr = new TextFile(headerFileName, TextFile.WriteOnly);
+ fhdr.write("// a rather empty header file\n");
+ fhdr.close();
+ }
+ fsrc.write("int main() { return 0; }\n");
+ fsrc.close();
+ };
+ }
+ cmd.description = "flexing " + FileInfo.fileName(input.fileName);
+ return cmd;
+ }
+ }
+ }
+}
+
diff --git a/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/numbers.l b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/numbers.l
new file mode 100644
index 000000000..19f503562
--- /dev/null
+++ b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/numbers.l
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Build Suite.
+**
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+****************************************************************************/
+
+/* scanner for integer and float numbers */
+
+%option noyywrap
+%option outfile="numberscanner.c" header-file="numberscanner.h"
+
+%{
+/* need this for the call to atof() below */
+#include <math.h>
+%}
+
+DIGIT [0-9]
+
+%%
+
+{DIGIT}+ {
+ printf("integer: %s (%d)\n", yytext, atoi(yytext));
+ }
+
+{DIGIT}+"."{DIGIT}* {
+ printf("float: %s (%g)\n", yytext, atof(yytext));
+ }
+
+"{"[\^{}}\n]*"}" /* eat up one-line comments */
+
+[ \t\n]+ /* eat up whitespace */
+
+. printf("Unexpected character: %s\n", yytext);
+
+%%
+
+int main(int argc, char **argv)
+{
+ if (argc > 1)
+ yyin = fopen(argv[1], "r");
+ else
+ yyin = stdin;
+
+ yylex();
+ return 0;
+}
+
diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp
index 8e894d2ae..47778a030 100644
--- a/tests/auto/blackbox/tst_blackbox.cpp
+++ b/tests/auto/blackbox/tst_blackbox.cpp
@@ -1368,6 +1368,59 @@ void TestBlackbox::dynamicLibs()
QCOMPARE(runQbs(), 0);
}
+void TestBlackbox::dynamicRuleOutputs()
+{
+ QSKIP("QBS-370");
+ const QString testDir = testDataDir + "/dynamicRuleOutputs";
+ QDir::setCurrent(testDir);
+ if (QFile::exists("work"))
+ rmDirR("work");
+ QDir().mkdir("work");
+ ccp("before", "work");
+ 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";
+
+ // 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(!QFile::exists(sourceFile2));
+
+ QDateTime appFileTimeStamp1 = QFileInfo(appFile).lastModified();
+ waitForNewTimestamp();
+ QFile::remove("numbers.l");
+ QFile::copy("../after/numbers.l", "numbers.l");
+ touch("numbers.l");
+ QCOMPARE(runQbs(), 0);
+
+ // Check build #2: no file names are specified in numbers.l
+ // flex will default to lex.yy.c without header file.
+ QDateTime appFileTimeStamp2 = QFileInfo(appFile).lastModified();
+ QVERIFY(appFileTimeStamp1 < appFileTimeStamp2);
+ QVERIFY(!QFile::exists(headerFile1));
+ QVERIFY(!QFile::exists(sourceFile1));
+ QVERIFY(QFile::exists(sourceFile2));
+
+ waitForNewTimestamp();
+ QFile::remove("numbers.l");
+ QFile::copy("../before/numbers.l", "numbers.l");
+ touch("numbers.l");
+ QCOMPARE(runQbs(), 0);
+
+ // 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(!QFile::exists(sourceFile2));
+}
+
void TestBlackbox::explicitlyDependsOn()
{
QDir::setCurrent(testDataDir + "/explicitlyDependsOn");
diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h
index 2d0d6ff33..7d9c2a6d2 100644
--- a/tests/auto/blackbox/tst_blackbox.h
+++ b/tests/auto/blackbox/tst_blackbox.h
@@ -107,6 +107,7 @@ private slots:
void duplicateProductNames();
void duplicateProductNames_data();
void dynamicLibs();
+ void dynamicRuleOutputs();
void explicitlyDependsOn();
void fileDependencies();
void jsExtensionsFile();