Changeset 561 for trunk/src/testlib/qtestcase.cpp
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/vendor/nokia/qt/4.6.1 merged eligible /branches/vendor/nokia/qt/current merged eligible /branches/vendor/trolltech/qt/current 3-149
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/testlib/qtestcase.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information ([email protected]) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation ([email protected]) 5 6 ** 6 7 ** This file is part of the QtTest module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you 37 ** @nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 55 55 #include <QtCore/qprocess.h> 56 56 #include <QtCore/qdebug.h> 57 57 58 58 59 #include "QtTest/private/qtestlog_p.h" … … 72 73 #endif 73 74 #ifdef Q_OS_UNIX 75 76 74 77 #include <time.h> 75 78 #endif … … 301 304 Use this macro to build stand-alone executables. 302 305 306 307 308 309 310 303 311 Example: 304 312 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 11 305 313 306 \sa QTEST_APPLESS_MAIN(), QTest::qExec() 314 \sa QTEST_APPLESS_MAIN(), QTest::qExec() 307 315 */ 308 316 … … 348 356 {Chapter 5: Writing a Benchmark}{Writing a Benchmark} 349 357 */ 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 350 381 351 382 /*! \enum QTest::SkipMode … … 401 432 \overload 402 433 403 Simulates clicking of \a key with an optional \a modifier on a \a widget. If \a delay is larger than 0, the test will wait for \a delay milliseconds. 434 Simulates clicking of \a key with an optional \a modifier on a \a widget. 435 If \a delay is larger than 0, the test will wait for \a delay milliseconds. 404 436 405 437 Example: … … 414 446 /*! \fn void QTest::keyClick(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1) 415 447 416 Simulates clicking of \a key with an optional \a modifier on a \a widget. If \a delay is larger than 0, the test will wait for \a delay milliseconds. 448 Simulates clicking of \a key with an optional \a modifier on a \a widget. 449 If \a delay is larger than 0, the test will wait for \a delay milliseconds. 417 450 418 451 Examples: … … 429 462 /*! \fn void QTest::keyEvent(KeyAction action, QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1) 430 463 431 Sends a Qt key event to \a widget with the given \a key and an associated \a action. Optionally, a keyboard \a modifier can be specified, as well as a \a delay (in milliseconds) of the test before sending the event. 464 Sends a Qt key event to \a widget with the given \a key and an associated \a action. 465 Optionally, a keyboard \a modifier can be specified, as well as a \a delay 466 (in milliseconds) of the test before sending the event. 432 467 */ 433 468 … … 436 471 \overload 437 472 438 Sends a Qt key event to \a widget with the given key \a ascii and an associated \a action. Optionally, a keyboard \a modifier can be specified, as well as a \a delay (in milliseconds) of the test before sending the event. 473 Sends a Qt key event to \a widget with the given key \a ascii and an associated \a action. 474 Optionally, a keyboard \a modifier can be specified, as well as a \a delay 475 (in milliseconds) of the test before sending the event. 439 476 440 477 */ … … 442 479 /*! \fn void QTest::keyPress(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1) 443 480 444 Simulates pressing a \a key with an optional \a modifier on a \a widget. If \a delay is larger than 0, the test will wait for \a delay milliseconds. 481 Simulates pressing a \a key with an optional \a modifier on a \a widget. If \a delay 482 is larger than 0, the test will wait for \a delay milliseconds. 445 483 446 484 \bold {Note:} At some point you should release the key using \l keyRelease(). … … 453 491 \overload 454 492 455 Simulates pressing a \a key with an optional \a modifier on a \a widget. If \a delay is larger than 0, the test will wait for \a delay milliseconds. 493 Simulates pressing a \a key with an optional \a modifier on a \a widget. 494 If \a delay is larger than 0, the test will wait for \a delay milliseconds. 456 495 457 496 \bold {Note:} At some point you should release the key using \l keyRelease(). … … 462 501 /*! \fn void QTest::keyRelease(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1) 463 502 464 Simulates releasing a \a key with an optional \a modifier on a \a widget. If \a delay is larger than 0, the test will wait for \a delay milliseconds. 503 Simulates releasing a \a key with an optional \a modifier on a \a widget. 504 If \a delay is larger than 0, the test will wait for \a delay milliseconds. 465 505 466 506 \sa QTest::keyPress(), QTest::keyClick() … … 471 511 \overload 472 512 473 Simulates releasing a \a key with an optional \a modifier on a \a widget. If \a delay is larger than 0, the test will wait for \a delay milliseconds. 513 Simulates releasing a \a key with an optional \a modifier on a \a widget. 514 If \a delay is larger than 0, the test will wait for \a delay milliseconds. 474 515 475 516 \sa QTest::keyClick() … … 673 714 */ 674 715 716 717 718 719 720 721 722 675 723 /*! \fn void QTest::qWait(int ms) 676 724 … … 687 735 */ 688 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 689 826 namespace QTest 690 827 { 691 828 static QObject *currentTestObject = 0; 692 829 693 st ruct TestFunction {830 struct TestFunction { 694 831 TestFunction():function(0), data(0) {} 695 832 ~TestFunction() { delete [] data; } 696 833 int function; 697 834 char *data; 698 } testFuncs[512];835 } ; 699 836 700 837 /** … … 711 848 static int keyVerbose = -1; 712 849 713 /*! \internal 714 */ 715 int qt_snprintf(char *str, int size, const char *format, ...) 716 { 717 va_list ap; 718 int res = 0; 719 720 va_start(ap, format); 721 qvsnprintf(str, size, format, ap); 722 va_end(ap); 723 str[size - 1] = '\0'; 724 850 void filter_unprintable(char *str) 851 { 725 852 char *idx = str; 726 853 while (*idx) { … … 729 856 ++idx; 730 857 } 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 731 874 return res; 732 875 } … … 819 962 " options:\n" 820 963 " -functions : Returns a list of current testfunctions\n" 964 821 965 " -xml : Outputs results as XML document\n" 822 966 " -lightxml : Outputs results as stream of XML tags\n" 967 823 968 " -o filename: Writes all output into a file\n" 824 969 " -silent : Only outputs warnings and failures\n" … … 845 990 " -median n : Sets the number of median iterations.\n" 846 991 " -vb : Print out verbose benchmarking information.\n" 847 #ifndef QT_NO_PROCESS 848 // Will be enabled when tools are integrated. 849 // " -chart : Runs the chart generator after the test. No output is printed to the console\n" 992 #if !defined(QT_NO_PROCESS) && !defined(QT_NO_SETTINGS) 993 " -chart : Create chart based on the benchmark result.\n" 850 994 #endif 851 995 "\n" … … 862 1006 qPrintTestSlots(); 863 1007 exit(0); 1008 1009 864 1010 } else if (strcmp(argv[i], "-xml") == 0) { 865 1011 QTestLog::setLogMode(QTestLog::XML); 866 1012 } else if (strcmp(argv[i], "-lightxml") == 0) { 867 1013 QTestLog::setLogMode(QTestLog::LightXML); 1014 1015 868 1016 } else if (strcmp(argv[i], "-silent") == 0) { 869 1017 QTestLog::setVerboseLevel(-1); … … 958 1106 } else if (strcmp(argv[i], "-vb") == 0) { 959 1107 QBenchmarkGlobalData::current->verboseOutput = true; 960 #if ndef QT_NO_PROCESS1108 #if 961 1109 } else if (strcmp(argv[i], "-chart") == 0) { 962 1110 QBenchmarkGlobalData::current->createChart = true; … … 992 1140 } 993 1141 ++QTest::lastTestFuncIdx; 1142 1143 1144 1145 1146 994 1147 QTest::testFuncs[QTest::lastTestFuncIdx].function = idx; 995 1148 QTest::testFuncs[QTest::lastTestFuncIdx].data = data; … … 1007 1160 if (count == 1) 1008 1161 return container.at(0); 1009 1162 1010 1163 QList<QBenchmarkResult> containerCopy = container; 1011 1164 qSort(containerCopy); … … 1057 1210 ? QTestResult::currentDataTag() : ""); 1058 1211 1059 invokeOk = QMetaObject::invokeMethod(QTest::currentTestObject, slot, 1212 invokeOk = QMetaObject::invokeMethod(QTest::currentTestObject, slot, 1060 1213 Qt::DirectConnection); 1061 1214 if (!invokeOk) … … 1078 1231 results.append(QBenchmarkTestMethodData::current->result); 1079 1232 1080 if (QBenchmarkTestMethodData::current->isBenchmark() && 1233 if (QBenchmarkTestMethodData::current->isBenchmark() && 1081 1234 QBenchmarkGlobalData::current->verboseOutput) { 1082 1235 if (i == -1) { … … 1209 1362 /*! 1210 1363 \fn char* QTest::toHexRepresentation(const char *ba, int length) 1211 1364 1212 1365 Returns a pointer to a string that is the string \a ba represented 1213 1366 as a space-separated sequence of hex characters. If the input is … … 1215 1368 the returned string as an ellipsis at the end. 1216 1369 1217 \a length is the length of the string \a ba. 1370 \a length is the length of the string \a ba. 1218 1371 */ 1219 1372 char *toHexRepresentation(const char *ba, int length) … … 1274 1427 } 1275 1428 1276 static void qInvokeTestMethods(QObject *testObject) 1277 { 1278 const QMetaObject *metaObject = testObject->metaObject(); 1279 QTEST_ASSERT(metaObject); 1280 1281 QTestLog::startLogging(); 1282 1283 QTestResult::setCurrentTestFunction("initTestCase"); 1284 QTestResult::setCurrentTestLocation(QTestResult::DataFunc); 1285 QTestTable::globalTestTable(); 1286 QMetaObject::invokeMethod(testObject, "initTestCase_data", Qt::DirectConnection); 1287 1288 if (!QTestResult::skipCurrentTest() && !QTest::currentTestFailed()) { 1289 QTestResult::setCurrentTestLocation(QTestResult::InitFunc); 1290 QMetaObject::invokeMethod(testObject, "initTestCase"); 1291 1292 // finishedCurrentTestFunction() resets QTestResult::testFailed(), so use a local copy. 1293 const bool previousFailed = QTestResult::testFailed(); 1294 QTestResult::finishedCurrentTestFunction(); 1295 1296 if(!QTestResult::skipCurrentTest() && !previousFailed) { 1297 1298 if (lastTestFuncIdx >= 0) { 1299 for (int i = 0; i <= lastTestFuncIdx; ++i) { 1300 if (!qInvokeTestMethod(metaObject->method(testFuncs[i].function).signature(), 1301 testFuncs[i].data)) 1302 break; 1303 } 1304 } else { 1305 int methodCount = metaObject->methodCount(); 1306 for (int i = 0; i < methodCount; ++i) { 1307 QMetaMethod slotMethod = metaObject->method(i); 1308 if (!isValidSlot(slotMethod)) 1309 continue; 1310 if (!qInvokeTestMethod(slotMethod.signature())) 1311 break; 1312 } 1313 } 1314 } 1315 1316 QTestResult::setSkipCurrentTest(false); 1317 QTestResult::setCurrentTestFunction("cleanupTestCase"); 1318 QMetaObject::invokeMethod(testObject, "cleanupTestCase"); 1319 } 1320 QTestResult::finishedCurrentTestFunction(); 1321 QTestResult::setCurrentTestFunction(0); 1322 QTestTable::clearGlobalTestTable(); 1323 1324 QTestLog::stopLogging(); 1325 } 1429 static void qInvokeTestMethods(QObject *testObject) 1430 { 1431 const QMetaObject *metaObject = testObject->metaObject(); 1432 QTEST_ASSERT(metaObject); 1433 1434 QTestLog::startLogging(); 1435 1436 QTestResult::setCurrentTestFunction("initTestCase"); 1437 QTestResult::setCurrentTestLocation(QTestResult::DataFunc); 1438 QTestTable::globalTestTable(); 1439 QMetaObject::invokeMethod(testObject, "initTestCase_data", Qt::DirectConnection); 1440 1441 if (!QTestResult::skipCurrentTest() && !QTest::currentTestFailed()) { 1442 QTestResult::setCurrentTestLocation(QTestResult::InitFunc); 1443 QMetaObject::invokeMethod(testObject, "initTestCase"); 1444 1445 // finishedCurrentTestFunction() resets QTestResult::testFailed(), so use a local copy. 1446 const bool previousFailed = QTestResult::testFailed(); 1447 QTestResult::finishedCurrentTestFunction(); 1448 1449 if(!QTestResult::skipCurrentTest() && !previousFailed) { 1450 1451 if (lastTestFuncIdx >= 0) { 1452 for (int i = 0; i <= lastTestFuncIdx; ++i) { 1453 if (!qInvokeTestMethod(metaObject->method(testFuncs[i].function).signature(), 1454 testFuncs[i].data)) 1455 break; 1456 } 1457 } else { 1458 int methodCount = metaObject->methodCount(); 1459 for (int i = 0; i < methodCount; ++i) { 1460 QMetaMethod slotMethod = metaObject->method(i); 1461 if (!isValidSlot(slotMethod)) 1462 continue; 1463 if (!qInvokeTestMethod(slotMethod.signature())) 1464 break; 1465 } 1466 } 1467 } 1468 1469 QTestResult::setSkipCurrentTest(false); 1470 QTestResult::setCurrentTestFunction("cleanupTestCase"); 1471 QMetaObject::invokeMethod(testObject, "cleanupTestCase"); 1472 } 1473 QTestResult::finishedCurrentTestFunction(); 1474 QTestResult::setCurrentTestFunction(0); 1475 QTestTable::clearGlobalTestTable(); 1476 1477 QTestLog::stopLogging(); 1478 } 1479 1480 #if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) 1481 class FatalSignalHandler 1482 { 1483 public: 1484 FatalSignalHandler(); 1485 ~FatalSignalHandler(); 1486 1487 private: 1488 static void signal(int); 1489 sigset_t handledSignals; 1490 }; 1491 1492 void FatalSignalHandler::signal(int signum) 1493 { 1494 qFatal("Received signal %d", signum); 1495 } 1496 1497 FatalSignalHandler::FatalSignalHandler() 1498 { 1499 sigemptyset(&handledSignals); 1500 1501 const int fatalSignals[] = { 1502 SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGFPE, SIGSEGV, SIGPIPE, SIGTERM, 0 }; 1503 1504 struct sigaction act; 1505 memset(&act, 0, sizeof(act)); 1506 act.sa_handler = FatalSignalHandler::signal; 1507 1508 // Remove the handler after it is invoked. 1509 act.sa_flags = SA_RESETHAND; 1510 1511 // Block all fatal signals in our signal handler so we don't try to close 1512 // the testlog twice. 1513 sigemptyset(&act.sa_mask); 1514 for (int i = 0; fatalSignals[i]; ++i) 1515 sigaddset(&act.sa_mask, fatalSignals[i]); 1516 1517 struct sigaction oldact; 1518 1519 for (int i = 0; fatalSignals[i]; ++i) { 1520 sigaction(fatalSignals[i], &act, &oldact); 1521 #ifndef Q_WS_QWS 1522 // Don't overwrite any non-default handlers 1523 // however, we need to replace the default QWS handlers 1524 if (oldact.sa_flags & SA_SIGINFO || oldact.sa_handler != SIG_DFL) { 1525 sigaction(fatalSignals[i], &oldact, 0); 1526 } else 1527 #endif 1528 { 1529 sigaddset(&handledSignals, fatalSignals[i]); 1530 } 1531 } 1532 } 1533 1534 1535 FatalSignalHandler::~FatalSignalHandler() 1536 { 1537 // Unregister any of our remaining signal handlers 1538 struct sigaction act; 1539 memset(&act, 0, sizeof(act)); 1540 act.sa_handler = SIG_DFL; 1541 1542 struct sigaction oldact; 1543 1544 for (int i = 1; i < 32; ++i) { 1545 if (!sigismember(&handledSignals, i)) 1546 continue; 1547 sigaction(i, &act, &oldact); 1548 1549 // If someone overwrote it in the mean time, put it back 1550 if (oldact.sa_handler != FatalSignalHandler::signal) 1551 sigaction(i, &oldact, 0); 1552 } 1553 } 1554 1555 #endif 1556 1326 1557 1327 1558 } // namespace … … 1400 1631 #endif 1401 1632 1633 1634 1635 1636 1637 1638 1639 1640 1402 1641 QTestResult::reset(); 1403 1642 … … 1419 1658 QBenchmarkValgrindUtils::cleanup(); 1420 1659 1421 } else { 1422 #endif 1423 1660 } else 1661 #endif 1662 { 1663 #if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) 1664 FatalSignalHandler handler; 1665 #endif 1424 1666 qInvokeTestMethods(testObject); 1425 1426 #ifdef QTESTLIB_USE_VALGRIND1427 1667 } 1428 #endif 1429 1430 #ifndef QT_NO_EXCEPTIONS 1668 1669 #ifndef QT_NO_EXCEPTIONS 1431 1670 } catch (...) { 1432 1671 QTestResult::addFailure("Caught unhandled exception", __FILE__, __LINE__); … … 1442 1681 } 1443 1682 #endif 1444 #ifdef Q_OS_WIN 1445 // rethrow exception to make debugging easier 1683 // Rethrow exception to make debugging easier. 1446 1684 throw; 1447 #endif 1448 return -1; 1685 return 1; 1449 1686 } 1450 #endif1687 endif 1451 1688 1452 1689 currentTestObject = 0; … … 1458 1695 1459 1696 1460 #if ndef QT_NO_PROCESS1697 #if 1461 1698 if (QBenchmarkGlobalData::current->createChart) { 1462 1463 #define XSTR(s) STR(s) 1464 #define STR(s) #s 1699 QString chartLocation = QLibraryInfo::location(QLibraryInfo::BinariesPath); 1465 1700 #ifdef Q_OS_WIN 1466 const char * path = XSTR(QBENCHLIB_BASE) "/tools/generatereport/generatereport.exe";1701 ; 1467 1702 #else 1468 const char * path = XSTR(QBENCHLIB_BASE) "/tools/generatereport/generatereport"; 1469 #endif 1470 #undef XSTR 1471 #undef STR 1472 1473 if (QFile::exists(QLatin1String(path))) { 1703 chartLocation += QLatin1String("/../tools/qtestlib/chart/chart"); 1704 #endif 1705 if (QFile::exists(chartLocation)) { 1474 1706 QProcess p; 1475 1707 p.setProcessChannelMode(QProcess::ForwardedChannels); 1476 p.start( QLatin1String(path), QStringList() << QLatin1String("results.xml"));1708 p.start(, QStringList() << QLatin1String("results.xml")); 1477 1709 p.waitForFinished(-1); 1478 1710 } else { 1479 q Warning("Could not find %s, please make sure it is compiled.", path);1711 q); 1480 1712 } 1481 1713 } 1482 1714 #endif 1483 1715 1484 #if defined(QTEST_NOEXITCODE) || (defined(QT_BUILD_INTERNAL) && !defined(QTEST_FORCE_EXITCODE))1716 #if defined(QTEST_NOEXITCODE) 1485 1717 return 0; 1486 1718 #else … … 1756 1988 */ 1757 1989 template <> 1758 bool QTest::qCompare<float>(float const &t1, float const &t2, const char *actual, const char *expected,1990 bool QTest::qCompare<float>(float const &t1, float const &t2, const char *actual, const char *expected, 1759 1991 const char *file, int line) 1760 1992 { … … 1769 2001 */ 1770 2002 template <> 1771 bool QTest::qCompare<double>(double const &t1, double const &t2, const char *actual, const char *expected,2003 bool QTest::qCompare<double>(double const &t1, double const &t2, const char *actual, const char *expected, 1772 2004 const char *file, int line) 1773 2005 { … … 1779 2011 1780 2012 #define COMPARE_IMPL2(TYPE, FORMAT) \ 1781 template <> char *QTest::toString<TYPE >(const TYPE &t) \2013 template <> char *QTest::toString<TYPE >(const TYPE &t) \ 1782 2014 { \ 1783 2015 char *msg = new char[128]; \ … … 1801 2033 COMPARE_IMPL2(bool, %d) 1802 2034 COMPARE_IMPL2(char, %c) 1803 COMPARE_IMPL2(float, %g) ;1804 COMPARE_IMPL2(double, %lg) ;2035 COMPARE_IMPL2(float, %g) 2036 COMPARE_IMPL2(double, %lg) 1805 2037 1806 2038 /*! \internal … … 1911 2143 */ 1912 2144 2145 2146 2147 2148 1913 2149 /*! \fn bool QTest::qTest(const T& actual, const char *elementName, const char *actualStr, const char *expected, const char *file, int line) 1914 2150 \internal … … 1927 2163 */ 1928 2164 1929 /*! \fn int QTest::qt_snprintf(char *str, int size, const char *format, ...)1930 \internal1931 */1932 1933 2165 QT_END_NAMESPACE
Note:
See TracChangeset
for help on using the changeset viewer.