#include "testenv.h" #include "fixtures.h" #include "javalocator.h" #include "javaruntime.h" #include "localization.h" #include class TestJavaLocator : public QObject { Q_OBJECT QString m_game; int m_unique = 0; // majorVersion() кеширует ответ по пути, поэтому каждая подставная java — в своей папке. QString fakeJava(const QString &version) { return Fixtures::installFakeJava(m_game + QStringLiteral("/jdk-%1").arg(++m_unique), version); } private slots: void init() { TestEnv::resetLauncherRoot(); m_game = TestEnv::freshDir(QStringLiteral("game")); } void majorVersion_data() { QTest::addColumn("version"); QTest::addColumn("major"); QTest::newRow("java8") << "1.8.0_392" << 8; QTest::newRow("java11") << "11.0.21" << 11; QTest::newRow("java17") << "17.0.8" << 17; QTest::newRow("java21 short") << "21" << 21; QTest::newRow("java25 ea") << "25-ea" << 25; } void majorVersion() { QFETCH(QString, version); QFETCH(int, major); QCOMPARE(JavaLocator::majorVersion(fakeJava(version)), major); } void majorVersionOfNonJava() { QCOMPARE(JavaLocator::majorVersion(m_game + QStringLiteral("/nope/java")), 0); } void windowlessVariant() { const QString java = fakeJava("17.0.8"); #if defined(Q_OS_WIN) QCOMPARE(JavaLocator::windowlessVariant(java), QFileInfo(java).absolutePath() + "/javaw.exe"); QFile::remove(QFileInfo(java).absolutePath() + "/javaw.exe"); QCOMPARE(JavaLocator::windowlessVariant(java), java); #else QCOMPARE(JavaLocator::windowlessVariant(java), java); #endif QCOMPARE(JavaLocator::windowlessVariant(QStringLiteral("/opt/custom/launcher")), QStringLiteral("/opt/custom/launcher")); } void findAllSeesManagedAndGameRuntimes() { // Java, поставленная лаунчером (JavaRuntimeStore). InstalledJavaRuntime managed; managed.id = QStringLiteral("temurin-jdk-21"); managed.kind = QStringLiteral("jdk"); managed.major = 21; managed.version = QStringLiteral("21.0.2"); managed.javaPath = Fixtures::installFakeJava(JavaRuntimeStore::dirFor(managed.id), "21.0.2"); QVERIFY(JavaRuntimeStore::writeMeta(managed, nullptr)); // Java официального лаунчера внутри .minecraft/runtime. const QString mojang = Fixtures::installFakeJava( m_game + "/runtime/java-runtime-gamma/linux/java-runtime-gamma", "17.0.8"); const QStringList all = JavaLocator::findAll(m_game); QVERIFY(all.size() >= 2); QCOMPARE(QFileInfo(all.at(0)).canonicalFilePath(), QFileInfo(managed.javaPath).canonicalFilePath()); bool hasMojang = false; for (const QString &path : all) hasMojang |= QFileInfo(path).canonicalFilePath() == QFileInfo(mojang).canonicalFilePath(); QVERIFY(hasMojang); QStringList unique = all; QCOMPARE(unique.removeDuplicates(), 0); } void selectPrefersPreferredWhenSuitable() { const QString java = fakeJava("21.0.2"); QString error; QCOMPARE(JavaLocator::select(m_game, 17, java, &error), QFileInfo(java).absoluteFilePath()); QVERIFY(error.isEmpty()); // Папка JDK тоже годится: берётся bin/java. const QString fromDir = JavaLocator::select(m_game, 17, QFileInfo(java).absolutePath() + "/..", &error); QCOMPARE(QFileInfo(fromDir).canonicalFilePath(), QFileInfo(java).canonicalFilePath()); } void selectReportsMissingPreferred() { QString error; const QString missing = m_game + "/no-such-java"; QVERIFY(JavaLocator::select(m_game, 17, missing, &error).isEmpty()); QCOMPARE(error, Loc::text("java.error.notAtPath").arg(QDir::toNativeSeparators(missing))); } void selectFallsBackToManagedRuntime() { InstalledJavaRuntime managed; managed.id = QStringLiteral("temurin-jdk-21b"); managed.kind = QStringLiteral("jdk"); managed.major = 21; managed.version = QStringLiteral("21.0.2"); managed.javaPath = Fixtures::installFakeJava(JavaRuntimeStore::dirFor(managed.id), "21.0.2"); QVERIFY(JavaRuntimeStore::writeMeta(managed, nullptr)); const QString old = fakeJava("1.8.0_392"); QString error; const QString chosen = JavaLocator::select(m_game, 21, old, &error); QCOMPARE(QFileInfo(chosen).canonicalFilePath(), QFileInfo(managed.javaPath).canonicalFilePath()); } void selectExplainsTooOld() { for (const QString &candidate : JavaLocator::findAll(m_game)) { if (JavaLocator::majorVersion(candidate) >= 99) QSKIP("в системе есть Java 99+"); } const QString old = fakeJava("17.0.8"); QString error; QVERIFY(JavaLocator::select(m_game, 99, old, &error).isEmpty()); // Сообщение называет лучшую из найденных — она не ниже нашей 17. QVERIFY(!error.isEmpty()); QVERIFY(error.contains(QStringLiteral("99"))); } }; BILAUNCHER_TEST_MAIN(TestJavaLocator) #include "tst_javalocator.moc"