Files
voxelforge/tests/testItem.cpp
T

144 lines
4.9 KiB
C++

#include "testHarness.h"
#include "vf/Item.h"
using namespace vf;
VF_TEST(blockItemRoundTripsBothWays) {
CHECK(itemForBlock(Block::Stone) == ItemId::Stone);
CHECK(blockForItem(ItemId::Stone) == Block::Stone);
CHECK(itemForBlock(Block::CraftingTable) == ItemId::CraftingTable);
CHECK(blockForItem(ItemId::CraftingTable) == Block::CraftingTable);
CHECK(itemForBlock(Block::Tnt) == ItemId::Tnt);
CHECK(blockForItem(ItemId::Tnt) == Block::Tnt);
}
VF_TEST(blockItemMappingHasNoCounterpartForUnobtainableBlocks) {
CHECK(itemForBlock(Block::Bedrock) == ItemId::None);
CHECK(itemForBlock(Block::Air) == ItemId::None);
CHECK(itemForBlock(Block::Water) == ItemId::None);
CHECK(blockForItem(ItemId::IronIngot) == Block::Air);
CHECK(blockForItem(ItemId::Stick) == Block::Air);
CHECK(blockForItem(ItemId::WoodPickaxe) == Block::Air);
}
VF_TEST(itemKindsAndStackSizesAreCorrect) {
CHECK(isBlockItem(ItemId::Stone));
CHECK(!isBlockItem(ItemId::WoodPickaxe));
CHECK(isTool(ItemId::DiamondSword));
CHECK(!isTool(ItemId::Stone));
CHECK(isFood(ItemId::Bread));
CHECK(!isFood(ItemId::Stick));
CHECK_EQ(maxStackSize(ItemId::Stone), 64);
CHECK_EQ(maxStackSize(ItemId::WoodPickaxe), 1);
CHECK_EQ(maxStackSize(ItemId::Bread), 64);
}
VF_TEST(toolDurabilityRisesWithTierExceptGold) {
int wood = toolMaxDurability(ItemId::WoodPickaxe);
int stone = toolMaxDurability(ItemId::StonePickaxe);
int iron = toolMaxDurability(ItemId::IronPickaxe);
int gold = toolMaxDurability(ItemId::GoldPickaxe);
int diamond = toolMaxDurability(ItemId::DiamondPickaxe);
CHECK(wood > 0);
CHECK(stone > wood);
CHECK(iron > stone);
CHECK(diamond > iron);
CHECK(gold < wood); // gold tools are notoriously fragile
CHECK_EQ(toolMaxDurability(ItemId::Stone), 0);
}
VF_TEST(correctToolMatchesExpectedBlockClasses) {
CHECK(correctToolFor(Block::Stone) == ToolType::Pickaxe);
CHECK(correctToolFor(Block::Cobblestone) == ToolType::Pickaxe);
CHECK(correctToolFor(Block::Wood) == ToolType::Axe);
CHECK(correctToolFor(Block::Planks) == ToolType::Axe);
CHECK(correctToolFor(Block::Dirt) == ToolType::Shovel);
CHECK(correctToolFor(Block::Sand) == ToolType::Shovel);
CHECK(correctToolFor(Block::Leaves) == ToolType::Hoe);
CHECK(correctToolFor(Block::Torch) == ToolType::None);
}
VF_TEST(miningSpeedMultiplierRewardsMatchingToolAndTier) {
CHECK_NEAR(miningSpeedMultiplier(ItemId::None, Block::Stone), 1.0f, 1e-6f);
CHECK_NEAR(miningSpeedMultiplier(ItemId::WoodPickaxe, Block::Stone), 2.0f, 1e-6f);
CHECK_NEAR(miningSpeedMultiplier(ItemId::DiamondPickaxe, Block::Stone), 8.0f, 1e-6f);
// Wrong tool class for the block: no bonus, same as bare hands.
CHECK_NEAR(miningSpeedMultiplier(ItemId::StonePickaxe, Block::Wood), 1.0f, 1e-6f);
CHECK_NEAR(miningSpeedMultiplier(ItemId::StoneAxe, Block::Wood), 4.0f, 1e-6f);
}
VF_TEST(damageToolBreaksAtZeroDurability) {
ItemSlot stack = makeToolStack(ItemId::WoodPickaxe);
int durability = stack.durability;
CHECK(durability > 0);
bool broke = false;
for (int i = 0; i < durability - 1; ++i) {
broke = damageTool(stack);
CHECK(!broke);
CHECK(!stack.empty());
}
broke = damageTool(stack);
CHECK(broke);
CHECK(stack.empty());
CHECK(stack.item == ItemId::None);
}
VF_TEST(damageToolIsNoOpOnNonTools) {
ItemSlot stack{ItemId::Stone, 10, 0};
bool broke = damageTool(stack);
CHECK(!broke);
CHECK_EQ(stack.count, 10);
}
VF_TEST(mergeStacksFillsUpToLimitAndLeavesRemainder) {
ItemSlot into{ItemId::Stone, 60, 0};
ItemSlot from{ItemId::Stone, 20, 0};
int moved = mergeStacks(into, from);
CHECK_EQ(moved, 4);
CHECK_EQ(into.count, 64);
CHECK_EQ(from.count, 16);
}
VF_TEST(mergeStacksIntoEmptyMovesEverything) {
ItemSlot into{};
ItemSlot from{ItemId::Cobblestone, 30, 0};
int moved = mergeStacks(into, from);
CHECK_EQ(moved, 30);
CHECK(into.item == ItemId::Cobblestone);
CHECK_EQ(into.count, 30);
CHECK(from.empty());
}
VF_TEST(mergeStacksRefusesDifferentItems) {
ItemSlot into{ItemId::Stone, 5, 0};
ItemSlot from{ItemId::Dirt, 5, 0};
int moved = mergeStacks(into, from);
CHECK_EQ(moved, 0);
CHECK_EQ(into.count, 5);
CHECK_EQ(from.count, 5);
}
VF_TEST(splitStackDividesAndEmptiesFully) {
ItemSlot stack{ItemId::Planks, 10, 0};
ItemSlot half = splitStack(stack, 4);
CHECK_EQ(half.count, 4);
CHECK(half.item == ItemId::Planks);
CHECK_EQ(stack.count, 6);
ItemSlot rest = splitStack(stack, 100);
CHECK_EQ(rest.count, 6);
CHECK(stack.empty());
}
VF_TEST(foodValueRewardsCookedOverRaw) {
FoodValue raw = foodValue(ItemId::RawPorkchop);
FoodValue cooked = foodValue(ItemId::CookedPorkchop);
CHECK(cooked.hunger > raw.hunger);
CHECK(cooked.saturation > raw.saturation);
FoodValue notFood = foodValue(ItemId::Stone);
CHECK_EQ(notFood.hunger, 0);
}