LCOV - code coverage report
Current view: top level - src/unittest - test.cpp (source / functions) Hit Total Coverage
Test: report Lines: 1 166 0.6 %
Date: 2015-07-11 18:23:49 Functions: 2 22 9.1 %

          Line data    Source code
       1             : /*
       2             : Minetest
       3             : Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
       4             : 
       5             : This program is free software; you can redistribute it and/or modify
       6             : it under the terms of the GNU Lesser General Public License as published by
       7             : the Free Software Foundation; either version 2.1 of the License, or
       8             : (at your option) any later version.
       9             : 
      10             : This program is distributed in the hope that it will be useful,
      11             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             : GNU Lesser General Public License for more details.
      14             : 
      15             : You should have received a copy of the GNU Lesser General Public License along
      16             : with this program; if not, write to the Free Software Foundation, Inc.,
      17             : 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             : */
      19             : 
      20             : #include "test.h"
      21             : 
      22             : #include "debug.h"
      23             : #include "log.h"
      24             : #include "nodedef.h"
      25             : #include "itemdef.h"
      26             : #include "gamedef.h"
      27             : 
      28             : content_t t_CONTENT_STONE;
      29             : content_t t_CONTENT_GRASS;
      30             : content_t t_CONTENT_TORCH;
      31             : content_t t_CONTENT_WATER;
      32             : content_t t_CONTENT_LAVA;
      33             : content_t t_CONTENT_BRICK;
      34             : 
      35             : ////////////////////////////////////////////////////////////////////////////////
      36             : 
      37             : ////
      38             : //// TestGameDef
      39             : ////
      40             : 
      41             : class TestGameDef : public IGameDef {
      42             : public:
      43             :         TestGameDef();
      44             :         ~TestGameDef();
      45             : 
      46           0 :         IItemDefManager *getItemDefManager() { return m_itemdef; }
      47           0 :         INodeDefManager *getNodeDefManager() { return m_nodedef; }
      48           0 :         ICraftDefManager *getCraftDefManager() { return m_craftdef; }
      49           0 :         ITextureSource *getTextureSource() { return m_texturesrc; }
      50           0 :         IShaderSource *getShaderSource() { return m_shadersrc; }
      51           0 :         ISoundManager *getSoundManager() { return m_soundmgr; }
      52           0 :         MtEventManager *getEventManager() { return m_eventmgr; }
      53           0 :         scene::ISceneManager *getSceneManager() { return m_scenemgr; }
      54           0 :         IRollbackManager *getRollbackManager() { return m_rollbackmgr; }
      55           0 :         EmergeManager *getEmergeManager() { return m_emergemgr; }
      56             : 
      57           0 :         scene::IAnimatedMesh *getMesh(const std::string &filename) { return NULL; }
      58           0 :         bool checkLocalPrivilege(const std::string &priv) { return false; }
      59           0 :         u16 allocateUnknownNodeId(const std::string &name) { return 0; }
      60             : 
      61             :         void defineSomeNodes();
      62             : 
      63             : private:
      64             :         IItemDefManager *m_itemdef;
      65             :         INodeDefManager *m_nodedef;
      66             :         ICraftDefManager *m_craftdef;
      67             :         ITextureSource *m_texturesrc;
      68             :         IShaderSource *m_shadersrc;
      69             :         ISoundManager *m_soundmgr;
      70             :         MtEventManager *m_eventmgr;
      71             :         scene::ISceneManager *m_scenemgr;
      72             :         IRollbackManager *m_rollbackmgr;
      73             :         EmergeManager *m_emergemgr;
      74             : };
      75             : 
      76             : 
      77           0 : TestGameDef::TestGameDef()
      78             : {
      79           0 :         m_itemdef = createItemDefManager();
      80           0 :         m_nodedef = createNodeDefManager();
      81             : 
      82           0 :         defineSomeNodes();
      83           0 : }
      84             : 
      85             : 
      86           0 : TestGameDef::~TestGameDef()
      87             : {
      88           0 :         delete m_itemdef;
      89           0 :         delete m_nodedef;
      90           0 : }
      91             : 
      92             : 
      93           0 : void TestGameDef::defineSomeNodes()
      94             : {
      95           0 :         IWritableItemDefManager *idef = (IWritableItemDefManager *)m_itemdef;
      96           0 :         IWritableNodeDefManager *ndef = (IWritableNodeDefManager *)m_nodedef;
      97             : 
      98           0 :         ItemDefinition itemdef;
      99           0 :         ContentFeatures f;
     100             : 
     101             :         //// Stone
     102           0 :         itemdef = ItemDefinition();
     103           0 :         itemdef.type = ITEM_NODE;
     104           0 :         itemdef.name = "default:stone";
     105           0 :         itemdef.description = "Stone";
     106           0 :         itemdef.groups["cracky"] = 3;
     107             :         itemdef.inventory_image = "[inventorycube"
     108             :                 "{default_stone.png"
     109             :                 "{default_stone.png"
     110           0 :                 "{default_stone.png";
     111           0 :         f = ContentFeatures();
     112           0 :         f.name = itemdef.name;
     113           0 :         for(int i = 0; i < 6; i++)
     114           0 :                 f.tiledef[i].name = "default_stone.png";
     115           0 :         f.is_ground_content = true;
     116           0 :         idef->registerItem(itemdef);
     117           0 :         t_CONTENT_STONE = ndef->set(f.name, f);
     118             : 
     119             :         //// Grass
     120           0 :         itemdef = ItemDefinition();
     121           0 :         itemdef.type = ITEM_NODE;
     122           0 :         itemdef.name = "default:dirt_with_grass";
     123           0 :         itemdef.description = "Dirt with grass";
     124           0 :         itemdef.groups["crumbly"] = 3;
     125             :         itemdef.inventory_image = "[inventorycube"
     126             :                 "{default_grass.png"
     127             :                 "{default_dirt.png&default_grass_side.png"
     128           0 :                 "{default_dirt.png&default_grass_side.png";
     129           0 :         f = ContentFeatures();
     130           0 :         f.name = itemdef.name;
     131           0 :         f.tiledef[0].name = "default_grass.png";
     132           0 :         f.tiledef[1].name = "default_dirt.png";
     133           0 :         for(int i = 2; i < 6; i++)
     134           0 :                 f.tiledef[i].name = "default_dirt.png^default_grass_side.png";
     135           0 :         f.is_ground_content = true;
     136           0 :         idef->registerItem(itemdef);
     137           0 :         t_CONTENT_GRASS = ndef->set(f.name, f);
     138             : 
     139             :         //// Torch (minimal definition for lighting tests)
     140           0 :         itemdef = ItemDefinition();
     141           0 :         itemdef.type = ITEM_NODE;
     142           0 :         itemdef.name = "default:torch";
     143           0 :         f = ContentFeatures();
     144           0 :         f.name = itemdef.name;
     145           0 :         f.param_type = CPT_LIGHT;
     146           0 :         f.light_propagates = true;
     147           0 :         f.sunlight_propagates = true;
     148           0 :         f.light_source = LIGHT_MAX-1;
     149           0 :         idef->registerItem(itemdef);
     150           0 :         t_CONTENT_TORCH = ndef->set(f.name, f);
     151             : 
     152             :         //// Water
     153           0 :         itemdef = ItemDefinition();
     154           0 :         itemdef.type = ITEM_NODE;
     155           0 :         itemdef.name = "default:water";
     156           0 :         itemdef.description = "Water";
     157             :         itemdef.inventory_image = "[inventorycube"
     158             :                 "{default_water.png"
     159             :                 "{default_water.png"
     160           0 :                 "{default_water.png";
     161           0 :         f = ContentFeatures();
     162           0 :         f.name = itemdef.name;
     163           0 :         f.alpha = 128;
     164           0 :         f.liquid_type = LIQUID_SOURCE;
     165           0 :         f.liquid_viscosity = 4;
     166           0 :         f.is_ground_content = true;
     167           0 :         f.groups["liquids"] = 3;
     168           0 :         for(int i = 0; i < 6; i++)
     169           0 :                 f.tiledef[i].name = "default_water.png";
     170           0 :         idef->registerItem(itemdef);
     171           0 :         t_CONTENT_WATER = ndef->set(f.name, f);
     172             : 
     173             :         //// Lava
     174           0 :         itemdef = ItemDefinition();
     175           0 :         itemdef.type = ITEM_NODE;
     176           0 :         itemdef.name = "default:lava";
     177           0 :         itemdef.description = "Lava";
     178             :         itemdef.inventory_image = "[inventorycube"
     179             :                 "{default_lava.png"
     180             :                 "{default_lava.png"
     181           0 :                 "{default_lava.png";
     182           0 :         f = ContentFeatures();
     183           0 :         f.name = itemdef.name;
     184           0 :         f.alpha = 128;
     185           0 :         f.liquid_type = LIQUID_SOURCE;
     186           0 :         f.liquid_viscosity = 7;
     187           0 :         f.light_source = LIGHT_MAX-1;
     188           0 :         f.is_ground_content = true;
     189           0 :         f.groups["liquids"] = 3;
     190           0 :         for(int i = 0; i < 6; i++)
     191           0 :                 f.tiledef[i].name = "default_lava.png";
     192           0 :         idef->registerItem(itemdef);
     193           0 :         t_CONTENT_LAVA = ndef->set(f.name, f);
     194             : 
     195             : 
     196             :         //// Brick
     197           0 :         itemdef = ItemDefinition();
     198           0 :         itemdef.type = ITEM_NODE;
     199           0 :         itemdef.name = "default:brick";
     200           0 :         itemdef.description = "Brick";
     201           0 :         itemdef.groups["cracky"] = 3;
     202             :         itemdef.inventory_image = "[inventorycube"
     203             :                 "{default_brick.png"
     204             :                 "{default_brick.png"
     205           0 :                 "{default_brick.png";
     206           0 :         f = ContentFeatures();
     207           0 :         f.name = itemdef.name;
     208           0 :         for(int i = 0; i < 6; i++)
     209           0 :                 f.tiledef[i].name = "default_brick.png";
     210           0 :         f.is_ground_content = true;
     211           0 :         idef->registerItem(itemdef);
     212           0 :         t_CONTENT_BRICK = ndef->set(f.name, f);
     213           0 : }
     214             : 
     215             : ////
     216             : //// run_tests
     217             : ////
     218             : 
     219           0 : void run_tests()
     220             : {
     221           0 :         DSTACK(__FUNCTION_NAME);
     222             : 
     223           0 :         u32 t1 = porting::getTime(PRECISION_MILLI);
     224           0 :         TestGameDef gamedef;
     225             : 
     226           0 :         log_set_lev_silence(LMT_ERROR, true);
     227             : 
     228           0 :         u32 num_modules_failed     = 0;
     229           0 :         u32 num_total_tests_failed = 0;
     230           0 :         u32 num_total_tests_run    = 0;
     231           0 :         std::vector<TestBase *> &testmods = TestManager::getTestModules();
     232           0 :         for (size_t i = 0; i != testmods.size(); i++) {
     233           0 :                 if (!testmods[i]->testModule(&gamedef))
     234           0 :                         num_modules_failed++;
     235             : 
     236           0 :                 num_total_tests_failed += testmods[i]->num_tests_failed;
     237           0 :                 num_total_tests_run += testmods[i]->num_tests_run;
     238             :         }
     239             : 
     240           0 :         u32 tdiff = porting::getTime(PRECISION_MILLI) - t1;
     241             : 
     242           0 :         log_set_lev_silence(LMT_ERROR, false);
     243             : 
     244           0 :         const char *overall_status = (num_modules_failed == 0) ? "PASSED" : "FAILED";
     245             : 
     246             :         dstream
     247           0 :                 << "++++++++++++++++++++++++++++++++++++++++"
     248           0 :                 << "++++++++++++++++++++++++++++++++++++++++" << std::endl
     249           0 :                 << "Unit Test Results: " << overall_status << std::endl
     250           0 :                 << "    " << num_modules_failed << " / " << testmods.size()
     251           0 :                 << " failed modules (" << num_total_tests_failed << " / "
     252           0 :                 << num_total_tests_run << " failed individual tests)." << std::endl
     253           0 :                 << "    Testing took " << tdiff << "ms total." << std::endl
     254           0 :                 << "++++++++++++++++++++++++++++++++++++++++"
     255           0 :                 << "++++++++++++++++++++++++++++++++++++++++" << std::endl;
     256             : 
     257           0 :         if (num_modules_failed)
     258           0 :                 abort();
     259           0 : }
     260             : 
     261             : ////
     262             : //// TestBase
     263             : ////
     264             : 
     265           0 : bool TestBase::testModule(IGameDef *gamedef)
     266             : {
     267           0 :         dstream << "======== Testing module " << getName() << std::endl;
     268           0 :         u32 t1 = porting::getTime(PRECISION_MILLI);
     269             : 
     270             : 
     271           0 :         runTests(gamedef);
     272             : 
     273           0 :         u32 tdiff = porting::getTime(PRECISION_MILLI) - t1;
     274           0 :         dstream << "======== Module " << getName() << " "
     275           0 :                 << (num_tests_failed ? "failed" : "passed") << " (" << num_tests_failed
     276           0 :                 << " failures / " << num_tests_run << " tests) - " << tdiff
     277           0 :                 << "ms" << std::endl;
     278             : 
     279           0 :         if (!m_test_dir.empty())
     280           0 :                 fs::RecursiveDelete(m_test_dir);
     281             : 
     282           0 :         return num_tests_failed == 0;
     283             : }
     284             : 
     285           0 : std::string TestBase::getTestTempDirectory()
     286             : {
     287           0 :         if (!m_test_dir.empty())
     288           0 :                 return m_test_dir;
     289             : 
     290             :         char buf[32];
     291           0 :         snprintf(buf, sizeof(buf), "%08X", myrand());
     292             : 
     293           0 :         m_test_dir = fs::TempPath() + DIR_DELIM "mttest_" + buf;
     294           0 :         if (!fs::CreateDir(m_test_dir))
     295           0 :                 throw TestFailedException();
     296             : 
     297           0 :         return m_test_dir;
     298             : }
     299             : 
     300           0 : std::string TestBase::getTestTempFile()
     301             : {
     302             :         char buf[32];
     303           0 :         snprintf(buf, sizeof(buf), "%08X", myrand());
     304             : 
     305           0 :         return getTestTempDirectory() + DIR_DELIM + buf + ".tmp";
     306           3 : }
     307             : 
     308             : 
     309             : /*
     310             :         NOTE: These tests became non-working then NodeContainer was removed.
     311             :               These should be redone, utilizing some kind of a virtual
     312             :                   interface for Map (IMap would be fine).
     313             : */
     314             : #if 0
     315             : struct TestMapBlock: public TestBase
     316             : {
     317             :         class TC : public NodeContainer
     318             :         {
     319             :         public:
     320             : 
     321             :                 MapNode node;
     322             :                 bool position_valid;
     323             :                 core::list<v3s16> validity_exceptions;
     324             : 
     325             :                 TC()
     326             :                 {
     327             :                         position_valid = true;
     328             :                 }
     329             : 
     330             :                 virtual bool isValidPosition(v3s16 p)
     331             :                 {
     332             :                         //return position_valid ^ (p==position_valid_exception);
     333             :                         bool exception = false;
     334             :                         for(core::list<v3s16>::Iterator i=validity_exceptions.begin();
     335             :                                         i != validity_exceptions.end(); i++)
     336             :                         {
     337             :                                 if(p == *i)
     338             :                                 {
     339             :                                         exception = true;
     340             :                                         break;
     341             :                                 }
     342             :                         }
     343             :                         return exception ? !position_valid : position_valid;
     344             :                 }
     345             : 
     346             :                 virtual MapNode getNode(v3s16 p)
     347             :                 {
     348             :                         if(isValidPosition(p) == false)
     349             :                                 throw InvalidPositionException();
     350             :                         return node;
     351             :                 }
     352             : 
     353             :                 virtual void setNode(v3s16 p, MapNode & n)
     354             :                 {
     355             :                         if(isValidPosition(p) == false)
     356             :                                 throw InvalidPositionException();
     357             :                 };
     358             : 
     359             :                 virtual u16 nodeContainerId() const
     360             :                 {
     361             :                         return 666;
     362             :                 }
     363             :         };
     364             : 
     365             :         void Run()
     366             :         {
     367             :                 TC parent;
     368             : 
     369             :                 MapBlock b(&parent, v3s16(1,1,1));
     370             :                 v3s16 relpos(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE);
     371             : 
     372             :                 UASSERT(b.getPosRelative() == relpos);
     373             : 
     374             :                 UASSERT(b.getBox().MinEdge.X == MAP_BLOCKSIZE);
     375             :                 UASSERT(b.getBox().MaxEdge.X == MAP_BLOCKSIZE*2-1);
     376             :                 UASSERT(b.getBox().MinEdge.Y == MAP_BLOCKSIZE);
     377             :                 UASSERT(b.getBox().MaxEdge.Y == MAP_BLOCKSIZE*2-1);
     378             :                 UASSERT(b.getBox().MinEdge.Z == MAP_BLOCKSIZE);
     379             :                 UASSERT(b.getBox().MaxEdge.Z == MAP_BLOCKSIZE*2-1);
     380             : 
     381             :                 UASSERT(b.isValidPosition(v3s16(0,0,0)) == true);
     382             :                 UASSERT(b.isValidPosition(v3s16(-1,0,0)) == false);
     383             :                 UASSERT(b.isValidPosition(v3s16(-1,-142,-2341)) == false);
     384             :                 UASSERT(b.isValidPosition(v3s16(-124,142,2341)) == false);
     385             :                 UASSERT(b.isValidPosition(v3s16(MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1)) == true);
     386             :                 UASSERT(b.isValidPosition(v3s16(MAP_BLOCKSIZE-1,MAP_BLOCKSIZE,MAP_BLOCKSIZE-1)) == false);
     387             : 
     388             :                 /*
     389             :                         TODO: this method should probably be removed
     390             :                         if the block size isn't going to be set variable
     391             :                 */
     392             :                 /*UASSERT(b.getSizeNodes() == v3s16(MAP_BLOCKSIZE,
     393             :                                 MAP_BLOCKSIZE, MAP_BLOCKSIZE));*/
     394             : 
     395             :                 // Changed flag should be initially set
     396             :                 UASSERT(b.getModified() == MOD_STATE_WRITE_NEEDED);
     397             :                 b.resetModified();
     398             :                 UASSERT(b.getModified() == MOD_STATE_CLEAN);
     399             : 
     400             :                 // All nodes should have been set to
     401             :                 // .d=CONTENT_IGNORE and .getLight() = 0
     402             :                 for(u16 z=0; z<MAP_BLOCKSIZE; z++)
     403             :                 for(u16 y=0; y<MAP_BLOCKSIZE; y++)
     404             :                 for(u16 x=0; x<MAP_BLOCKSIZE; x++)
     405             :                 {
     406             :                         //UASSERT(b.getNode(v3s16(x,y,z)).getContent() == CONTENT_AIR);
     407             :                         UASSERT(b.getNode(v3s16(x,y,z)).getContent() == CONTENT_IGNORE);
     408             :                         UASSERT(b.getNode(v3s16(x,y,z)).getLight(LIGHTBANK_DAY) == 0);
     409             :                         UASSERT(b.getNode(v3s16(x,y,z)).getLight(LIGHTBANK_NIGHT) == 0);
     410             :                 }
     411             : 
     412             :                 {
     413             :                         MapNode n(CONTENT_AIR);
     414             :                         for(u16 z=0; z<MAP_BLOCKSIZE; z++)
     415             :                         for(u16 y=0; y<MAP_BLOCKSIZE; y++)
     416             :                         for(u16 x=0; x<MAP_BLOCKSIZE; x++)
     417             :                         {
     418             :                                 b.setNode(v3s16(x,y,z), n);
     419             :                         }
     420             :                 }
     421             : 
     422             :                 /*
     423             :                         Parent fetch functions
     424             :                 */
     425             :                 parent.position_valid = false;
     426             :                 parent.node.setContent(5);
     427             : 
     428             :                 MapNode n;
     429             : 
     430             :                 // Positions in the block should still be valid
     431             :                 UASSERT(b.isValidPositionParent(v3s16(0,0,0)) == true);
     432             :                 UASSERT(b.isValidPositionParent(v3s16(MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1)) == true);
     433             :                 n = b.getNodeParent(v3s16(0,MAP_BLOCKSIZE-1,0));
     434             :                 UASSERT(n.getContent() == CONTENT_AIR);
     435             : 
     436             :                 // ...but outside the block they should be invalid
     437             :                 UASSERT(b.isValidPositionParent(v3s16(-121,2341,0)) == false);
     438             :                 UASSERT(b.isValidPositionParent(v3s16(-1,0,0)) == false);
     439             :                 UASSERT(b.isValidPositionParent(v3s16(MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1,MAP_BLOCKSIZE)) == false);
     440             : 
     441             :                 {
     442             :                         bool exception_thrown = false;
     443             :                         try{
     444             :                                 // This should throw an exception
     445             :                                 MapNode n = b.getNodeParent(v3s16(0,0,-1));
     446             :                         }
     447             :                         catch(InvalidPositionException &e)
     448             :                         {
     449             :                                 exception_thrown = true;
     450             :                         }
     451             :                         UASSERT(exception_thrown);
     452             :                 }
     453             : 
     454             :                 parent.position_valid = true;
     455             :                 // Now the positions outside should be valid
     456             :                 UASSERT(b.isValidPositionParent(v3s16(-121,2341,0)) == true);
     457             :                 UASSERT(b.isValidPositionParent(v3s16(-1,0,0)) == true);
     458             :                 UASSERT(b.isValidPositionParent(v3s16(MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1,MAP_BLOCKSIZE)) == true);
     459             :                 n = b.getNodeParent(v3s16(0,0,MAP_BLOCKSIZE));
     460             :                 UASSERT(n.getContent() == 5);
     461             : 
     462             :                 /*
     463             :                         Set a node
     464             :                 */
     465             :                 v3s16 p(1,2,0);
     466             :                 n.setContent(4);
     467             :                 b.setNode(p, n);
     468             :                 UASSERT(b.getNode(p).getContent() == 4);
     469             :                 //TODO: Update to new system
     470             :                 /*UASSERT(b.getNodeTile(p) == 4);
     471             :                 UASSERT(b.getNodeTile(v3s16(-1,-1,0)) == 5);*/
     472             : 
     473             :                 /*
     474             :                         propagateSunlight()
     475             :                 */
     476             :                 // Set lighting of all nodes to 0
     477             :                 for(u16 z=0; z<MAP_BLOCKSIZE; z++){
     478             :                         for(u16 y=0; y<MAP_BLOCKSIZE; y++){
     479             :                                 for(u16 x=0; x<MAP_BLOCKSIZE; x++){
     480             :                                         MapNode n = b.getNode(v3s16(x,y,z));
     481             :                                         n.setLight(LIGHTBANK_DAY, 0);
     482             :                                         n.setLight(LIGHTBANK_NIGHT, 0);
     483             :                                         b.setNode(v3s16(x,y,z), n);
     484             :                                 }
     485             :                         }
     486             :                 }
     487             :                 {
     488             :                         /*
     489             :                                 Check how the block handles being a lonely sky block
     490             :                         */
     491             :                         parent.position_valid = true;
     492             :                         b.setIsUnderground(false);
     493             :                         parent.node.setContent(CONTENT_AIR);
     494             :                         parent.node.setLight(LIGHTBANK_DAY, LIGHT_SUN);
     495             :                         parent.node.setLight(LIGHTBANK_NIGHT, 0);
     496             :                         core::map<v3s16, bool> light_sources;
     497             :                         // The bottom block is invalid, because we have a shadowing node
     498             :                         UASSERT(b.propagateSunlight(light_sources) == false);
     499             :                         UASSERT(b.getNode(v3s16(1,4,0)).getLight(LIGHTBANK_DAY) == LIGHT_SUN);
     500             :                         UASSERT(b.getNode(v3s16(1,3,0)).getLight(LIGHTBANK_DAY) == LIGHT_SUN);
     501             :                         UASSERT(b.getNode(v3s16(1,2,0)).getLight(LIGHTBANK_DAY) == 0);
     502             :                         UASSERT(b.getNode(v3s16(1,1,0)).getLight(LIGHTBANK_DAY) == 0);
     503             :                         UASSERT(b.getNode(v3s16(1,0,0)).getLight(LIGHTBANK_DAY) == 0);
     504             :                         UASSERT(b.getNode(v3s16(1,2,3)).getLight(LIGHTBANK_DAY) == LIGHT_SUN);
     505             :                         UASSERT(b.getFaceLight2(1000, p, v3s16(0,1,0)) == LIGHT_SUN);
     506             :                         UASSERT(b.getFaceLight2(1000, p, v3s16(0,-1,0)) == 0);
     507             :                         UASSERT(b.getFaceLight2(0, p, v3s16(0,-1,0)) == 0);
     508             :                         // According to MapBlock::getFaceLight,
     509             :                         // The face on the z+ side should have double-diminished light
     510             :                         //UASSERT(b.getFaceLight(p, v3s16(0,0,1)) == diminish_light(diminish_light(LIGHT_MAX)));
     511             :                         // The face on the z+ side should have diminished light
     512             :                         UASSERT(b.getFaceLight2(1000, p, v3s16(0,0,1)) == diminish_light(LIGHT_MAX));
     513             :                 }
     514             :                 /*
     515             :                         Check how the block handles being in between blocks with some non-sunlight
     516             :                         while being underground
     517             :                 */
     518             :                 {
     519             :                         // Make neighbours to exist and set some non-sunlight to them
     520             :                         parent.position_valid = true;
     521             :                         b.setIsUnderground(true);
     522             :                         parent.node.setLight(LIGHTBANK_DAY, LIGHT_MAX/2);
     523             :                         core::map<v3s16, bool> light_sources;
     524             :                         // The block below should be valid because there shouldn't be
     525             :                         // sunlight in there either
     526             :                         UASSERT(b.propagateSunlight(light_sources, true) == true);
     527             :                         // Should not touch nodes that are not affected (that is, all of them)
     528             :                         //UASSERT(b.getNode(v3s16(1,2,3)).getLight() == LIGHT_SUN);
     529             :                         // Should set light of non-sunlighted blocks to 0.
     530             :                         UASSERT(b.getNode(v3s16(1,2,3)).getLight(LIGHTBANK_DAY) == 0);
     531             :                 }
     532             :                 /*
     533             :                         Set up a situation where:
     534             :                         - There is only air in this block
     535             :                         - There is a valid non-sunlighted block at the bottom, and
     536             :                         - Invalid blocks elsewhere.
     537             :                         - the block is not underground.
     538             : 
     539             :                         This should result in bottom block invalidity
     540             :                 */
     541             :                 {
     542             :                         b.setIsUnderground(false);
     543             :                         // Clear block
     544             :                         for(u16 z=0; z<MAP_BLOCKSIZE; z++){
     545             :                                 for(u16 y=0; y<MAP_BLOCKSIZE; y++){
     546             :                                         for(u16 x=0; x<MAP_BLOCKSIZE; x++){
     547             :                                                 MapNode n;
     548             :                                                 n.setContent(CONTENT_AIR);
     549             :                                                 n.setLight(LIGHTBANK_DAY, 0);
     550             :                                                 b.setNode(v3s16(x,y,z), n);
     551             :                                         }
     552             :                                 }
     553             :                         }
     554             :                         // Make neighbours invalid
     555             :                         parent.position_valid = false;
     556             :                         // Add exceptions to the top of the bottom block
     557             :                         for(u16 x=0; x<MAP_BLOCKSIZE; x++)
     558             :                         for(u16 z=0; z<MAP_BLOCKSIZE; z++)
     559             :                         {
     560             :                                 parent.validity_exceptions.push_back(v3s16(MAP_BLOCKSIZE+x, MAP_BLOCKSIZE-1, MAP_BLOCKSIZE+z));
     561             :                         }
     562             :                         // Lighting value for the valid nodes
     563             :                         parent.node.setLight(LIGHTBANK_DAY, LIGHT_MAX/2);
     564             :                         core::map<v3s16, bool> light_sources;
     565             :                         // Bottom block is not valid
     566             :                         UASSERT(b.propagateSunlight(light_sources) == false);
     567             :                 }
     568             :         }
     569             : };
     570             : 
     571             : struct TestMapSector: public TestBase
     572             : {
     573             :         class TC : public NodeContainer
     574             :         {
     575             :         public:
     576             : 
     577             :                 MapNode node;
     578             :                 bool position_valid;
     579             : 
     580             :                 TC()
     581             :                 {
     582             :                         position_valid = true;
     583             :                 }
     584             : 
     585             :                 virtual bool isValidPosition(v3s16 p)
     586             :                 {
     587             :                         return position_valid;
     588             :                 }
     589             : 
     590             :                 virtual MapNode getNode(v3s16 p)
     591             :                 {
     592             :                         if(position_valid == false)
     593             :                                 throw InvalidPositionException();
     594             :                         return node;
     595             :                 }
     596             : 
     597             :                 virtual void setNode(v3s16 p, MapNode & n)
     598             :                 {
     599             :                         if(position_valid == false)
     600             :                                 throw InvalidPositionException();
     601             :                 };
     602             : 
     603             :                 virtual u16 nodeContainerId() const
     604             :                 {
     605             :                         return 666;
     606             :                 }
     607             :         };
     608             : 
     609             :         void Run()
     610             :         {
     611             :                 TC parent;
     612             :                 parent.position_valid = false;
     613             : 
     614             :                 // Create one with no heightmaps
     615             :                 ServerMapSector sector(&parent, v2s16(1,1));
     616             : 
     617             :                 UASSERT(sector.getBlockNoCreateNoEx(0) == 0);
     618             :                 UASSERT(sector.getBlockNoCreateNoEx(1) == 0);
     619             : 
     620             :                 MapBlock * bref = sector.createBlankBlock(-2);
     621             : 
     622             :                 UASSERT(sector.getBlockNoCreateNoEx(0) == 0);
     623             :                 UASSERT(sector.getBlockNoCreateNoEx(-2) == bref);
     624             : 
     625             :                 //TODO: Check for AlreadyExistsException
     626             : 
     627             :                 /*bool exception_thrown = false;
     628             :                 try{
     629             :                         sector.getBlock(0);
     630             :                 }
     631             :                 catch(InvalidPositionException &e){
     632             :                         exception_thrown = true;
     633             :                 }
     634             :                 UASSERT(exception_thrown);*/
     635             : 
     636             :         }
     637             : };
     638             : #endif

Generated by: LCOV version 1.11