test+fix: add basic tests and fix issues with it
This commit is contained in:
parent
4439666e67
commit
d7f6b36990
@ -551,6 +551,12 @@ set(PACKWIZ_SOURCES
|
|||||||
modplatform/packwiz/Packwiz.cpp
|
modplatform/packwiz/Packwiz.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_unit_test(Packwiz
|
||||||
|
SOURCES modplatform/packwiz/Packwiz_test.cpp
|
||||||
|
DATA modplatform/packwiz/testdata
|
||||||
|
LIBS Launcher_logic
|
||||||
|
)
|
||||||
|
|
||||||
set(TECHNIC_SOURCES
|
set(TECHNIC_SOURCES
|
||||||
modplatform/technic/SingleZipPackInstallTask.h
|
modplatform/technic/SingleZipPackInstallTask.h
|
||||||
modplatform/technic/SingleZipPackInstallTask.cpp
|
modplatform/technic/SingleZipPackInstallTask.cpp
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#include <FileSystem.h>
|
#include <FileSystem.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include "Application.h"
|
||||||
#include "MetadataHandler.h"
|
#include "MetadataHandler.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -174,8 +176,7 @@ void Mod::finishResolvingWithDetails(std::shared_ptr<ModDetails> details)
|
|||||||
m_resolved = true;
|
m_resolved = true;
|
||||||
m_localDetails = details;
|
m_localDetails = details;
|
||||||
|
|
||||||
if (fromMetadata() && m_temp_metadata->isValid()) {
|
if (fromMetadata() && m_temp_metadata->isValid() && m_localDetails.get()) {
|
||||||
m_localDetails->metadata = m_temp_metadata;
|
m_localDetails->metadata.swap(m_temp_metadata);
|
||||||
m_temp_metadata.reset();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
||||||
#include "ModDetails.h"
|
#include "ModDetails.h"
|
||||||
#include "minecraft/mod/MetadataHandler.h"
|
|
||||||
|
|
||||||
class Mod
|
class Mod
|
||||||
{
|
{
|
||||||
|
@ -34,8 +34,14 @@ void ModFolderLoadTask::getFromMetadata()
|
|||||||
if (entry == "." || entry == "..")
|
if (entry == "." || entry == "..")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
entry.chop(5); // Remove .toml at the end
|
auto metadata = Metadata::get(m_index_dir, entry);
|
||||||
Mod mod(m_mods_dir, Metadata::get(m_index_dir, entry));
|
// TODO: Don't simply return. Instead, show to the user that the metadata is there, but
|
||||||
|
// it's not currently 'installed' (i.e. there's no JAR file yet).
|
||||||
|
if(!metadata.isValid()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mod mod(m_mods_dir, metadata);
|
||||||
m_result->mods[mod.internal_id()] = mod;
|
m_result->mods[mod.internal_id()] = mod;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ class ProviderCapabilities {
|
|||||||
{
|
{
|
||||||
switch(p){
|
switch(p){
|
||||||
case Provider::MODRINTH:
|
case Provider::MODRINTH:
|
||||||
return "sha256";
|
return "sha512";
|
||||||
case Provider::FLAME:
|
case Provider::FLAME:
|
||||||
return "murmur2";
|
return "murmur2";
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@ namespace Packwiz {
|
|||||||
// Helpers
|
// Helpers
|
||||||
static inline QString indexFileName(QString const& mod_name)
|
static inline QString indexFileName(QString const& mod_name)
|
||||||
{
|
{
|
||||||
|
if(mod_name.endsWith(".toml"))
|
||||||
|
return mod_name;
|
||||||
return QString("%1.toml").arg(mod_name);
|
return QString("%1.toml").arg(mod_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,8 +93,16 @@ void V1::updateModIndex(QDir& index_dir, Mod& mod)
|
|||||||
|
|
||||||
in_stream << QString("\n[update]\n");
|
in_stream << QString("\n[update]\n");
|
||||||
in_stream << QString("[update.%1]\n").arg(ModPlatform::ProviderCapabilities::providerName(mod.provider));
|
in_stream << QString("[update.%1]\n").arg(ModPlatform::ProviderCapabilities::providerName(mod.provider));
|
||||||
addToStream("file-id", mod.file_id.toString());
|
switch(mod.provider){
|
||||||
addToStream("project-id", mod.project_id.toString());
|
case(ModPlatform::Provider::FLAME):
|
||||||
|
in_stream << QString("file-id = %1\n").arg(mod.file_id.toString());
|
||||||
|
in_stream << QString("project-id = %1\n").arg(mod.project_id.toString());
|
||||||
|
break;
|
||||||
|
case(ModPlatform::Provider::MODRINTH):
|
||||||
|
addToStream("mod-id", mod.mod_id().toString());
|
||||||
|
addToStream("version", mod.version().toString());
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,18 +120,44 @@ void V1::deleteModIndex(QDir& index_dir, QString& mod_name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto V1::getIndexForMod(QDir& index_dir, QString& mod_name) -> Mod
|
// Helper functions for extracting data from the TOML file
|
||||||
|
static auto stringEntry(toml_table_t* parent, const char* entry_name) -> QString
|
||||||
|
{
|
||||||
|
toml_datum_t var = toml_string_in(parent, entry_name);
|
||||||
|
if (!var.ok) {
|
||||||
|
qCritical() << QString("Failed to read str property '%1' in mod metadata.").arg(entry_name);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QString tmp = var.u.s;
|
||||||
|
free(var.u.s);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto intEntry(toml_table_t* parent, const char* entry_name) -> int
|
||||||
|
{
|
||||||
|
toml_datum_t var = toml_int_in(parent, entry_name);
|
||||||
|
if (!var.ok) {
|
||||||
|
qCritical() << QString("Failed to read int property '%1' in mod metadata.").arg(entry_name);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return var.u.i;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto V1::getIndexForMod(QDir& index_dir, QString& index_file_name) -> Mod
|
||||||
{
|
{
|
||||||
Mod mod;
|
Mod mod;
|
||||||
|
|
||||||
QFile index_file(index_dir.absoluteFilePath(indexFileName(mod_name)));
|
QFile index_file(index_dir.absoluteFilePath(indexFileName(index_file_name)));
|
||||||
|
|
||||||
if (!index_file.exists()) {
|
if (!index_file.exists()) {
|
||||||
qWarning() << QString("Tried to get a non-existent mod metadata for %1").arg(mod_name);
|
qWarning() << QString("Tried to get a non-existent mod metadata for %1").arg(index_file_name);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
if (!index_file.open(QIODevice::ReadOnly)) {
|
if (!index_file.open(QIODevice::ReadOnly)) {
|
||||||
qWarning() << QString("Failed to open mod metadata for %1").arg(mod_name);
|
qWarning() << QString("Failed to open mod metadata for %1").arg(index_file_name);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,29 +172,9 @@ auto V1::getIndexForMod(QDir& index_dir, QString& mod_name) -> Mod
|
|||||||
qCritical() << QString("Could not open file %1!").arg(indexFileName(mod.name));
|
qCritical() << QString("Could not open file %1!").arg(indexFileName(mod.name));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function for extracting data from the TOML file
|
|
||||||
auto stringEntry = [&](toml_table_t* parent, const char* entry_name) -> QString {
|
|
||||||
toml_datum_t var = toml_string_in(parent, entry_name);
|
|
||||||
if (!var.ok) {
|
|
||||||
qCritical() << QString("Failed to read property '%1' in mod metadata.").arg(entry_name);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QString tmp = var.u.s;
|
|
||||||
free(var.u.s);
|
|
||||||
|
|
||||||
return tmp;
|
|
||||||
};
|
|
||||||
|
|
||||||
{ // Basic info
|
{ // Basic info
|
||||||
mod.name = stringEntry(table, "name");
|
mod.name = stringEntry(table, "name");
|
||||||
// Basic sanity check
|
|
||||||
if (mod.name != mod_name) {
|
|
||||||
qCritical() << QString("Name mismatch in mod metadata:\nExpected:%1\nGot:%2").arg(mod_name, mod.name);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
mod.filename = stringEntry(table, "filename");
|
mod.filename = stringEntry(table, "filename");
|
||||||
mod.side = stringEntry(table, "side");
|
mod.side = stringEntry(table, "side");
|
||||||
}
|
}
|
||||||
@ -188,15 +204,17 @@ auto V1::getIndexForMod(QDir& index_dir, QString& mod_name) -> Mod
|
|||||||
toml_table_t* mod_provider_table;
|
toml_table_t* mod_provider_table;
|
||||||
if ((mod_provider_table = toml_table_in(update_table, ProviderCaps::providerName(Provider::FLAME)))) {
|
if ((mod_provider_table = toml_table_in(update_table, ProviderCaps::providerName(Provider::FLAME)))) {
|
||||||
mod.provider = Provider::FLAME;
|
mod.provider = Provider::FLAME;
|
||||||
|
mod.file_id = intEntry(mod_provider_table, "file-id");
|
||||||
|
mod.project_id = intEntry(mod_provider_table, "project-id");
|
||||||
} else if ((mod_provider_table = toml_table_in(update_table, ProviderCaps::providerName(Provider::MODRINTH)))) {
|
} else if ((mod_provider_table = toml_table_in(update_table, ProviderCaps::providerName(Provider::MODRINTH)))) {
|
||||||
mod.provider = Provider::MODRINTH;
|
mod.provider = Provider::MODRINTH;
|
||||||
|
mod.mod_id() = stringEntry(mod_provider_table, "mod-id");
|
||||||
|
mod.version() = stringEntry(mod_provider_table, "version");
|
||||||
} else {
|
} else {
|
||||||
qCritical() << QString("No mod provider on mod metadata!");
|
qCritical() << QString("No mod provider on mod metadata!");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
mod.file_id = stringEntry(mod_provider_table, "file-id");
|
|
||||||
mod.project_id = stringEntry(mod_provider_table, "project-id");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toml_free(table);
|
toml_free(table);
|
||||||
|
@ -33,8 +33,13 @@ class V1 {
|
|||||||
QVariant project_id {};
|
QVariant project_id {};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// This is a heuristic, but should work for now.
|
// This is a totally heuristic, but should work for now.
|
||||||
auto isValid() const -> bool { return !name.isEmpty(); }
|
auto isValid() const -> bool { return !name.isEmpty() && !project_id.isNull(); }
|
||||||
|
|
||||||
|
// Different providers can use different names for the same thing
|
||||||
|
// Modrinth-specific
|
||||||
|
auto mod_id() -> QVariant& { return project_id; }
|
||||||
|
auto version() -> QVariant& { return file_id; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Generates the object representing the information in a mod.toml file via
|
/* Generates the object representing the information in a mod.toml file via
|
||||||
@ -58,7 +63,7 @@ class V1 {
|
|||||||
/* Gets the metadata for a mod with a particular name.
|
/* Gets the metadata for a mod with a particular name.
|
||||||
* If the mod doesn't have a metadata, it simply returns an empty Mod object.
|
* If the mod doesn't have a metadata, it simply returns an empty Mod object.
|
||||||
* */
|
* */
|
||||||
static auto getIndexForMod(QDir& index_dir, QString& mod_name) -> Mod;
|
static auto getIndexForMod(QDir& index_dir, QString& index_file_name) -> Mod;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Packwiz
|
} // namespace Packwiz
|
||||||
|
68
launcher/modplatform/packwiz/Packwiz_test.cpp
Normal file
68
launcher/modplatform/packwiz/Packwiz_test.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#include <QTemporaryDir>
|
||||||
|
#include <QTest>
|
||||||
|
|
||||||
|
#include "TestUtil.h"
|
||||||
|
#include "Packwiz.h"
|
||||||
|
|
||||||
|
class PackwizTest : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
// Files taken from https://github.com/packwiz/packwiz-example-pack
|
||||||
|
void loadFromFile_Modrinth()
|
||||||
|
{
|
||||||
|
QString source = QFINDTESTDATA("testdata");
|
||||||
|
|
||||||
|
QDir index_dir(source);
|
||||||
|
QString name_mod("borderless-mining.toml");
|
||||||
|
QVERIFY(index_dir.entryList().contains(name_mod));
|
||||||
|
|
||||||
|
auto metadata = Packwiz::V1::getIndexForMod(index_dir, name_mod);
|
||||||
|
|
||||||
|
QVERIFY(metadata.isValid());
|
||||||
|
|
||||||
|
QCOMPARE(metadata.name, "Borderless Mining");
|
||||||
|
QCOMPARE(metadata.filename, "borderless-mining-1.1.1+1.18.jar");
|
||||||
|
QCOMPARE(metadata.side, "client");
|
||||||
|
|
||||||
|
QCOMPARE(metadata.url, QUrl("https://cdn.modrinth.com/data/kYq5qkSL/versions/1.1.1+1.18/borderless-mining-1.1.1+1.18.jar"));
|
||||||
|
QCOMPARE(metadata.hash_format, "sha512");
|
||||||
|
QCOMPARE(metadata.hash, "c8fe6e15ddea32668822dddb26e1851e5f03834be4bcb2eff9c0da7fdc086a9b6cead78e31a44d3bc66335cba11144ee0337c6d5346f1ba63623064499b3188d");
|
||||||
|
|
||||||
|
QCOMPARE(metadata.provider, ModPlatform::Provider::MODRINTH);
|
||||||
|
QCOMPARE(metadata.version(), "ug2qKTPR");
|
||||||
|
QCOMPARE(metadata.mod_id(), "kYq5qkSL");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadFromFile_Curseforge()
|
||||||
|
{
|
||||||
|
QString source = QFINDTESTDATA("testdata");
|
||||||
|
|
||||||
|
QDir index_dir(source);
|
||||||
|
QString name_mod("screenshot-to-clipboard-fabric.toml");
|
||||||
|
QVERIFY(index_dir.entryList().contains(name_mod));
|
||||||
|
|
||||||
|
// Try without the .toml at the end
|
||||||
|
name_mod.chop(5);
|
||||||
|
|
||||||
|
auto metadata = Packwiz::V1::getIndexForMod(index_dir, name_mod);
|
||||||
|
|
||||||
|
QVERIFY(metadata.isValid());
|
||||||
|
|
||||||
|
QCOMPARE(metadata.name, "Screenshot to Clipboard (Fabric)");
|
||||||
|
QCOMPARE(metadata.filename, "screenshot-to-clipboard-1.0.7-fabric.jar");
|
||||||
|
QCOMPARE(metadata.side, "both");
|
||||||
|
|
||||||
|
QCOMPARE(metadata.url, QUrl("https://edge.forgecdn.net/files/3509/43/screenshot-to-clipboard-1.0.7-fabric.jar"));
|
||||||
|
QCOMPARE(metadata.hash_format, "murmur2");
|
||||||
|
QCOMPARE(metadata.hash, "1781245820");
|
||||||
|
|
||||||
|
QCOMPARE(metadata.provider, ModPlatform::Provider::FLAME);
|
||||||
|
QCOMPARE(metadata.file_id, 3509043);
|
||||||
|
QCOMPARE(metadata.project_id, 327154);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(PackwizTest)
|
||||||
|
|
||||||
|
#include "Packwiz_test.moc"
|
BIN
launcher/modplatform/packwiz/testdata/borderless-mining.toml
vendored
Normal file
BIN
launcher/modplatform/packwiz/testdata/borderless-mining.toml
vendored
Normal file
Binary file not shown.
BIN
launcher/modplatform/packwiz/testdata/screenshot-to-clipboard-fabric.toml
vendored
Normal file
BIN
launcher/modplatform/packwiz/testdata/screenshot-to-clipboard-fabric.toml
vendored
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user