test: cover bottleOf and replayOnAStand
This commit is contained in:
1 parent
7eb223fa7a
commit
3bd3ad25bc
1 file changed
+157
@@ -0,0 +1,157 @@
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
#include "testHarness.h"
|
||||
#include "vf/PotionCatalog.h"
|
||||
|
||||
using namespace vf;
|
||||
|
||||
namespace {
|
||||
|
||||
using Ingredient = BrewRecipe::Ingredient;
|
||||
|
||||
PotionItem bottleOf(PotionKind kind, bool upgraded = false, bool extended = false,
|
||||
PotionItem::Form form = PotionItem::Form::Drinkable) {
|
||||
PotionItem potion;
|
||||
potion.kind = kind;
|
||||
potion.upgraded = upgraded;
|
||||
potion.extended = extended;
|
||||
potion.form = form;
|
||||
return potion;
|
||||
}
|
||||
|
||||
// Runs a whole ingredient list through an actual brewing stand, one full
|
||||
// four hundred tick brew per step.
|
||||
PotionItem replayOnAStand(const std::vector<Ingredient>& steps) {
|
||||
BrewingStandState stand;
|
||||
setBottle(stand, 0, PotionItem{});
|
||||
addFuel(stand, blazePowderForBrews(static_cast<int>(steps.size())) + 1);
|
||||
for (Ingredient ingredient : steps) {
|
||||
setIngredient(stand, ingredient, 1);
|
||||
for (int tick = 0; tick < brewDurationTicks; ++tick) tickBrewing(stand);
|
||||
}
|
||||
return stand.bottles[0].potion;
|
||||
}
|
||||
|
||||
PotionItem replayThroughSteps(const std::vector<Ingredient>& steps) {
|
||||
PotionItem bottle;
|
||||
for (Ingredient ingredient : steps) {
|
||||
bool changed = false;
|
||||
bottle = catalogBrewStep(bottle, ingredient, changed);
|
||||
if (!changed) return PotionItem{};
|
||||
}
|
||||
return bottle;
|
||||
}
|
||||
|
||||
int splashDurationThroughTheStand(const PotionItem& potion) {
|
||||
PotionItem splash = potion;
|
||||
splash.form = PotionItem::Form::Splash;
|
||||
EffectSet target;
|
||||
if (!splashPotion(target, splash, 0.0f, 4.0f)) return 0;
|
||||
return target.active[0].durationTicks;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
VF_TEST(theCatalogsPublishedConstantsAreTheOnesTheNumbersWereDerivedFrom) {
|
||||
CHECK_NEAR(splashDurationScale, 0.75f, 0.0001f);
|
||||
CHECK_NEAR(lingeringDoseScale, 0.25f, 0.0001f);
|
||||
CHECK_EQ(lingeringCloudTicks, 600);
|
||||
CHECK_EQ(lingeringCloudTicks, 30 * ticksPerSecond);
|
||||
|
||||
// Pinned against literals rather than the constants, so shifting a constant
|
||||
// cannot quietly shift the expectations with it.
|
||||
const PotionCatalog& catalog = potionCatalog();
|
||||
PotionItem swiftness = bottleOf(PotionKind::Swiftness);
|
||||
CHECK_EQ(catalog.variantTicks(swiftness), 3600);
|
||||
swiftness.form = PotionItem::Form::Splash;
|
||||
CHECK_EQ(catalog.variantTicks(swiftness), 2700);
|
||||
swiftness.form = PotionItem::Form::Lingering;
|
||||
CHECK_EQ(catalog.variantTicks(swiftness), 900);
|
||||
CHECK_EQ(catalog.cloudTicks(swiftness), 600);
|
||||
}
|
||||
|
||||
VF_TEST(theCatalogHasExactlyOneRowPerPotionKindInEnumOrder) {
|
||||
const PotionCatalog& catalog = potionCatalog();
|
||||
CHECK_EQ(catalog.size(), static_cast<std::size_t>(PotionKind::Count));
|
||||
|
||||
for (int index = 0; index < static_cast<int>(PotionKind::Count); ++index) {
|
||||
PotionKind kind = static_cast<PotionKind>(index);
|
||||
const PotionEntry& row = catalog.entry(kind);
|
||||
CHECK_EQ(row.kind, kind);
|
||||
CHECK(row.name != nullptr);
|
||||
CHECK(std::strlen(row.name) > 0);
|
||||
}
|
||||
|
||||
int duplicateNames = 0;
|
||||
const std::vector<PotionEntry>& rows = catalog.entries();
|
||||
for (std::size_t i = 0; i < rows.size(); ++i) {
|
||||
for (std::size_t j = i + 1; j < rows.size(); ++j) {
|
||||
if (std::strcmp(rows[i].name, rows[j].name) == 0) ++duplicateNames;
|
||||
}
|
||||
}
|
||||
CHECK_EQ(duplicateNames, 0);
|
||||
}
|
||||
|
||||
VF_TEST(everyCatalogDurationAndLevelMatchesWhatTheStandActuallyApplies) {
|
||||
const PotionCatalog& catalog = potionCatalog();
|
||||
for (int index = 0; index < static_cast<int>(PotionKind::Count); ++index) {
|
||||
PotionKind kind = static_cast<PotionKind>(index);
|
||||
const PotionEntry& row = catalog.entry(kind);
|
||||
|
||||
const struct { bool upgraded; bool extended; } modifiers[] = {
|
||||
{false, false}, {true, false}, {false, true}, {true, true}};
|
||||
for (const auto& modifier : modifiers) {
|
||||
PotionItem potion = bottleOf(kind, modifier.upgraded, modifier.extended);
|
||||
EffectInstance applied = potionEffect(potion);
|
||||
|
||||
CHECK_EQ(catalog.variantTicks(potion), applied.durationTicks);
|
||||
if (row.carriesEffect()) {
|
||||
CHECK_EQ(catalog.variantLevel(potion), applied.level());
|
||||
CHECK_EQ(row.effect, applied.kind);
|
||||
} else {
|
||||
CHECK_EQ(catalog.variantLevel(potion), 0);
|
||||
CHECK_EQ(applied.kind, EffectKind::Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VF_TEST(theSplashColumnOfTheCatalogMatchesWhatASplashBottleLandsAtTheImpactPoint) {
|
||||
const PotionCatalog& catalog = potionCatalog();
|
||||
int checkedTimedPotions = 0;
|
||||
for (const PotionEntry& row : catalog.entries()) {
|
||||
if (!row.carriesEffect()) continue;
|
||||
|
||||
const struct { bool upgraded; bool extended; } modifiers[] = {
|
||||
{false, false}, {true, false}, {false, true}};
|
||||
for (const auto& modifier : modifiers) {
|
||||
PotionItem drinkable = bottleOf(row.kind, modifier.upgraded, modifier.extended);
|
||||
PotionItem splash = drinkable;
|
||||
splash.form = PotionItem::Form::Splash;
|
||||
|
||||
CHECK_EQ(catalog.variantTicks(splash), splashDurationThroughTheStand(drinkable));
|
||||
CHECK_EQ(catalog.variantLevel(splash), catalog.variantLevel(drinkable));
|
||||
if (!row.instant) ++checkedTimedPotions;
|
||||
}
|
||||
}
|
||||
CHECK(checkedTimedPotions >= 30);
|
||||
}
|
||||
|
||||
VF_TEST(lingeringBottlesDoseAQuarterAndLeaveACloudBehindThem) {
|
||||
const PotionCatalog& catalog = potionCatalog();
|
||||
|
||||
PotionItem swiftness = bottleOf(PotionKind::Swiftness);
|
||||
CHECK_EQ(catalog.variantTicks(swiftness), 3600);
|
||||
CHECK_EQ(catalog.cloudTicks(swiftness), 0);
|
||||
|
||||
PotionItem lingering = bottleOf(PotionKind::Swiftness, false, false,
|
||||
PotionItem::Form::Lingering);
|
||||
CHECK_EQ(catalog.variantTicks(lingering), 900);
|
||||
CHECK_EQ(catalog.cloudTicks(lingering), lingeringCloudTicks);
|
||||
|
||||
PotionItem lingeringStrong = bottleOf(PotionKind::Swiftness, true, false,
|
||||
PotionItem::Form::Lingering);
|
||||
CHECK_EQ(catalog.variantTicks(lingeringStrong), 450);
|
||||
CHECK_EQ(catalog.variantLevel(lingeringStrong), 2);
|
||||
|
||||
Reference in new issue
Block a user