test: cover contentPack and loadTree
This commit is contained in:
1 parent
f2aac049e8
commit
32aef57a1b
1 file changed
+156
@@ -0,0 +1,156 @@
|
|||||||
|
#include "testHarness.h"
|
||||||
|
#include "vf/Advancement.h"
|
||||||
|
#include "vf/Scoreboard.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace vf;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using Event = AdvancementCriterion::Event;
|
||||||
|
using Trigger = AdvancementCriterion::Trigger;
|
||||||
|
|
||||||
|
ResourceId id(const std::string& text) {
|
||||||
|
ResourceId parsed;
|
||||||
|
ResourceId::parse(text, "voxelforge", parsed);
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* const rootAdvancement = R"json({
|
||||||
|
"display": {"title": "Getting started", "description": "Chop something down"},
|
||||||
|
"criteria": {
|
||||||
|
"anyWood": {"trigger": "itemObtained", "item": "voxelforge:wood"}
|
||||||
|
},
|
||||||
|
"rewards": {"experience": 5}
|
||||||
|
})json";
|
||||||
|
|
||||||
|
const char* const toolsAdvancement = R"json({
|
||||||
|
"parent": "voxelforge:root",
|
||||||
|
"display": {"title": "A workbench of your own"},
|
||||||
|
"criteria": {
|
||||||
|
"sticks": {"trigger": "itemObtained", "item": "voxelforge:stick", "count": 4},
|
||||||
|
"table": {"trigger": "itemObtained", "item": "voxelforge:crafting_table"}
|
||||||
|
},
|
||||||
|
"rewards": {"experience": 10, "recipes": ["voxelforge:redstone_torch"]}
|
||||||
|
})json";
|
||||||
|
|
||||||
|
const char* const hunterAdvancement = R"json({
|
||||||
|
"parent": "voxelforge:tools",
|
||||||
|
"display": {"title": "Monster hunter", "hidden": true},
|
||||||
|
"criteria": {
|
||||||
|
"zombies": {"trigger": "mobKilled", "species": "zombie", "count": 3},
|
||||||
|
"creeper": {"trigger": "mobKilled", "species": "creeper"}
|
||||||
|
},
|
||||||
|
"requirements": [["zombies", "creeper"]],
|
||||||
|
"rewards": {"experience": 20, "loot": ["voxelforge:chests/starter"]}
|
||||||
|
})json";
|
||||||
|
|
||||||
|
const char* const travellerAdvancement = R"json({
|
||||||
|
"parent": "voxelforge:root",
|
||||||
|
"display": {"title": "Into the fire"},
|
||||||
|
"criteria": {
|
||||||
|
"portal": {"trigger": "dimensionEntered", "dimension": "nether"},
|
||||||
|
"brew": {"trigger": "potionBrewed", "potion": "healing"},
|
||||||
|
"trade": {"trigger": "villagerTraded", "profession": "librarian",
|
||||||
|
"item": "voxelforge:emerald_gem"},
|
||||||
|
"mine": {"trigger": "blockBroken", "block": "voxelforge:obsidian",
|
||||||
|
"tool": "voxelforge:diamond_pickaxe"}
|
||||||
|
},
|
||||||
|
"requirements": [["portal"], ["brew", "trade", "mine"]]
|
||||||
|
})json";
|
||||||
|
|
||||||
|
DataPack contentPack() {
|
||||||
|
DataPackMeta meta;
|
||||||
|
meta.name = "story";
|
||||||
|
DataPack pack(meta);
|
||||||
|
pack.addFile("data/voxelforge/advancements/root.json", rootAdvancement);
|
||||||
|
pack.addFile("data/voxelforge/advancements/tools.json", toolsAdvancement);
|
||||||
|
pack.addFile("data/voxelforge/advancements/hunter.json", hunterAdvancement);
|
||||||
|
pack.addFile("data/voxelforge/advancements/traveller.json", travellerAdvancement);
|
||||||
|
return pack;
|
||||||
|
}
|
||||||
|
|
||||||
|
AdvancementTree loadTree(const DataPack& pack, std::vector<DataPackError>& errors) {
|
||||||
|
DataPackLoader loader;
|
||||||
|
loader.addPack(pack);
|
||||||
|
loader.load();
|
||||||
|
return loadAdvancements(loader, errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
Advancement makeAdvancement(const std::string& self, const std::string& parent) {
|
||||||
|
Advancement node;
|
||||||
|
node.id = id(self);
|
||||||
|
if (!parent.empty()) node.parent = id(parent);
|
||||||
|
AdvancementCriterion criterion;
|
||||||
|
criterion.name = "tick";
|
||||||
|
criterion.trigger = Trigger::ItemObtained;
|
||||||
|
node.criteria.push_back(criterion);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
VF_TEST(advancementsLoadOutOfAPackAndKeepTheirTreeShape) {
|
||||||
|
std::vector<DataPackError> errors;
|
||||||
|
AdvancementTree tree = loadTree(contentPack(), errors);
|
||||||
|
CHECK(errors.empty());
|
||||||
|
CHECK_EQ(tree.size(), static_cast<std::size_t>(4));
|
||||||
|
|
||||||
|
const Advancement* root = tree.find(id("voxelforge:root"));
|
||||||
|
CHECK(root != nullptr);
|
||||||
|
CHECK(root->isRoot());
|
||||||
|
CHECK_EQ(root->title, std::string("Getting started"));
|
||||||
|
CHECK_EQ(root->description, std::string("Chop something down"));
|
||||||
|
CHECK_EQ(root->criteria.size(), static_cast<std::size_t>(1));
|
||||||
|
CHECK(root->criteria[0].item == ItemId::Wood);
|
||||||
|
CHECK_EQ(root->criteria[0].matchMask, AdvancementCriterion::MatchItem);
|
||||||
|
CHECK_EQ(root->reward.experience, 5);
|
||||||
|
|
||||||
|
const Advancement* tools = tree.find(id("voxelforge:tools"));
|
||||||
|
CHECK(tools != nullptr);
|
||||||
|
CHECK(!tools->isRoot());
|
||||||
|
CHECK(tools->parent == id("voxelforge:root"));
|
||||||
|
CHECK_EQ(tools->criteria.size(), static_cast<std::size_t>(2));
|
||||||
|
CHECK_EQ(tools->findCriterion("sticks")->requiredCount, 4);
|
||||||
|
CHECK(tools->findCriterion("absent") == nullptr);
|
||||||
|
CHECK_EQ(tools->reward.recipes.size(), static_cast<std::size_t>(1));
|
||||||
|
CHECK(tools->reward.recipes[0] == id("voxelforge:redstone_torch"));
|
||||||
|
|
||||||
|
const Advancement* traveller = tree.find(id("voxelforge:traveller"));
|
||||||
|
CHECK(traveller->findCriterion("portal")->dimension == DimensionId::Nether);
|
||||||
|
CHECK(traveller->findCriterion("brew")->potion == PotionKind::Healing);
|
||||||
|
CHECK(traveller->findCriterion("trade")->profession == VillagerProfession::Librarian);
|
||||||
|
CHECK(traveller->findCriterion("trade")->item == ItemId::EmeraldGem);
|
||||||
|
CHECK(traveller->findCriterion("mine")->block == Block::Obsidian);
|
||||||
|
CHECK(traveller->findCriterion("mine")->tool == ItemId::DiamondPickaxe);
|
||||||
|
CHECK_EQ(traveller->requirements.size(), static_cast<std::size_t>(2));
|
||||||
|
|
||||||
|
CHECK_EQ(tree.roots().size(), static_cast<std::size_t>(1));
|
||||||
|
CHECK(tree.roots()[0] == id("voxelforge:root"));
|
||||||
|
CHECK_EQ(tree.childrenOf(id("voxelforge:root")).size(), static_cast<std::size_t>(2));
|
||||||
|
CHECK_EQ(tree.childrenOf(id("voxelforge:tools")).size(), static_cast<std::size_t>(1));
|
||||||
|
CHECK_EQ(tree.depthOf(id("voxelforge:root")), 0);
|
||||||
|
CHECK_EQ(tree.depthOf(id("voxelforge:tools")), 1);
|
||||||
|
CHECK_EQ(tree.depthOf(id("voxelforge:hunter")), 2);
|
||||||
|
CHECK_EQ(tree.depthOf(id("voxelforge:absent")), -1);
|
||||||
|
CHECK(!tree.hasCycle());
|
||||||
|
CHECK(tree.missingParents().empty());
|
||||||
|
CHECK_EQ(tree.ids().size(), static_cast<std::size_t>(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(anAdvancementIsGrantedOnlyWhenItsLastCriterionCompletes) {
|
||||||
|
std::vector<DataPackError> errors;
|
||||||
|
AdvancementTree tree = loadTree(contentPack(), errors);
|
||||||
|
AdvancementProgress progress(tree);
|
||||||
|
const AdvancementId tools = id("voxelforge:tools");
|
||||||
|
|
||||||
|
CHECK(!progress.granted(tools));
|
||||||
|
CHECK_EQ(progress.grantedCount(), 0);
|
||||||
|
|
||||||
|
std::vector<AdvancementId> granted = progress.notify(Event::itemObtained(ItemId::Stick, 2), 100);
|
||||||
|
CHECK(granted.empty());
|
||||||
|
CHECK(!progress.criterionDone(tools, "sticks"));
|
||||||
|
CHECK_EQ(progress.criterionProgress(tools, "sticks"), 2);
|
||||||
|
CHECK_EQ(progress.criterionTick(tools, "sticks"), -1);
|
||||||
|
|
||||||
Reference in new issue
Block a user