1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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";
}
|