diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp | 16 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qpair/tst_qpair.cpp | 30 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp | 8 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qstring/tst_qstring.cpp | 69 | ||||
-rwxr-xr-x | tests/auto/testlib/selftests/generate_expected_output.py | 1 | ||||
-rw-r--r-- | tests/auto/tools/moc/tst_moc.cpp | 9 | ||||
-rw-r--r-- | tests/auto/tools/qmakelib/evaltest.cpp | 111 | ||||
-rw-r--r-- | tests/auto/tools/qmakelib/parsertest.cpp | 7 | ||||
-rw-r--r-- | tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp | 19 | ||||
-rw-r--r-- | tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp | 25 |
10 files changed, 286 insertions, 9 deletions
diff --git a/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp index 7cdee891bb..1a70ac5e75 100644 --- a/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp +++ b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp @@ -40,6 +40,8 @@ class tst_QHashFunctions : public QObject Q_OBJECT private Q_SLOTS: void qhash(); + void qhash_of_empty_and_null_qstring(); + void qhash_of_empty_and_null_qbytearray(); void fp_qhash_of_zero_is_zero(); void qthash_data(); void qthash(); @@ -128,6 +130,20 @@ void tst_QHashFunctions::qhash() } } +void tst_QHashFunctions::qhash_of_empty_and_null_qstring() +{ + QString null, empty(""); + QCOMPARE(null, empty); + QCOMPARE(qHash(null), qHash(empty)); +} + +void tst_QHashFunctions::qhash_of_empty_and_null_qbytearray() +{ + QByteArray null, empty(""); + QCOMPARE(null, empty); + QCOMPARE(qHash(null), qHash(empty)); +} + void tst_QHashFunctions::fp_qhash_of_zero_is_zero() { QCOMPARE(qHash(-0.0f), 0U); diff --git a/tests/auto/corelib/tools/qpair/tst_qpair.cpp b/tests/auto/corelib/tools/qpair/tst_qpair.cpp index fb0986d05b..1d5f7536c8 100644 --- a/tests/auto/corelib/tools/qpair/tst_qpair.cpp +++ b/tests/auto/corelib/tools/qpair/tst_qpair.cpp @@ -35,6 +35,7 @@ class tst_QPair : public QObject { Q_OBJECT private Q_SLOTS: + void pairOfReferences(); void testConstexpr(); void testConversions(); void taskQTBUG_48780_pairContainingCArray(); @@ -91,6 +92,35 @@ Q_STATIC_ASSERT(!QTypeInfo<QPairPP>::isDummy ); Q_STATIC_ASSERT(!QTypeInfo<QPairPP>::isPointer); +void tst_QPair::pairOfReferences() +{ + int i = 0; + QString s; + + QPair<int&, QString&> p(i, s); + + p.first = 1; + QCOMPARE(i, 1); + + i = 2; + QCOMPARE(p.first, 2); + + p.second = QLatin1String("Hello"); + QCOMPARE(s, QLatin1String("Hello")); + + s = QLatin1String("olleH"); + QCOMPARE(p.second, QLatin1String("olleH")); + + QPair<int&, QString&> q = p; + q.first = 3; + QCOMPARE(i, 3); + QCOMPARE(p.first, 3); + + q.second = QLatin1String("World"); + QCOMPARE(s, QLatin1String("World")); + QCOMPARE(p.second, QLatin1String("World")); +} + void tst_QPair::testConstexpr() { Q_CONSTEXPR QPair<int, double> pID = qMakePair(0, 0.0); diff --git a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp index 7bd732379d..c212589f59 100644 --- a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp +++ b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp @@ -206,9 +206,9 @@ void tst_QRingBuffer::free() ringBuffer.append(QByteArray("01234", 5)); ringBuffer.free(1); - QCOMPARE(ringBuffer.size(), Q_INT64_C(4095 + 2048 + 5)); + QCOMPARE(ringBuffer.size(), Q_INT64_C(4095) + 2048 + 5); ringBuffer.free(4096); - QCOMPARE(ringBuffer.size(), Q_INT64_C(2047 + 5)); + QCOMPARE(ringBuffer.size(), Q_INT64_C(2047) + 5); ringBuffer.free(48); ringBuffer.free(2000); QCOMPARE(ringBuffer.size(), Q_INT64_C(4)); @@ -268,9 +268,9 @@ void tst_QRingBuffer::chop() ringBuffer.reserve(4096); ringBuffer.chop(1); - QCOMPARE(ringBuffer.size(), Q_INT64_C(5 + 2048 + 4095)); + QCOMPARE(ringBuffer.size(), Q_INT64_C(5) + 2048 + 4095); ringBuffer.chop(4096); - QCOMPARE(ringBuffer.size(), Q_INT64_C(5 + 2047)); + QCOMPARE(ringBuffer.size(), Q_INT64_C(5) + 2047); ringBuffer.chop(48); ringBuffer.chop(2000); QCOMPARE(ringBuffer.size(), Q_INT64_C(4)); diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 0a81e3f6bb..fdce9a71be 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -356,7 +356,7 @@ private slots: void replace_qchar_qstring(); void replace_uint_uint_data(); void replace_uint_uint(); - void replace_uint_uint_extra(); + void replace_extra(); void replace_string_data(); void replace_string(); void replace_regexp_data(); @@ -479,6 +479,8 @@ private slots: void sprintfS(); void fill(); void truncate(); + void chop_data(); + void chop(); void constructor(); void constructorQByteArray_data(); void constructorQByteArray(); @@ -1219,6 +1221,31 @@ void tst_QString::truncate() } +void tst_QString::chop_data() +{ + QTest::addColumn<QString>("input"); + QTest::addColumn<int>("count" ); + QTest::addColumn<QString>("result"); + + const QString original("abcd"); + + QTest::newRow("data0") << original << 1 << QString("abc"); + QTest::newRow("data1") << original << 0 << original; + QTest::newRow("data2") << original << -1 << original; + QTest::newRow("data3") << original << original.size() << QString(); + QTest::newRow("data4") << original << 1000 << QString(); +} + +void tst_QString::chop() +{ + QFETCH(QString, input); + QFETCH(int, count); + QFETCH(QString, result); + + input.chop(count); + QCOMPARE(input, result); +} + void tst_QString::fill() { QString e; @@ -2784,7 +2811,7 @@ void tst_QString::replace_uint_uint() } } -void tst_QString::replace_uint_uint_extra() +void tst_QString::replace_extra() { /* This test is designed to be extremely slow if QString::replace() doesn't optimize the case @@ -2821,6 +2848,44 @@ void tst_QString::replace_uint_uint_extra() QString str5("abcdefghij"); str5.replace(8, 10, str5); QCOMPARE(str5, QString("abcdefghabcdefghij")); + + // Replacements using only part of the string modified: + QString str6("abcdefghij"); + str6.replace(1, 8, str6.constData() + 3, 3); + QCOMPARE(str6, QString("adefj")); + + QString str7("abcdefghibcdefghij"); + str7.replace(str7.constData() + 1, 6, str7.constData() + 2, 3); + QCOMPARE(str7, QString("acdehicdehij")); + + const int many = 1024; + /* + QS::replace(const QChar *, int, const QChar *, int, Qt::CaseSensitivity) + does its replacements in batches of many (please keep in sync with any + changes to batch size), which lead to misbehaviour if ether QChar * array + was part of the data being modified. + */ + QString str8("abcdefg"), ans8("acdeg"); + { + // Make str8 and ans8 repeat themselves many + 1 times: + int i = many; + QString big(str8), small(ans8); + while (i && !(i & 1)) { // Exploit many being a power of 2: + big += big; + small += small; + i >>= 1; + } + while (i-- > 0) { + str8 += big; + ans8 += small; + } + } + str8.replace(str8.constData() + 1, 5, str8.constData() + 2, 3); + // Pre-test the bit where the diff happens, so it gets displayed: + QCOMPARE(str8.mid((many - 3) * 5), ans8.mid((many - 3) * 5)); + // Also check the full values match, of course: + QCOMPARE(str8.size(), ans8.size()); + QCOMPARE(str8, ans8); } void tst_QString::replace_string() diff --git a/tests/auto/testlib/selftests/generate_expected_output.py b/tests/auto/testlib/selftests/generate_expected_output.py index aed8829ed6..66a75a304f 100755 --- a/tests/auto/testlib/selftests/generate_expected_output.py +++ b/tests/auto/testlib/selftests/generate_expected_output.py @@ -104,6 +104,7 @@ if isWindows: exit() tests = sys.argv[1:] +os.environ['LC_ALL'] = 'C' if len(tests) == 0: tests = subdirs() print("Generating " + str(len(tests)) + " test results for: " + qtver + " in: " + rootPath) diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 4a423b036c..ef4fb5bda5 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -1931,6 +1931,13 @@ void tst_Moc::warnings_data() << 1 << QString("IGNORE_ALL_STDOUT") << QString(":2: Error: Macro invoked with too few parameters for a use of '#'"); + + QTest::newRow("QTBUG-54609: crash on invalid input") + << QByteArray::fromBase64("EAkJCQkJbGFzcyBjbGFzcyBiYWkcV2kgTUEKcGYjZGVmaW5lIE1BKFEs/4D/FoQ=") + << QStringList() + << 1 + << QString("IGNORE_ALL_STDOUT") + << QString(":-1: Error: Unexpected character in macro argument list."); } void tst_Moc::warnings() @@ -1946,7 +1953,7 @@ void tst_Moc::warnings() #ifdef Q_CC_MSVC // for some reasons, moc compiled with MSVC uses a different output format - QRegExp lineNumberRe(":(\\d+):"); + QRegExp lineNumberRe(":(-?\\d+):"); lineNumberRe.setMinimal(true); expectedStdErr.replace(lineNumberRe, "(\\1):"); #endif diff --git a/tests/auto/tools/qmakelib/evaltest.cpp b/tests/auto/tools/qmakelib/evaltest.cpp index aaa4bb3724..4cd335d732 100644 --- a/tests/auto/tools/qmakelib/evaltest.cpp +++ b/tests/auto/tools/qmakelib/evaltest.cpp @@ -594,6 +594,23 @@ void tst_qmakelib::addControlStructs() << "" << true; + QTest::newRow("function arguments") + << "defineTest(func) {\n" + "defined(1, var) {\nd1 = 1\nexport(d1)\n}\n" + "defined(3, var) {\nd3 = 1\nexport(d3)\n}\n" + "x1 = $$1\nexport(x1)\n" + "2 += foo\nx2 = $$2\nexport(x2)\n" + "x3 = $$3\nexport(x3)\n" + "4 += foo\nx4 = $$4\nexport(x4)\n" + "x5 = $$5\nexport(x5)\n" + "6 += foo\nx6 = $$6\nexport(x6)\n" + "}\n" + "1 = first\n2 = second\n3 = third\n4 = fourth\nfunc(one, two)" + << "1 = first\n2 = second\n3 = third\n4 = fourth\n5 = UNDEF\n6 = UNDEF\n" + "d1 = 1\nd3 = UNDEF\nx1 = one\nx2 = two foo\nx3 =\nx4 = foo\nx5 =\nx6 = foo" + << "" + << true; + QTest::newRow("ARGC and ARGS") << "defineTest(func) {\n" "export(ARGC)\n" @@ -636,6 +653,86 @@ void tst_qmakelib::addControlStructs() << "VAR = final" << "" << true; + + QTest::newRow("error() from replace function (assignment)") + << "defineReplace(func) {\nerror(error)\n}\n" + "VAR = $$func()\n" + "OKE = 1" + << "VAR = UNDEF\nOKE = UNDEF" + << "Project ERROR: error" + << false; + + QTest::newRow("error() from replace function (replacement)") + << "defineReplace(func) {\nerror(error)\n}\n" + "VAR = $$func()\n" + "OKE = 1" + << "VAR = UNDEF\nOKE = UNDEF" + << "Project ERROR: error" + << false; + + QTest::newRow("error() from replace function (LHS)") + << "defineReplace(func) {\nerror(error)\nreturn(VAR)\n}\n" + "$$func() = 1\n" + "OKE = 1" + << "VAR = UNDEF\nOKE = UNDEF" + << "Project ERROR: error" + << false; + + QTest::newRow("error() from replace function (loop variable)") + << "defineReplace(func) {\nerror(error)\nreturn(BLAH)\n}\n" + "for($$func()) {\nVAR = $$BLAH\nbreak()\n}\n" + "OKE = 1" + << "VAR = UNDEF\nOKE = UNDEF" + << "Project ERROR: error" + << false; + + QTest::newRow("error() from replace function (built-in test arguments)") + << "defineReplace(func) {\nerror(error)\n}\n" + "message($$func()): VAR = 1\n" + "OKE = 1" + << "VAR = UNDEF\nOKE = UNDEF" + << "Project ERROR: error" + << false; + + QTest::newRow("error() from replace function (built-in replace arguments)") + << "defineReplace(func) {\nerror(error)\n}\n" + "VAR = $$upper($$func())\n" + "OKE = 1" + << "VAR = UNDEF\nOKE = UNDEF" + << "Project ERROR: error" + << false; + + QTest::newRow("error() from replace function (custom test arguments)") + << "defineReplace(func) {\nerror(error)\n}\n" + "defineTest(custom) {\n}\n" + "custom($$func()): VAR = 1\n" + "OKE = 1" + << "VAR = UNDEF\nOKE = UNDEF" + << "Project ERROR: error" + << false; + + QTest::newRow("error() from replace function (custom replace arguments)") + << "defineReplace(func) {\nerror(error)\nreturn(1)\n}\n" + "defineReplace(custom) {\nreturn($$1)\n}\n" + "VAR = $$custom($$func(1))\n" + "OKE = 1" + << "VAR = UNDEF\nOKE = UNDEF" + << "Project ERROR: error" + << false; + + QTest::newRow("REQUIRES = error()") + << "REQUIRES = error(error)\n" + "OKE = 1" + << "OKE = UNDEF" + << "Project ERROR: error" + << false; + + QTest::newRow("requires(error())") + << "requires(error(error))\n" + "OKE = 1" + << "OKE = UNDEF" + << "Project ERROR: error" + << false; } void tst_qmakelib::addReplaceFunctions(const QString &qindir) @@ -2098,6 +2195,12 @@ void tst_qmakelib::addTestFunctions(const QString &qindir) << "Project ERROR: World, you FAIL!" << false; + QTest::newRow("if(error())") + << "if(error(\\'World, you FAIL!\\')): OK = 1\nOKE = 1" + << "OK = UNDEF\nOKE = UNDEF" + << "Project ERROR: World, you FAIL!" + << false; + QTest::newRow("system()") << "system('" #ifdef Q_OS_WIN @@ -2374,6 +2477,14 @@ void tst_qmakelib::proEval_data() "Project MESSAGE: assign split joined: word: this is a test:done\n" "Project MESSAGE: assign split quoted: word this is a test done" << true; + + // Raw data leak with empty file name. Verify with Valgrind or asan. + QTest::newRow("QTBUG-54550") + << "FULL = /there/is\n" + "VAR = $$absolute_path(, $$FULL/nothing/here/really)" + << "VAR = /there/is/nothing/here/really" + << "" + << true; } static QString formatValue(const ProStringList &vals) diff --git a/tests/auto/tools/qmakelib/parsertest.cpp b/tests/auto/tools/qmakelib/parsertest.cpp index 5f345617db..5e12d930f8 100644 --- a/tests/auto/tools/qmakelib/parsertest.cpp +++ b/tests/auto/tools/qmakelib/parsertest.cpp @@ -1867,6 +1867,13 @@ void tst_qmakelib::addParseAbuse() /* 24 */ /* else branch */ << I(0)) << "in:1: OR operator without prior condition." << false; + + // Token buffer overflow. Verify with Valgrind or asan. + QTest::newRow("QTCREATORBUG-16508") + << "a{b{c{d{" + << TS() + << "in:2: Missing closing brace(s)." + << false; } void tst_qmakelib::proParser_data() diff --git a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp index b2824c00ee..ff71a6d56b 100644 --- a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp @@ -286,8 +286,8 @@ retry: // Testing get/set functions void tst_QCompleter::getSetCheck() { - QStandardItemModel model(3,3); - QCompleter completer(&model); + QStandardItemModel standardItemModel(3,3); + QCompleter completer(&standardItemModel); // QString QCompleter::completionPrefix() // void QCompleter::setCompletionPrefix(QString) @@ -347,6 +347,21 @@ void tst_QCompleter::getSetCheck() QCOMPARE(completer.wrapAround(), true); // default value completer.setWrapAround(false); QCOMPARE(completer.wrapAround(), false); + +#ifndef QT_NO_FILESYSTEMMODEL + // QTBUG-54642, changing from QFileSystemModel to another model should restore role. + completer.setCompletionRole(Qt::EditRole); + QCOMPARE(completer.completionRole(), static_cast<int>(Qt::EditRole)); // default value + QFileSystemModel fileSystemModel; + completer.setModel(&fileSystemModel); + QCOMPARE(completer.completionRole(), static_cast<int>(QFileSystemModel::FileNameRole)); + completer.setModel(&standardItemModel); + QCOMPARE(completer.completionRole(), static_cast<int>(Qt::EditRole)); + completer.setCompletionRole(Qt::ToolTipRole); + QStandardItemModel standardItemModel2(2, 2); // Do not clobber a custom role when changing models + completer.setModel(&standardItemModel2); + QCOMPARE(completer.completionRole(), static_cast<int>(Qt::ToolTipRole)); +#endif // QT_NO_FILESYSTEMMODEL } void tst_QCompleter::csMatchingOnCsSortedModel_data() diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index 2a356f574c..50024460fc 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -156,6 +156,7 @@ private slots: void itemData(); void task_QTBUG_31146_popupCompletion(); void task_QTBUG_41288_completerChangesCurrentIndex(); + void task_QTBUG_54191_slotOnEditTextChangedSetsComboBoxToReadOnly(); void keyboardSelection(); void setCustomModelAndView(); void updateDelegateOnEditableChange(); @@ -3121,6 +3122,30 @@ void tst_QComboBox::task_QTBUG_41288_completerChangesCurrentIndex() } } +namespace { + struct SetReadOnly { + QComboBox *cb; + explicit SetReadOnly(QComboBox *cb) : cb(cb) {} + void operator()() const + { cb->setEditable(false); } + }; +} + +void tst_QComboBox::task_QTBUG_54191_slotOnEditTextChangedSetsComboBoxToReadOnly() +{ + QComboBox cb; + cb.addItems(QStringList() << "one" << "two"); + cb.setEditable(true); + cb.setCurrentIndex(0); + + connect(&cb, &QComboBox::editTextChanged, + SetReadOnly(&cb)); + + cb.setCurrentIndex(1); + // the real test is that it didn't crash... + QCOMPARE(cb.currentIndex(), 1); +} + void tst_QComboBox::keyboardSelection() { QComboBox comboBox; |