]> git.mxchange.org Git - simgear.git/commitdiff
PropertyObject enhancements, unit-test for make check
authorJames Turner <zakalawe@mac.com>
Sat, 20 Nov 2010 10:49:04 +0000 (02:49 -0800)
committerJames Turner <zakalawe@mac.com>
Sat, 20 Nov 2010 10:49:04 +0000 (02:49 -0800)
simgear/props/.gitignore
simgear/props/Makefile.am
simgear/props/propertyObject.cxx
simgear/props/propertyObject.hxx
simgear/props/propertyObject_test.cxx [new file with mode: 0644]

index 671825c503c52fc1a3e5d1dbacba7ed9af1017ac..8da794e8378bbb21cfedfb97574766a8acf373e6 100644 (file)
@@ -1,2 +1,3 @@
 props_test
+propertyObject_test
 
index c39bd0a038cee300e26d8546b82906a81186dc33..23666451fc20960f24cd53bab0109612ec77f901 100644 (file)
@@ -17,7 +17,8 @@ libsgprops_a_SOURCES = \
        AtomicChangeListener.cxx \
        propertyObject.cxx
 
-check_PROGRAMS = props_test
+check_PROGRAMS = props_test propertyObject_test
+TESTS           = propertyObject_test
 
 props_test_SOURCES = props_test.cxx
 props_test_LDADD = \
@@ -27,6 +28,15 @@ props_test_LDADD = \
        $(top_builddir)/simgear/debug/libsgdebug.a \
        $(top_builddir)/simgear/structure/libsgstructure.a
 
+propertyObject_test_SOURCES = propertyObject_test.cxx
+propertyObject_test_LDADD = \
+       libsgprops.a \
+       $(top_builddir)/simgear/xml/libsgxml.a \
+       $(top_builddir)/simgear/misc/libsgmisc.a \
+       $(top_builddir)/simgear/debug/libsgdebug.a \
+       $(top_builddir)/simgear/structure/libsgstructure.a
+
+
 if HAVE_FRAMEWORK_OSG
 props_test_LDFLAGS = $(openthreads_FRAMEWORK)
 else
index ff90ce77afdd3701630020ee39ad712a7643cf75..0685ae917463802481a8c7ab2f5e7769f4e469af 100644 (file)
@@ -31,6 +31,14 @@ void PropertyObjectBase::setDefaultRoot(SGPropertyNode* aRoot)
   static_defaultRoot = aRoot;
 }
 
+PropertyObjectBase::PropertyObjectBase(const PropertyObjectBase& aOther) :
+  _base(aOther._base),
+  _path(aOther._path),
+  _prop(aOther._prop)
+{
+
+}
+
 PropertyObjectBase::PropertyObjectBase(const char* aChild) :
   _base(NULL),
   _path(aChild),
@@ -62,30 +70,3 @@ SGPropertyNode* PropertyObjectBase::node(bool aCreate) const
 
 } // of namespace simgear
 
-void test()
-{
-  SGPropObjDouble foo("/bar/foo");
-
-  SGPropertyNode* zoob;
-
-  SGPropObjDouble foo2 = SGPropObjDouble::create(zoob, "foo2", 42.0);
-  
-  foo = 1123.0;
-  foo2 =  43;
-  
-  std::string s("lalala");
-  
-  foo = "lalal";
-  
-  
-  SGPropObjString sp(zoob);
-  sp = "fooo";
-  s =  sp;
-  
-
-  SGPropObjBool bp("/some nice big path");
-  bp = false;
-  
-  bp = 456;
-  int i5 = bp;
-}
index 0067cb5e3eba1dae60ff7aef708d894a37d85e15..7aeb0337285217166133f849807425db6b7f7708 100644 (file)
@@ -29,6 +29,8 @@ class PropertyObjectBase
 public:
   static void setDefaultRoot(SGPropertyNode* aRoot);
   
+  PropertyObjectBase(const PropertyObjectBase& aOther);
+    
   PropertyObjectBase(const char* aChild);
   
   PropertyObjectBase(SGPropertyNode* aNode, const char* aChild = NULL);
@@ -61,6 +63,12 @@ public:
   
   }
   
