From 01575deafb7d26ca2431374e92c6d71de96547c7 Mon Sep 17 00:00:00 2001 From: jasplin Date: Wed, 8 Jun 2011 17:13:13 +0200 Subject: Added -datatags option to QTestLib Passing the -datatags option to a QTestLib program prints the available data tags to standard output. Data tags for each test function (f() in this case) are printed in four different ways depending on the presence of local and global data tags: Case 1: No tags: f() Case 2: Local tags only: f() local tag 1 f() local tag 2 ... Case 3: Global tags only: f() __global__ global tag 1 f() __global__ global tag 2 ... Case 4: Local and global tags: f() local tag 1 __global__ global tag 1 f() local tag 2 __global__ global tag 1 ... f() local tag 1 __global__ global tag 2 f() local tag 2 __global__ global tag 2 ... ... Reviewed-by: Rohan McGovern Task-number: QTQAINFRA-226 Change-Id: I14de203b586a0085b8efda8e62772711e44677d2 --- doc/src/development/qtestlib.qdoc | 3 + src/testlib/qtestcase.cpp | 63 +++++++++++++++++++++ src/testlib/qtestlog.cpp | 11 ++++ tests/auto/selftests/expected_printdatatags.txt | 6 ++ .../expected_printdatatagswithglobaltags.txt | 12 ++++ .../auto/selftests/printdatatags/printdatatags.pro | 8 +++ .../selftests/printdatatags/tst_printdatatags.cpp | 48 ++++++++++++++++ .../printdatatagswithglobaltags.pro | 8 +++ .../tst_printdatatagswithglobaltags.cpp | 64 ++++++++++++++++++++++ tests/auto/selftests/selftests.pro | 3 +- tests/auto/selftests/selftests.qrc | 2 + tests/auto/selftests/tst_selftests.cpp | 14 +++++ 12 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 tests/auto/selftests/expected_printdatatags.txt create mode 100644 tests/auto/selftests/expected_printdatatagswithglobaltags.txt create mode 100644 tests/auto/selftests/printdatatags/printdatatags.pro create mode 100644 tests/auto/selftests/printdatatags/tst_printdatatags.cpp create mode 100644 tests/auto/selftests/printdatatagswithglobaltags/printdatatagswithglobaltags.pro create mode 100644 tests/auto/selftests/printdatatagswithglobaltags/tst_printdatatagswithglobaltags.cpp diff --git a/doc/src/development/qtestlib.qdoc b/doc/src/development/qtestlib.qdoc index 10ae285..3b338e3 100644 --- a/doc/src/development/qtestlib.qdoc +++ b/doc/src/development/qtestlib.qdoc @@ -181,6 +181,9 @@ outputs the possible command line arguments and give some useful help. \o \c -functions \BR outputs all test functions available in the test. + \o \c -datatags \BR + outputs all data tags available in the test. + A global data tag is preceded by ' __global__ '. \o \c -o \e filename \BR write output to the specified file, rather than to standard output \o \c -silent \BR diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 023df89..efa0122 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1015,6 +1015,7 @@ static bool isValidSlot(const QMetaMethod &sl) } Q_TESTLIB_EXPORT bool printAvailableFunctions = false; +Q_TESTLIB_EXPORT bool printAvailableTags = false; Q_TESTLIB_EXPORT QStringList testFunctions; Q_TESTLIB_EXPORT QStringList testTags; @@ -1027,6 +1028,60 @@ static void qPrintTestSlots() } } +static void qPrintDataTags() +{ + // Get global data tags: + QTestTable::globalTestTable(); + invokeMethod(QTest::currentTestObject, "initTestCase_data()"); + const QTestTable *gTable = QTestTable::globalTestTable(); + + // Process test functions: + for (int i = 0; i < QTest::currentTestObject->metaObject()->methodCount(); ++i) { + QMetaMethod tf = QTest::currentTestObject->metaObject()->method(i); + if (isValidSlot(tf)) { + const char *slotName = tf.signature(); + + // Retrieve local tags: + QStringList localTags; + QTestTable table; + char member[512]; + char *slot = qstrdup(slotName); + slot[strlen(slot) - 2] = '\0'; + QTest::qt_snprintf(member, 512, "%s_data()", slot); + delete[] slot; + invokeMethod(QTest::currentTestObject, member); + for (int j = 0; j < table.dataCount(); ++j) + localTags << QLatin1String(table.testData(j)->dataTag()); + + // Print all tag combinations: + if (gTable->dataCount() == 0) { + if (localTags.count() == 0) { + // No tags at all, so just print the test function: + printf("%s\n", slotName); + } else { + // Only local tags, so print each of them: + for (int k = 0; k < localTags.size(); ++k) + printf("%s %s\n", slotName, localTags.at(k).toLatin1().data()); + } + } else { + for (int j = 0; j < gTable->dataCount(); ++j) { + if (localTags.count() == 0) { + // Only global tags, so print the current one: + printf("%s __global__ %s\n", slotName, gTable->testData(j)->dataTag()); + } else { + // Local and global tags, so print each of the local ones and + // the current global one: + for (int k = 0; k < localTags.size(); ++k) + printf( + "%s %s __global__ %s\n", slotName, + localTags.at(k).toLatin1().data(), gTable->testData(j)->dataTag()); + } + } + } + } + } +} + static int qToInt(char *str) { char *pEnd; @@ -1043,6 +1098,8 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml) const char *testOptions = " options:\n" " -functions : Returns a list of current testfunctions\n" + " -datatags : Returns a list of current data tags.\n" + " A global data tag is preceded by ' __global__ '.\n" " -xunitxml : Outputs results as XML XUnit document\n" " -xml : Outputs results as XML document\n" " -lightxml : Outputs results as stream of XML tags\n" @@ -1094,6 +1151,12 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml) qPrintTestSlots(); exit(0); } + } else if (strcmp(argv[i], "-datatags") == 0) { + QTest::printAvailableTags = true; + if (!qml) { + qPrintDataTags(); + exit(0); + } } else if(strcmp(argv[i], "-xunitxml") == 0){ QTestLog::setLogMode(QTestLog::XunitXML); } else if (strcmp(argv[i], "-xml") == 0) { diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp index 8a2d559..03fafe0 100644 --- a/src/testlib/qtestlog.cpp +++ b/src/testlib/qtestlog.cpp @@ -191,6 +191,8 @@ void initLogger() } } +extern Q_TESTLIB_EXPORT bool printAvailableTags; + } QTestLog::QTestLog() @@ -203,6 +205,9 @@ QTestLog::~QTestLog() void QTestLog::enterTestFunction(const char* function) { + if (QTest::printAvailableTags) + return; + QTEST_ASSERT(QTest::testLogger); QTEST_ASSERT(function); @@ -222,6 +227,9 @@ int QTestLog::unhandledIgnoreMessages() void QTestLog::leaveTestFunction() { + if (QTest::printAvailableTags) + return; + QTEST_ASSERT(QTest::testLogger); QTest::IgnoreResultList::clearList(QTest::ignoreResultList); @@ -244,6 +252,9 @@ void QTestLog::printUnhandledIgnoreMessages() void QTestLog::addPass(const char *msg) { + if (QTest::printAvailableTags) + return; + QTEST_ASSERT(QTest::testLogger); QTEST_ASSERT(msg); diff --git a/tests/auto/selftests/expected_printdatatags.txt b/tests/auto/selftests/expected_printdatatags.txt new file mode 100644 index 0000000..02390dc --- /dev/null +++ b/tests/auto/selftests/expected_printdatatags.txt @@ -0,0 +1,6 @@ +a() data tag a1 +a() data tag a2 +b() +c() data tag c1 +c() data tag c2 +c() data tag c3 diff --git a/tests/auto/selftests/expected_printdatatagswithglobaltags.txt b/tests/auto/selftests/expected_printdatatagswithglobaltags.txt new file mode 100644 index 0000000..a91e1b8 --- /dev/null +++ b/tests/auto/selftests/expected_printdatatagswithglobaltags.txt @@ -0,0 +1,12 @@ +a() data tag a1 __global__ global data tag 1 +a() data tag a2 __global__ global data tag 1 +a() data tag a1 __global__ global data tag 2 +a() data tag a2 __global__ global data tag 2 +b() __global__ global data tag 1 +b() __global__ global data tag 2 +c() data tag c1 __global__ global data tag 1 +c() data tag c2 __global__ global data tag 1 +c() data tag c3 __global__ global data tag 1 +c() data tag c1 __global__ global data tag 2 +c() data tag c2 __global__ global data tag 2 +c() data tag c3 __global__ global data tag 2 diff --git a/tests/auto/selftests/printdatatags/printdatatags.pro b/tests/auto/selftests/printdatatags/printdatatags.pro new file mode 100644 index 0000000..a134422 --- /dev/null +++ b/tests/auto/selftests/printdatatags/printdatatags.pro @@ -0,0 +1,8 @@ +load(qttest_p4) +SOURCES += tst_printdatatags.cpp +QT = core + +mac:CONFIG -= app_bundle +CONFIG -= debug_and_release_target + +TARGET = printdatatags diff --git a/tests/auto/selftests/printdatatags/tst_printdatatags.cpp b/tests/auto/selftests/printdatatags/tst_printdatatags.cpp new file mode 100644 index 0000000..fe4bcf0 --- /dev/null +++ b/tests/auto/selftests/printdatatags/tst_printdatatags.cpp @@ -0,0 +1,48 @@ +#include + +class tst_Foo: public QObject +{ + Q_OBJECT +private slots: + void a_data() const; + void a() const; + + void b() const; + + void c_data() const; + void c() const; +}; + +void tst_Foo::a_data() const +{ + QTest::addColumn("x"); + QTest::addColumn("y"); + + QTest::newRow("data tag a1 ") << 1 << 2; + QTest::newRow("data tag a2") << 1 << 2; +} + +void tst_Foo::a() const +{ +} + +void tst_Foo::b() const +{ +} + +void tst_Foo::c_data() const +{ + QTest::addColumn("x"); + + QTest::newRow("data tag c1") << 1; + QTest::newRow("data tag c2") << 1; + QTest::newRow("data tag c3") << 1; +} + +void tst_Foo::c() const +{ +} + +QTEST_MAIN(tst_Foo) + +#include "tst_printdatatags.moc" diff --git a/tests/auto/selftests/printdatatagswithglobaltags/printdatatagswithglobaltags.pro b/tests/auto/selftests/printdatatagswithglobaltags/printdatatagswithglobaltags.pro new file mode 100644 index 0000000..100ba1c --- /dev/null +++ b/tests/auto/selftests/printdatatagswithglobaltags/printdatatagswithglobaltags.pro @@ -0,0 +1,8 @@ +load(qttest_p4) +SOURCES += tst_printdatatagswithglobaltags.cpp +QT = core + +mac:CONFIG -= app_bundle +CONFIG -= debug_and_release_target + +TARGET = printdatatagswithglobaltags diff --git a/tests/auto/selftests/printdatatagswithglobaltags/tst_printdatatagswithglobaltags.cpp b/tests/auto/selftests/printdatatagswithglobaltags/tst_printdatatagswithglobaltags.cpp new file mode 100644 index 0000000..cc58bec --- /dev/null +++ b/tests/auto/selftests/printdatatagswithglobaltags/tst_printdatatagswithglobaltags.cpp @@ -0,0 +1,64 @@ +#include + +class tst_Foo: public QObject +{ + Q_OBJECT +private slots: + void initTestCase_data() const; + void initTestCase() const; + + void a_data() const; + void a() const; + + void b() const; + + void c_data() const; + void c() const; +}; + +void tst_Foo::initTestCase_data() const +{ + QTest::addColumn("f"); + QTest::addColumn("g"); + + QTest::newRow("global data tag 1 ") << 1 << 2; + QTest::newRow("global data tag 2") << 1 << 2; +} + +void tst_Foo::initTestCase() const +{ +} + +void tst_Foo::a_data() const +{ + QTest::addColumn("x"); + QTest::addColumn("y"); + + QTest::newRow("data tag a1 ") << 1 << 2; + QTest::newRow("data tag a2") << 1 << 2; +} + +void tst_Foo::a() const +{ +} + +void tst_Foo::b() const +{ +} + +void tst_Foo::c_data() const +{ + QTest::addColumn("x"); + + QTest::newRow("data tag c1") << 1; + QTest::newRow("data tag c2") << 1; + QTest::newRow("data tag c3") << 1; +} + +void tst_Foo::c() const +{ +} + +QTEST_MAIN(tst_Foo) + +#include "tst_printdatatagswithglobaltags.moc" diff --git a/tests/auto/selftests/selftests.pro b/tests/auto/selftests/selftests.pro index 2f1c327..74cd075 100644 --- a/tests/auto/selftests/selftests.pro +++ b/tests/auto/selftests/selftests.pro @@ -5,7 +5,8 @@ SUBDIRS = subtest test warnings maxwarnings cmptest globaldata skipglobal skip \ skipinit skipinitdata datetime singleskip assert waitwithoutgui differentexec \ exceptionthrow qexecstringlist datatable commandlinedata\ benchlibwalltime benchlibcallgrind benchlibeventcounter benchlibtickcounter \ - benchliboptions xunit badxml longstring + benchliboptions xunit badxml longstring printdatatags \ + printdatatagswithglobaltags INSTALLS = diff --git a/tests/auto/selftests/selftests.qrc b/tests/auto/selftests/selftests.qrc index f82722b..5bd0e12 100644 --- a/tests/auto/selftests/selftests.qrc +++ b/tests/auto/selftests/selftests.qrc @@ -89,6 +89,8 @@ expected_multiexec.txt expected_multiexec.xml expected_multiexec.xunitxml + expected_printdatatags.txt + expected_printdatatagswithglobaltags.txt expected_qexecstringlist.txt expected_singleskip.lightxml expected_singleskip.txt diff --git a/tests/auto/selftests/tst_selftests.cpp b/tests/auto/selftests/tst_selftests.cpp index 1a95420..3686304 100644 --- a/tests/auto/selftests/tst_selftests.cpp +++ b/tests/auto/selftests/tst_selftests.cpp @@ -245,6 +245,8 @@ void tst_Selftests::runSubTest_data() << "xunit" << "longstring" << "badxml" + << "printdatatags" + << "printdatatagswithglobaltags" ; foreach (Logger const& logger, allLoggers()) { @@ -273,6 +275,12 @@ void tst_Selftests::runSubTest_data() else if (subtest == "badxml") { arguments << "-eventcounter"; } + else if (subtest == "printdatatags") { + arguments << "-datatags"; + } + else if (subtest == "printdatatagswithglobaltags") { + arguments << "-datatags"; + } // These tests don't work right with loggers other than plain, usually because // they internally supply arguments to themselves. @@ -289,6 +297,12 @@ void tst_Selftests::runSubTest_data() if (subtest == "waitwithoutgui") { continue; } + if (subtest == "printdatatags") { + continue; + } + if (subtest == "printdatatagswithglobaltags") { + continue; + } // `crashes' will not output valid XML on platforms without a crash handler if (subtest == "crashes") { continue; -- cgit v0.12