Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
tst_qmltc_examples.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
3
4// Note: this file is published under a license that is different from a default
5// test sources license. This is intentional to comply with default
6// snippet license.
7
8#include <QtTest/qtest.h>
9#include <QtCore/qstring.h>
10#include <QtCore/qtimer.h>
11#include <QtGui/qguiapplication.h>
12#include <QtQuick/qquickwindow.h>
13
14//! [qqmlcomponent-include]
15#include <QtQml/qqmlcomponent.h>
16//! [qqmlcomponent-include]
17
18//! [qmltc-include]
19#include "myapp.h" // include generated C++ header
20//! [qmltc-include]
21
22#include <algorithm>
23
25{
26 Q_OBJECT
27
28 static constexpr int m_argc = 1;
29 static constexpr char *m_argv[] = { const_cast<char *>("tst_qmltc_examples") };
30
31public:
32 tst_qmltc_examples(QObject *parent = nullptr) : QObject(parent) { }
33
34private slots:
35 void app();
36 void appComponent();
37
38 void helloWorld();
39};
40
41#define CREATE_DUMMY_ARGC_ARGV()
42 int argc = 1;
43 char *argv[] = { const_cast<char *>("tst_qmltc_examples") };
44
45void tst_qmltc_examples::app()
46{
48
49 //! [qmltc-app-code]
50 QGuiApplication app(argc, argv);
51 app.setApplicationDisplayName(QStringLiteral("This example is powered by qmltc!"));
52
53 QQmlEngine e;
54 // If the root element is Window, you don't need to create a Window.
55 // The snippet is for the cases where the root element is not a Window.
56 QQuickWindow window;
57
58 QScopedPointer<QmltcExample::myApp> documentRoot(
59 new QmltcExample::myApp(&e, nullptr, [](auto& component){
60 component.setWidth(800);
61 }));
62
63 documentRoot->setParentItem(window.contentItem());
64 window.setHeight(documentRoot->height());
65 window.setWidth(documentRoot->width());
66 // ...
67 //! [qmltc-app-code]
68
69 QTimer::singleShot(1000, &app, QGuiApplication::quit);
70
71 //! [qmltc-app-exec]
72 window.show();
73 app.exec();
74 //! [qmltc-app-exec]
75}
76
77void tst_qmltc_examples::appComponent()
78{
80
81 //! [qqmlcomponent-app-code-0]
82 QGuiApplication app(argc, argv);
83 app.setApplicationDisplayName(QStringLiteral("This example is powered by QQmlComponent :("));
84
85 QQmlEngine e;
86 // If the root element is Window, you don't need to create a Window.
87 // The snippet is for the cases where the root element is not a Window.
88 QQuickWindow window;
89
90 QQmlComponent component(&e);
91 component.loadUrl(
92 QUrl(QStringLiteral("qrc:/qt/qml/QmltcExample/myApp.qml")));
93 //! [qqmlcomponent-app-code-0]
94
95 QVERIFY2(!component.isError(), qPrintable(component.errorString()));
96
97 //! [qqmlcomponent-app-code-1]
98 QScopedPointer<QObject> documentRoot(component.create());
99 QQuickItem *documentRootItem = qobject_cast<QQuickItem *>(documentRoot.get());
100 //! [qqmlcomponent-app-code-1]
101
102 QVERIFY(documentRootItem);
103
104 //! [qqmlcomponent-app-code-2]
105 documentRootItem->setParentItem(window.contentItem());
106 window.setHeight(documentRootItem->height());
107 window.setWidth(documentRootItem->width());
108 // ...
109 //! [qqmlcomponent-app-code-2]
110
111 QTimer::singleShot(1000, &app, QGuiApplication::quit);
112
113 window.show();
114 app.exec();
115}
116
117#if !defined(QMLTC_TESTS_SOURCE_DIR) || !defined(QMLTC_TESTS_BINARY_DIR)
118# error "Tests assume that QMLTC_TESTS_{SOURCE,BINARY}_DIR are specified (through CMake)"
119#endif
120
121// Note: QtTest macros need to be in void-returning function, so use output arg.
122template<typename Predicate>
123void readFileContent(QStringList *content, const QString &url, Predicate filter)
124{
125 QVERIFY(content);
126
127 QFile file(url);
128 QVERIFY(file.exists());
129 QVERIFY(file.open(QIODeviceBase::ReadOnly | QIODeviceBase::Text));
130
131 QTextStream stream(&file);
132 while (!stream.atEnd()) {
133 QString line = stream.readLine();
134 if (filter(line))
135 content->append(std::move(line));
136 }
137}
138
139void tst_qmltc_examples::helloWorld()
140{
141#ifdef Q_OS_ANDROID
142 QSKIP("expected C++ files are not bundled with Android tests.");
143#endif
144 QStringList generatedCode;
145 readFileContent(&generatedCode,
146 QStringLiteral(QMLTC_TESTS_BINARY_DIR)
147 + u"/.qmltc/tst_qmltc_examples/helloworld.h",
148 [](const QString &) { return true; });
149 if (QTest::currentTestFailed())
150 QFAIL("Reading _generated_ C++ content for special/HelloWorld.qml failed");
151
152 QStringList documentationCode;
153 const auto filterDocumentationLines = [encounteredStart = false](QStringView line) mutable {
154 if (line.startsWith(u"// MAGIC_QMLTC_TEST_DELIMITER_LINE")) {
155 encounteredStart = true;
156 return false; // we don't need this specific line
157 }
158 if (!encounteredStart)
159 return false;
160 line = line.trimmed();
161 return !line.isEmpty() && !line.startsWith(u"//");
162 };
163 readFileContent(&documentationCode,
164 QStringLiteral(QMLTC_TESTS_SOURCE_DIR) + u"/special/HelloWorld.qml.cpp",
165 filterDocumentationLines);
166 if (QTest::currentTestFailed())
167 QFAIL("Reading special/HelloWorld.qml.cpp failed");
168
169 QVERIFY(!generatedCode.isEmpty());
170 QVERIFY(!documentationCode.isEmpty());
171
172 auto begin = generatedCode.cbegin();
173 for (const QString &existingString : std::as_const(documentationCode)) {
174 auto pos = std::find(begin, generatedCode.cend(), existingString);
175 QVERIFY2(pos != generatedCode.cend(), qPrintable(u"Could not find: " + existingString));
176 begin = std::next(pos);
177 }
178}
179
180#undef CREATE_DUMMY_ARGC_ARGV
181
182QTEST_APPLESS_MAIN(tst_qmltc_examples)
183#include "tst_qmltc_examples.moc"
[qqmlcomponent-include]
tst_qmltc_examples(QObject *parent=nullptr)
void readFileContent(QStringList *content, const QString &url, Predicate filter)
#define CREATE_DUMMY_ARGC_ARGV()