diff options
| author | snowstormxd <214507868+snowstormxd@users.noreply.github.com> | 2026-11-01 18:37:51 +0000 |
|---|---|---|
| committer | snowstormxd <214507868+snowstormxd@users.noreply.github.com> | 2026-11-01 20:52:30 +0000 |
| commit | 8e777214b02be0f254abdcc1adbc195e765e36a6 (patch) | |
| tree | f205fffbad3c78bdbfff2d54356d43b421666942 /tools | |
| parent | ac22c4087d9a6380c1937337530a5d4e54808ad1 (diff) | |
game_list: discover loose dumps without walking their RomFS payloads
Defer RomFS construction, reuse one discovery result, omit recursive folder sizing, and release rows discarded by cancellation. Add scan suspension and regression coverage for extracted layouts and Unicode paths.
Assisted-by: Codex (implementation, selective integration and automated validation)
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/integration/game_discovery_test.cpp | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/tools/integration/game_discovery_test.cpp b/tools/integration/game_discovery_test.cpp new file mode 100644 index 0000000000..a5cfe0fc5a --- /dev/null +++ b/tools/integration/game_discovery_test.cpp @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "qt_common/game_list/discovery.h" +#include <chrono> +#include <cstdlib> +#include <fstream> +#include <iostream> +#include <source_location> + +namespace fs = std::filesystem; + +void Check(bool condition, + std::source_location location = std::source_location::current()) { + if (!condition) { + std::cerr << "Game discovery regression failed at line " << location.line() + << '\n'; + std::exit(1); + } +} + +int main() { + const auto temp = fs::temp_directory_path(); + const auto root = + temp / ("eglantine-discovery-" + + std::to_string( + std::chrono::steady_clock::now().time_since_epoch().count())); + Check(fs::equivalent(root.parent_path(), temp) && fs::create_directory(root)); + struct Cleanup { + fs::path path; + ~Cleanup() { fs::remove_all(path); } + } cleanup{root}; + const auto touch = [](const fs::path &path) { + fs::create_directories(path.parent_path()); + std::ofstream{path}.put('x'); + }; + const auto dump = [&](const fs::path &path) { + touch(path / "exefs/main"); + touch(path / "exefs/main.npdm"); + }; + const auto supported = [](const fs::path &path) { + return path.filename() == "main" || path.extension() == ".nsp"; + }; + const auto discover = [&](const fs::path &path, bool deep) { + return GameListDiscovery::Discover(path, deep, supported, + [] { return false; }); + }; + + const auto game = root / fs::path{u8"MKW-églantine"}; + dump(game / "base"); + dump(game / "updates/0100000000000800"); + for (unsigned i = 0; i < 400; ++i) { + touch(game / "base/romfs/assets" / std::to_string(i) / "false-game.nsp"); + } + touch(root / "standalone.nsp"); + touch(root / "unrelated/romfs/actual-game.nsp"); + + const auto deep = discover(root, true); + Check(deep.files.size() == 4 && deep.skipped_romfs == 1 && deep.errors == 0); + Check(deep.directories.size() < 20); + Check(discover(root, false).files.size() == 3); + Check(discover(game / "base", false).files.size() == 1); + Check(discover(game / "base/exefs", false).files.size() == 1); + Check(discover(root / "missing", true).files.empty()); + + touch(root / "incomplete/exefs/main"); + touch(root / "incomplete/romfs/actual-game.nsp"); + Check(discover(root, true).files.size() == 6); + + unsigned calls{}; + const auto cancelled = GameListDiscovery::Discover( + root, true, supported, [&] { return ++calls > 3; }); + Check(calls < 10 && cancelled.directories.size() <= 1); + std::cout << "Discovery: loose layouts, payload pruning, Unicode, shallow " + "scans and cancellation passed\n"; +} |
