mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Add C++-side unit tests for MMVManip
This commit is contained in:
parent
7c7a9ceb53
commit
1e8fae2100
3 changed files with 89 additions and 44 deletions
|
@ -27,12 +27,13 @@ public:
|
||||||
void fill(v3s16 bpmin, v3s16 bpmax, MapNode n)
|
void fill(v3s16 bpmin, v3s16 bpmax, MapNode n)
|
||||||
{
|
{
|
||||||
for (s16 z = bpmin.Z; z <= bpmax.Z; z++)
|
for (s16 z = bpmin.Z; z <= bpmax.Z; z++)
|
||||||
for (s16 y = bpmin.Y; y <= bpmax.Y; y++)
|
for (s16 x = bpmin.X; x <= bpmax.X; x++)
|
||||||
for (s16 x = bpmin.X; x <= bpmax.X; x++) {
|
for (s16 y = bpmin.Y; y <= bpmax.Y; y++) {
|
||||||
MapBlock *block = getBlockNoCreateNoEx({x, y, z});
|
MapBlock *block = getBlockNoCreateNoEx({x, y, z});
|
||||||
if (block) {
|
if (block) {
|
||||||
|
auto *data = block->getData();
|
||||||
for (size_t i = 0; i < MapBlock::nodecount; i++)
|
for (size_t i = 0; i < MapBlock::nodecount; i++)
|
||||||
block->getData()[i] = n;
|
data[i] = n;
|
||||||
block->expireIsAirCache();
|
block->expireIsAirCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -772,7 +772,7 @@ void MMVManip::initialEmerge(v3s16 p_min, v3s16 p_max, bool load_if_inexistent)
|
||||||
infostream<<std::endl;
|
infostream<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool all_new = m_area.hasEmptyExtent() || block_area_nodes.contains(m_area);
|
const bool all_new = m_area.hasEmptyExtent();
|
||||||
addArea(block_area_nodes);
|
addArea(block_area_nodes);
|
||||||
|
|
||||||
for(s32 z=p_min.Z; z<=p_max.Z; z++)
|
for(s32 z=p_min.Z; z<=p_max.Z; z++)
|
||||||
|
@ -798,9 +798,9 @@ void MMVManip::initialEmerge(v3s16 p_min, v3s16 p_max, bool load_if_inexistent)
|
||||||
|
|
||||||
if(block_data_inexistent)
|
if(block_data_inexistent)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (load_if_inexistent && !blockpos_over_max_limit(p)) {
|
if (load_if_inexistent && !blockpos_over_max_limit(p)) {
|
||||||
block = m_map->emergeBlock(p, true);
|
block = m_map->emergeBlock(p, true);
|
||||||
|
assert(block);
|
||||||
block->copyTo(*this);
|
block->copyTo(*this);
|
||||||
} else {
|
} else {
|
||||||
flags |= VMANIP_BLOCK_DATA_INEXIST;
|
flags |= VMANIP_BLOCK_DATA_INEXIST;
|
||||||
|
|
|
@ -4,11 +4,13 @@
|
||||||
|
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <memory>
|
||||||
|
|
||||||
#include "gamedef.h"
|
#include "gamedef.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "voxel.h"
|
#include "voxel.h"
|
||||||
|
#include "dummymap.h"
|
||||||
|
#include "irrlicht_changes/printing.h"
|
||||||
|
|
||||||
class TestVoxelManipulator : public TestBase {
|
class TestVoxelManipulator : public TestBase {
|
||||||
public:
|
public:
|
||||||
|
@ -17,59 +19,30 @@ public:
|
||||||
|
|
||||||
void runTests(IGameDef *gamedef);
|
void runTests(IGameDef *gamedef);
|
||||||
|
|
||||||
void testVoxelArea();
|
void testBasic(const NodeDefManager *nodedef);
|
||||||
void testVoxelManipulator(const NodeDefManager *nodedef);
|
void testEmerge(IGameDef *gamedef);
|
||||||
|
void testBlitBack(IGameDef *gamedef);
|
||||||
};
|
};
|
||||||
|
|
||||||
static TestVoxelManipulator g_test_instance;
|
static TestVoxelManipulator g_test_instance;
|
||||||
|
|
||||||
void TestVoxelManipulator::runTests(IGameDef *gamedef)
|
void TestVoxelManipulator::runTests(IGameDef *gamedef)
|
||||||
{
|
{
|
||||||
TEST(testVoxelArea);
|
TEST(testBasic, gamedef->ndef());
|
||||||
TEST(testVoxelManipulator, gamedef->getNodeDefManager());
|
TEST(testEmerge, gamedef);
|
||||||
|
TEST(testBlitBack, gamedef);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void TestVoxelManipulator::testVoxelArea()
|
void TestVoxelManipulator::testBasic(const NodeDefManager *nodedef)
|
||||||
{
|
|
||||||
VoxelArea a(v3s16(-1,-1,-1), v3s16(1,1,1));
|
|
||||||
UASSERT(a.index(0,0,0) == 1*3*3 + 1*3 + 1);
|
|
||||||
UASSERT(a.index(-1,-1,-1) == 0);
|
|
||||||
|
|
||||||
VoxelArea c(v3s16(-2,-2,-2), v3s16(2,2,2));
|
|
||||||
// An area that is 1 bigger in x+ and z-
|
|
||||||
VoxelArea d(v3s16(-2,-2,-3), v3s16(3,2,2));
|
|
||||||
|
|
||||||
std::list<VoxelArea> aa;
|
|
||||||
d.diff(c, aa);
|
|
||||||
|
|
||||||
// Correct results
|
|
||||||
std::vector<VoxelArea> results;
|
|
||||||
results.emplace_back(v3s16(-2,-2,-3), v3s16(3,2,-3));
|
|
||||||
results.emplace_back(v3s16(3,-2,-2), v3s16(3,2,2));
|
|
||||||
|
|
||||||
UASSERT(aa.size() == results.size());
|
|
||||||
|
|
||||||
infostream<<"Result of diff:"<<std::endl;
|
|
||||||
for (auto it = aa.begin(); it != aa.end(); ++it) {
|
|
||||||
it->print(infostream);
|
|
||||||
infostream << std::endl;
|
|
||||||
|
|
||||||
auto j = std::find(results.begin(), results.end(), *it);
|
|
||||||
UASSERT(j != results.end());
|
|
||||||
results.erase(j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TestVoxelManipulator::testVoxelManipulator(const NodeDefManager *nodedef)
|
|
||||||
{
|
{
|
||||||
VoxelManipulator v;
|
VoxelManipulator v;
|
||||||
|
|
||||||
v.print(infostream, nodedef);
|
v.print(infostream, nodedef);
|
||||||
|
UASSERT(v.m_area.hasEmptyExtent());
|
||||||
|
|
||||||
infostream << "*** Setting (-1,0,-1)=2 ***" << std::endl;
|
infostream << "*** Setting (-1,0,-1) ***" << std::endl;
|
||||||
v.setNode(v3s16(-1,0,-1), MapNode(t_CONTENT_GRASS));
|
v.setNode(v3s16(-1,0,-1), MapNode(t_CONTENT_GRASS));
|
||||||
|
|
||||||
v.print(infostream, nodedef);
|
v.print(infostream, nodedef);
|
||||||
|
@ -89,3 +62,74 @@ void TestVoxelManipulator::testVoxelManipulator(const NodeDefManager *nodedef)
|
||||||
UASSERT(v.getNode(v3s16(-1,0,-1)).getContent() == t_CONTENT_GRASS);
|
UASSERT(v.getNode(v3s16(-1,0,-1)).getContent() == t_CONTENT_GRASS);
|
||||||
EXCEPTION_CHECK(InvalidPositionException, v.getNode(v3s16(0,1,1)));
|
EXCEPTION_CHECK(InvalidPositionException, v.getNode(v3s16(0,1,1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestVoxelManipulator::testEmerge(IGameDef *gamedef)
|
||||||
|
{
|
||||||
|
constexpr int bs = MAP_BLOCKSIZE;
|
||||||
|
|
||||||
|
DummyMap map(gamedef, {0,0,0}, {1,1,1});
|
||||||
|
map.fill({0,0,0}, {1,1,1}, CONTENT_AIR);
|
||||||
|
|
||||||
|
MMVManip vm(&map);
|
||||||
|
UASSERT(!vm.isOrphan());
|
||||||
|
|
||||||
|
// emerge something
|
||||||
|
vm.initialEmerge({0,0,0}, {0,0,0});
|
||||||
|
UASSERTEQ(auto, vm.m_area.MinEdge, v3s16(0));
|
||||||
|
UASSERTEQ(auto, vm.m_area.MaxEdge, v3s16(bs-1));
|
||||||
|
UASSERTEQ(auto, vm.getNodeNoExNoEmerge({0,0,0}).getContent(), CONTENT_AIR);
|
||||||
|
|
||||||
|
map.setNode({0, 1,0}, t_CONTENT_BRICK);
|
||||||
|
map.setNode({0,bs+1,0}, t_CONTENT_BRICK);
|
||||||
|
|
||||||
|
// emerge top block: this should not re-read the first one
|
||||||
|
vm.initialEmerge({0,0,0}, {0,1,0});
|
||||||
|
UASSERTEQ(auto, vm.m_area.getExtent(), v3s32(bs,2*bs,bs));
|
||||||
|
|
||||||
|
UASSERTEQ(auto, vm.getNodeNoExNoEmerge({0, 1,0}).getContent(), CONTENT_AIR);
|
||||||
|
UASSERTEQ(auto, vm.getNodeNoExNoEmerge({0,bs+1,0}).getContent(), t_CONTENT_BRICK);
|
||||||
|
|
||||||
|
// emerge out of bounds: should produce empty data
|
||||||
|
vm.initialEmerge({0,0,0}, {0,2,0}, false);
|
||||||
|
UASSERTEQ(auto, vm.m_area.getExtent(), v3s32(bs,3*bs,bs));
|
||||||
|
|
||||||
|
UASSERTEQ(auto, vm.getNodeNoExNoEmerge({0,2*bs,0}).getContent(), CONTENT_IGNORE);
|
||||||
|
UASSERT(!vm.exists({0,2*bs,0}));
|
||||||
|
|
||||||
|
// clear
|
||||||
|
vm.clear();
|
||||||
|
UASSERT(vm.m_area.hasEmptyExtent());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestVoxelManipulator::testBlitBack(IGameDef *gamedef)
|
||||||
|
{
|
||||||
|
DummyMap map(gamedef, {-1,-1,-1}, {1,1,1});
|
||||||
|
map.fill({0,0,0}, {0,0,0}, CONTENT_AIR);
|
||||||
|
|
||||||
|
std::unique_ptr<MMVManip> vm2;
|
||||||
|
|
||||||
|
{
|
||||||
|
MMVManip vm(&map);
|
||||||
|
vm.initialEmerge({0,0,0}, {0,0,0});
|
||||||
|
UASSERT(vm.exists({0,0,0}));
|
||||||
|
vm.setNodeNoEmerge({0,0,0}, t_CONTENT_STONE);
|
||||||
|
vm.setNodeNoEmerge({1,1,1}, t_CONTENT_GRASS);
|
||||||
|
vm.setNodeNoEmerge({2,2,2}, CONTENT_IGNORE);
|
||||||
|
// test out clone and reparent too
|
||||||
|
vm2.reset(vm.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
UASSERT(vm2);
|
||||||
|
UASSERT(vm2->isOrphan());
|
||||||
|
vm2->reparent(&map);
|
||||||
|
|
||||||
|
std::map<v3s16, MapBlock*> modified;
|
||||||
|
vm2->blitBackAll(&modified);
|
||||||
|
UASSERTEQ(size_t, modified.size(), 1);
|
||||||
|
UASSERTEQ(auto, modified.begin()->first, v3s16(0,0,0));
|
||||||
|
|
||||||
|
UASSERTEQ(auto, map.getNode({0,0,0}).getContent(), t_CONTENT_STONE);
|
||||||
|
UASSERTEQ(auto, map.getNode({1,1,1}).getContent(), t_CONTENT_GRASS);
|
||||||
|
// ignore nodes are not written (is this an intentional feature?)
|
||||||
|
UASSERTEQ(auto, map.getNode({2,2,2}).getContent(), CONTENT_AIR);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue