6#include <QtTest/qtestsystem.h>
9#include <QtQml/qqmlengine.h>
10#include <QtQml/qqmlcontext.h>
11#include <QtQuick/private/qquickitem_p.h>
12#include <QtQuick/private/qquickwindow_p.h>
13#include <QtQuick/qquickitem.h>
14#include <QtQuick/qquickview.h>
15#include <QtQuick/qquickwindow.h>
16#include <QtQml/qjsvalue.h>
17#include <QtQml/qjsengine.h>
18#include <QtQml/qqmlpropertymap.h>
19#include <QtQuick/private/qquickitem_p.h>
20#include <QtQuick/qquickitem.h>
22#include <QtCore/qurl.h>
23#include <QtCore/qfileinfo.h>
24#include <QtCore/qdir.h>
25#include <QtCore/qdiriterator.h>
26#include <QtCore/qfile.h>
27#include <QtCore/qdebug.h>
28#include <QtCore/qeventloop.h>
29#include <QtCore/qtextstream.h>
30#include <QtCore/qtimer.h>
31#include <QtGui/qtextdocument.h>
33#include <QtGui/QGuiApplication>
34#include <QtCore/QTranslator>
35#include <QtTest/QSignalSpy>
36#include <QtQml/QQmlFileSelector>
38#include <private/qqmlcomponent_p.h>
39#include <private/qv4resolvedtypereference_p.h>
106#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
107#if QT_DEPRECATED_SINCE(6, 4)
171 return s.
mid(1,
s.size() - 2);
189 << errors.
size() <<
" error(s):\n";
192 if (
e.url().isLocalFile()) {
195 str <<
e.url().toString();
198 str <<
':' <<
e.line() <<
',' <<
e.column();
199 str <<
": " <<
e.description() <<
'\n';
205 str <<
"View: " <<
view->metaObject()->className() <<
", ";
206 str <<
"Import paths:\n";
207 const auto importPaths =
engine->importPathList();
208 for (
const QString &
i : importPaths)
211 str <<
" Plugin paths:\n";
212 for (
const QString &
p : pluginPaths)
218 errors.
at(0).url(), errors.
at(0).line());
220 results.finishTestDataCleanup();
244template <
typename... Args>
252 const QMetaObject *setupMetaObject = setupObject->metaObject();
253 const int methodIndex = setupMetaObject->
indexOfMethod(member);
254 if (methodIndex != -1) {
256 method.invoke(setupObject, std::forward<Args>(
args)...);
279 TestCaseEnumerationResult
result = enumerateTestCases(rootCompilationUnit.
data());
280 m_testCases =
result.testCases +
result.finalizedPartialTestCases();
281 m_errors +=
result.errors;
292 struct TestCaseEnumerationResult
298 bool isTestCase =
false;
305 for (
const QString &function : testFunctions)
310 TestCaseEnumerationResult &
operator<<(
const TestCaseEnumerationResult &
other)
312 testCases +=
other.testCases +
other.finalizedPartialTestCases();
313 errors +=
other.errors;
318 TestCaseEnumerationResult enumerateTestCases(
320 const Object *
object =
nullptr)
324 const Import *
import = compilationUnit->importAt(
i);
325 if (compilationUnit->stringAt(import->uriIndex) !=
QLatin1String(
"QtTest"))
329 QString typeQualifier = compilationUnit->stringAt(import->qualifierIndex);
331 testCaseTypeName = typeQualifier %
QLatin1Char(
'.') % testCaseTypeName;
333 testCaseType = compilationUnit->typeNameCache->query(testCaseTypeName).type;
338 TestCaseEnumerationResult
result;
341 object = compilationUnit->objectAt(0);
342 if (
object->hasFlag(Object::IsInlineComponentRoot))
345 if (
const auto superTypeUnit = compilationUnit->resolvedTypes.value(
346 object->inheritedTypeNameIndex)->compilationUnit()) {
348 if (testCaseType.
isValid() && superTypeUnit->url() == testCaseType.
sourceUrl())
350 else if (superTypeUnit->url() != compilationUnit->url()) {
351 result = enumerateTestCases(superTypeUnit);
356 for (
auto binding =
object->bindingsBegin(); binding !=
object->bindingsEnd(); ++binding) {
357 if (compilationUnit->stringAt(binding->propertyNameIndex) ==
QLatin1String(
"name")) {
359 result.testCaseName = compilationUnit->stringAt(binding->stringIndex);
362 error.setUrl(compilationUnit->url());
363 error.setLine(binding->location.line());
364 error.setColumn(binding->location.column());
365 error.setDescription(
QStringLiteral(
"the 'name' property of a TestCase must be a literal string"));
373 auto functionsEnd = compilationUnit->objectFunctionsEnd(
object);
374 for (
auto function = compilationUnit->objectFunctionsBegin(
object);
function != functionsEnd; ++
function) {
382 result.testFunctions << functionName;
387 for (
auto binding =
object->bindingsBegin(); binding !=
object->bindingsEnd(); ++binding) {
389 const Object *
child = compilationUnit->objectAt(binding->value.objectIndex);
390 result << enumerateTestCases(compilationUnit,
child);
425 testArgV[0] = argv[0];
427 while (
index < argc) {
428 if (strcmp(argv[
index],
"-import") == 0 && (
index + 1) < argc) {
431 }
else if (strcmp(argv[
index],
"-plugins") == 0 && (
index + 1) < argc) {
434 }
else if (strcmp(argv[
index],
"-input") == 0 && (
index + 1) < argc) {
437 }
else if (strcmp(argv[
index],
"-opengl") == 0) {
439 }
else if (strcmp(argv[
index],
"-translation") == 0 && (
index + 1) < argc) {
442 }
else if (strcmp(argv[
index],
"-file-selector") == 0 && (
index + 1) < argc) {
446 testArgV[testArgC++] = argv[
index++];
449 testArgV[testArgC] = 0;
458#if QT_CONFIG(translation)
460 if (!translationFile.
isEmpty()) {
461 if (translator.
load(translationFile)) {
470 if (testPath.
isEmpty() && sourceDir) {
476#if defined(Q_OS_ANDROID) || defined(Q_OS_INTEGRITY)
494 if (testPathInfo.
isFile()) {
506 files.append(filePath);
512 if (
files.isEmpty()) {
513 qWarning(
"The file '%s' does not contain any tests files",
521 qWarning(
"'%s' does not have the suffix '.qml' or '.qmltests'.",
qPrintable(testPath));
524 }
else if (testPathInfo.
isDir()) {
530 while (
iter.hasNext())
533 if (
files.isEmpty()) {
534 qWarning(
"The directory '%s' does not contain any test files matching '%s'",
539 qWarning(
"'%s' does not exist under '%s'.",
544 qputenv(
"QT_QTESTLIB_RUNNING",
"1");
547 const bool filteringTestFunctions = !commandLineTestFunctions.
isEmpty();
559 for (
const QString &
path : std::as_const(pluginPaths))
562 if (!fileSelectors.isEmpty()) {
588 if (filteringTestFunctions && !availableTestSet.
intersects(commandLineTestFunctions))
590 commandLineTestFunctions.
subtract(availableTestSet);
600 &eventLoop,
SLOT(quit()));
621 if (
view.size().isEmpty()) {
622 view.resize(200, 200);
629 view.requestActivate();
634 if (
view.isExposed()) {
642 <<
"If the test case was expecting windowShown, it will hang.";
656 if (!commandLineTestFunctions.
isEmpty()) {
657 qWarning() <<
"Could not find the following test functions:";
658 for (
const QString &functionName : std::as_const(commandLineTestFunctions))
660 return commandLineTestFunctions.
size();
669#include "moc_quicktest_p.cpp"
static void processEvents(QEventLoop::ProcessEventsFlags flags=QEventLoop::AllEvents)
Processes some pending events for the calling thread according to the specified flags.
static QCoreApplication * instance() noexcept
Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance.
static bool installTranslator(QTranslator *messageFile)
Adds the translation file translationFile to the list of translation files to be used for translation...
static void sendPostedEvents(QObject *receiver=nullptr, int event_type=0)
Immediately dispatches all events which have been previously queued with QCoreApplication::postEvent(...
The QDirIterator class provides an iterator for directory entrylists.
bool cdUp()
Changes directory by moving one directory up from the QDir's current directory.
QString dirName() const
Returns the name of the directory; this is not the same as the path, e.g.
static QDir current()
Returns the application's current directory.
QString absolutePath() const
Returns the absolute path (a path that starts with "/" or with a drive specification),...
QString filePath(const QString &fileName) const
Returns the path name of a file in the directory.
static QString toNativeSeparators(const QString &pathName)
static QString currentPath()
Returns the absolute path of the application's current directory.
int exec(ProcessEventsFlags flags=AllEvents)
Enters the main event loop and waits until exit() is called.
bool atEnd() const override
Returns true if the end of the file has been reached; otherwise returns false.
void close() override
Calls QFileDevice::flush() and closes the file.
\inmodule QtCore \reentrant
QString baseName() const
Returns the base name of the file without the path.
QString absoluteFilePath() const
Returns an absolute path including the file name.
bool isFile() const
Returns true if this object points to a file or to a symbolic link to a file.
bool isDir() const
Returns true if this object points to a directory or to a symbolic link to a directory.
QDir dir() const
Returns the path of the object's parent directory as a QDir object.
bool exists() const
Returns true if the file exists; otherwise returns false.
bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
bool exists() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
qint64 readLine(char *data, qint64 maxlen)
This function reads a line of ASCII characters from the device, up to a maximum of maxSize - 1 bytes,...
qsizetype size() const noexcept
bool isEmpty() const noexcept
const_reference at(qsizetype i) const noexcept
const_iterator cend() const noexcept
const_iterator cbegin() const noexcept
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
QString objectName
the name of this object
Q_WEAK_OVERLOAD void setObjectName(const QString &name)
Sets the object's name to name.
\inmodule QtCore\reentrant
QQmlRefPointer< QV4::ExecutableCompilationUnit > compilationUnit
static QQmlComponentPrivate * get(QQmlComponent *c)
The QQmlComponent class encapsulates a QML component definition.
void setContextProperty(const QString &, QObject *)
Set the value of the name property on this context.
The QQmlEngine class provides an environment for instantiating QML components.
The QQmlError class encapsulates a QML error.
A class for applying a QFileSelector to QML file loading.
void setExtraSelectors(const QStringList &strings)
Adds extra selectors contained in strings to the current QFileSelector being used.
static QQuickItemPrivate * get(QQuickItem *item)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
The QQuickView class provides a window for displaying a Qt Quick user interface.
QList< QQmlError > errors() const
Return the list of errors that occurred during the last compile or create operation.
Status status
The component's current \l{QQuickView::Status} {status}.
QQmlEngine * engine() const
Returns a pointer to the QQmlEngine used for instantiating QML Components.
QQmlContext * rootContext() const
This function returns the root of the context hierarchy.
void setSource(const QUrl &)
Sets the source to the url, loads the QML component and instantiates it.
static QQuickWindowPrivate * get(QQuickWindow *c)
QVector< QQuickItem * > itemsToPolish
\qmltype Window \instantiates QQuickWindow \inqmlmodule QtQuick
T * data() const noexcept
Returns the value of the pointer referenced by this object.
bool intersects(const QSet< T > &other) const
QSet< T > & subtract(const QSet< T > &other)
constexpr QStringView mid(qsizetype pos, qsizetype n=-1) const noexcept
Returns the substring of length length starting at position start in this object.
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
int compare(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
QString trimmed() const &
QString & prepend(QChar c)
void setWindowShown(bool value)
static QTestRootObject * instance()
void start(int msec)
Starts or restarts the timer with a timeout interval of msec milliseconds.
bool singleShot
whether the timer is a single-shot timer
bool load(const QString &filename, const QString &directory=QString(), const QString &search_delimiters=QString(), const QString &suffix=QString())
Loads filename + suffix (".qm" if the suffix is not specified), which may be an absolute file name or...
static QUrl fromLocalFile(const QString &localfile)
Returns a QUrl representation of localFile, interpreted as a local file.
void show()
Shows the window.
void setTitle(const QString &)
static void setCurrentAppname(const char *appname)
static void setProgramName(const char *name)
static void parseArgs(int argc, char *argv[])
QList< QString > TestCaseList
QList< QQmlError > errors() const
TestCaseList testCases() const
TestCaseCollector(const QFileInfo &fileInfo, QQmlEngine *engine)
QSignalSpy spy(myCustomObject, SIGNAL(mySignal(int, QString, double)))
[0]
Q_QUICK_TEST_EXPORT bool qWaitForPolish(const QQuickItem *item, int timeout=defaultTimeout)
Q_QUICK_TEST_EXPORT bool qIsPolishScheduled(const QQuickItem *item)
Combined button and popup list for selecting options.
Q_GUI_EXPORT bool qWaitForWindowActive(QWindow *window, int timeout=5000)
Q_GUI_EXPORT bool qWaitForWindowExposed(QWindow *window, int timeout=5000)
Q_TESTLIB_EXPORT QStringList testFunctions
Q_CORE_EXPORT void qSleep(int ms)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Q_TESTLIB_EXPORT bool printAvailableFunctions
static bool qWaitFor(Functor predicate, QDeadlineTimer deadline=QDeadlineTimer(std::chrono::seconds{5}))
Q_CORE_EXPORT void qWait(int ms)
This is an overloaded member function, provided for convenience. It differs from the above function o...
@ WindowMinMaxButtonsHint
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter * iter
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
DBusConnection const char DBusError * error
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
#define Q_ARG(Type, data)
GLenum GLenum GLsizei count
GLbitfield GLuint64 timeout
[4]
GLuint GLsizei const GLchar * message
GLsizei const GLchar *const * path
static qreal component(const QPointF &point, unsigned int i)
static QString absolutePath(const QString &path)
#define qUtf8Printable(string)
#define qPrintable(string)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
bool qputenv(const char *varName, QByteArrayView raw)
bool qWaitForSignal(QObject *obj, const char *signal, int timeout)
static QString stripQuotes(const QString &s)
int quick_test_main(int argc, char **argv, const char *name, const char *sourceDir)
static void handleCompileErrors(const QFileInfo &fi, const QList< QQmlError > &errors, QQmlEngine *engine, QQuickView *view=nullptr)
void maybeInvokeSetupMethod(QObject *setupObject, const char *member, Args &&... args)
int quick_test_main_with_setup(int argc, char **argv, const char *name, const char *sourceDir, QObject *setup)
QFileInfo fi("c:/temp/foo")
[newstuff]
const QStringList filters({"Image files (*.png *.xpm *.jpg)", "Text files (*.txt)", "Any files (*)" })
[6]
QApplication app(argc, argv)
[0]
\inmodule QtCore \reentrant