+// copy-constructor
+  PropertyObject(const PropertyObject<T>& aOther) :
+    PropertyObjectBase(aOther)
+  {
+  }
+
 // create() form creates the property immediately
   static PropertyObject<T> create(const char* aPath, T aValue)
   {
@@ -86,7 +94,7 @@ public:
 // conversion operators
   operator T () const
   {
-    SGPropertyNode* n = node(false);
+    SGPropertyNode* n = node();
     if (!n) {
       throw sg_exception("read of undefined property:", _path);
     }
@@ -96,7 +104,7 @@ public:
 
   T operator=(const T& aValue)
   {
-    SGPropertyNode* n = node(true);
+    SGPropertyNode* n = PropertyObjectBase::node(true);
     if (!n) {
       return aValue;
     }
@@ -105,6 +113,10 @@ public:
     return aValue;
   }
 
+  SGPropertyNode* node() const
+  {
+    return PropertyObjectBase::node(false);
+  }
 }; // of template PropertyObject
 
 
@@ -130,7 +142,7 @@ public:
   
   operator std::string () const
   {
-    SGPropertyNode* n = node(false);
+    SGPropertyNode* n = node();
     if (!n) {
       throw sg_exception("read of undefined property:", _path);
     }
@@ -140,7 +152,7 @@ public:
   
   const char* operator=(const char* aValue)
   {
-    SGPropertyNode* n = node(true);
+    SGPropertyNode* n = PropertyObjectBase::node(true);
     if (!n) {
       return aValue;
     }
@@ -151,7 +163,7 @@ public:
   
   std::string operator=(const std::string& aValue)
   {
-    SGPropertyNode* n = node(true);
+    SGPropertyNode* n = PropertyObjectBase::node(true);
     if (!n) {
       return aValue;
     }
@@ -160,6 +172,22 @@ public:
     return aValue;
   }
   
+  bool operator==(const char* value) const
+  {
+    std::string s(*this);
+    return (s == value);    
+  }
+
+  bool operator==(const std::string& value) const
+  {
+    std::string s(*this);
+    return (s == value);    
+  }
+
+  SGPropertyNode* node() const
+  {
+    return PropertyObjectBase::node(false);
+  }
 private:
 };
 
diff --git a/simgear/props/propertyObject_test.cxx b/simgear/props/propertyObject_test.cxx
new file mode 100644 (file)
index 0000000..38e925e
--- /dev/null
@@ -0,0 +1,155 @@
+
+#include <simgear/compiler.h>
+
+#include <iostream>
+#include <cassert>
+#include <cstring>
+
+#include "propertyObject.hxx"
+
+using std::cout;
+using std::cerr;
+using std::endl;
+
+using namespace simgear;
+
+SGPropertyNode* testRoot = NULL;
+
+bool testBasic()
+{
+  PropertyObject<int> aBar("a/bar");
+  assert(aBar == 1234);
+
+
+  PropertyObject<int> aWib("a/wib"); // doesn't exist
+  aWib = 999; // create + set
+  assert(aWib == 999); // read back
+  assert(testRoot->getIntValue("a/wib") == 999);
+
+  assert(aWib < 1000);
+  assert(998 < aWib);
+
+  PropertyObject<double> aFoo("a/foo");
+  assert(aFoo == 12.0);
+
+  double ff(aFoo);
+  assert(ff == 12.0); // comparison with literal
+  
+  const float fff(12.0f);
+  assert(fff == aFoo); // comparion with float value
+
+  return true;
+}
+
+void testString()
+{
+  PropertyObject<std::string> sp("a/alice");
+  assert(sp == "aaaa"); // read
+
+  sp = "xxxx"; // assignment from char* literal
+  assert(!strcmp(testRoot->getStringValue("a/alice"), "xxxx"));
+
+  std::string d = "yyyy";
+  sp = d; // assignment from std::string
+  assert(sp == d);  // comaprisom with std::string
+
+  std::string e(sp), f; // check construction-conversion
+  assert(e == "yyyy");
+  f = sp; // assignment conversion
+  assert(f == "yyyy");
+}
+
+void testAssignment()
+{
+  PropertyObject<int> a1("a/bar");
+  PropertyObject<int> a2("b/blah/foo[1]");
+
+ // ensure assignment between property objects copies values, *not*
+ // copies the property reference
+  a2 = a1 = 88; // a2 should *not* point to a/bar after this!
+  assert(testRoot->getIntValue("b/blah/foo[1]") == 88);
+  assert(a2.node() == testRoot->getNode("b/blah/foo[1]"));
+  a2 = 99;
+  assert(a2 == 99);
+  assert(a1 == 88);
+
+  PropertyObject<int> a3(a1);
+  assert(a1.node() == a3.node());
+  a3 = 44;
+  assert(a1 == 44);
+
+}
+
+void testSTLContainer()
+{
+  std::vector<PropertyObject<int> > vec;
+// enlarging the vec causes the copy-constructor to be called,
+// when the storage is re-sized
+  vec.push_back(PropertyObject<int>("a/thing[0]")); 
+  vec.push_back(PropertyObject<int>("a/thing[1]")); 
+  vec.push_back(PropertyObject<int>("a/thing[2]")); 
+  vec.push_back(PropertyObject<int>("a/thing[3]")); 
+
+  vec[0] = 1234;
+  vec[1] = 2345;
+  vec[2] = 6789;
+  vec[3] = -11;
+
+  assert(testRoot->getIntValue("a/thing[2]") == 6789);
+  assert(testRoot->getIntValue("a/thing[3]") == -11);
+  assert(testRoot->getIntValue("a/thing[0]") == 1234);
+
+  for (int i=0; i<100; ++i) {
+    char path[128];
+    ::snprintf(path, 128, "d/foo[%d]", i);
+    vec.push_back(PropertyObject<int>(path));
+    testRoot->setIntValue(path, i * 4);
+  }
+
+  assert(vec[0] == 1234);
+  assert(vec[3] == -11);
+}
+
+void testReadMissing()
+{
+  PropertyObject<bool> b("not/found/honest");
+
+  try {
+    bool v = b;    
+    assert(false && "read of missing property didn't throw");
+  } catch (sg_exception& e) {
+    // expected
+  }
+
+  PropertyObject<std::string> s("also/missing");
+  try {
+    std::string s2 = s;
+  } catch (sg_exception& e) {
+    // expected
+  }
+}
+
+int main(int argc, char* argv[])
+{
+       testRoot = new SGPropertyNode();
+       simgear::PropertyObjectBase::setDefaultRoot(testRoot);
+
+// create some properties 'manually'
+       testRoot->setDoubleValue("a/foo", 12.0);
+       testRoot->setIntValue("a/bar", 1234);
+       testRoot->setBoolValue("a/flags[3]", true);
+  testRoot->setStringValue("a/alice", "aaaa");
+
+// basic reading / setting
+       if (!testBasic()) {
+               return EXIT_FAILURE;            
+       }
+
+  testReadMissing();
+  testString();
+  testAssignment();
+  testSTLContainer();
+
+  return EXIT_SUCCESS;
+}
+