Long live QVERIFY_THROWS_EXCEPTION!
Use variable args macros to swallow any extra commas in the expression. To use this, the type of the exception has to be first. Use Eddy's suggestion for a new name to avoid breaking the old macro. [ChangeLog][QtTest] Added QVERIFY_THROWS_EXCEPTION, replacing QVERIFY_EXCEPTION_THROWN, which has therefore been deprecated. Change-Id: I16825c35bae0631c5fad5a9a3ace4d6edc067f83 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
parent
b9be035c62
commit
1edf153a6b
@ -93,11 +93,21 @@ do {\
|
||||
|
||||
#ifndef QT_NO_EXCEPTIONS
|
||||
|
||||
#if QT_DEPRECATED_SINCE(6, 3)
|
||||
namespace QTest {
|
||||
QT_DEPRECATED_VERSION_X_6_3("Don't use QVERIFY_EXCEPTION_THROWN(expr, type) anymore, "
|
||||
"use QVERIFY_THROWS_EXCEPTION(type, expr...) instead")
|
||||
inline void useVerifyThrowsException() {}
|
||||
} // namespace QTest
|
||||
# define QVERIFY_EXCEPTION_THROWN(expression, exceptiontype) \
|
||||
QVERIFY_THROWS_EXCEPTION(exceptiontype, QTest::useVerifyThrowsException(); expression)
|
||||
#endif
|
||||
|
||||
# define QVERIFY_THROWS_EXCEPTION(exceptiontype, ...) \
|
||||
do {\
|
||||
QT_TRY {\
|
||||
QT_TRY {\
|
||||
expression;\
|
||||
__VA_ARGS__;\
|
||||
QTest::qFail("Expected exception of type " #exceptiontype " to be thrown" \
|
||||
" but no exception caught", __FILE__, __LINE__);\
|
||||
return;\
|
||||
@ -125,7 +135,7 @@ do {\
|
||||
* So, users must use Qt with exception support enabled if they use exceptions
|
||||
* in their code.
|
||||
*/
|
||||
# define QVERIFY_EXCEPTION_THROWN(expression, exceptiontype) \
|
||||
# define QVERIFY_THROWS_EXCEPTION(...) \
|
||||
static_assert(false, "Support of exceptions is disabled")
|
||||
|
||||
#endif // !QT_NO_EXCEPTIONS
|
||||
|
@ -158,17 +158,23 @@
|
||||
\since 5.3
|
||||
|
||||
\relates QTest
|
||||
\deprecated [6.3] Use \c{QVERIFY_THROWS_EXCEPTION(exceptiontype, expression)} instead.
|
||||
*/
|
||||
|
||||
The QVERIFY_EXCEPTION_THROWN macro executes \a expression
|
||||
and tries to catch an exception thrown from \a expression.
|
||||
/*!
|
||||
\macro QVERIFY_THROWS_EXCEPTION(exceptiontype, ...)
|
||||
\since 6.3
|
||||
|
||||
The QVERIFY_THROWS_EXCEPTION macro executes the expression given in the variadic
|
||||
argument and expects to catch an exception thrown from the expression.
|
||||
|
||||
There are several possible outcomes:
|
||||
|
||||
\list
|
||||
\li If \a expression throws an exception that is either the same as
|
||||
\li If the expression throws an exception that is either the same as
|
||||
\a exceptiontype or derived from \a exceptiontype, then execution will continue.
|
||||
|
||||
\li Otherwise, if \a expression throws no exception, or the
|
||||
\li Otherwise, if the expression throws no exception, or the
|
||||
exception thrown derives from \c{std::exception}, then a failure
|
||||
will be recorded in the test log and the macro returns early
|
||||
(from enclosing function).
|
||||
@ -178,6 +184,16 @@
|
||||
re-thrown. This avoids problems with e.g. pthread cancellation exceptions.
|
||||
\endlist
|
||||
|
||||
The macro uses variadic arguments so the expression can contain commas that the
|
||||
preprocessor considers argument separators, e.g. as in
|
||||
\code
|
||||
QVERIFY_THROWS_EXCEPTION(std::bad_alloc,
|
||||
// macro arguments: ^ exceptiontype
|
||||
std::vector<std::pair<int, long>>{42'000'000'000, {42, 42L}});
|
||||
// macro arguments: \---------- 1 ----------/ \-------- 2 --------/ \3/ \ 4 /
|
||||
// \----------------------- expression -----------------------/
|
||||
\endcode
|
||||
|
||||
\note This macro can only be used in a test function that is invoked
|
||||
by the test framework.
|
||||
*/
|
||||
|
@ -1584,7 +1584,7 @@ void tst_QThread::create()
|
||||
const auto &function = [](const ThrowWhenCopying &){};
|
||||
QScopedPointer<QThread> thread;
|
||||
ThrowWhenCopying t;
|
||||
QVERIFY_EXCEPTION_THROWN(thread.reset(QThread::create(function, t)), ThreadException);
|
||||
QVERIFY_THROWS_EXCEPTION(ThreadException, thread.reset(QThread::create(function, t)));
|
||||
QVERIFY(!thread);
|
||||
}
|
||||
#endif // QT_NO_EXCEPTIONS
|
||||
|
@ -2688,7 +2688,7 @@ void tst_QSharedPointer::constructorThrow()
|
||||
int childDestructorCounter = ThrowData::childDestructorCounter;
|
||||
|
||||
QSharedPointer<ThrowData> ptr;
|
||||
QVERIFY_EXCEPTION_THROWN(ptr = QSharedPointer<ThrowData>::create(), QString);
|
||||
QVERIFY_THROWS_EXCEPTION(QString, ptr = QSharedPointer<ThrowData>::create());
|
||||
QVERIFY(ptr.isNull());
|
||||
QCOMPARE(ThrowData::childGenerationCounter, childGeneration + 1);
|
||||
// destructor should never be called, if a constructor throws
|
||||
|
@ -81,67 +81,105 @@ private slots:
|
||||
|
||||
void tst_VerifyExceptionThrown::testCorrectStdTypes() const
|
||||
{
|
||||
QVERIFY_THROWS_EXCEPTION(int, throw int(5));
|
||||
QVERIFY_THROWS_EXCEPTION(float, throw float(9.8));
|
||||
QVERIFY_THROWS_EXCEPTION(bool, throw bool(true));
|
||||
QVERIFY_THROWS_EXCEPTION(std::string, throw std::string("some string"));
|
||||
#if QT_DEPRECATED_SINCE(6, 3)
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
QVERIFY_EXCEPTION_THROWN(throw int(5), int);
|
||||
QVERIFY_EXCEPTION_THROWN(throw float(9.8), float);
|
||||
QVERIFY_EXCEPTION_THROWN(throw bool(true), bool);
|
||||
QVERIFY_EXCEPTION_THROWN(throw std::string("some string"), std::string);
|
||||
QT_WARNING_POP
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_VerifyExceptionThrown::testCorrectStdExceptions() const
|
||||
{
|
||||
// same type
|
||||
QVERIFY_THROWS_EXCEPTION(std::exception, throw std::exception());
|
||||
QVERIFY_THROWS_EXCEPTION(std::runtime_error, throw std::runtime_error("runtime error"));
|
||||
QVERIFY_THROWS_EXCEPTION(std::overflow_error, throw std::overflow_error("overflow error"));
|
||||
#if QT_DEPRECATED_SINCE(6, 3)
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
QVERIFY_EXCEPTION_THROWN(throw std::exception(), std::exception);
|
||||
QVERIFY_EXCEPTION_THROWN(throw std::runtime_error("runtime error"), std::runtime_error);
|
||||
QVERIFY_EXCEPTION_THROWN(throw std::overflow_error("overflow error"), std::overflow_error);
|
||||
QT_WARNING_POP
|
||||
#endif
|
||||
|
||||
// inheritance
|
||||
QVERIFY_THROWS_EXCEPTION(std::runtime_error, throw std::overflow_error("overflow error"));
|
||||
QVERIFY_THROWS_EXCEPTION(std::exception, throw std::overflow_error("overflow error"));
|
||||
#if QT_DEPRECATED_SINCE(6, 3)
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
QVERIFY_EXCEPTION_THROWN(throw std::overflow_error("overflow error"), std::runtime_error);
|
||||
QVERIFY_EXCEPTION_THROWN(throw std::overflow_error("overflow error"), std::exception);
|
||||
QT_WARNING_POP
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_VerifyExceptionThrown::testCorrectMyExceptions() const
|
||||
{
|
||||
// same type
|
||||
QVERIFY_THROWS_EXCEPTION(MyBaseException, throw MyBaseException());
|
||||
QVERIFY_THROWS_EXCEPTION(MyDerivedException, throw MyDerivedException());
|
||||
#if QT_DEPRECATED_SINCE(6, 3)
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
QVERIFY_EXCEPTION_THROWN(throw MyBaseException(), MyBaseException);
|
||||
QVERIFY_EXCEPTION_THROWN(throw MyDerivedException(), MyDerivedException);
|
||||
QT_WARNING_POP
|
||||
#endif
|
||||
|
||||
// inheritance
|
||||
QVERIFY_THROWS_EXCEPTION(MyBaseException, throw MyDerivedException());
|
||||
QVERIFY_THROWS_EXCEPTION(std::domain_error, throw MyDerivedException());
|
||||
#if QT_DEPRECATED_SINCE(6, 3)
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
QVERIFY_EXCEPTION_THROWN(throw MyDerivedException(), MyBaseException);
|
||||
QVERIFY_EXCEPTION_THROWN(throw MyDerivedException(), std::domain_error);
|
||||
QT_WARNING_POP
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_VerifyExceptionThrown::testFailInt() const
|
||||
{
|
||||
try {
|
||||
QVERIFY_EXCEPTION_THROWN(throw int(5), double);
|
||||
QVERIFY_THROWS_EXCEPTION(double, throw int(5));
|
||||
} catch (int) {}
|
||||
}
|
||||
|
||||
void tst_VerifyExceptionThrown::testFailStdString() const
|
||||
{
|
||||
try {
|
||||
QVERIFY_EXCEPTION_THROWN(throw std::string("some string"), char*);
|
||||
QVERIFY_THROWS_EXCEPTION(char*, throw std::string("some string"));
|
||||
} catch (const std::string &) {}
|
||||
}
|
||||
|
||||
void tst_VerifyExceptionThrown::testFailStdRuntimeError() const
|
||||
{
|
||||
QVERIFY_EXCEPTION_THROWN(throw std::logic_error("logic error"), std::runtime_error);
|
||||
QVERIFY_THROWS_EXCEPTION(std::runtime_error, throw std::logic_error("logic error"));
|
||||
}
|
||||
|
||||
void tst_VerifyExceptionThrown::testFailMyException() const
|
||||
{
|
||||
QVERIFY_EXCEPTION_THROWN(throw std::logic_error("logic error"), MyBaseException);
|
||||
QVERIFY_THROWS_EXCEPTION(MyBaseException, throw std::logic_error("logic error"));
|
||||
}
|
||||
|
||||
void tst_VerifyExceptionThrown::testFailMyDerivedException() const
|
||||
{
|
||||
QVERIFY_EXCEPTION_THROWN(throw MyDerivedException(), std::runtime_error);
|
||||
QVERIFY_THROWS_EXCEPTION(std::runtime_error, throw MyDerivedException());
|
||||
}
|
||||
|
||||
void tst_VerifyExceptionThrown::testFailNoException() const
|
||||
{
|
||||
QVERIFY_EXCEPTION_THROWN(doSomething(), std::exception);
|
||||
QVERIFY_THROWS_EXCEPTION(std::exception, doSomething());
|
||||
}
|
||||
|
||||
#endif // !QT_NO_EXCEPTIONS
|
||||
|
Loading…
Reference in New Issue
Block a user