110 lines
4.8 KiB
C++
110 lines
4.8 KiB
C++
// Дымовой тест главного окна: Main.qml поднимается так же, как в main.cpp,
|
|
// без единого предупреждения QML, и ни одного запроса в настоящую сеть.
|
|
// Ловит то, что не видно компилятору: опечатки в именах свойств и ключах Loc.t,
|
|
// сломанные биндинги, несуществующие картинки в ресурсах.
|
|
|
|
#include "testenv.h"
|
|
#include "fakeinternet.h"
|
|
#include "fixtures.h"
|
|
|
|
#include "launcherpaths.h"
|
|
#include "localization.h"
|
|
|
|
#include <QGuiApplication>
|
|
#include <QQmlApplicationEngine>
|
|
#include <QQuickStyle>
|
|
#include <QQuickWindow>
|
|
#include <QtQml/qqmlextensionplugin.h>
|
|
|
|
Q_IMPORT_QML_PLUGIN(BiLauncherPlugin)
|
|
|
|
namespace {
|
|
|
|
QStringList g_problems;
|
|
QtMessageHandler g_previous = nullptr;
|
|
|
|
void collect(QtMsgType type, const QMessageLogContext &context, const QString &message)
|
|
{
|
|
// Предупреждения QML приходят с файлом qrc:/… или с категорией qt.qml.*.
|
|
const QString file = QString::fromUtf8(context.file ? context.file : "");
|
|
const QString category = QString::fromUtf8(context.category ? context.category : "");
|
|
const bool fromQml = file.startsWith(QLatin1String("qrc:")) || file.endsWith(QLatin1String(".qml"))
|
|
|| category.startsWith(QLatin1String("qt.qml"))
|
|
|| message.contains(QLatin1String(".qml:"));
|
|
if (type != QtDebugMsg && type != QtInfoMsg && fromQml)
|
|
g_problems << message;
|
|
if (g_previous)
|
|
g_previous(type, context, message);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
class TestQmlSmoke : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
FakeInternet m_net;
|
|
|
|
private slots:
|
|
void initTestCase()
|
|
{
|
|
QString error;
|
|
if (m_net.start(&error))
|
|
m_net.setFallback(FakeResponse::error(503));
|
|
const QString game = TestEnv::freshDir(QStringLiteral("game"));
|
|
Fixtures::writeJson(LauncherPaths::settingsFile(), QJsonObject{{"gameDir", game}, {"language", "en"}});
|
|
QQuickStyle::setStyle(QStringLiteral("Basic"));
|
|
g_previous = qInstallMessageHandler(collect);
|
|
}
|
|
|
|
void cleanupTestCase() { qInstallMessageHandler(g_previous); }
|
|
|
|
void init() { g_problems.clear(); }
|
|
|
|
void mainWindowLoadsCleanly()
|
|
{
|
|
// Один движок на весь тест, как в приложении: Localization держит указатель
|
|
// на JS-движок, создавший синглтон, и второй QQmlApplicationEngine после
|
|
// уничтожения первого оставил бы его висячим.
|
|
QQmlApplicationEngine engine;
|
|
QStringList warnings;
|
|
connect(&engine, &QQmlEngine::warnings, this, [&](const QList<QQmlError> &list) {
|
|
for (const QQmlError &e : list)
|
|
warnings << e.toString();
|
|
});
|
|
engine.loadFromModule("BiLauncher", "Main");
|
|
QCOMPARE(engine.rootObjects().size(), 1);
|
|
auto *window = qobject_cast<QQuickWindow *>(engine.rootObjects().constFirst());
|
|
QVERIFY(window);
|
|
QVERIFY(QTest::qWaitForWindowExposed(window));
|
|
|
|
// Даём отработать отложенным таймерам, загрузке каталогов и анимациям.
|
|
QTest::qWait(2500);
|
|
QVERIFY2(warnings.isEmpty(), qPrintable(warnings.join(u'\n')));
|
|
QVERIFY2(g_problems.isEmpty(), qPrintable(g_problems.join(u'\n')));
|
|
|
|
// Смена языка на лету перестраивает Loc.t — биндинги не должны ломаться.
|
|
const QString titleEn = window->title();
|
|
Localization::instance().setLanguage(QStringLiteral("ru"));
|
|
QTest::qWait(500);
|
|
Localization::instance().setLanguage(QStringLiteral("en"));
|
|
QTest::qWait(300);
|
|
QCOMPARE(window->title(), titleEn);
|
|
QVERIFY2(warnings.isEmpty(), qPrintable(warnings.join(u'\n')));
|
|
QVERIFY2(g_problems.isEmpty(), qPrintable(g_problems.join(u'\n')));
|
|
|
|
// Наружу — только через FakeInternet, и только на известные адреса лаунчера.
|
|
static const QStringList known{"mojang.com", "galeonworx.com", "adoptium.net", "fabricmc.net",
|
|
"quiltmc.org", "minecraftforge.net", "neoforged.net"};
|
|
for (const QString &url : m_net.requestedUrls()) {
|
|
const QString host = QUrl(url).host();
|
|
const bool ok = std::any_of(known.cbegin(), known.cend(),
|
|
[&](const QString &domain) { return host.endsWith(domain); });
|
|
QVERIFY2(ok, qPrintable("неожиданный запрос: " + url));
|
|
}
|
|
}
|
|
};
|
|
|
|
BILAUNCHER_GUI_TEST_MAIN(TestQmlSmoke)
|
|
#include "tst_qml_smoke.moc"
|