summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp16
-rw-r--r--tests/auto/corelib/tools/qpair/tst_qpair.cpp30
-rw-r--r--tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp8
-rw-r--r--tests/auto/corelib/tools/qstring/tst_qstring.cpp69
-rwxr-xr-xtests/auto/testlib/selftests/generate_expected_output.py1
-rw-r--r--tests/auto/tools/moc/tst_moc.cpp9
-rw-r--r--tests/auto/tools/qmakelib/evaltest.cpp111
-rw-r--r--tests/auto/tools/qmakelib/parsertest.cpp7
-rw-r--r--tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp19
-rw-r--r--tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp25
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;