test+fix: add basic tests and fix issues with it

This commit is contained in:
flow 2022-04-17 11:40:41 -03:00 committed by flow
parent 4439666e67
commit d7f6b36990
No known key found for this signature in database
GPG Key ID: 8D0F221F0A59F469
10 changed files with 142 additions and 39 deletions

View File

@ -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

View File

@ -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();
} }
} }

View File

@ -20,7 +20,6 @@
#include <QList> #include <QList>
#include "ModDetails.h" #include "ModDetails.h"
#include "minecraft/mod/MetadataHandler.h"
class Mod class Mod
{ {

View File

@ -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;
} }
} }

View File

@ -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";
} }

View File

@ -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);

View File

@ -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

View 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"

Binary file not shown.