summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp')
-rw-r--r--tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp289
1 files changed, 235 insertions, 54 deletions
diff --git a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp
index c828551e44..f520e9742a 100644
--- a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp
+++ b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp
@@ -33,11 +33,60 @@
#include <qstringlist.h>
#include <qhash.h>
-#include "tst_qregularexpression.h"
+#include <qobject.h>
+#include <qregularexpression.h>
+#include <qthread.h>
-#ifndef forceOptimize
-#define forceOptimize false
-#endif
+Q_DECLARE_METATYPE(QRegularExpression::PatternOptions)
+Q_DECLARE_METATYPE(QRegularExpression::MatchType)
+Q_DECLARE_METATYPE(QRegularExpression::MatchOptions)
+
+class tst_QRegularExpression : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void defaultConstructors();
+ void gettersSetters_data();
+ void gettersSetters();
+ void escape_data();
+ void escape();
+ void validity_data();
+ void validity();
+ void patternOptions_data();
+ void patternOptions();
+ void normalMatch_data();
+ void normalMatch();
+ void partialMatch_data();
+ void partialMatch();
+ void globalMatch_data();
+ void globalMatch();
+ void serialize_data();
+ void serialize();
+ void operatoreq_data();
+ void operatoreq();
+ void captureCount_data();
+ void captureCount();
+ void captureNames_data();
+ void captureNames();
+ void pcreJitStackUsage_data();
+ void pcreJitStackUsage();
+ void regularExpressionMatch_data();
+ void regularExpressionMatch();
+ void JOptionUsage_data();
+ void JOptionUsage();
+ void QStringAndQStringRefEquivalence();
+ void threadSafety_data();
+ void threadSafety();
+
+ void wildcard_data();
+ void wildcard();
+ void testInvalidWildcard_data();
+ void testInvalidWildcard();
+
+private:
+ void provideRegularExpressions();
+};
struct Match
{
@@ -292,9 +341,6 @@ static void testMatch(const QRegularExpression &regexp,
QRegularExpression::MatchOptions matchOptions,
const Result &result)
{
- if (forceOptimize)
- regexp.optimize();
-
// test with QString as subject type
testMatchImpl<QREMatch>(regexp, matchingMethodForString, subject, offset, matchType, matchOptions, result);
@@ -401,30 +447,22 @@ void tst_QRegularExpression::gettersSetters()
{
QRegularExpression re;
re.setPattern(pattern);
- if (forceOptimize)
- re.optimize();
QCOMPARE(re.pattern(), pattern);
QCOMPARE(re.patternOptions(), QRegularExpression::NoPatternOption);
}
{
QRegularExpression re;
re.setPatternOptions(patternOptions);
- if (forceOptimize)
- re.optimize();
QCOMPARE(re.pattern(), QString());
QCOMPARE(re.patternOptions(), patternOptions);
}
{
QRegularExpression re(pattern);
- if (forceOptimize)
- re.optimize();
QCOMPARE(re.pattern(), pattern);
QCOMPARE(re.patternOptions(), QRegularExpression::NoPatternOption);
}
{
QRegularExpression re(pattern, patternOptions);
- if (forceOptimize)
- re.optimize();
QCOMPARE(re.pattern(), pattern);
QCOMPARE(re.patternOptions(), patternOptions);
}
@@ -465,8 +503,6 @@ void tst_QRegularExpression::escape()
QFETCH(QString, escaped);
QCOMPARE(QRegularExpression::escape(string), escaped);
QRegularExpression re(escaped);
- if (forceOptimize)
- re.optimize();
QCOMPARE(re.isValid(), true);
}
@@ -497,8 +533,6 @@ void tst_QRegularExpression::validity()
QFETCH(QString, pattern);
QFETCH(bool, validity);
QRegularExpression re(pattern);
- if (forceOptimize)
- re.optimize();
QCOMPARE(re.isValid(), validity);
if (!validity)
QTest::ignoreMessage(QtWarningMsg, "QRegularExpressionPrivate::doMatch(): called on an invalid QRegularExpression object");
@@ -585,9 +619,6 @@ void tst_QRegularExpression::patternOptions()
QFETCH(QString, subject);
QFETCH(Match, match);
- if (forceOptimize)
- regexp.optimize();
-
QRegularExpressionMatch m = regexp.match(subject);
consistencyCheck(m);
QVERIFY(m == match);
@@ -1403,9 +1434,6 @@ void tst_QRegularExpression::serialize()
QFETCH(QRegularExpression::PatternOptions, patternOptions);
QRegularExpression outRe(pattern, patternOptions);
- if (forceOptimize)
- outRe.optimize();
-
QByteArray buffer;
{
QDataStream out(&buffer, QIODevice::WriteOnly);
@@ -1468,33 +1496,18 @@ void tst_QRegularExpression::operatoreq()
QRegularExpression re1(pattern);
QRegularExpression re2(pattern);
- if (forceOptimize)
- re1.optimize();
- if (forceOptimize)
- re2.optimize();
-
verifyEquality(re1, re2);
}
{
QRegularExpression re1(QString(), patternOptions);
QRegularExpression re2(QString(), patternOptions);
- if (forceOptimize)
- re1.optimize();
- if (forceOptimize)
- re2.optimize();
-
verifyEquality(re1, re2);
}
{
QRegularExpression re1(pattern, patternOptions);
QRegularExpression re2(pattern, patternOptions);
- if (forceOptimize)
- re1.optimize();
- if (forceOptimize)
- re2.optimize();
-
verifyEquality(re1, re2);
}
}
@@ -1524,9 +1537,6 @@ void tst_QRegularExpression::captureCount()
QFETCH(QString, pattern);
QRegularExpression re(pattern);
- if (forceOptimize)
- re.optimize();
-
QTEST(re.captureCount(), "captureCount");
if (!re.isValid())
QCOMPARE(re.captureCount(), -1);
@@ -1595,9 +1605,6 @@ void tst_QRegularExpression::captureNames()
QRegularExpression re(pattern);
- if (forceOptimize)
- re.optimize();
-
QStringList namedCaptureGroups = re.namedCaptureGroups();
int namedCaptureGroupsCount = namedCaptureGroups.size();
@@ -1633,9 +1640,6 @@ void tst_QRegularExpression::pcreJitStackUsage()
QRegularExpression re(pattern);
- if (forceOptimize)
- re.optimize();
-
QVERIFY(re.isValid());
QRegularExpressionMatch match = re.match(subject);
consistencyCheck(match);
@@ -1663,9 +1667,6 @@ void tst_QRegularExpression::regularExpressionMatch()
QRegularExpression re(pattern);
- if (forceOptimize)
- re.optimize();
-
QVERIFY(re.isValid());
QRegularExpressionMatch match = re.match(subject);
consistencyCheck(match);
@@ -1705,8 +1706,6 @@ void tst_QRegularExpression::JOptionUsage()
QRegularExpression re(pattern);
if (isValid && JOptionUsed)
QTest::ignoreMessage(QtWarningMsg, qPrintable(warningMessage.arg(pattern)));
- if (forceOptimize)
- re.optimize();
QCOMPARE(re.isValid(), isValid);
}
@@ -2066,3 +2065,185 @@ void tst_QRegularExpression::QStringAndQStringRefEquivalence()
}
}
}
+
+class MatcherThread : public QThread
+{
+public:
+ explicit MatcherThread(const QRegularExpression &re, const QString &subject, QObject *parent = nullptr)
+ : QThread(parent),
+ m_re(re),
+ m_subject(subject)
+ {
+ }
+
+private:
+ static const int MATCH_ITERATIONS = 50;
+
+ void run() override
+ {
+ yieldCurrentThread();
+ for (int i = 0; i < MATCH_ITERATIONS; ++i)
+ m_re.match(m_subject);
+ }
+
+ const QRegularExpression &m_re;
+ const QString &m_subject;
+};
+
+void tst_QRegularExpression::threadSafety_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QString>("subject");
+
+ int i = 0;
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abcd";
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abd";
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abbbbcccd";
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abababcd";
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abcabcd";
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << "abccccccababd";
+
+ {
+ QString subject(512*1024, QLatin1Char('x'));
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << subject;
+ }
+
+ {
+ QString subject = "ab";
+ subject.append(QString(512*1024, QLatin1Char('x')));
+ subject.append("c");
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << subject;
+ }
+
+ {
+ QString subject = "ab";
+ subject.append(QString(512*1024, QLatin1Char('x')));
+ subject.append("cd");
+ QTest::addRow("pattern%d", ++i) << "ab.*cd" << subject;
+ }
+
+ QTest::addRow("pattern%d", ++i) << "(?(R)a*(?1)|((?R))b)" << "aaaabcde";
+ QTest::addRow("pattern%d", ++i) << "(?(R)a*(?1)|((?R))b)" << "aaaaaaabcde";
+}
+
+void tst_QRegularExpression::threadSafety()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QString, subject);
+
+ static const int THREAD_SAFETY_ITERATIONS = 50;
+
+ const int threadCount = qMax(QThread::idealThreadCount(), 4);
+
+ for (int threadSafetyIteration = 0; threadSafetyIteration < THREAD_SAFETY_ITERATIONS; ++threadSafetyIteration) {
+ QRegularExpression re(pattern);
+
+ QVector<MatcherThread *> threads;
+ for (int i = 0; i < threadCount; ++i) {
+ MatcherThread *thread = new MatcherThread(re, subject);
+ thread->start();
+ threads.push_back(thread);
+ }
+
+ for (int i = 0; i < threadCount; ++i)
+ threads[i]->wait();
+
+ qDeleteAll(threads);
+ }
+}
+
+void tst_QRegularExpression::wildcard_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<int>("foundIndex");
+
+ auto addRow = [](const char *pattern, const char *string, int foundIndex) {
+ QTest::newRow(pattern) << pattern << string << foundIndex;
+ };
+
+ addRow("*.html", "test.html", 0);
+ addRow("*.html", "test.htm", -1);
+ addRow("bar*", "foobarbaz", 3);
+ addRow("*", "Qt Rocks!", 0);
+ addRow(".html", "test.html", 4);
+ addRow(".h", "test.cpp", -1);
+ addRow(".???l", "test.html", 4);
+ addRow("?", "test.html", 0);
+ addRow("?m", "test.html", 6);
+ addRow("[*]", "test.html", -1);
+ addRow("[?]","test.html", -1);
+ addRow("[?]","test.h?ml", 6);
+ addRow("[[]","test.h[ml", 6);
+ addRow("[]]","test.h]ml", 6);
+ addRow(".h[a-z]ml", "test.html", 4);
+ addRow(".h[A-Z]ml", "test.html", -1);
+ addRow(".h[A-Z]ml", "test.hTml", 4);
+ addRow(".h[!A-Z]ml", "test.hTml", -1);
+ addRow(".h[!A-Z]ml", "test.html", 4);
+ addRow(".h[!T]ml", "test.hTml", -1);
+ addRow(".h[!T]ml", "test.html", 4);
+ addRow(".h[!T]m[!L]", "test.htmL", -1);
+ addRow(".h[!T]m[!L]", "test.html", 4);
+ addRow(".h[][!]", "test.h]ml", 4);
+ addRow(".h[][!]", "test.h[ml", 4);
+ addRow(".h[][!]", "test.h!ml", 4);
+
+ addRow("foo/*/bar", "Qt/foo/baz/bar", 3);
+ addRow("foo/(*)/bar", "Qt/foo/baz/bar", -1);
+ addRow("foo/(*)/bar", "Qt/foo/(baz)/bar", 3);
+ addRow("foo/?/bar", "Qt/foo/Q/bar", 3);
+ addRow("foo/?/bar", "Qt/foo/Qt/bar", -1);
+ addRow("foo/(?)/bar", "Qt/foo/Q/bar", -1);
+ addRow("foo/(?)/bar", "Qt/foo/(Q)/bar", 3);
+
+#ifdef Q_OS_WIN
+ addRow("foo\\*\\bar", "Qt\\foo\\baz\\bar", 3);
+ addRow("foo\\(*)\\bar", "Qt\\foo\\baz\\bar", -1);
+ addRow("foo\\(*)\\bar", "Qt\\foo\\(baz)\\bar", 3);
+ addRow("foo\\?\\bar", "Qt\\foo\\Q\\bar", 3);
+ addRow("foo\\?\\bar", "Qt\\foo\\Qt\\bar", -1);
+ addRow("foo\\(?)\\bar", "Qt\\foo\\Q\\bar", -1);
+ addRow("foo\\(?)\\bar", "Qt\\foo\\(Q)\\bar", 3);
+#endif
+}
+
+void tst_QRegularExpression::wildcard()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QString, string);
+ QFETCH(int, foundIndex);
+
+ QRegularExpression re(QRegularExpression::wildcardToRegularExpression(pattern));
+ QRegularExpressionMatch match = re.match(string);
+
+ QCOMPARE(match.capturedStart(), foundIndex);
+}
+
+void tst_QRegularExpression::testInvalidWildcard_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<bool>("isValid");
+
+ QTest::newRow("valid []") << "[abc]" << true;
+ QTest::newRow("valid ending ]") << "abc]" << true;
+ QTest::newRow("invalid [") << "[abc" << false;
+ QTest::newRow("ending [") << "abc[" << false;
+ QTest::newRow("ending [^") << "abc[^" << false;
+ QTest::newRow("ending [\\") << "abc[\\" << false;
+ QTest::newRow("ending []") << "abc[]" << false;
+ QTest::newRow("ending [[") << "abc[[" << false;
+}
+
+void tst_QRegularExpression::testInvalidWildcard()
+{
+ QFETCH(QString, pattern);
+ QFETCH(bool, isValid);
+
+ QRegularExpression re(QRegularExpression::wildcardToRegularExpression(pattern));
+ QCOMPARE(re.isValid(), isValid);
+}
+
+QTEST_APPLESS_MAIN(tst_QRegularExpression)
+
+#include "tst_qregularexpression.moc"