From 905ce4b23d9e9dad51de726ce1674100938e851c Mon Sep 17 00:00:00 2001 From: DualFroz Date: Fri, 11 Sep 2026 16:54:58 +0200 Subject: [PATCH] test: cover testDimension --- tests/testDimension.cpp | 156 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 tests/testDimension.cpp diff --git a/tests/testDimension.cpp b/tests/testDimension.cpp new file mode 100644 index 0000000..a701461 --- /dev/null +++ b/tests/testDimension.cpp @@ -0,0 +1,156 @@ +#include "testHarness.h" +#include "vf/Dimension.h" + +#include +#include + +using namespace vf; + +VF_TEST(dimensionConfigDescribesEachWorldsOwnRules) { + DimensionConfig overworld = DimensionConfig::forDimension(DimensionId::Overworld); + DimensionConfig nether = DimensionConfig::forDimension(DimensionId::Nether); + DimensionConfig end = DimensionConfig::forDimension(DimensionId::End); + + CHECK(overworld.hasSky); + CHECK(overworld.hasDayCycle); + CHECK(!overworld.hasCeiling); + CHECK(!overworld.bedsExplode); + CHECK(!overworld.waterEvaporates); + CHECK_NEAR(overworld.coordinateScale, 1.0f, 1e-6f); + + CHECK(!nether.hasSky); + CHECK(!nether.hasDayCycle); + CHECK(nether.hasCeiling); + CHECK(nether.bedsExplode); + CHECK(nether.waterEvaporates); + CHECK_NEAR(nether.coordinateScale, 8.0f, 1e-6f); + CHECK(nether.ambientLight > overworld.ambientLight); + + CHECK(!end.hasSky); + CHECK(!end.hasDayCycle); + CHECK(!end.hasCeiling); + CHECK(end.bedsExplode); + CHECK(!end.waterEvaporates); + CHECK_NEAR(end.coordinateScale, 1.0f, 1e-6f); + + CHECK(std::string(DimensionConfig::nameOf(DimensionId::Nether)) == "nether"); + CHECK(std::string(DimensionConfig::nameOf(DimensionId::End)) == "end"); + CHECK(std::string(DimensionConfig::nameOf(DimensionId::Overworld)) == "overworld"); +} + +VF_TEST(dimensionConfigClampsToItsOwnPlaceableRange) { + DimensionConfig nether = DimensionConfig::forDimension(DimensionId::Nether); + DimensionConfig overworld = DimensionConfig::forDimension(DimensionId::Overworld); + + CHECK_EQ(nether.clampY(-40), nether.lowestPlaceableY()); + CHECK_EQ(nether.clampY(9000), nether.highestPlaceableY()); + CHECK_EQ(nether.clampY(60), 60); + + // A dimension with a solid roof keeps one more block of margin than an + // open-sky one. + CHECK(nether.highestPlaceableY() < overworld.highestPlaceableY()); + CHECK_EQ(nether.height(), 128); +} + +VF_TEST(dimensionSetHoldsOneIndependentWorldPerDimension) { + DimensionSet dimensions(2026u); + + CHECK_EQ(static_cast(dimensions.overworld().id()), static_cast(DimensionId::Overworld)); + CHECK_EQ(static_cast(dimensions.nether().id()), static_cast(DimensionId::Nether)); + CHECK_EQ(static_cast(dimensions.end().id()), static_cast(DimensionId::End)); + + std::set seeds; + seeds.insert(dimensions.overworld().seed()); + seeds.insert(dimensions.nether().seed()); + seeds.insert(dimensions.end().seed()); + CHECK_EQ(seeds.size(), static_cast(3)); + + dimensions.nether().generateColumn(0, 0); + CHECK(dimensions.nether().world().chunkCount() > 0); + CHECK_EQ(dimensions.overworld().world().chunkCount(), static_cast(0)); + CHECK_EQ(dimensions.end().world().chunkCount(), static_cast(0)); + CHECK_EQ(dimensions.totalChunks(), dimensions.nether().world().chunkCount()); +} + +VF_TEST(dimensionSeedsFollowTheBaseSeedDeterministically) { + DimensionSet first(99u); + DimensionSet second(99u); + DimensionSet other(100u); + + CHECK_EQ(first.nether().seed(), second.nether().seed()); + CHECK_EQ(first.end().seed(), second.end().seed()); + CHECK(first.nether().seed() != other.nether().seed()); + CHECK(first.overworld().seed() != first.nether().seed()); +} + +VF_TEST(dimensionsTickIndependentlyOfEachOther) { + DimensionSet dimensions(7u); + + dimensions.tickOnly(DimensionId::Nether, 500); + CHECK_EQ(dimensions.nether().ticks(), 500ll); + CHECK_EQ(dimensions.overworld().ticks(), 0ll); + + dimensions.tickAll(100); + CHECK_EQ(dimensions.nether().ticks(), 600ll); + CHECK_EQ(dimensions.overworld().ticks(), 100ll); + CHECK_EQ(dimensions.end().ticks(), 100ll); + + dimensions.tickAll(11900); + CHECK_NEAR(dimensions.overworld().dayFraction(), 0.5f, 1e-4f); + CHECK_NEAR(dimensions.nether().dayFraction(), 0.0f, 1e-6f); + CHECK_NEAR(dimensions.end().dayFraction(), 0.0f, 1e-6f); +} + +VF_TEST(eachDimensionOwnsExactlyOneGenerator) { + DimensionSet dimensions(11u); + + CHECK(dimensions.overworld().overworldGenerator() != nullptr); + CHECK(dimensions.overworld().netherGenerator() == nullptr); + CHECK(dimensions.overworld().endGenerator() == nullptr); + + CHECK(dimensions.nether().netherGenerator() != nullptr); + CHECK(dimensions.nether().overworldGenerator() == nullptr); + + CHECK(dimensions.end().endGenerator() != nullptr); + CHECK(dimensions.end().netherGenerator() == nullptr); +} + +VF_TEST(dimensionGeneratesTerrainFromItsOwnGenerator) { + DimensionSet dimensions(31u); + + CHECK(!dimensions.nether().columnGenerated(2, -1)); + dimensions.nether().generateColumn(2, -1); + CHECK(dimensions.nether().columnGenerated(2, -1)); + CHECK_EQ(dimensions.nether().generatedColumnCount(), static_cast(1)); + + int netherrack = 0; + int endStone = 0; + for (int gx = 32; gx < 48; ++gx) + for (int gz = -16; gz < 0; ++gz) + for (int gy = 0; gy < 128; ++gy) + if (dimensions.nether().world().blockAt(gx, gy, gz) == Block::Netherrack) ++netherrack; + CHECK(netherrack > 500); + + dimensions.end().generateColumn(0, 0); + for (int gy = 0; gy < 128; ++gy) + if (dimensions.end().world().blockAt(4, gy, 4) == Block::EndStone) ++endStone; + CHECK(endStone > 0); + + // A second request for the same column is a no-op, not a regeneration. + std::size_t before = dimensions.nether().world().chunkCount(); + dimensions.nether().generateColumn(2, -1); + CHECK_EQ(dimensions.nether().world().chunkCount(), before); +} + +VF_TEST(generateAreaFillsTheWholeNeighbourhoodOnce) { + DimensionSet dimensions(5u); + int made = dimensions.end().generateArea(0, 0, 1); + CHECK_EQ(made, 9); + CHECK_EQ(dimensions.end().generateArea(0, 0, 1), 0); + CHECK_EQ(dimensions.end().generatedColumnCount(), static_cast(9)); +} + +VF_TEST(standingSpotNeedsSolidGroundAndHeadroom) { + DimensionSet dimensions(3u); + World& world = dimensions.overworld().world(); +