QML test lib: propagate failOnWarning() feature to QML

With efb283fb7f72e950c8ecf755b960a3c1b36b5507 in qtbase, we can now
fail a test if a particular warning is encountered. Let's also have this
functionality in QML as it seems useful there as well

[ChangeLog][QtQuickTest][TestCase] Added failOnWarning() for allowing to
fail a test if a particular warning is output during that test execution

Change-Id: I011ed119c318859a2bccd98f0d491904b10305e5
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
This commit is contained in:
Andrei Golubev 2021-12-02 14:09:44 +01:00
parent e64c04b140
commit ab287508d5
4 changed files with 83 additions and 1 deletions

View File

@ -1178,6 +1178,45 @@ Item {
qtest_results.ignoreWarning(msg)
}
/*!
\qmlmethod TestCase::failOnWarning(message)
\since 6.3
Fails the test if a warning \a message appears during the test run.
Similar to \c{QTest::failOnWarning(message)} in C++.
\a message can be either a string, or a regular expression providing a
pattern of messages. In the latter case, the first encountered message
would fail the test.
For example, the following snippet will fail a test if a warning is
produced:
\qml
failOnWarning("Something bad happened")
\endqml
And the following snippet will fail a test if any warning matching a
pattern is encountered:
\qml
failOnWarning(new RegExp("[0-9]+ bad things happened"))
\endqml
\note Despite being a JavaScript RegExp object, it will not be
interpreted as such; instead, the pattern will be passed to \l
QRegularExpression.
\note ignoreMessage() takes precedence over this function, so any
warnings that match a pattern given to both \c ignoreMessage() and \c
failOnWarning() will be ignored.
\sa warn()
*/
function failOnWarning(msg) {
if (msg === undefined)
msg = ""
qtest_results.failOnWarning(msg)
}
/*!
\qmlmethod TestCase::wait(ms)

View File

@ -645,13 +645,24 @@ void QuickTestResult::ignoreWarning(const QJSValue &message)
{
if (message.isRegExp()) {
#if QT_CONFIG(regularexpression)
QTestLog::ignoreMessage(QtWarningMsg, message.toVariant().toRegularExpression());
QTestLog::ignoreMessage(QtWarningMsg, qjsvalue_cast<QRegularExpression>(message));
#endif
} else {
QTestLog::ignoreMessage(QtWarningMsg, message.toString().toUtf8());
}
}
void QuickTestResult::failOnWarning(const QJSValue &message)
{
if (message.isRegExp()) {
#if QT_CONFIG(regularexpression)
QTestLog::failOnWarning(qjsvalue_cast<QRegularExpression>(message));
#endif
} else {
QTestLog::failOnWarning(message.toString().toUtf8());
}
}
void QuickTestResult::wait(int ms)
{
QTest::qWait(ms);

View File

@ -143,6 +143,7 @@ public Q_SLOTS:
void warn(const QString &message, const QUrl &location, int line);
void ignoreWarning(const QJSValue &message);
void failOnWarning(const QJSValue &message);
void wait(int ms);
void sleep(int ms);

View File

@ -76,6 +76,10 @@ TestCase {
function stringify(str) {
return str;
}
function failOnWarning(msg) {
failmsg = msg; // use failmsg property for simplicity
}
}
TestCase {
@ -309,4 +313,31 @@ TestCase {
function test_blacklistWithData(row) {
verify(row.success)
}
function test_failOnWarning() {
compare(functions.failmsg, "invalid") // Checks that init() was run
failOnWarning("Warning that will never appear") // shouldn't fail the test
// without going to C++ or QTestLog introspection, we can kind of only
// make sure that TestCase does correct job by duck-typing TestResult
testCase.failOnWarning(undefined)
compare(functions.failmsg, "")
testCase.failOnWarning("foobar")
compare(functions.failmsg, "foobar")
// one case that is actually testable is whether ignoreWarning()
// suppresses the failure of failOnWarning()
var pattern = new RegExp("This warning has to happen")
var string = "And this one too!"
failOnWarning(pattern)
ignoreWarning(pattern)
console.warn("This warning has to happen!!")
failOnWarning(string)
ignoreWarning(string)
console.warn(string)
}
}