// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/> // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. #ifndef UT_LIGO_PRIMITIVE #define UT_LIGO_PRIMITIVE #include <nel/ligo/ligo_config.h> #include <nel/ligo/primitive_utils.h> class CUTLigoPrimitive : public Test::Suite { public: CUTLigoPrimitive() { TEST_ADD(CUTLigoPrimitive::testAliasGenerator) } private: string _RestorePath; string _WorkingPath; string _RefPrimFileName; void setup() { _RestorePath = NLMISC::CPath::getCurrentPath(); NLMISC::CPath::setCurrentPath(_WorkingPath.c_str()); _RefPrimFileName = "__test_prim.primitive"; // register ligo class factory NLLIGO::Register(); // create a primitive config file nlinfo("Building a default ligo class file"); const char *CLASS_FILE_NAME = "__ligo_class.xml"; string classfile; classfile = string() + "<?xml version=\"1.0\"?>\n" + "<NEL_LIGO_PRIMITIVE_CLASS>\n" + " <ALIAS_DYNAMIC_BITS BIT_COUNT=\"20\"/>\n" + " <ALIAS_STATIC_FILE_ID FILE_NAME=\"file_index.cfg\"/>\n" + "\n" + " <PRIMITIVE CLASS_NAME=\"root\" TYPE=\"node\" AUTO_INIT=\"true\" DELETABLE=\"true\">\n" + " <PARAMETER NAME=\"name\" TYPE=\"string\" VISIBLE=\"true\"/>\n" + " <PARAMETER NAME=\"path\" TYPE=\"string\" VISIBLE=\"true\"/>\n" + " <DYNAMIC_CHILD CLASS_NAME=\"test\"/>\n" + " </PRIMITIVE>\n" + "\n" + " <!-- the alias class, used by all other class that need persistent aliases-->\n" + " <PRIMITIVE CLASS_NAME=\"alias\" TYPE=\"alias\" AUTO_INIT=\"true\" DELETABLE=\"false\">\n" + " </PRIMITIVE>\n" + "\n" + " <PRIMITIVE CLASS_NAME=\"test\" TYPE=\"node\" AUTO_INIT=\"false\" DELETABLE=\"true\" NUMBERIZE=\"false\">\n" + " <PARAMETER NAME=\"name\" TYPE=\"string\" VISIBLE=\"true\"/>\n" + " <STATIC_CHILD CLASS_NAME=\"alias\" NAME=\"alias\"/>\n" + " <DYNAMIC_CHILD CLASS_NAME=\"test\"/>\n" + " </PRIMITIVE>\n" + "</NEL_LIGO_PRIMITIVE_CLASS>"; FILE *fp = fopen(CLASS_FILE_NAME, "wt"); nlassert(fp != NULL); size_t s = fwrite(classfile.data(), 1, classfile.size(), fp); nlassert(s == classfile.size()); fclose(fp); // init ligo NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig = &_LigoConfig; _LigoConfig.readPrimitiveClass(CLASS_FILE_NAME, false); // create a reference primitive if (NLMISC::CFile::isExists(_RefPrimFileName)) { NLMISC::CFile::deleteFile(_RefPrimFileName); } NLLIGO::CPrimitives primDoc; nlassert(primDoc.RootNode != NULL); NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = &primDoc; NLLIGO::IPrimitive *p = dynamic_cast<NLLIGO::IPrimitive *> (NLMISC::CClassRegistry::create ("CPrimNode")); p->addPropertyByName("class", new NLLIGO::CPropertyString("test")); p->addPropertyByName("name", new NLLIGO::CPropertyString("test_root")); primDoc.RootNode->insertChild(p); NLLIGO::CPrimAlias *pa = dynamic_cast<NLLIGO::CPrimAlias *> (NLMISC::CClassRegistry::create ("CPrimAlias")); pa->addPropertyByName("class", new NLLIGO::CPropertyString("alias")); pa->addPropertyByName("name", new NLLIGO::CPropertyString("alias")); p->insertChild(pa); NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL; // save the file saveXmlPrimitiveFile(primDoc, _RefPrimFileName); } void tear_down() { NLMISC::CPath::setCurrentPath(_RestorePath.c_str()); } void testAliasGenerator() { //Known bug : is we load/save a primitive and replacing a primitive node with itself (conserving the alias), the // 'last generated alias' counter is incremented. uint32 lastGeneratedAlias; // First, load then save the doc { NLLIGO::CPrimitives primDoc; NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = &primDoc; loadXmlPrimitiveFile(primDoc, _RefPrimFileName, _LigoConfig); NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL; lastGeneratedAlias = primDoc.getLastGeneratedAlias(); // get a copy of the primitive NLLIGO::IPrimitive *prim = NULL; NLLIGO::IPrimitive *primCopy = NULL; TEST_ASSERT(primDoc.RootNode->getChild(prim, 0)); if (prim) { primCopy = prim->copy(); TEST_ASSERT(primCopy != NULL); if (primCopy) { // remove the primitive primDoc.RootNode->removeChild(prim); // insert the copy NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = &primDoc; primDoc.RootNode->insertChild(primCopy); NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL; } } // save the file saveXmlPrimitiveFile(primDoc, _RefPrimFileName); } // second, reload the file and check the last generated alias { NLLIGO::CPrimitives primDoc; NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = &primDoc; loadXmlPrimitiveFile(primDoc, _RefPrimFileName, _LigoConfig); NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL; TEST_ASSERT(lastGeneratedAlias == primDoc.getLastGeneratedAlias()); } } NLLIGO::CLigoConfig _LigoConfig; }; #endif