cyphesis/tests/MemMapTest.cpp

521 lines
14 KiB
C++
Raw Permalink Normal View History

2009-05-20 01:30:46 +01:00
// Cyphesis Online RPG Server and AI Engine
// Copyright (C) 2009 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
2011-02-15 09:30:46 +00:00
#ifdef NDEBUG
#undef NDEBUG
#endif
#ifndef DEBUG
#define DEBUG
#endif
2013-01-17 14:14:23 +00:00
#include "TestBase.h"
#include "rules/ai/MemMap.h"
#include "rules/ai/MemEntity.h"
#include "rules/Script.h"
2009-05-20 01:30:46 +01:00
#include "common/log.h"
#include "common/TypeNode.h"
2013-01-17 16:54:21 +00:00
#include <Atlas/Objects/Anonymous.h>
2009-05-20 01:30:46 +01:00
#include <Atlas/Objects/Operation.h>
#include <Atlas/Objects/SmartPtr.h>
#include <cstdlib>
2009-05-20 01:30:46 +01:00
#include <cassert>
#include <rules/SimpleTypeStore.h>
2018-11-03 16:43:33 +01:00
#include <rules/ai/TypeResolver.h>
2009-05-20 01:30:46 +01:00
2013-01-17 16:54:21 +00:00
using Atlas::Objects::Entity::Anonymous;
2013-01-17 22:38:28 +00:00
using Atlas::Objects::Root;
2013-01-17 16:54:21 +00:00
2018-10-27 13:13:45 +02:00
struct TestTypeStore : public TypeStore
{
std::map<std::string, TypeNode*> m_types;
virtual const TypeNode* getType(const std::string& parent) const
{
auto I = m_types.find(parent);
if (I != m_types.end()) {
return I->second;
}
return nullptr;
}
virtual TypeNode* addChild(const Atlas::Objects::Root& obj)
{
auto type = new TypeNode(obj->getId());
type->setDescription(obj);
m_types[obj->getId()] = type;
return type;
}
};
2013-01-17 14:14:23 +00:00
class MemMaptest : public Cyphesis::TestBase
{
private:
2013-01-17 22:38:28 +00:00
TypeNode * m_sampleType;
2018-10-27 13:13:45 +02:00
TypeStore* m_typeStore;
TypeResolver* m_typeResolver;
2013-01-17 14:14:23 +00:00
MemMap * m_memMap;
2013-01-17 22:38:28 +00:00
static std::string m_Script_hook_called;
static LocatedEntity * m_Script_hook_called_with;
2009-05-20 01:30:46 +01:00
public:
2013-01-17 14:14:23 +00:00
MemMaptest();
2009-05-20 01:30:46 +01:00
2013-01-17 14:14:23 +00:00
void setup();
void teardown();
2013-01-17 16:54:21 +00:00
void test_addId();
void test_sendLooks();
void test_del();
void test_addEntity();
2013-01-17 22:38:28 +00:00
void test_addEntity_script();
void test_addEntity_script_hook();
2013-01-17 16:54:21 +00:00
void test_readEntity();
2013-01-17 22:38:28 +00:00
void test_readEntity_type();
void test_readEntity_type_nonexist();
void test_addEntityMemory();
void test_recallEntityMemory();
void test_getEntityRelatedMemory();
2013-01-18 14:02:33 +00:00
void test_findByLoc();
void test_findByLoc_results();
void test_findByLoc_invalid();
void test_findByLoc_consistency_check();
2013-01-17 22:38:28 +00:00
static void Script_hook_called(const std::string &, LocatedEntity *);
2013-01-17 22:38:28 +00:00
};
std::string MemMaptest::m_Script_hook_called;
LocatedEntity * MemMaptest::m_Script_hook_called_with = 0;
void MemMaptest::Script_hook_called(const std::string & hook,
LocatedEntity * ent)
{
m_Script_hook_called = hook;
m_Script_hook_called_with = ent;
}
class TestScript : public Script
{
public:
virtual void hook(const std::string & function, LocatedEntity * entity);
2009-05-20 01:30:46 +01:00
};
2013-01-17 22:38:28 +00:00
void TestScript::hook(const std::string & function, LocatedEntity * entity)
{
MemMaptest::Script_hook_called(function, entity);
}
2013-01-17 14:14:23 +00:00
MemMaptest::MemMaptest()
{
2013-01-17 16:54:21 +00:00
ADD_TEST(MemMaptest::test_addId);
ADD_TEST(MemMaptest::test_sendLooks);
ADD_TEST(MemMaptest::test_del);
ADD_TEST(MemMaptest::test_addEntity);
2013-01-17 22:38:28 +00:00
ADD_TEST(MemMaptest::test_addEntity_script);
ADD_TEST(MemMaptest::test_addEntity_script_hook);
2013-01-17 16:54:21 +00:00
ADD_TEST(MemMaptest::test_readEntity);
2013-01-17 22:38:28 +00:00
ADD_TEST(MemMaptest::test_readEntity_type);
ADD_TEST(MemMaptest::test_readEntity_type_nonexist);
ADD_TEST(MemMaptest::test_addEntityMemory);
ADD_TEST(MemMaptest::test_recallEntityMemory);
ADD_TEST(MemMaptest::test_getEntityRelatedMemory)
2013-01-18 14:02:33 +00:00
ADD_TEST(MemMaptest::test_findByLoc);
ADD_TEST(MemMaptest::test_findByLoc_results);
ADD_TEST(MemMaptest::test_findByLoc_invalid);
ADD_TEST(MemMaptest::test_findByLoc_consistency_check);
2013-01-17 14:14:23 +00:00
}
void MemMaptest::setup()
{
2013-01-17 22:38:28 +00:00
m_Script_hook_called = "";
2018-10-27 13:13:45 +02:00
m_Script_hook_called_with = nullptr;
m_typeStore = new TestTypeStore();
m_typeResolver = new TypeResolver(*m_typeStore);
2013-01-17 22:38:28 +00:00
Root type_desc;
type_desc->setId("sample_type");
2018-10-27 13:13:45 +02:00
m_sampleType = m_typeStore->addChild(type_desc);
m_memMap = new MemMap(*m_typeResolver);
2013-01-17 14:14:23 +00:00
}
void MemMaptest::teardown()
2009-05-20 01:30:46 +01:00
{
2013-01-17 14:14:23 +00:00
delete m_memMap;
2018-10-27 13:13:45 +02:00
delete m_typeResolver;
delete m_typeStore;
delete m_sampleType;
2013-01-17 14:14:23 +00:00
}
2009-05-20 01:30:46 +01:00
2013-01-17 16:54:21 +00:00
void MemMaptest::test_addId()
2013-01-17 14:14:23 +00:00
{
m_memMap->addId("2", 2);
2013-01-17 16:54:21 +00:00
}
2009-05-20 01:30:46 +01:00
2013-01-17 16:54:21 +00:00
void MemMaptest::test_sendLooks()
{
2009-05-20 01:30:46 +01:00
OpVector res;
2013-01-17 14:14:23 +00:00
m_memMap->sendLooks(res);
2013-01-17 16:54:21 +00:00
}
2009-05-20 01:30:46 +01:00
2013-01-17 16:54:21 +00:00
void MemMaptest::test_del()
{
2013-01-17 14:14:23 +00:00
m_memMap->del("2");
}
2013-01-17 16:54:21 +00:00
void MemMaptest::test_addEntity()
{
const std::string new_id("3");
2018-07-24 21:18:50 +02:00
ASSERT_FALSE(m_memMap->get(new_id));
2013-01-17 16:54:21 +00:00
MemEntity * ent = new MemEntity(new_id, 3);
2018-10-27 13:13:45 +02:00
ent->setType(m_sampleType);
2013-01-17 16:54:21 +00:00
m_memMap->addEntity(ent);
2018-07-24 21:18:50 +02:00
ASSERT_TRUE(m_memMap->get(new_id));
2013-01-17 22:38:28 +00:00
ASSERT_NULL(m_Script_hook_called_with);
}
void MemMaptest::test_addEntity_script()
{
auto script = new TestScript;
m_memMap->setScript(script);
2013-01-17 22:38:28 +00:00
const std::string new_id("3");
2018-07-24 21:18:50 +02:00
ASSERT_FALSE(m_memMap->get(new_id));
2013-01-17 22:38:28 +00:00
MemEntity * ent = new MemEntity(new_id, 3);
2018-10-27 13:13:45 +02:00
ent->setType(m_sampleType);
2013-01-17 22:38:28 +00:00
m_memMap->addEntity(ent);
2018-07-24 21:18:50 +02:00
ASSERT_TRUE(m_memMap->get(new_id));
2013-01-17 22:38:28 +00:00
ASSERT_NULL(m_Script_hook_called_with);
}
void MemMaptest::test_addEntity_script_hook()
{
const std::string new_id("3");
const std::string test_add_hook_name("test_add_hook");
auto script = new TestScript;
m_memMap->setScript(script);
2013-01-17 22:38:28 +00:00
m_memMap->m_addHooks.push_back(test_add_hook_name);
2018-07-24 21:18:50 +02:00
ASSERT_FALSE(m_memMap->get(new_id));
2013-01-17 22:38:28 +00:00
MemEntity * ent = new MemEntity(new_id, 3);
2018-10-27 13:13:45 +02:00
ent->setType(m_sampleType);
2013-01-17 22:38:28 +00:00
m_memMap->addEntity(ent);
2018-07-24 21:18:50 +02:00
ASSERT_TRUE(m_memMap->get(new_id));
2013-01-17 22:38:28 +00:00
ASSERT_NOT_NULL(m_Script_hook_called_with);
ASSERT_EQUAL(m_Script_hook_called, test_add_hook_name);
2013-01-17 16:54:21 +00:00
}
void MemMaptest::test_readEntity()
{
const std::string new_id("3");
2013-01-17 22:38:28 +00:00
Anonymous data;
MemEntity * ent = new MemEntity(new_id, 3);
2018-10-27 13:13:45 +02:00
ent->setType(m_sampleType);
2013-01-17 22:38:28 +00:00
2016-02-07 15:15:04 +01:00
m_memMap->readEntity(ent, data, 0);
2013-01-17 22:38:28 +00:00
}
void MemMaptest::test_readEntity_type()
{
const std::string new_id("3");
2013-01-17 16:54:21 +00:00
Anonymous data;
2017-07-24 13:39:22 +02:00
data->setParent("sample_type");
2013-01-17 16:54:21 +00:00
MemEntity * ent = new MemEntity(new_id, 3);
2016-02-07 15:15:04 +01:00
m_memMap->readEntity(ent, data, 0);
2013-01-17 22:38:28 +00:00
ASSERT_EQUAL(ent->getType(), m_sampleType);
}
void MemMaptest::test_readEntity_type_nonexist()
{
const std::string new_id("3");
Anonymous data;
2017-07-24 13:39:22 +02:00
data->setParent("non_sample_type");
2013-01-17 22:38:28 +00:00
MemEntity * ent = new MemEntity(new_id, 3);
2016-02-07 15:15:04 +01:00
m_memMap->readEntity(ent, data, 0);
2013-01-17 22:38:28 +00:00
2018-10-27 13:13:45 +02:00
ASSERT_NULL(ent->getType());
2013-01-17 16:54:21 +00:00
}
void MemMaptest::test_addEntityMemory(){
using Atlas::Message::Element;
//The entities that we have memories about don't actually have to exist
//Add some new memories
m_memMap->addEntityMemory("1", "disposition", 25);
m_memMap->addEntityMemory("1", "have_met", true);
//Check if they were added properly
assert(m_memMap->m_entityRelatedMemory["1"]["disposition"] == Element(25));
assert(m_memMap->m_entityRelatedMemory["1"]["have_met"] == Element(true));
//update an existing memory
m_memMap->addEntityMemory("1", "disposition", 30);
assert(m_memMap->m_entityRelatedMemory["1"]["disposition"] == Element(30));
}
void MemMaptest::test_recallEntityMemory(){
using Atlas::Message::Element;
//set up a map with 1 memory: disposition with value 25 related to entity with id 1
std::map<std::string, std::map<std::string, Element>> memories{{"1", std::map<std::string, Element>{{"disposition", 25}}}};
Element val1, val2;
m_memMap->m_entityRelatedMemory = memories;
//try recalling an existing memory
m_memMap->recallEntityMemory("1", "disposition", val1);
assert(val1 == Element(25));
//try recalling a non-existing memory about known entity
m_memMap->recallEntityMemory("1", "foo", val2);
assert(val2.isNone());
//try recalling about an unknown entity
m_memMap->recallEntityMemory("2", "disposition", val2);
assert(val2.isNone());
}
void MemMaptest::test_getEntityRelatedMemory(){
using Atlas::Message::Element;
std::map<std::string, std::map<std::string, Element>> memories{{"1", std::map<std::string, Element>{{"disposition", 25}}}};
m_memMap->m_entityRelatedMemory = memories;
assert(m_memMap->getEntityRelatedMemory() == memories);
}
2013-01-18 14:02:33 +00:00
void MemMaptest::test_findByLoc()
{
MemEntity * tlve = new MemEntity("3", 3);
tlve->setVisible();
m_memMap->m_entities[3] = tlve;
tlve->m_contains = new LocatedEntitySet;
MemEntity * e4 = new MemEntity("4", 4);
e4->setVisible();
e4->setType(m_sampleType);
m_memMap->m_entities[4] = tlve;
2018-08-17 22:04:07 +02:00
e4->m_location.m_parent = tlve;
2013-01-18 14:02:33 +00:00
e4->m_location.m_pos = Point3D(1,1,0);
tlve->m_contains->insert(e4);
MemEntity * e5 = new MemEntity("5", 5);
e5->setVisible();
e5->setType(m_sampleType);
m_memMap->m_entities[5] = tlve;
2018-08-17 22:04:07 +02:00
e5->m_location.m_parent = tlve;
2013-01-18 14:02:33 +00:00
e5->m_location.m_pos = Point3D(2,2,0);
tlve->m_contains->insert(e5);
Location find_here(tlve);
// Radius too small
EntityVector res = m_memMap->findByLocation(find_here,
1.f,
"sample_type");
2013-01-18 14:02:33 +00:00
ASSERT_TRUE(res.empty());
}
void MemMaptest::test_findByLoc_results()
{
MemEntity * tlve = new MemEntity("3", 3);
tlve->setVisible();
m_memMap->m_entities[3] = tlve;
tlve->m_contains = new LocatedEntitySet;
MemEntity * e4 = new MemEntity("4", 4);
e4->setVisible();
e4->setType(m_sampleType);
m_memMap->m_entities[4] = tlve;
2018-08-17 22:04:07 +02:00
e4->m_location.m_parent = tlve;
2013-01-18 14:02:33 +00:00
e4->m_location.m_pos = Point3D(1,1,0);
tlve->m_contains->insert(e4);
MemEntity * e5 = new MemEntity("5", 5);
e5->setVisible();
e5->setType(m_sampleType);
m_memMap->m_entities[5] = tlve;
2018-08-17 22:04:07 +02:00
e5->m_location.m_parent = tlve;
2013-01-18 14:02:33 +00:00
e5->m_location.m_pos = Point3D(2,2,0);
tlve->m_contains->insert(e5);
2018-10-27 13:13:45 +02:00
EntityLocation find_here(tlve);
2013-01-18 14:02:33 +00:00
EntityVector res = m_memMap->findByLocation(find_here,
5.f,
"sample_type");
2013-01-18 14:02:33 +00:00
ASSERT_TRUE(!res.empty());
ASSERT_EQUAL(res.size(), 2u);
}
void MemMaptest::test_findByLoc_invalid()
{
MemEntity * tlve = new MemEntity("3", 3);
tlve->setVisible();
m_memMap->m_entities[3] = tlve;
tlve->m_contains = new LocatedEntitySet;
MemEntity * e4 = new MemEntity("4", 4);
e4->setVisible();
e4->setType(m_sampleType);
m_memMap->m_entities[4] = tlve;
2018-08-17 22:04:07 +02:00
e4->m_location.m_parent = tlve;
2013-01-18 14:02:33 +00:00
e4->m_location.m_pos = Point3D(1,1,0);
tlve->m_contains->insert(e4);
MemEntity * e5 = new MemEntity("5", 5);
e5->setVisible();
e5->setType(m_sampleType);
m_memMap->m_entities[5] = tlve;
2018-08-17 22:04:07 +02:00
e5->m_location.m_parent = tlve;
2013-01-18 14:02:33 +00:00
e5->m_location.m_pos = Point3D(2,2,0);
tlve->m_contains->insert(e5);
// Look in a location where these is nothing - no contains at all
Location find_here(e4);
EntityVector res = m_memMap->findByLocation(find_here,
5.f,
"sample_type");
2013-01-18 14:02:33 +00:00
ASSERT_TRUE(res.empty());
}
void MemMaptest::test_findByLoc_consistency_check()
{
MemEntity * tlve = new MemEntity("3", 3);
tlve->setVisible();
tlve->setType(m_sampleType);
m_memMap->m_entities[3] = tlve;
tlve->m_contains = new LocatedEntitySet;
MemEntity * e4 = new MemEntity("4", 4);
e4->setVisible();
e4->setType(m_sampleType);
m_memMap->m_entities[4] = tlve;
2018-08-17 22:04:07 +02:00
e4->m_location.m_parent = tlve;
2013-01-18 14:02:33 +00:00
e4->m_location.m_pos = Point3D(1,1,0);
tlve->m_contains->insert(e4);
MemEntity * e5 = new MemEntity("5", 5);
e5->setVisible();
e5->setType(m_sampleType);
m_memMap->m_entities[5] = tlve;
2018-08-17 22:04:07 +02:00
e5->m_location.m_parent = tlve;
2013-01-18 14:02:33 +00:00
e5->m_location.m_pos = Point3D(2,2,0);
tlve->m_contains->insert(e5);
// Duplicated of tlve. Same ID, but not the same entity as in
// memmap. This will fail, but via a different path depending on
// DEBUG/NDEBUG. In debug build, the check in findByLoc will fail
// resulting in early return. In ndebug build, it will return empty
// by a longer path, as e3_dup contains no other entities.
MemEntity * e3_dup = new MemEntity("3", 3);
e3_dup->setType(m_sampleType);
e3_dup->m_contains = new LocatedEntitySet;
Location find_here(e3_dup);
EntityVector res = m_memMap->findByLocation(find_here,
5.f,
"sample_type");
2013-01-18 14:02:33 +00:00
ASSERT_TRUE(res.empty());
}
2013-01-17 14:14:23 +00:00
int main()
{
MemMaptest t;
2009-05-20 01:30:46 +01:00
2013-01-17 14:14:23 +00:00
return t.run();
2009-05-20 01:30:46 +01:00
}
// stubs
2018-11-03 16:43:33 +01:00
#include "stubs/rules/ai/stubMemEntity.h"
#include "stubs/rules/stubLocatedEntity.h"
#include "stubs/common/stubRouter.h"
2018-10-27 13:13:45 +02:00
#include "stubs/common/stubTypeNode.h"
2018-11-03 16:43:33 +01:00
#include "stubs/rules/stubLocation.h"
2018-10-27 13:13:45 +02:00
#define STUB_TypeResolver_requestType
const TypeNode* TypeResolver::requestType(const std::string& id, OpVector& res)
{
2018-10-27 13:13:45 +02:00
return m_typeStore.getType(id);
}
2018-10-27 13:13:45 +02:00
#define STUB_TypeResolver_getTypeStore
const TypeStore& TypeResolver::getTypeStore() const
{
2018-10-27 13:13:45 +02:00
return m_typeStore;
}
2018-11-03 16:43:33 +01:00
#include "stubs/rules/ai/stubTypeResolver.h"
2013-01-17 22:38:28 +00:00
2018-11-03 16:43:33 +01:00
#include "stubs/rules/stubScript.h"
2013-01-17 22:38:28 +00:00
float squareDistance(const Point3D & u, const Point3D & v)
{
return 1.f;
}
void log(LogLevel lvl, const std::string & msg)
{
2013-01-18 14:02:33 +00:00
std::cout << msg << std::endl;
}
long integerId(const std::string & id)
{
long intId = strtol(id.c_str(), 0, 10);
if (intId == 0 && id != "0") {
intId = -1L;
}
return intId;
}