test: extend coverage of testDataPack
This commit is contained in:
1 parent
157b6e5207
commit
c3d658be63
1 file changed
+158
@@ -318,3 +318,161 @@ VF_TEST(aTagMarkedReplaceWipesWhatCameBeforeIt) {
|
|||||||
CHECK_EQ(logs.size(), static_cast<std::size_t>(1));
|
CHECK_EQ(logs.size(), static_cast<std::size_t>(1));
|
||||||
if (!logs.empty()) CHECK(logs[0] == Block::Cactus);
|
if (!logs.empty()) CHECK(logs[0] == Block::Cactus);
|
||||||
|
|
||||||
|
const BlockTag* tag = loader.blockTags().find(id("voxelforge:logs"));
|
||||||
|
CHECK(tag != nullptr);
|
||||||
|
CHECK(tag->replace);
|
||||||
|
CHECK(tag->contains(id("voxelforge:cactus")));
|
||||||
|
CHECK(!tag->contains(id("voxelforge:wood")));
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(tagReferencesFlattenIntoTheirMembersWithoutDuplicates) {
|
||||||
|
DataPackLoader loader;
|
||||||
|
loader.addPack(basePack());
|
||||||
|
CHECK(loader.load());
|
||||||
|
|
||||||
|
std::vector<ResourceId> members;
|
||||||
|
CHECK(loader.blockTags().resolve(id("voxelforge:mineable"), members));
|
||||||
|
CHECK_EQ(members.size(), static_cast<std::size_t>(3));
|
||||||
|
if (members.size() == 3u) {
|
||||||
|
CHECK(members[0] == id("voxelforge:wood"));
|
||||||
|
CHECK(members[1] == id("voxelforge:stone"));
|
||||||
|
CHECK(members[2] == id("voxelforge:sand"));
|
||||||
|
}
|
||||||
|
CHECK(loader.blockTags().contains(id("voxelforge:mineable"), id("voxelforge:wood")));
|
||||||
|
CHECK(!loader.blockTags().contains(id("voxelforge:mineable"), id("voxelforge:cactus")));
|
||||||
|
|
||||||
|
std::vector<Block> blocks;
|
||||||
|
CHECK(loader.blocksInTag(id("voxelforge:mineable"), blocks));
|
||||||
|
CHECK_EQ(blocks.size(), static_cast<std::size_t>(3));
|
||||||
|
if (!blocks.empty()) CHECK(blocks[0] == Block::Wood);
|
||||||
|
|
||||||
|
std::vector<ItemId> fuel;
|
||||||
|
CHECK(loader.itemsInTag(id("voxelforge:fuel"), fuel));
|
||||||
|
CHECK_EQ(fuel.size(), static_cast<std::size_t>(2));
|
||||||
|
if (fuel.size() == 2u) {
|
||||||
|
CHECK(fuel[0] == ItemId::CoalLump);
|
||||||
|
CHECK(fuel[1] == ItemId::Planks);
|
||||||
|
}
|
||||||
|
|
||||||
|
// A tag that names a tag nobody defined resolves to nothing, loudly.
|
||||||
|
std::vector<ResourceId> unresolved;
|
||||||
|
std::string problem;
|
||||||
|
TagRegistry registry;
|
||||||
|
BlockTag dangling;
|
||||||
|
dangling.id = id("voxelforge:dangling");
|
||||||
|
dangling.entries.push_back({id("voxelforge:absent"), true});
|
||||||
|
registry.define(dangling);
|
||||||
|
CHECK(!registry.resolve(dangling.id, unresolved, problem));
|
||||||
|
CHECK(problem.find("unknown tag") != std::string::npos);
|
||||||
|
CHECK(!registry.hasCycle(dangling.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(aTagThatReferencesItselfIsReportedAsACycleInsteadOfLoopingForever) {
|
||||||
|
DataPackMeta meta;
|
||||||
|
meta.name = "looping";
|
||||||
|
DataPack pack(meta);
|
||||||
|
pack.addFile("data/voxelforge/tags/blocks/first.json",
|
||||||
|
R"json({"values": ["voxelforge:stone", "#voxelforge:second"]})json");
|
||||||
|
pack.addFile("data/voxelforge/tags/blocks/second.json",
|
||||||
|
R"json({"values": ["voxelforge:sand", "#voxelforge:third"]})json");
|
||||||
|
pack.addFile("data/voxelforge/tags/blocks/third.json",
|
||||||
|
R"json({"values": ["#voxelforge:first"]})json");
|
||||||
|
pack.addFile("data/voxelforge/tags/blocks/selfish.json",
|
||||||
|
R"json({"values": ["#voxelforge:selfish"]})json");
|
||||||
|
|
||||||
|
DataPackLoader loader;
|
||||||
|
loader.addPack(pack);
|
||||||
|
CHECK(loader.load());
|
||||||
|
|
||||||
|
const TagRegistry& tags = loader.blockTags();
|
||||||
|
std::vector<ResourceId> members;
|
||||||
|
std::string problem;
|
||||||
|
CHECK(!tags.resolve(id("voxelforge:first"), members, problem));
|
||||||
|
CHECK(problem.find("tag cycle") != std::string::npos);
|
||||||
|
CHECK(members.empty());
|
||||||
|
CHECK(tags.hasCycle(id("voxelforge:first")));
|
||||||
|
CHECK(tags.hasCycle(id("voxelforge:second")));
|
||||||
|
CHECK(tags.hasCycle(id("voxelforge:selfish")));
|
||||||
|
|
||||||
|
std::vector<Block> blocks;
|
||||||
|
CHECK(!loader.blocksInTag(id("voxelforge:first"), blocks));
|
||||||
|
CHECK(blocks.empty());
|
||||||
|
|
||||||
|
// A diamond is not a cycle: two paths onto the same tag still resolve.
|
||||||
|
DataPackMeta diamondMeta;
|
||||||
|
diamondMeta.name = "diamond";
|
||||||
|
DataPack diamond(diamondMeta);
|
||||||
|
diamond.addFile("data/voxelforge/tags/blocks/leaf.json",
|
||||||
|
R"json({"values": ["voxelforge:stone"]})json");
|
||||||
|
diamond.addFile("data/voxelforge/tags/blocks/left.json",
|
||||||
|
R"json({"values": ["#voxelforge:leaf"]})json");
|
||||||
|
diamond.addFile("data/voxelforge/tags/blocks/right.json",
|
||||||
|
R"json({"values": ["#voxelforge:leaf"]})json");
|
||||||
|
diamond.addFile("data/voxelforge/tags/blocks/top.json",
|
||||||
|
R"json({"values": ["#voxelforge:left", "#voxelforge:right"]})json");
|
||||||
|
DataPackLoader diamondLoader;
|
||||||
|
diamondLoader.addPack(diamond);
|
||||||
|
CHECK(diamondLoader.load());
|
||||||
|
CHECK(diamondLoader.blockTags().resolve(id("voxelforge:top"), members));
|
||||||
|
CHECK_EQ(members.size(), static_cast<std::size_t>(1));
|
||||||
|
CHECK(!diamondLoader.blockTags().hasCycle(id("voxelforge:top")));
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(oneRottenFileCostsItselfAndNothingElseInThePack) {
|
||||||
|
DataPackMeta meta;
|
||||||
|
meta.name = "mixed";
|
||||||
|
DataPack pack(meta);
|
||||||
|
pack.addFile("data/voxelforge/recipes/good.json", appleBread);
|
||||||
|
pack.addFile("data/voxelforge/recipes/torn.json", "{\"type\": \"craftingShapeless\",");
|
||||||
|
pack.addFile("data/voxelforge/recipes/ghost_item.json",
|
||||||
|
R"json({"type": "craftingShapeless", "ingredients": ["voxelforge:cheese"],
|
||||||
|
"result": {"item": "voxelforge:bread"}})json");
|
||||||
|
pack.addFile("data/voxelforge/recipes/nonsense.json",
|
||||||
|
R"json({"type": "alchemy", "result": {"item": "voxelforge:bread"}})json");
|
||||||
|
pack.addFile("data/voxelforge/nowhere/lost.json", R"json({"values": []})json");
|
||||||
|
pack.addFile("data/voxelforge/lootTables/empty.json", R"json({"pools": []})json");
|
||||||
|
pack.addFile("data/voxelforge/tags/blocks/bad_entry.json",
|
||||||
|
R"json({"values": ["Not An Id"]})json");
|
||||||
|
pack.addFile("data/voxelforge/tags/blocks/fine.json",
|
||||||
|
R"json({"values": ["voxelforge:stone"]})json");
|
||||||
|
pack.addFile("data/voxelforge/recipes/ShoutyName.json", appleBread);
|
||||||
|
|
||||||
|
DataPackLoader loader;
|
||||||
|
loader.addPack(pack);
|
||||||
|
CHECK(!loader.load());
|
||||||
|
CHECK_EQ(loader.errors().size(), static_cast<std::size_t>(7));
|
||||||
|
|
||||||
|
for (const DataPackError& failure : loader.errors()) {
|
||||||
|
CHECK(!failure.file.empty());
|
||||||
|
CHECK(!failure.reason.empty());
|
||||||
|
CHECK_EQ(failure.pack, std::string("mixed"));
|
||||||
|
CHECK(failure.text().find("mixed/data/") != std::string::npos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The healthy files in the very same pack still landed.
|
||||||
|
CHECK_EQ(loader.recipes().size(), static_cast<std::size_t>(1));
|
||||||
|
CHECK(loader.recipe(id("voxelforge:good")) != nullptr);
|
||||||
|
CHECK_EQ(loader.blockTags().size(), static_cast<std::size_t>(1));
|
||||||
|
CHECK(loader.blockTags().has(id("voxelforge:fine")));
|
||||||
|
|
||||||
|
bool sawParseError = false;
|
||||||
|
bool sawUnknownItem = false;
|
||||||
|
bool sawUnknownFolder = false;
|
||||||
|
bool sawUppercaseId = false;
|
||||||
|
for (const DataPackError& failure : loader.errors()) {
|
||||||
|
if (failure.file == "data/voxelforge/recipes/torn.json") {
|
||||||
|
sawParseError = failure.line > 0;
|
||||||
|
}
|
||||||
|
if (failure.file == "data/voxelforge/recipes/ghost_item.json")
|
||||||
|
sawUnknownItem = failure.reason.find("no such item") != std::string::npos;
|
||||||
|
if (failure.file == "data/voxelforge/nowhere/lost.json")
|
||||||
|
sawUnknownFolder = failure.reason.find("known folder") != std::string::npos;
|
||||||
|
if (failure.file == "data/voxelforge/recipes/ShoutyName.json")
|
||||||
|
sawUppercaseId = failure.reason.find("valid resource id") != std::string::npos;
|
||||||
|
}
|
||||||
|
CHECK(sawParseError);
|
||||||
|
CHECK(sawUnknownItem);
|
||||||
|
CHECK(sawUnknownFolder);
|
||||||
|
CHECK(sawUppercaseId);
|
||||||
|
}
|
||||||
|
|
||||||
Reference in new issue
Block a user