qtestcase.cpp

来自「奇趣公司比较新的qt/emd版本」· C++ 代码 · 共 1,706 行 · 第 1/4 页

CPP
1,706
字号
            printf(" Usage: %s [options] [testfunctions[:testdata]]...\n"                   "    By default, all testfunction will be run.\n\n"                   "%s", argv[0], testOptions);            exit(0);        } else if (strcmp(argv[i], "-functions") == 0) {            qPrintTestSlots();            exit(0);        } else if (strcmp(argv[i], "-xml") == 0) {            QTestLog::setLogMode(QTestLog::XML);        } else if (strcmp(argv[i], "-lightxml") == 0) {            QTestLog::setLogMode(QTestLog::LightXML);        } else if (strcmp(argv[i], "-silent") == 0) {            QTestLog::setVerboseLevel(-1);        } else if (strcmp(argv[i], "-v1") == 0) {            QTestLog::setVerboseLevel(1);        } else if (strcmp(argv[i], "-v2") == 0) {            QTestLog::setVerboseLevel(2);        } else if (strcmp(argv[i], "-vs") == 0) {            QSignalDumper::startDump();        } else if (strcmp(argv[i], "-o") == 0) {            if (i + 1 >= argc) {                printf("-o needs an extra parameter specifying the filename\n");                exit(1);            } else {                QTestLog::redirectOutput(argv[++i]);            }        } else if (strcmp(argv[i], "-eventdelay") == 0) {            if (i + 1 >= argc) {                printf("-eventdelay needs an extra parameter to indicate the delay(ms)\n");                exit(1);            } else {                QTest::eventDelay = qToInt(argv[++i]);            }        } else if (strcmp(argv[i], "-keydelay") == 0) {            if (i + 1 >= argc) {                printf("-keydelay needs an extra parameter to indicate the delay(ms)\n");                exit(1);            } else {                QTest::keyDelay = qToInt(argv[++i]);            }        } else if (strcmp(argv[i], "-mousedelay") == 0) {            if (i + 1 >= argc) {                printf("-mousedelay needs an extra parameter to indicate the delay(ms)\n");                exit(1);            } else {                QTest::mouseDelay = qToInt(argv[++i]);            }        } else if (strcmp(argv[i], "-maxwarnings") == 0) {            if (i + 1 >= argc) {                printf("-maxwarnings needs an extra parameter with the amount of warnings\n");                exit(1);            } else {                QTestLog::setMaxWarnings(qToInt(argv[++i]));            }        } else if (strcmp(argv[i], "-keyevent-verbose") == 0) {            QTest::keyVerbose = 1;        } else if (strcmp(argv[i], "-qws") == 0) {            // do nothing        } else if (argv[i][0] == '-') {            printf("Unknown option: '%s'\n\n%s", argv[i], testOptions);            exit(1);        } else {            int colon = -1;            char buf[512], *data=0;            for(int off = 0; *(argv[i]+off); ++off) {                if (*(argv[i]+off) == ':') {                    colon = off;                    break;                }            }            if(colon != -1) {                *(argv[i]+colon) = '\0';                data = qstrdup(argv[i]+colon+1);            }            QTest::qt_snprintf(buf, 512, "%s()", argv[i]);            int idx = QTest::currentTestObject->metaObject()->indexOfMethod(buf);            if (idx < 0 || !isValidSlot(QTest::currentTestObject->metaObject()->method(idx))) {                printf("Unknown testfunction: '%s'\n", buf);                printf("Available testfunctions:\n");                qPrintTestSlots();                exit(1);            }            ++QTest::lastTestFuncIdx;            QTest::testFuncs[QTest::lastTestFuncIdx].function = idx;            QTest::testFuncs[QTest::lastTestFuncIdx].data = data;            QTEST_ASSERT(QTest::lastTestFuncIdx < 512);        }    }}struct QTestDataSetter{    QTestDataSetter(QTestData *data)    {        QTestResult::setCurrentTestData(data);    }    ~QTestDataSetter()    {        QTestResult::setCurrentTestData(0);    }};/*!    \internal    Call init(), slot_data(), slot(), slot(), slot()..., cleanup()    If data is set then it is the only test that is performed    If the function was successfully called, true is returned, otherwise    false. */static bool qInvokeTestMethod(const char *slotName, const char *data=0){    QTEST_ASSERT(slotName);    char member[512];    QTestTable table;    char *slot = qstrdup(slotName);    slot[strlen(slot) - 2] = '\0';    QTestResult::setCurrentTestFunction(slot);    const QTestTable *gTable = QTestTable::globalTestTable();    const int globalDataCount = gTable->dataCount();    int curGlobalDataIndex = 0;    /* For each test function that has a *_data() table/function, do: */    do {        if (!gTable->isEmpty())            QTestResult::setCurrentGlobalTestData(gTable->testData(curGlobalDataIndex));        if (curGlobalDataIndex == 0) {            QTestResult::setCurrentTestLocation(QTestResult::DataFunc);            QTest::qt_snprintf(member, 512, "%s_data", slot);            QMetaObject::invokeMethod(QTest::currentTestObject, member, Qt::DirectConnection);            // if we encounter a SkipAll in the _data slot, we skip the whole            // testfunction, no matter how much global data exists            if (QTestResult::skipCurrentTest()) {                QTestResult::setCurrentGlobalTestData(0);                break;            }        }        bool foundFunction = false;        if (!QTestResult::skipCurrentTest()) {            int curDataIndex = 0;            const int dataCount = table.dataCount();            QTestResult::setSkipCurrentTest(false);            /* For each entry in the data table, do: */            do {                if (!data || !qstrcmp(data, table.testData(curDataIndex)->dataTag())) {                    foundFunction = true;                    QTestDataSetter s(table.isEmpty() ? static_cast<QTestData *>(0)                                                      : table.testData(curDataIndex));                    QTestResult::setCurrentTestLocation(QTestResult::InitFunc);                    QMetaObject::invokeMethod(QTest::currentTestObject, "init");                    if (QTestResult::skipCurrentTest())                        break;                    QTestResult::setCurrentTestLocation(QTestResult::Func);                    if (!QMetaObject::invokeMethod(QTest::currentTestObject, slot,                                                  Qt::DirectConnection)) {                        QTestResult::addFailure("Unable to execute slot", __FILE__, __LINE__);                        break;                    }                    QTestResult::setCurrentTestLocation(QTestResult::CleanupFunc);                    QMetaObject::invokeMethod(QTest::currentTestObject, "cleanup");                    QTestResult::setCurrentTestLocation(QTestResult::NoWhere);                    if (QTestResult::skipCurrentTest())                        // check whether SkipAll was requested                        break;                    if (data)                        break;                }                ++curDataIndex;            } while (curDataIndex < dataCount);        }        if (data && !foundFunction) {            printf("Unknown testdata for function %s: '%s'\n", slotName, data);            printf("Available testdata:\n");            for(int i = 0; i < table.dataCount(); ++i)                printf("%s\n", table.testData(i)->dataTag());            return false;        }        QTestResult::setCurrentGlobalTestData(0);        ++curGlobalDataIndex;    } while (curGlobalDataIndex < globalDataCount);    QTestResult::finishedCurrentTestFunction();    QTestResult::setSkipCurrentTest(false);    QTestResult::setCurrentTestData(0);    delete[] slot;    return true;}void *fetchData(QTestData *data, const char *tagName, int typeId){    QTEST_ASSERT(typeId);    QTEST_ASSERT_X(data, "QTest::fetchData()", "Test data requested, but no testdata available.");    QTEST_ASSERT(data->parent());    int idx = data->parent()->indexOf(tagName);    if (idx == -1 || idx >= data->dataCount()) {        qFatal("QFETCH: Requested testdata '%s' not available, check your _data function.",                tagName);    }    if (typeId != data->parent()->elementTypeId(idx)) {        qFatal("Requested type '%s' does not match available type '%s'.",               QMetaType::typeName(typeId),               QMetaType::typeName(data->parent()->elementTypeId(idx)));    }    return data->data(idx);}/*!  \fn char* QTest::toHexRepresentation(const char *ba, int length)    Returns a pointer to a string that is the string \a ba represented  as a space-separated sequence of hex characters. If the input is  considered too long, it is truncated. A trucation is indicated in  the returned string as an ellipsis at the end.  \a length is the length of the string \a ba.  */char *toHexRepresentation(const char *ba, int length){    if(length == 0)        return qstrdup("");    /* We output at maximum about maxLen characters in order to avoid     * running out of memory and flooding things when the byte array     * is large.     *     * maxLen can't be for example 200 because QTestLib is sprinkled with fixed     * size char arrays.     * */    const int maxLen = 50;    const int len = qMin(maxLen, length);    char *result = 0;    if(length > maxLen) {        const int size = len * 3 + 4;        result = new char[size];        char *const forElipsis = result + size - 5;        forElipsis[0] = ' ';        forElipsis[1] = '.';        forElipsis[2] = '.';        forElipsis[3] = '.';        result[size - 1] = '\0';    }    else {        const int size = len * 3;        result = new char[size];        result[size - 1] = '\0';    }    const char toHex[] = "0123456789ABCDEF";    int i = 0;    int o = 0;    while(true) {        const char at = ba[i];        result[o] = toHex[(at >> 4) & 0x0F];        ++o;        result[o] = toHex[at & 0x0F];        ++i;        ++o;        if(i == len)            break;        else {            result[o] = ' ';            ++o;        }    }    return result;}} // namespace/*!    Executes tests declared in \a testObject. In addition, the private slots    \c{initTestCase()}, \c{cleanupTestCase()}, \c{init()} and \c{cleanup()}    are executed if they exist. See \l{Creating a test} for more details.    Optionally, the command line arguments \a argc and \a argv can be provided.    For a list of recognized arguments, read \l {QTestLib Command Line Arguments}.    For stand-alone tests, the convenience macro \l QTEST_MAIN() can    be used to declare a main method that parses the command line arguments    and executes the tests.    The following example will run all tests in \c MyFirstTestObject and    \c{MySecondTestObject}:    \code    MyFirstTestObject test1;    QTest::qExec(&test1);    MySecondTestObject test2;    QTest::qExec(&test2);    \endcode    Note: This function is not reentrant, only one test can run at a time. A    test that was executed with qExec() can't run another test via qExec() and    threads are not allowed to call qExec() simultaneously.    \sa QTEST_MAIN()*/int QTest::qExec(QObject *testObject, int argc, char **argv){ #ifndef QT_NO_EXCEPTIONS     try { #endif #if defined(Q_OS_WIN)     SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX); #endif    QTestResult::reset();    QTEST_ASSERT(testObject);    QTEST_ASSERT(!currentTestObject);    currentTestObject = testObject;    const QMetaObject *metaObject = testObject->metaObject();    QTEST_ASSERT(metaObject);    QTestResult::setCurrentTestObject(metaObject->className());    qParseArgs(argc, argv);    QTestLog::startLogging();    QTestResult::setCurrentTestFunction("initTestCase");    QTestResult::setCurrentTestLocation(QTestResult::DataFunc);    QTestTable::globalTestTable();    QMetaObject::invokeMethod(testObject, "initTestCase_data", Qt::DirectConnection);    if (!QTestResult::skipCurrentTest() && !QTest::currentTestFailed()) {        QTestResult::setCurrentTestLocation(QTestResult::InitFunc);        QMetaObject::invokeMethod(testObject, "initTestCase");        // finishedCurrentTestFunction() resets QTestResult::testFailed(), so use a local copy.        const bool previousFailed = QTestResult::testFailed();        QTestResult::finishedCurrentTestFunction();        if(!QTestResult::skipCurrentTest() && !previousFailed) {            if (lastTestFuncIdx >= 0) {                for (int i = 0; i <= lastTestFuncIdx; ++i) {                    if (!qInvokeTestMethod(metaObject->method(testFuncs[i].function).signature(),                                           testFuncs[i].data))                        break;                }            } else {                int methodCount = metaObject->methodCount();                for (int i = 0; i < methodCount; ++i) {                    QMetaMethod slotMethod = metaObject->method(i);                    if (!isValidSlot(slotMethod))                        continue;                    if (!qInvokeTestMethod(slotMethod.signature()))                        break;                }            }        }        QTestResult::setSkipCurrentTest(false);        QTestResult::setCurrentTestFunction("cleanupTestCase");        QMetaObject::invokeMethod(testObject, "cleanupTestCase");    }    QTestResult::finishedCurrentTestFunction();    QTestResult::setCurrentTestFunction(0);    QTestTable::clearGlobalTestTable(); #ifndef QT_NO_EXCEPTIONS     } catch (...) {         QTestResult::addFailure("Caught unhandled exception", __FILE__, __LINE__);         if (QTestResult::currentTestFunction()) {             QTestResult::finishedCurrentTestFunction();             QTestResult::setCurrentTestFunction(0);         }         QTestLog::stopLogging(); #ifdef Q_OS_WIN         // rethrow exception to make debugging easier         throw; #endif         return -1;     } #endif    QTestLog::stopLogging();    currentTestObject = 0;#if defined(QTEST_NOEXITCODE) || defined(QT_BUILD_INTERNAL)    return 0;#else    return QTestResult::failCount();#endif}/*! \internal */void QTest::qFail(const char *statementStr, const char *file, int line){    QTestResult::addFailure(statementStr, file, line);}/*! \internal */bool QTest::qVerify(bool statement, const char *statementStr, const char *description,                   const char *file, int line){    return QTestResult::verify(statement, statementStr, description, file, line);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?