Minor refactor of ReferenceHelper

Removed some asserts
Added more unit tests
This commit is contained in:
Magne Sjaastad 2015-10-06 15:03:55 +02:00
parent 6e67c61f28
commit bbc6fb1511
3 changed files with 345 additions and 44 deletions

View File

@ -17,6 +17,7 @@ set( PROJECT_FILES
gtest/gtest-all.cpp
cafPdmCoreBasicTest.cpp
cafPdmReferenceHelperTest.cpp
Child.cpp
Child.h

View File

@ -0,0 +1,287 @@
#include "gtest/gtest.h"
#include "cafAppEnum.h"
#include "cafPdmObjectHandle.h"
#include "cafPdmProxyValueField.h"
#include "cafPdmPtrField.h"
#include "cafPdmReferenceHelper.h"
#include "cafPdmDataValueField.h"
#include "cafPdmChildArrayField.h"
#include "cafPdmChildField.h"
class SimpleObj : public caf::PdmObjectHandle
{
public:
SimpleObj() : PdmObjectHandle()
{
this->addField(&m_position, "m_position");
this->addField(&m_dir, "m_dir");
this->addField(&m_up, "m_up");
this->addField(&m_proxyDouble, "m_proxyDouble");
}
caf::PdmDataValueField<double> m_position;
caf::PdmDataValueField<double> m_dir;
caf::PdmDataValueField<double> m_up;
caf::PdmProxyValueField<double> m_proxyDouble;
void setDoubleMember(const double& d) { m_doubleMember = d; std::cout << "setDoubleMember" << std::endl; }
double doubleMember() const { std::cout << "doubleMember" << std::endl; return m_doubleMember; }
double m_doubleMember;
};
class ReferenceSimpleObj : public caf::PdmObjectHandle
{
public:
ReferenceSimpleObj() : PdmObjectHandle()
{
this->addField(&m_pointersField, "m_pointersField");
this->addField(&m_simpleObjPtrField, "m_simpleObjPtrField");
}
~ReferenceSimpleObj()
{
delete m_pointersField();
m_simpleObjPtrField.deleteAllChildObjects();
}
// Fields
caf::PdmChildField<PdmObjectHandle*> m_pointersField;
caf::PdmChildArrayField<SimpleObj*> m_simpleObjPtrField;
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(PdmReferenceHelperTest, FindRootFromObject)
{
{
caf::PdmObjectHandle* obj = NULL;
EXPECT_EQ(NULL, caf::PdmReferenceHelper::findRoot(obj));
}
{
caf::PdmObjectHandle* obj = new SimpleObj;
EXPECT_EQ(obj, caf::PdmReferenceHelper::findRoot(obj));
delete obj;
}
{
SimpleObj* s1 = new SimpleObj;
ReferenceSimpleObj* ihd1 = new ReferenceSimpleObj;
ihd1->m_simpleObjPtrField.push_back(s1);
EXPECT_EQ(ihd1, caf::PdmReferenceHelper::findRoot(s1));
delete ihd1;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(PdmReferenceHelperTest, FindRootFromField)
{
{
caf::PdmFieldHandle* fieldHandle = NULL;
EXPECT_EQ(NULL, caf::PdmReferenceHelper::findRoot(fieldHandle));
}
{
SimpleObj* s1 = new SimpleObj;
ReferenceSimpleObj* ihd1 = new ReferenceSimpleObj;
ihd1->m_simpleObjPtrField.push_back(s1);
EXPECT_EQ(ihd1, caf::PdmReferenceHelper::findRoot(&s1->m_dir));
delete ihd1;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(PdmReferenceHelperTest, ReferenceFrommRootToField)
{
{
caf::PdmObjectHandle* obj = NULL;
caf::PdmFieldHandle* fieldHandle = NULL;
EXPECT_TRUE(caf::PdmReferenceHelper::referenceFromRootToField(obj, fieldHandle).isEmpty());
}
{
SimpleObj* s1 = new SimpleObj;
SimpleObj* s2 = new SimpleObj;
SimpleObj* s3 = new SimpleObj;
ReferenceSimpleObj* ihd1 = new ReferenceSimpleObj;
ihd1->m_simpleObjPtrField.push_back(s1);
ihd1->m_simpleObjPtrField.push_back(s2);
ihd1->m_simpleObjPtrField.push_back(s3);
EXPECT_TRUE(caf::PdmReferenceHelper::referenceFromRootToField(NULL, &s3->m_dir).isEmpty());
EXPECT_TRUE(caf::PdmReferenceHelper::referenceFromRootToField(ihd1, NULL).isEmpty());
QString refString = caf::PdmReferenceHelper::referenceFromRootToField(ihd1, &s3->m_dir);
QString expectedString = "m_dir m_simpleObjPtrField 2";
EXPECT_STREQ(expectedString.toAscii(), refString.toAscii());
delete ihd1;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(PdmReferenceHelperTest, ReferenceFrommRootToObject)
{
{
caf::PdmObjectHandle* root = NULL;
caf::PdmObjectHandle* obj = NULL;
EXPECT_TRUE(caf::PdmReferenceHelper::referenceFromRootToObject(root, obj).isEmpty());
}
{
SimpleObj* s1 = new SimpleObj;
SimpleObj* s2 = new SimpleObj;
SimpleObj* s3 = new SimpleObj;
ReferenceSimpleObj* ihd1 = new ReferenceSimpleObj;
ihd1->m_simpleObjPtrField.push_back(s1);
ihd1->m_simpleObjPtrField.push_back(s2);
ihd1->m_simpleObjPtrField.push_back(s3);
EXPECT_TRUE(caf::PdmReferenceHelper::referenceFromRootToObject(NULL, s3).isEmpty());
EXPECT_TRUE(caf::PdmReferenceHelper::referenceFromRootToObject(ihd1, NULL).isEmpty());
QString refString = caf::PdmReferenceHelper::referenceFromRootToObject(ihd1, s3);
QString expectedString = "m_simpleObjPtrField 2";
EXPECT_STREQ(expectedString.toAscii(), refString.toAscii());
ReferenceSimpleObj* ihd2 = new ReferenceSimpleObj;
SimpleObj* s4 = new SimpleObj;
ihd2->m_simpleObjPtrField.push_back(s4);
EXPECT_TRUE(caf::PdmReferenceHelper::referenceFromRootToObject(ihd1, s4).isEmpty());
delete ihd1;
delete ihd2;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(PdmReferenceHelperTest, ObjectFromReference)
{
{
caf::PdmObjectHandle* root = NULL;
EXPECT_EQ(NULL, caf::PdmReferenceHelper::objectFromReference(root, ""));
EXPECT_EQ(NULL, caf::PdmReferenceHelper::objectFromReference(root, "a 2 b 4"));
}
{
SimpleObj* s1 = new SimpleObj;
SimpleObj* s2 = new SimpleObj;
ReferenceSimpleObj* ihd1 = new ReferenceSimpleObj;
ihd1->m_simpleObjPtrField.push_back(s1);
ihd1->m_simpleObjPtrField.push_back(s2);
EXPECT_EQ(NULL, caf::PdmReferenceHelper::objectFromReference(ihd1, ""));
EXPECT_EQ(NULL, caf::PdmReferenceHelper::objectFromReference(ihd1, "a 2 b 4"));
QString refString = caf::PdmReferenceHelper::referenceFromRootToObject(ihd1, s2);
EXPECT_EQ(s2, caf::PdmReferenceHelper::objectFromReference(ihd1, refString));
ihd1->m_simpleObjPtrField.removeChildObject(s2);
EXPECT_EQ(NULL, caf::PdmReferenceHelper::objectFromReference(ihd1, refString));
ihd1->m_simpleObjPtrField.deleteAllChildObjects();
EXPECT_EQ(NULL, caf::PdmReferenceHelper::objectFromReference(ihd1, refString));
delete s2;
delete ihd1;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(PdmReferenceHelperTest, FieldFromReference)
{
{
caf::PdmObjectHandle* root = NULL;
EXPECT_EQ(NULL, caf::PdmReferenceHelper::fieldFromReference(root, ""));
EXPECT_EQ(NULL, caf::PdmReferenceHelper::fieldFromReference(root, "a 2 b 4"));
}
{
SimpleObj* s1 = new SimpleObj;
SimpleObj* s2 = new SimpleObj;
ReferenceSimpleObj* ihd1 = new ReferenceSimpleObj;
ihd1->m_simpleObjPtrField.push_back(s1);
ihd1->m_simpleObjPtrField.push_back(s2);
EXPECT_EQ(NULL, caf::PdmReferenceHelper::fieldFromReference(ihd1, ""));
EXPECT_EQ(NULL, caf::PdmReferenceHelper::fieldFromReference(ihd1, "a 2 b 4"));
caf::PdmFieldHandle* fHandle = &s2->m_position;
QString refString = caf::PdmReferenceHelper::referenceFromRootToField(ihd1, fHandle);
EXPECT_EQ(fHandle, caf::PdmReferenceHelper::fieldFromReference(ihd1, refString));
ihd1->m_simpleObjPtrField.removeChildObject(s2);
EXPECT_EQ(NULL, caf::PdmReferenceHelper::fieldFromReference(ihd1, refString));
ihd1->m_simpleObjPtrField.deleteAllChildObjects();
EXPECT_EQ(NULL, caf::PdmReferenceHelper::fieldFromReference(ihd1, refString));
delete s2;
delete ihd1;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST(PdmReferenceHelperTest, ReferenceFromFieldToObject)
{
{
caf::PdmObjectHandle* root = NULL;
caf::PdmFieldHandle* fieldHandle = NULL;
EXPECT_TRUE(caf::PdmReferenceHelper::referenceFromFieldToObject(fieldHandle, root).isEmpty());
}
{
SimpleObj* s1 = new SimpleObj;
SimpleObj* s2 = new SimpleObj;
caf::PdmFieldHandle* s2FieldHandle = &s2->m_dir;
// Unrelated objects
EXPECT_TRUE(caf::PdmReferenceHelper::referenceFromFieldToObject(s2FieldHandle, s1).isEmpty());
ReferenceSimpleObj* root = new ReferenceSimpleObj;
SimpleObj* root_s1 = new SimpleObj;
root->m_simpleObjPtrField.push_back(root_s1);
ReferenceSimpleObj* ihd1 = new ReferenceSimpleObj;
root->m_pointersField = ihd1;
ihd1->m_simpleObjPtrField.push_back(s1);
ihd1->m_simpleObjPtrField.push_back(s2);
QString refString = caf::PdmReferenceHelper::referenceFromFieldToObject(s2FieldHandle, root_s1);
caf::PdmObjectHandle* obj = caf::PdmReferenceHelper::objectFromFieldReference(s2FieldHandle, refString);
EXPECT_EQ(root_s1, obj);
delete root;
}
}

View File

@ -54,13 +54,14 @@ namespace caf
//--------------------------------------------------------------------------------------------------
QString PdmReferenceHelper::referenceFromRootToObject(PdmObjectHandle* root, PdmObjectHandle* obj)
{
QStringList objectNames = referenceFromRootToObjectAsStringList(root, obj);
if (obj == NULL || root == NULL) return QString();
QStringList objectNames = referenceFromRootToObjectAsStringList(root, obj);
QString completeReference = objectNames.join(" ");
return completeReference;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -81,7 +82,6 @@ QString PdmReferenceHelper::referenceFromRootToField(PdmObjectHandle* root, PdmF
return completeReference;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -130,7 +130,11 @@ QStringList PdmReferenceHelper::referenceFromRootToObjectAsStringList(PdmObjectH
while (continueParsing)
{
caf::PdmFieldHandle* parentField = currentObject->parentField();
assert(parentField);
if (!parentField)
{
// Could not find a path from obj to root, obj and root are unrelated objects
return QStringList();
}
std::vector<PdmObjectHandle*> childObjects;
parentField->childObjects(&childObjects);
@ -157,7 +161,11 @@ QStringList PdmReferenceHelper::referenceFromRootToObjectAsStringList(PdmObjectH
}
PdmObjectHandle* ownerObject = parentField->ownerObject();
assert(ownerObject);
if (!ownerObject)
{
// Could not find a path from obj to root, obj and root are unrelated objects
return QStringList();
}
if (ownerObject == root)
{
@ -172,13 +180,13 @@ QStringList PdmReferenceHelper::referenceFromRootToObjectAsStringList(PdmObjectH
return objectNames;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmFieldHandle* PdmReferenceHelper::fieldFromReference(PdmObjectHandle* root, const QString& reference)
{
QStringList decodedReference = reference.split(" ");
if (decodedReference.size() == 0) return NULL;
QString fieldKeyword = decodedReference[0];
decodedReference.pop_front();
@ -192,6 +200,9 @@ PdmFieldHandle* PdmReferenceHelper::fieldFromReference(PdmObjectHandle* root, co
//--------------------------------------------------------------------------------------------------
PdmObjectHandle* PdmReferenceHelper::objectFromReferenceStringList(PdmObjectHandle* root, const QStringList& reference)
{
if (!root) return NULL;
if (reference.size() == 0) return NULL;
PdmObjectHandle* currentObject = root;
int i = 0;
@ -199,47 +210,42 @@ PdmObjectHandle* PdmReferenceHelper::objectFromReferenceStringList(PdmObjectHand
{
QString fieldKeyword = reference.at(i++);
PdmFieldHandle* field = findField(currentObject, fieldKeyword);
if (field)
PdmFieldHandle* fieldHandle = findField(currentObject, fieldKeyword);
if (!fieldHandle)
{
std::vector<PdmObjectHandle*> childObjects;
field->childObjects(&childObjects);
if (childObjects.size() > 0)
{
QString fieldIndex = reference.at(i++);
bool conversionOk = true;
int index = fieldIndex.toInt(&conversionOk);
if (!conversionOk)
{
index = -1;
}
if (index > -1)
{
if (index > childObjects.size() - 1)
{
return NULL;
}
PdmObjectHandle* listObject = childObjects[index];
currentObject = listObject;
}
else
{
return NULL;
}
}
else
{
return NULL;
}
return NULL;
}
std::vector<PdmObjectHandle*> childObjects;
fieldHandle->childObjects(&childObjects);
if (childObjects.size() == 0)
{
return NULL;
}
QString fieldIndex = reference.at(i++);
bool conversionOk = true;
int index = fieldIndex.toInt(&conversionOk);
if (!conversionOk)
{
return NULL;
}
if (index > childObjects.size() - 1)
{
return NULL;
}
currentObject = childObjects[index];
}
return currentObject;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<PdmObjectHandle*> findPathToObjectFromRoot(PdmObjectHandle* obj)
{
std::vector<PdmObjectHandle*> objPath;
@ -262,17 +268,21 @@ std::vector<PdmObjectHandle*> findPathToObjectFromRoot(PdmObjectHandle* obj)
return objPath;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString PdmReferenceHelper::referenceFromFieldToObject(PdmFieldHandle* fromField, PdmObjectHandle* toObj)
{
assert(fromField);
if (toObj == NULL) return "";
if (!fromField || !toObj) return "";
PdmObjectHandle* fromObj = fromField->ownerObject();
if (!fromObj) return "";
std::vector<PdmObjectHandle*> fromObjPath = findPathToObjectFromRoot(fromObj);
std::vector<PdmObjectHandle*> toObjPath = findPathToObjectFromRoot(toObj);
// Make sure the objects actually have at least one common ancestor
assert(fromObjPath.front() == toObjPath.front());
if (fromObjPath.front() != toObjPath.front()) return NULL;
bool anchestorIsEqual = true;
size_t idxToLastCommonAnchestor = 0;
@ -304,10 +314,13 @@ QString PdmReferenceHelper::referenceFromFieldToObject(PdmFieldHandle* fromField
return completeReference;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmObjectHandle* PdmReferenceHelper::objectFromFieldReference(PdmFieldHandle* fromField, const QString& reference)
{
if (!fromField) return NULL;
if (reference.isEmpty()) return NULL;
assert(fromField);
QStringList decodedReference = reference.split(" ");
PdmObjectHandle* lastCommonAnchestor = fromField->ownerObject();