1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef QQMLTESTUTILS_P_H
#define QQMLTESTUTILS_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/QTemporaryDir>
#include <QtCore/QDir>
#include <QtCore/QUrl>
#include <QtCore/QCoreApplication>
#include <QtCore/QStringList>
#include <QtTest/QTest>
#include <QtCore/private/qglobal_p.h>
#include <private/qqmljsgrammar_p.h>
QT_BEGIN_NAMESPACE
/* Base class for tests with data that are located in a "data" subfolder. */
class QQmlDataTest : public QObject
{
Q_OBJECT
public:
enum class FailOnWarningsPolicy {
DoNotFailOnWarnings,
FailOnWarnings
};
QQmlDataTest(
const char *qmlTestDataDir,
FailOnWarningsPolicy failOnWarningsPolicy = FailOnWarningsPolicy::DoNotFailOnWarnings,
const char *dataSubdir = "data");
virtual ~QQmlDataTest();
QString testFile(const QString &fileName) const;
inline QString testFile(const char *fileName) const
{ return testFile(QLatin1String(fileName)); }
inline QUrl testFileUrl(const QString &fileName) const
{
const QString fn = testFile(fileName);
return fn.startsWith(QLatin1Char(':'))
? QUrl(QLatin1String("qrc") + fn)
: QUrl::fromLocalFile(fn);
}
inline QUrl testFileUrl(const char *fileName) const
{ return testFileUrl(QLatin1String(fileName)); }
inline QString dataDirectory() const { return m_dataDirectory; }
inline QUrl dataDirectoryUrl() const { return m_dataDirectoryUrl; }
inline QString directory() const { return m_directory; }
static inline QQmlDataTest *instance() { return m_instance; }
bool canImportModule(const QString &importTestQmlSource) const;
public Q_SLOTS:
virtual void initTestCase();
virtual void init();
private:
static QQmlDataTest *m_instance;
// The directory in which to search for m_dataSubDir.
const char *m_qmlTestDataDir = nullptr;
// The subdirectory containing the actual data. Typically "data"
const char *m_dataSubDir = nullptr;
// The path to m_dataSubDir, if found.
const QString m_dataDirectory;
const QUrl m_dataDirectoryUrl;
QTemporaryDir m_cacheDir;
QString m_directory;
bool m_usesOwnCacheDir = false;
FailOnWarningsPolicy m_failOnWarningsPolicy = FailOnWarningsPolicy::DoNotFailOnWarnings;
};
class QQmlTestMessageHandler
{
Q_DISABLE_COPY(QQmlTestMessageHandler)
public:
QQmlTestMessageHandler();
~QQmlTestMessageHandler();
const QStringList &messages() const { return m_messages; }
const QString messageString() const { return m_messages.join(QLatin1Char('\n')); }
void clear() { m_messages.clear(); }
void setIncludeCategoriesEnabled(bool enabled) { m_includeCategories = enabled; }
private:
static void messageHandler(QtMsgType, const QMessageLogContext &context, const QString &message);
static QQmlTestMessageHandler *m_instance;
QStringList m_messages;
QtMessageHandler m_oldHandler;
bool m_includeCategories;
};
class QQmlEngine;
namespace QV4 {
struct ExecutionEngine;
}
enum class GCFlags {
None = 0,
DontSendPostedEvents = 1
};
bool gcDone(const QV4::ExecutionEngine *engine);
void gc(QV4::ExecutionEngine &engine, GCFlags flags = GCFlags::None);
bool gcDone(QQmlEngine *engine);
void gc(QQmlEngine &engine, GCFlags flags = GCFlags::None);
namespace Syntax {
using Token = QQmlJSGrammar::VariousConstants;
// TODO(QTBUG-138020)
constexpr auto spellFor(Token token) -> QLatin1StringView
{
switch (token) {
case Token::T_COLON:
return QLatin1StringView(":");
case Token::T_LBRACE:
return QLatin1StringView("{");
case Token::T_RBRACE:
return QLatin1StringView("}");
case Token::T_VAR:
return QLatin1StringView("var");
case Token::T_PROPERTY:
return QLatin1StringView("property");
case Token::T_DEFAULT:
return QLatin1StringView("default");
case Token::T_READONLY:
return QLatin1StringView("readonly");
case Token::T_REQUIRED:
return QLatin1StringView("required");
case Token::T_FINAL:
return QLatin1StringView("final");
case Token::T_VIRTUAL:
return QLatin1StringView("virtual");
case Token::T_OVERRIDE:
return QLatin1StringView("override");
default:
break;
}
Q_UNREACHABLE_RETURN({});
}
using Word = std::variant<Token, QLatin1StringView>;
auto stringView(const Word &word) -> QLatin1StringView;
using Phrase = QList<Word>;
auto toString(const Phrase &phrase) -> QString;
// comfort
auto operator+(const Word &word, const Phrase &phrase) -> Phrase;
auto operator+(const Word &word1, const Word &word2) -> Phrase;
// if such declaration generating functions start to grow it might be worth creating a dedicated
// more optimized generator
// can probably be generalized later to accept QList<Phrase> if needed
auto objectDeclaration(Phrase &&objectMember = {},
QLatin1StringView objName = QLatin1StringView("QtObject")) -> Phrase;
} // namespace Syntax
QT_END_NAMESPACE
#endif // QQMLTESTUTILS_P_H
|