test: cover testAdvancement
This commit is contained in:
1 parent
32aef57a1b
commit
1530c4701e
1 file changed
+159
@@ -154,3 +154,162 @@ VF_TEST(anAdvancementIsGrantedOnlyWhenItsLastCriterionCompletes) {
|
|||||||
CHECK_EQ(progress.criterionProgress(tools, "sticks"), 2);
|
CHECK_EQ(progress.criterionProgress(tools, "sticks"), 2);
|
||||||
CHECK_EQ(progress.criterionTick(tools, "sticks"), -1);
|
CHECK_EQ(progress.criterionTick(tools, "sticks"), -1);
|
||||||
|
|
||||||
|
granted = progress.notify(Event::itemObtained(ItemId::Stick, 2), 140);
|
||||||
|
CHECK(granted.empty());
|
||||||
|
CHECK(progress.criterionDone(tools, "sticks"));
|
||||||
|
CHECK_EQ(progress.criterionProgress(tools, "sticks"), 4);
|
||||||
|
CHECK_EQ(progress.criterionTick(tools, "sticks"), 140);
|
||||||
|
CHECK(!progress.granted(tools));
|
||||||
|
|
||||||
|
// An unrelated item moves nothing.
|
||||||
|
granted = progress.notify(Event::itemObtained(ItemId::Dirt, 64), 150);
|
||||||
|
CHECK(granted.empty());
|
||||||
|
CHECK(!progress.granted(tools));
|
||||||
|
|
||||||
|
granted = progress.notify(Event::itemObtained(ItemId::CraftingTable), 200);
|
||||||
|
CHECK_EQ(granted.size(), static_cast<std::size_t>(1));
|
||||||
|
if (!granted.empty()) CHECK(granted[0] == tools);
|
||||||
|
CHECK(progress.granted(tools));
|
||||||
|
CHECK_EQ(progress.grantedTick(tools), 200);
|
||||||
|
CHECK_EQ(progress.completedCriteria(tools).size(), static_cast<std::size_t>(2));
|
||||||
|
CHECK_EQ(progress.totalExperience(), 10);
|
||||||
|
|
||||||
|
// Granting is a one shot: repeating the last event awards nothing again.
|
||||||
|
granted = progress.notify(Event::itemObtained(ItemId::CraftingTable), 260);
|
||||||
|
CHECK(granted.empty());
|
||||||
|
CHECK_EQ(progress.grantedTick(tools), 200);
|
||||||
|
CHECK_EQ(progress.totalExperience(), 10);
|
||||||
|
CHECK_EQ(progress.grantedCount(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(requirementGroupsAreSatisfiedByAnyOneOfTheirCriteria) {
|
||||||
|
std::vector<DataPackError> errors;
|
||||||
|
AdvancementTree tree = loadTree(contentPack(), errors);
|
||||||
|
const Advancement* hunter = tree.find(id("voxelforge:hunter"));
|
||||||
|
CHECK(hunter != nullptr);
|
||||||
|
CHECK(!hunter->satisfiedBy({}));
|
||||||
|
CHECK(hunter->satisfiedBy({"creeper"}));
|
||||||
|
CHECK(hunter->satisfiedBy({"zombies"}));
|
||||||
|
CHECK(hunter->danglingRequirements().empty());
|
||||||
|
|
||||||
|
// Without requirement groups every criterion is needed.
|
||||||
|
const Advancement* tools = tree.find(id("voxelforge:tools"));
|
||||||
|
CHECK(tools->requirements.empty());
|
||||||
|
CHECK(!tools->satisfiedBy({"sticks"}));
|
||||||
|
CHECK(tools->satisfiedBy({"sticks", "table"}));
|
||||||
|
|
||||||
|
const Advancement* traveller = tree.find(id("voxelforge:traveller"));
|
||||||
|
CHECK(!traveller->satisfiedBy({"portal"}));
|
||||||
|
CHECK(!traveller->satisfiedBy({"brew", "trade", "mine"}));
|
||||||
|
CHECK(traveller->satisfiedBy({"portal", "mine"}));
|
||||||
|
|
||||||
|
AdvancementProgress progress(tree);
|
||||||
|
std::vector<AdvancementId> granted =
|
||||||
|
progress.notify(Event::dimensionEntered(DimensionId::Nether), 10);
|
||||||
|
CHECK(granted.empty());
|
||||||
|
granted = progress.notify(Event::dimensionEntered(DimensionId::End), 20);
|
||||||
|
CHECK(granted.empty());
|
||||||
|
granted = progress.notify(Event::villagerTraded(VillagerProfession::Farmer,
|
||||||
|
ItemId::EmeraldGem),
|
||||||
|
30);
|
||||||
|
CHECK(granted.empty());
|
||||||
|
granted = progress.notify(Event::villagerTraded(VillagerProfession::Librarian,
|
||||||
|
ItemId::EmeraldGem),
|
||||||
|
40);
|
||||||
|
CHECK_EQ(granted.size(), static_cast<std::size_t>(1));
|
||||||
|
if (!granted.empty()) CHECK(granted[0] == id("voxelforge:traveller"));
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(countedCriteriaNeedEveryOneOfTheirEvents) {
|
||||||
|
std::vector<DataPackError> errors;
|
||||||
|
AdvancementTree tree = loadTree(contentPack(), errors);
|
||||||
|
AdvancementProgress progress(tree);
|
||||||
|
const AdvancementId hunter = id("voxelforge:hunter");
|
||||||
|
|
||||||
|
progress.notify(Event::mobKilled(Species::Zombie), 1);
|
||||||
|
progress.notify(Event::mobKilled(Species::Skeleton), 2);
|
||||||
|
CHECK_EQ(progress.criterionProgress(hunter, "zombies"), 1);
|
||||||
|
progress.notify(Event::mobKilled(Species::Zombie), 3);
|
||||||
|
CHECK_EQ(progress.criterionProgress(hunter, "zombies"), 2);
|
||||||
|
CHECK(!progress.granted(hunter));
|
||||||
|
|
||||||
|
std::vector<AdvancementId> granted = progress.notify(Event::mobKilled(Species::Zombie), 4);
|
||||||
|
CHECK_EQ(granted.size(), static_cast<std::size_t>(1));
|
||||||
|
if (!granted.empty()) CHECK(granted[0] == hunter);
|
||||||
|
CHECK(progress.criterionDone(hunter, "zombies"));
|
||||||
|
CHECK(!progress.criterionDone(hunter, "creeper"));
|
||||||
|
CHECK_EQ(progress.grantedTick(hunter), 4);
|
||||||
|
CHECK_EQ(progress.totalExperience(), 20);
|
||||||
|
CHECK_EQ(progress.awardedLootTables().size(), static_cast<std::size_t>(1));
|
||||||
|
CHECK(progress.awardedLootTables()[0] == id("voxelforge:chests/starter"));
|
||||||
|
CHECK(progress.unlockedRecipes().empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(hiddenAdvancementsStayOutOfSightUntilTheParentIsGranted) {
|
||||||
|
std::vector<DataPackError> errors;
|
||||||
|
AdvancementTree tree = loadTree(contentPack(), errors);
|
||||||
|
AdvancementProgress progress(tree);
|
||||||
|
const AdvancementId hunter = id("voxelforge:hunter");
|
||||||
|
const AdvancementId tools = id("voxelforge:tools");
|
||||||
|
|
||||||
|
CHECK(progress.visible(id("voxelforge:root")));
|
||||||
|
CHECK(progress.visible(tools));
|
||||||
|
CHECK(!progress.visible(hunter));
|
||||||
|
|
||||||
|
progress.notify(Event::itemObtained(ItemId::Stick, 4), 10);
|
||||||
|
CHECK(!progress.visible(hunter));
|
||||||
|
progress.notify(Event::itemObtained(ItemId::CraftingTable), 20);
|
||||||
|
CHECK(progress.granted(tools));
|
||||||
|
CHECK(progress.visible(hunter));
|
||||||
|
|
||||||
|
// A hidden advancement is also its own reveal once it is earned.
|
||||||
|
AdvancementTree lone;
|
||||||
|
Advancement secret = makeAdvancement("voxelforge:secret", "");
|
||||||
|
secret.hidden = true;
|
||||||
|
secret.criteria[0].matchMask = AdvancementCriterion::MatchItem;
|
||||||
|
secret.criteria[0].item = ItemId::DiamondGem;
|
||||||
|
CHECK(lone.add(secret));
|
||||||
|
AdvancementProgress hidden(lone);
|
||||||
|
CHECK(!hidden.visible(secret.id));
|
||||||
|
hidden.notify(Event::itemObtained(ItemId::DiamondGem), 5);
|
||||||
|
CHECK(hidden.granted(secret.id));
|
||||||
|
CHECK(hidden.visible(secret.id));
|
||||||
|
CHECK(!hidden.visible(id("voxelforge:nobody")));
|
||||||
|
}
|
||||||
|
|
||||||
|
VF_TEST(aParentLoopIsReportedInsteadOfWalkedForever) {
|
||||||
|
AdvancementTree tree;
|
||||||
|
CHECK(tree.add(makeAdvancement("voxelforge:first", "voxelforge:third")));
|
||||||
|
CHECK(tree.add(makeAdvancement("voxelforge:second", "voxelforge:first")));
|
||||||
|
CHECK(tree.add(makeAdvancement("voxelforge:third", "voxelforge:second")));
|
||||||
|
CHECK(tree.add(makeAdvancement("voxelforge:selfish", "voxelforge:selfish")));
|
||||||
|
CHECK(tree.add(makeAdvancement("voxelforge:orphan", "voxelforge:nowhere")));
|
||||||
|
|
||||||
|
CHECK(tree.hasCycle());
|
||||||
|
CHECK(tree.cycleFrom(id("voxelforge:first")));
|
||||||
|
CHECK(tree.cycleFrom(id("voxelforge:second")));
|
||||||
|
CHECK(tree.cycleFrom(id("voxelforge:selfish")));
|
||||||
|
CHECK(!tree.cycleFrom(id("voxelforge:orphan")));
|
||||||
|
CHECK_EQ(tree.depthOf(id("voxelforge:first")), -1);
|
||||||
|
CHECK_EQ(tree.depthOf(id("voxelforge:selfish")), -1);
|
||||||
|
CHECK_EQ(tree.depthOf(id("voxelforge:orphan")), -1);
|
||||||
|
CHECK_EQ(tree.missingParents().size(), static_cast<std::size_t>(1));
|
||||||
|
CHECK(tree.missingParents()[0] == id("voxelforge:orphan"));
|
||||||
|
CHECK(tree.roots().empty());
|
||||||
|
|
||||||
|
// A looping node still answers questions instead of hanging the caller.
|
||||||
|
AdvancementProgress progress(tree);
|
||||||
|
CHECK(progress.visible(id("voxelforge:first")));
|
||||||
|
std::vector<AdvancementId> granted = progress.notify(Event::itemObtained(ItemId::Dirt), 1);
|
||||||
|
CHECK_EQ(granted.size(), static_cast<std::size_t>(5));
|
||||||
|
CHECK(progress.granted(id("voxelforge:first")));
|
||||||
|
|
||||||
|
// Adding the same id twice is refused, so a duplicate cannot rewrite a node.
|
||||||
|
CHECK(!tree.add(makeAdvancement("voxelforge:first", "voxelforge:third")));
|
||||||
|
Advancement nameless;
|
||||||
|
CHECK(!tree.add(nameless));
|
||||||
|
CHECK_EQ(tree.size(), static_cast<std::size_t>(5));
|
||||||
|
tree.clear();
|
||||||
|
CHECK_EQ(tree.size(), static_cast<std::size_t>(0));
|
||||||
|
}
|
||||||
|
|
||||||
Reference in new issue
Block a user