From 3a7affff0c968f91b18404e2c3098c6045ae7163 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Thu, 10 Sep 2026 22:22:47 +0200 Subject: [PATCH] test: cover testBrewing --- tests/testBrewing.cpp | 156 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) diff --git a/tests/testBrewing.cpp b/tests/testBrewing.cpp index 14e8047..b0828d1 100644 --- a/tests/testBrewing.cpp +++ b/tests/testBrewing.cpp @@ -157,3 +157,159 @@ VF_TEST(theFullWaterToUpgradedSplashStrengthCycleRunsOnOneStand) { CHECK(upgraded.upgraded); CHECK(!upgraded.extended); + PotionItem splash = brewOnce(stand, Ingredient::Gunpowder); + CHECK_EQ(splash.form, PotionItem::Form::Splash); + CHECK_EQ(splash.kind, PotionKind::Strength); + CHECK(splash.upgraded); + + CHECK_EQ(stand.fuel, brewsPerBlazePowder - 4); + + EffectInstance effect = potionEffect(splash); + CHECK_EQ(effect.kind, EffectKind::Strength); + CHECK_EQ(effect.level(), 2); + CHECK_EQ(effect.durationTicks, 1800); +} + +VF_TEST(glowstoneRaisesTheLevelAndShortensWhileRedstoneOnlyLengthens) { + PotionItem plain = potionOf(PotionKind::Swiftness); + PotionItem upgraded = brewChain(plain, {Ingredient::Glowstone}); + PotionItem extended = brewChain(plain, {Ingredient::Redstone}); + + CHECK_EQ(potionEffect(plain).level(), 1); + CHECK_EQ(potionEffect(plain).durationTicks, 3600); + + CHECK(upgraded.upgraded); + CHECK_EQ(potionEffect(upgraded).level(), 2); + CHECK_EQ(potionEffect(upgraded).durationTicks, 1800); + + CHECK(extended.extended); + CHECK_EQ(potionEffect(extended).level(), 1); + CHECK_EQ(potionEffect(extended).durationTicks, 9600); +} + +VF_TEST(glowstoneAndRedstoneReplaceEachOtherAndNeverStack) { + BrewingStandState stand = fueledStand(potionOf(PotionKind::Swiftness), 5); + + PotionItem extended = brewOnce(stand, Ingredient::Redstone); + CHECK(extended.extended); + + PotionItem upgraded = brewOnce(stand, Ingredient::Glowstone); + CHECK(upgraded.upgraded); + CHECK(!upgraded.extended); + + PotionItem backToExtended = brewOnce(stand, Ingredient::Redstone); + CHECK(backToExtended.extended); + CHECK(!backToExtended.upgraded); + + bool changed = false; + brewResult(backToExtended, Ingredient::Redstone, changed); + CHECK(!changed); +} + +VF_TEST(potionsThatIgnoreAModifierRejectItInsteadOfSilentlyConsumingTheBrew) { + const PotionKind noGlowstone[] = {PotionKind::Weakness, PotionKind::FireResistance, + PotionKind::WaterBreathing, PotionKind::NightVision, + PotionKind::Invisibility}; + for (PotionKind kind : noGlowstone) { + bool changed = false; + brewResult(potionOf(kind), Ingredient::Glowstone, changed); + CHECK(!changed); + } + + const PotionKind noRedstone[] = {PotionKind::Healing, PotionKind::Harming}; + for (PotionKind kind : noRedstone) { + bool changed = false; + brewResult(potionOf(kind), Ingredient::Redstone, changed); + CHECK(!changed); + } + + bool healingUpgrades = false; + PotionItem strongHealing = brewResult(potionOf(PotionKind::Healing), Ingredient::Glowstone, + healingUpgrades); + CHECK(healingUpgrades); + CHECK_EQ(potionEffect(strongHealing).level(), 2); +} + +VF_TEST(fermentedSpiderEyeCorruptsAlongTheWholeInversionChain) { + const struct { PotionKind from; PotionKind to; } inversions[] = { + {PotionKind::Water, PotionKind::Weakness}, + {PotionKind::NightVision, PotionKind::Invisibility}, + {PotionKind::Healing, PotionKind::Harming}, + {PotionKind::Poison, PotionKind::Harming}, + {PotionKind::Swiftness, PotionKind::Slowness}, + {PotionKind::Leaping, PotionKind::Slowness}, + {PotionKind::Strength, PotionKind::Weakness}, + }; + for (const auto& inversion : inversions) { + bool changed = false; + PotionItem corrupted = brewResult(potionOf(inversion.from), Ingredient::FermentedSpiderEye, + changed); + CHECK(changed); + CHECK_EQ(corrupted.kind, inversion.to); + } + + const PotionKind uncorruptible[] = {PotionKind::Regeneration, PotionKind::FireResistance, + PotionKind::WaterBreathing, PotionKind::Awkward}; + for (PotionKind kind : uncorruptible) { + bool changed = false; + brewResult(potionOf(kind), Ingredient::FermentedSpiderEye, changed); + CHECK(!changed); + } +} + +VF_TEST(aKindChangeWipesTheModifiersButKeepsTheSplashForm) { + PotionItem source = potionOf(PotionKind::Swiftness); + source.upgraded = true; + source.form = PotionItem::Form::Splash; + + bool changed = false; + PotionItem corrupted = brewResult(source, Ingredient::FermentedSpiderEye, changed); + CHECK(changed); + CHECK_EQ(corrupted.kind, PotionKind::Slowness); + CHECK(!corrupted.upgraded); + CHECK(!corrupted.extended); + CHECK_EQ(corrupted.form, PotionItem::Form::Splash); +} + +VF_TEST(brewResultLeavesTheInputAloneWhenTheIngredientDoesNothing) { + PotionItem source = potionOf(PotionKind::Regeneration); + source.extended = true; + + bool changed = true; + PotionItem untouched = brewResult(source, Ingredient::SpiderEye, changed); + CHECK(!changed); + CHECK(untouched == source); + + changed = true; + PotionItem noIngredient = brewResult(source, Ingredient::None, changed); + CHECK(!changed); + CHECK(noIngredient == source); +} + +VF_TEST(theStandConvertsEveryOccupiedBottleInASinglePass) { + BrewingStandState stand; + CHECK(setBottle(stand, 0, PotionItem{})); + CHECK(setBottle(stand, 1, PotionItem{})); + CHECK(setBottle(stand, 2, PotionItem{})); + addFuel(stand, 1); + setIngredient(stand, Ingredient::NetherWart, 1); + + for (int tick = 0; tick < brewDurationTicks; ++tick) tickBrewing(stand); + + for (const BrewingSlot& bottle : stand.bottles) { + CHECK(bottle.occupied); + CHECK_EQ(bottle.potion.kind, PotionKind::Awkward); + } + CHECK_EQ(stand.fuel, brewsPerBlazePowder - 1); +} + +VF_TEST(bottlesTheIngredientCannotChangeAreLeftAsTheyWere) { + BrewingStandState stand; + setBottle(stand, 0, potionOf(PotionKind::Awkward)); + setBottle(stand, 1, PotionItem{}); + addFuel(stand, 1); + setIngredient(stand, Ingredient::Sugar, 1); + + CHECK(canBrew(stand)); + for (int tick = 0; tick < brewDurationTicks; ++tick) tickBrewing(stand); +