Allow ObjDefManager instances to be cloned
[oweals/minetest.git] / src / unittest / test_objdef.cpp
index c2acdcfe7c1c6c26bdfc806c43434423ab7b1f82..40f7faa9d72961406c47fb28dfd34c541262391b 100644 (file)
@@ -32,6 +32,7 @@ public:
 
        void testHandles();
        void testAddGetSetClear();
+       void testClone();
 };
 
 static TestObjDef g_test_instance;
@@ -40,10 +41,42 @@ void TestObjDef::runTests(IGameDef *gamedef)
 {
        TEST(testHandles);
        TEST(testAddGetSetClear);
+       TEST(testClone);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
+/* Minimal implementation of ObjDef and ObjDefManager subclass */
+
+class MyObjDef : public ObjDef
+{
+public:
+       ObjDef *clone() const
+       {
+               auto def = new MyObjDef();
+               ObjDef::cloneTo(def);
+               def->testvalue = testvalue;
+               return def;
+       };
+
+       u32 testvalue;
+};
+
+class MyObjDefManager : public ObjDefManager
+{
+public:
+       MyObjDefManager(ObjDefType type) : ObjDefManager(NULL, type){};
+       MyObjDefManager *clone() const
+       {
+               auto mgr = new MyObjDefManager();
+               ObjDefManager::cloneTo(mgr);
+               return mgr;
+       };
+
+protected:
+       MyObjDefManager(){};
+};
+
 void TestObjDef::testHandles()
 {
        u32 uid = 0;
@@ -69,25 +102,25 @@ void TestObjDef::testAddGetSetClear()
 
        UASSERTEQ(ObjDefType, testmgr.getType(), OBJDEF_GENERIC);
 
-       obj0 = new ObjDef;
+       obj0 = new MyObjDef;
        obj0->name = "foobar";
        hObj0 = testmgr.add(obj0);
        UASSERT(hObj0 != OBJDEF_INVALID_HANDLE);
        UASSERTEQ(u32, obj0->index, 0);
 
-       obj1 = new ObjDef;
+       obj1 = new MyObjDef;
        obj1->name = "FooBaz";
        hObj1 = testmgr.add(obj1);
        UASSERT(hObj1 != OBJDEF_INVALID_HANDLE);
        UASSERTEQ(u32, obj1->index, 1);
 
-       obj2 = new ObjDef;
+       obj2 = new MyObjDef;
        obj2->name = "asdf";
        hObj2 = testmgr.add(obj2);
        UASSERT(hObj2 != OBJDEF_INVALID_HANDLE);
        UASSERTEQ(u32, obj2->index, 2);
 
-       obj3 = new ObjDef;
+       obj3 = new MyObjDef;
        obj3->name = "foobaz";
        hObj3 = testmgr.add(obj3);
        UASSERT(hObj3 == OBJDEF_INVALID_HANDLE);
@@ -104,3 +137,38 @@ void TestObjDef::testAddGetSetClear()
        testmgr.clear();
        UASSERTEQ(size_t, testmgr.getNumObjects(), 0);
 }
+
+void TestObjDef::testClone()
+{
+       MyObjDefManager testmgr(OBJDEF_GENERIC);
+       ObjDefManager *mgrcopy;
+       MyObjDef *obj, *temp2;
+       ObjDef *temp1;
+       ObjDefHandle hObj;
+
+       obj = new MyObjDef;
+       obj->testvalue = 0xee00ff11;
+       hObj = testmgr.add(obj);
+       UASSERT(hObj != OBJDEF_INVALID_HANDLE);
+
+       mgrcopy = testmgr.clone();
+       UASSERT(mgrcopy);
+       UASSERTEQ(ObjDefType, mgrcopy->getType(), testmgr.getType());
+       UASSERTEQ(size_t, mgrcopy->getNumObjects(), testmgr.getNumObjects());
+
+       // 1) check that the same handle is still valid on the copy
+       temp1 = mgrcopy->get(hObj);
+       UASSERT(temp1);
+       UASSERT(temp1 == mgrcopy->getRaw(0));
+       // 2) check that the copy has the correct C++ class
+       temp2 = dynamic_cast<MyObjDef *>(temp1);
+       UASSERT(temp2);
+       // 3) check that it was correctly copied
+       UASSERTEQ(u32, obj->testvalue, temp2->testvalue);
+       // 4) check that it was copied AT ALL (not the same)
+       UASSERT(obj != temp2);
+
+       testmgr.clear();
+       mgrcopy->clear();
+       delete mgrcopy;
+}