aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp
blob: 8c2706531b2155badbd6a4ff62b8dbb39624724e (plain)
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
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

// Note: this file is published under a license that is different from a default
//       test sources license. This is intentional to comply with default
//       snippet license.

#include <QtTest/qtest.h>
#include <QtCore/qstring.h>
#include <QtCore/qtimer.h>
#include <QtGui/qguiapplication.h>
#include <QtQuick/qquickwindow.h>

//! [qqmlcomponent-include]
#include <QtQml/qqmlcomponent.h>
//! [qqmlcomponent-include]

//! [qmltc-include]
#include "myapp.h" // include generated C++ header
//! [qmltc-include]

#include <algorithm>

class tst_qmltc_examples : public QObject
{
    Q_OBJECT

    static constexpr int m_argc = 1;
    static constexpr char *m_argv[] = { const_cast<char *>("tst_qmltc_examples") };

public:
    tst_qmltc_examples(QObject *parent = nullptr) : QObject(parent) { }

private slots:
    void app();
    void appComponent();

    void helloWorld();
};

#define CREATE_DUMMY_ARGC_ARGV() \
    int argc = 1; \
    char *argv[] = { const_cast<char *>("tst_qmltc_examples") };

void tst_qmltc_examples::app()
{
    CREATE_DUMMY_ARGC_ARGV()

    //! [qmltc-app-code]
    QGuiApplication app(argc, argv);
    app.setApplicationDisplayName(QStringLiteral("This example is powered by qmltc!"));

    QQmlEngine e;
    QQuickWindow window;

    QScopedPointer<QmltcExample::myApp> documentRoot(
        new QmltcExample::myApp(&e, nullptr, [](auto& component){
            component.setWidth(800);
    }));

    documentRoot->setParentItem(window.contentItem());
    window.setHeight(documentRoot->height());
    window.setWidth(documentRoot->width());
    // ...
    //! [qmltc-app-code]

    QTimer::singleShot(1000, &app, QGuiApplication::quit);

    //! [qmltc-app-exec]
    window.show();
    app.exec();
    //! [qmltc-app-exec]
}

void tst_qmltc_examples::appComponent()
{
    CREATE_DUMMY_ARGC_ARGV()

    //! [qqmlcomponent-app-code-0]
    QGuiApplication app(argc, argv);
    app.setApplicationDisplayName(QStringLiteral("This example is powered by QQmlComponent :("));

    QQmlEngine e;
    QQuickWindow window;

    QQmlComponent component(&e);
    component.loadUrl(
                QUrl(QStringLiteral("qrc:/qt/qml/QmltcExample/myApp.qml")));
    //! [qqmlcomponent-app-code-0]

    QVERIFY2(!component.isError(), qPrintable(component.errorString()));

    //! [qqmlcomponent-app-code-1]
    QScopedPointer<QObject> documentRoot(component.create());
    QQuickItem *documentRootItem = qobject_cast<QQuickItem *>(documentRoot.get());
    //! [qqmlcomponent-app-code-1]

    QVERIFY(documentRootItem);

    //! [qqmlcomponent-app-code-2]
    documentRootItem->setParentItem(window.contentItem());
    window.setHeight(documentRootItem->height());
    window.setWidth(documentRootItem->width());
    // ...
    //! [qqmlcomponent-app-code-2]

    QTimer::singleShot(1000, &app, QGuiApplication::quit);

    window.show();
    app.exec();
}

#if !defined(QMLTC_TESTS_SOURCE_DIR) || !defined(QMLTC_TESTS_BINARY_DIR)
#    error "Tests assume that QMLTC_TESTS_{SOURCE,BINARY}_DIR are specified (through CMake)"
#endif

// Note: QtTest macros need to be in void-returning function, so use output arg.
template<typename Predicate>
void readFileContent(QStringList *content, const QString &url, Predicate filter)
{
    QVERIFY(content);

    QFile file(url);
    QVERIFY(file.exists());
    QVERIFY(file.open(QIODeviceBase::ReadOnly | QIODeviceBase::Text));

    QTextStream stream(&file);
    while (!stream.atEnd()) {
        QString line = stream.readLine();
        if (filter(line))
            content->append(std::move(line));
    }
}

void tst_qmltc_examples::helloWorld()
{
#ifdef Q_OS_ANDROID
    QSKIP("expected C++ files are not bundled with Android tests.");
#endif
    QStringList generatedCode;
    readFileContent(&generatedCode,
                    QStringLiteral(QMLTC_TESTS_BINARY_DIR)
                            + u"/.qmltc/tst_qmltc_examples/helloworld.h",
                    [](const QString &) { return true; });
    if (QTest::currentTestFailed())
        QFAIL("Reading _generated_ C++ content for special/HelloWorld.qml failed");

    QStringList documentationCode;
    const auto filterDocumentationLines = [encounteredStart = false](QStringView line) mutable {
        if (line.startsWith(u"// MAGIC_QMLTC_TEST_DELIMITER_LINE")) {
            encounteredStart = true;
            return false; // we don't need this specific line
        }
        if (!encounteredStart)
            return false;
        line = line.trimmed();
        return !line.isEmpty() && !line.startsWith(u"//");
    };
    readFileContent(&documentationCode,
                    QStringLiteral(QMLTC_TESTS_SOURCE_DIR) + u"/special/HelloWorld.qml.cpp",
                    filterDocumentationLines);
    if (QTest::currentTestFailed())
        QFAIL("Reading special/HelloWorld.qml.cpp failed");

    QVERIFY(!generatedCode.isEmpty());
    QVERIFY(!documentationCode.isEmpty());

    auto begin = generatedCode.cbegin();
    for (const QString &existingString : std::as_const(documentationCode)) {
        auto pos = std::find(begin, generatedCode.cend(), existingString);
        QVERIFY2(pos != generatedCode.cend(), qPrintable(u"Could not find: " + existingString));
        begin = std::next(pos);
    }
}

#undef CREATE_DUMMY_ARGC_ARGV

QTEST_APPLESS_MAIN(tst_qmltc_examples)
#include "tst_qmltc_examples.moc"