#include "testenv.h" #include "fixtures.h" #include "launcherpaths.h" #include "localization.h" #include #include class TestLocalization : public QObject { Q_OBJECT Localization &loc() { return Localization::instance(); } // Значения каталога напрямую из файла — эталон для сравнения. static QJsonObject catalogEntry(const QString &key) { return Fixtures::readJsonFile(QStringLiteral(BILAUNCHER_SOURCE_DIR "/i18n/translations.json")) .value(QStringLiteral("strings")) .toObject() .value(key) .toObject(); } private slots: void init() { TestEnv::resetLauncherRoot(); loc().setLanguage(QStringLiteral("en")); } void textFollowsLanguage() { const QJsonObject entry = catalogEntry(QStringLiteral("app.tooltip.openMods")); QCOMPARE(Loc::text("app.tooltip.openMods"), entry.value("en").toString()); QSignalSpy spy(&loc(), &Localization::languageChanged); loc().setLanguage(QStringLiteral("ru")); QCOMPARE(spy.count(), 1); QCOMPARE(loc().language(), QStringLiteral("ru")); QCOMPARE(loc().resolvedLanguage(), QStringLiteral("ru")); QCOMPARE(Loc::text("app.tooltip.openMods"), entry.value("ru").toString()); // Тот же язык ещё раз — без сигнала. loc().setLanguage(QStringLiteral("ru")); QCOMPARE(spy.count(), 1); } void unknownLanguageFallsBackToSystem() { QTest::ignoreMessage(QtWarningMsg, QRegularExpression(QStringLiteral("klingon"))); loc().setLanguage(QStringLiteral("klingon")); QCOMPARE(loc().language(), QStringLiteral("system")); const QString resolved = loc().resolvedLanguage(); QVERIFY(resolved == QLatin1String("ru") || resolved == QLatin1String("en")); } void missingKeyReturnsKey() { #ifndef QT_NO_DEBUG QTest::ignoreMessage(QtWarningMsg, QRegularExpression(QStringLiteral("no\\.such\\.key"))); #endif QCOMPARE(Loc::text("no.such.key"), QStringLiteral("no.such.key")); #ifndef QT_NO_DEBUG QTest::ignoreMessage(QtWarningMsg, QRegularExpression(QStringLiteral("no\\.such\\.list"))); #endif QCOMPARE(Loc::list("no.such.list"), QStringList{QStringLiteral("no.such.list")}); } void listsHaveSameShapeInAllLanguages() { const QJsonObject strings = Fixtures::readJsonFile(QStringLiteral(BILAUNCHER_SOURCE_DIR "/i18n/translations.json")) .value(QStringLiteral("strings")) .toObject(); int lists = 0; for (auto it = strings.constBegin(); it != strings.constEnd(); ++it) { if (!it.value().toObject().value("en").isArray()) continue; ++lists; const QByteArray key = it.key().toLatin1(); loc().setLanguage(QStringLiteral("en")); const QStringList en = Loc::list(key.constData()); loc().setLanguage(QStringLiteral("ru")); const QStringList ru = Loc::list(key.constData()); QCOMPARE(en.size(), ru.size()); QCOMPARE(en.size(), it.value().toObject().value("en").toArray().size()); } if (lists == 0) QSKIP("в каталоге нет списков"); } void availableLanguages() { const QVariantList languages = loc().availableLanguages(); QVERIFY(languages.size() >= 3); QCOMPARE(languages.first().toMap().value("code").toString(), QStringLiteral("system")); QStringList codes; for (const QVariant &item : languages) codes << item.toMap().value("code").toString(); QVERIFY(codes.contains("ru")); QVERIFY(codes.contains("en")); for (const QVariant &item : languages) QVERIFY(!item.toMap().value("name").toString().isEmpty()); } void storedLanguageIsReadOnLoad() { Fixtures::writeJson(LauncherPaths::settingsFile(), QJsonObject{{"language", "ru"}}); QVERIFY(loc().load()); QCOMPARE(loc().language(), QStringLiteral("ru")); Fixtures::writeJson(LauncherPaths::settingsFile(), QJsonObject{{"language", "xx"}}); QTest::ignoreMessage(QtWarningMsg, QRegularExpression(QStringLiteral("xx"))); QVERIFY(loc().load()); QCOMPARE(loc().language(), QStringLiteral("system")); Fixtures::write(LauncherPaths::settingsFile(), "garbage"); QVERIFY(loc().load()); QCOMPARE(loc().language(), QStringLiteral("system")); } void everyCppKeyExists() { // Тексты, которые код запрашивает через Loc::text("…"), должны быть в каталоге — // иначе пользователь увидит сам ключ. Полная проверка — tools/check_translations.py, // здесь — выборка ключей, которыми пользуются тесты. for (const char *key : {"storage.error.createFailed", "storage.error.notWritable", "java.error.invalidRuntimeId", "version.error.invalidId", "launch.error.filesMissing", "auth.offline.error.noNickname"}) { QVERIFY2(Loc::text(key) != QLatin1String(key), key); } } }; BILAUNCHER_TEST_MAIN(TestLocalization) #include "tst_localization.moc"