// Cyphesis Online RPG Server and AI Engine // Copyright (C) 2007 Alistair Riddoch // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software Foundation, // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // $Id: PropertyExerciser.cpp,v 1.7 2007-11-26 02:57:06 alriddoch Exp $ #include "PropertyExerciser.h" #include "common/random.h" #include "common/Property.h" #include "common/inheritance.h" #include #include #include using Atlas::Message::Element; using Atlas::Message::IntType; using Atlas::Message::PtrType; using Atlas::Message::FloatType; using Atlas::Message::StringType; using Atlas::Message::ListType; using Atlas::Message::MapType; using Atlas::Objects::Entity::Anonymous; PropertyExerciser::PropertyExerciser() { integer_values.push_back(0); integer_values.push_back(-1); integer_values.push_back(23); integer_values.push_back(42); integer_values.push_back(INT_MAX); integer_values.push_back(INT_MIN); integer_values.push_back(UINT_MAX); integer_values.push_back(LONG_MAX); integer_values.push_back(LONG_MIN); float_values.push_back(0.f); float_values.push_back(-0.f); float_values.push_back(1.f); float_values.push_back(-1.f); float_values.push_back(23.f); float_values.push_back(42.f); float_values.push_back(-23.f); float_values.push_back(-42.f); float_values.push_back(__FLT_MIN__); float_values.push_back(__FLT_MAX__); float_values.push_back(__DBL_MIN__); float_values.push_back(__DBL_MAX__); ptr_values.push_back(0); ptr_values.push_back(&integer_ptr_target); ptr_values.push_back(&float_ptr_target); ptr_values.push_back(&ptr_ptr_target); ptr_values.push_back(&string_ptr_target); ptr_values.push_back(&map_ptr_target); ptr_values.push_back(&list_ptr_target); string_values.push_back(""); string_values.push_back("hello world"); string_values.push_back("goodbye, cruel world"); string_values.push_back(std::string(32768, ' ')); string_values.push_back(std::string(32768, 'a')); string_values.push_back(std::string(32768, 'B')); string_values.push_back(std::string(32768, '0')); string_values.push_back("!£$%^&*()_+}{[]:@~#';<>?/.,l\\|"); string_values.push_back("pwu3dc5012cw*/-+3+Q£%$\"q%2"); // Add all the standard class names to the string values list const TypeNodeDict & allTypes = Inheritance::instance().getAllObjects(); TypeNodeDict::const_iterator J = allTypes.begin(); TypeNodeDict::const_iterator Jend = allTypes.end(); for (; J != Jend; ++J) { string_values.push_back(J->first); } // FIXME Add all the common property names to the string values // empty list list_values.push_back(ListType()); // A number of lists of ints std::vector::const_iterator I = integer_values.begin(); std::vector::const_iterator Iend = integer_values.end(); for (; I != Iend; ++I) { list_values.push_back(ListType(1, *I)); } // A number of lists of floats std::vector::const_iterator F = float_values.begin(); std::vector::const_iterator Fend = float_values.end(); for (; F != Fend; ++F) { list_values.push_back(ListType(1, *F)); } // A number of lists of strings std::vector::const_iterator S = string_values.begin(); std::vector::const_iterator Send = string_values.end(); for (; S != Send; ++S) { list_values.push_back(ListType(1, *S)); } // A number of lists of pointers std::vector::const_iterator P = ptr_values.begin(); std::vector::const_iterator Pend = ptr_values.end(); for (; P != Pend; ++P) { list_values.push_back(ListType(1, *P)); } // A list of all the ints list_values.push_back(ListType()); I = integer_values.begin(); for (; I != Iend; ++I) { list_values.back().push_back(*I); } // A list of all the floats list_values.push_back(ListType()); F = float_values.begin(); for (; F != Fend; ++F) { list_values.back().push_back(*F); } // A list of all the strings list_values.push_back(ListType()); S = string_values.begin(); for (; S != Send; ++S) { list_values.back().push_back(*S); } // A list of all the pointers list_values.push_back(ListType()); P = ptr_values.begin(); for (; P != Pend; ++P) { list_values.back().push_back(*P); } // A heterogenous list list_values.push_back(ListType()); list_values.back().push_back(integer_values.front()); list_values.back().push_back(float_values.front()); list_values.back().push_back(ptr_values.front()); list_values.back().push_back(string_values.front()); for (int i = 0; i < 64; ++i) { list_values.push_back(ListType()); for (int j = 0; j < 64; ++j) { list_values.back().push_back(randomAtlasValue()); } } // empty list map_values.push_back(MapType()); std::vector::const_iterator K = string_values.begin(); std::vector::const_iterator Kend = string_values.end(); for (; K != Kend; ++K) { // A number of maps of ints I = integer_values.begin(); Iend = integer_values.end(); for (; I != Iend; ++I) { map_values.push_back(MapType()); map_values.back().insert(std::make_pair(*K, *I)); } // A number of maps of floats F = float_values.begin(); Fend = float_values.end(); for (; F != Fend; ++F) { map_values.back().insert(std::make_pair(*K, *F)); } // A number of maps of strings S = string_values.begin(); Send = string_values.end(); for (; S != Send; ++S) { map_values.back().insert(std::make_pair(*K, *S)); } // A number of maps of pointers P = ptr_values.begin(); Pend = ptr_values.end(); for (; P != Pend; ++P) { map_values.back().insert(std::make_pair(*K, *P)); } } // A list of all the ints map_values.push_back(MapType()); I = integer_values.begin(); for (; I != Iend; ++I) { map_values.back().insert(std::make_pair(randomString(), *I)); } // A list of all the floats map_values.push_back(MapType()); F = float_values.begin(); for (; F != Fend; ++F) { map_values.back().insert(std::make_pair(randomString(), *F)); } // A list of all the strings map_values.push_back(MapType()); S = string_values.begin(); for (; S != Send; ++S) { map_values.back().insert(std::make_pair(randomString(), *S)); } // A list of all the pointers map_values.push_back(MapType()); P = ptr_values.begin(); for (; P != Pend; ++P) { map_values.back().insert(std::make_pair(randomString(), *P)); } // A map full of random crap for (int i = 0; i < 64; ++i) { map_values.push_back(MapType()); for (int j = 0; j < 64; ++j) { map_values.back().insert(std::make_pair(randomString(), randomAtlasValue())); } } // Now that map_values is populated, use it to put some random stuff in // list_values // A number of lists of maps std::vector::const_iterator M = map_values.begin(); std::vector::const_iterator Mend = map_values.end(); for (; M != Mend; ++M) { list_values.push_back(ListType(1, *M)); } // A list of all the maps list_values.push_back(ListType()); M = map_values.begin(); for (; M != Mend; ++M) { list_values.back().push_back(*M); } } Element PropertyExerciser::randomAtlasValue() { switch (randint(0, 6)) { case 0: if (integer_values.empty()) { integer_values.push_back(0); } return integer_values[randint(0, integer_values.size())]; break; case 1: if (float_values.empty()) { float_values.push_back(0.1f); } return float_values[randint(0, float_values.size())]; break; case 2: if (ptr_values.empty()) { ptr_values.push_back(NULL); } return ptr_values[randint(0, ptr_values.size())]; break; case 3: if (string_values.empty()) { string_values.push_back(""); } return string_values[randint(0, string_values.size())]; break; case 4: if (list_values.empty()) { list_values.push_back(ListType()); } return list_values[randint(0, list_values.size())]; break; case 5: if (map_values.empty()) { map_values.push_back(MapType()); } return map_values[randint(0, map_values.size())]; break; case 6: std::cout << "NNOON 6" << std::endl << std::flush; default: return Element(); break; } } const std::string & PropertyExerciser::randomString() const { static const std::string empty_string; if (string_values.empty()) { return empty_string; } return string_values[randint(0, string_values.size())]; } void PropertyExerciser::testGet(PropertyBase & property, Element::Type element_type) { Element get_target; if (property.get(get_target)) { assert(get_target.getType() == element_type); } else { assert(get_target.getType() == Element::TYPE_NONE); } } void PropertyExerciser::testAdd(PropertyBase & property, Element::Type element_type) { Anonymous add_target; MapType add_target2; std::vector::const_iterator I = string_values.begin(); std::vector::const_iterator Iend = string_values.end(); for (; I != Iend; ++I) { property.add(*I, add_target); property.add(*I, add_target2); } } template void PropertyExerciser::testSetByType(PropertyBase & property, Element::Type element_type, const std::vector & values) { typename std::vector::const_iterator I = values.begin(); typename std::vector::const_iterator Iend = values.end(); for (; I != Iend; ++I) { property.set(*I); testGet(property, element_type); testAdd(property, element_type); } } void PropertyExerciser::testSet(PropertyBase & property, Element::Type element_type) { testSetByType(property, element_type, integer_values); testSetByType(property, element_type, float_values); testSetByType(property, element_type, ptr_values); testSetByType(property, element_type, string_values); testSetByType(property, element_type, map_values); testSetByType(property, element_type, list_values); } int PropertyExerciser::exerciseProperty(PropertyBase & property, Element::Type element_type) { testGet(property, element_type); testAdd(property, element_type); testSet(property, element_type); return 0; }