test_property_node.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2010, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 #include <gtest/gtest.h>
00031 
00032 #include <rve_properties/property_node.h>
00033 #include <ros/console.h>
00034 
00035 #include <boost/bind.hpp>
00036 
00037 using namespace rve_properties;
00038 
00039 TEST(PropertyNode, setThenGetValue)
00040 {
00041   PropertyNodePtr pn(new PropertyNode);
00042   uint32_t val = 5;
00043   pn->set(val);
00044   val = pn->get<uint32_t>();
00045   EXPECT_EQ(val, 5U);
00046 }
00047 
00048 TEST(PropertyNode, setThenGetChildren)
00049 {
00050   PropertyNodePtr pn(new PropertyNode);
00051   pn->set<uint32_t>("foo", 5);
00052   pn->set<uint32_t>("bar", 10);
00053   pn->set<uint32_t>("baz", 15);
00054   pn->set<uint32_t>("a", 10);
00055   pn->set<uint32_t>("a/b", 100);
00056   pn->set<uint32_t>("a/b/c", 1000);
00057   pn->set<uint32_t>("a/b/c/d", 10000);
00058 
00059   EXPECT_EQ(pn->get<uint32_t>("foo"), 5U);
00060   EXPECT_EQ(pn->get<uint32_t>("bar"), 10U);
00061   EXPECT_EQ(pn->get<uint32_t>("baz"), 15U);
00062   EXPECT_EQ(pn->get<uint32_t>("a"), 10U);
00063   EXPECT_EQ(pn->get<uint32_t>("a/b"), 100U);
00064   EXPECT_EQ(pn->get<uint32_t>("a/b/c"), 1000U);
00065   EXPECT_EQ(pn->get<uint32_t>("a/b/c/d"), 10000U);
00066 }
00067 
00068 TEST(PropertyNode, getNode)
00069 {
00070   PropertyNodePtr pn(new PropertyNode);
00071   pn->set<uint32_t>("a/b/c", 5);
00072   PropertyNodePtr child = pn->getNode("a/b/c");
00073   EXPECT_EQ(child->get<uint32_t>(), 5U);
00074 }
00075 
00076 TEST(PropertyNode, getNonexistentWithoutDefault)
00077 {
00078   PropertyNodePtr pn(new PropertyNode);
00079   try
00080   {
00081     pn->get<uint32_t>();
00082     FAIL();
00083   }
00084   catch (std::bad_cast&)
00085   {
00086     SUCCEED();
00087   }
00088 }
00089 
00090 TEST(PropertyNode, getNonexistentWithDefault)
00091 {
00092   PropertyNodePtr pn(new PropertyNode);
00093   try
00094   {
00095     uint32_t foo = 5;
00096     pn->get(foo, 10U);
00097     EXPECT_EQ(foo, 10U);
00098   }
00099   catch (std::bad_cast&)
00100   {
00101     FAIL();
00102   }
00103 }
00104 
00105 TEST(PropertyNode, exists)
00106 {
00107   PropertyNodePtr pn(new PropertyNode);
00108   pn->set("a/b/c", 5);
00109   EXPECT_TRUE(pn->exists("a"));
00110   EXPECT_TRUE(pn->exists("a/b"));
00111   EXPECT_TRUE(pn->exists("a/b/c"));
00112   EXPECT_FALSE(pn->exists("b"));
00113   EXPECT_FALSE(pn->exists("b/c"));
00114   EXPECT_FALSE(pn->exists("a/c"));
00115   EXPECT_FALSE(pn->exists("a/b/d"));
00116 }
00117 
00118 TEST(PropertyNode, removeNode)
00119 {
00120   PropertyNodePtr pn(new PropertyNode);
00121   pn->set("a/b/c", 5);
00122   pn->set("x/y/z", 10);
00123   pn->removeNode("a/b/c");
00124   EXPECT_TRUE(pn->exists("a"));
00125   EXPECT_TRUE(pn->exists("a/b"));
00126   EXPECT_TRUE(pn->exists("x/y/z"));
00127   EXPECT_FALSE(pn->exists("a/b/c"));
00128 
00129   pn->removeNode("x");
00130   EXPECT_TRUE(pn->exists("a"));
00131   EXPECT_TRUE(pn->exists("a/b"));
00132   EXPECT_FALSE(pn->exists("x/y/z"));
00133   EXPECT_FALSE(pn->exists("x/y"));
00134   EXPECT_FALSE(pn->exists("x"));
00135 }
00136 
00137 TEST(PropertyNode, parenting)
00138 {
00139   PropertyNodePtr pn(new PropertyNode);
00140   pn->set("a/b/c/d/e/f", 5);
00141   EXPECT_EQ(pn->getNode("a/b/c/d/e/f")->getParent(), pn->getNode("a/b/c/d/e"));
00142   EXPECT_EQ(pn->getNode("a/b/c/d/e")->getParent(), pn->getNode("a/b/c/d"));
00143   EXPECT_EQ(pn->getNode("a/b/c/d")->getParent(), pn->getNode("a/b/c"));
00144   EXPECT_EQ(pn->getNode("a/b/c")->getParent(), pn->getNode("a/b"));
00145   EXPECT_EQ(pn->getNode("a/b")->getParent(), pn->getNode("a"));
00146   EXPECT_EQ(pn->getNode("a")->getParent(), pn);
00147   EXPECT_FALSE(pn->getParent());
00148 }
00149 
00150 struct ChangeHelper
00151 {
00152   void cb(const PropertyNodePtr& n, const std::string& p, PropertyChangeType t)
00153   {
00154     //ROS_INFO_STREAM(p);
00155     node = n;
00156     path = p;
00157     type = t;
00158   }
00159 
00160   void reset()
00161   {
00162     path.clear();
00163     node.reset();
00164   }
00165 
00166   std::string path;
00167   PropertyNodePtr node;
00168   PropertyChangeType type;
00169 };
00170 
00171 TEST(PropertyNode, propertyChanged)
00172 {
00173   PropertyNodePtr pn(new PropertyNode);
00174   ChangeHelper h;
00175   pn->set("a/b/c", 5);
00176   pn->addChangeCallback(boost::bind(&ChangeHelper::cb, &h, _1, _2, _3), &h, 0);
00177 
00178   pn->set("a/b/c", 10);
00179   EXPECT_STREQ(h.path.c_str(), "a/b/c");
00180   EXPECT_EQ(h.type, PropertyChanged);
00181   EXPECT_EQ(h.node, pn->getNode("a/b/c"));
00182 
00183   h.reset();
00184   pn->set("a/b", 55);
00185   EXPECT_STREQ(h.path.c_str(), "a/b");
00186   EXPECT_EQ(h.type, PropertyChanged);
00187   EXPECT_EQ(h.node, pn->getNode("a/b"));
00188 
00189   h.reset();
00190   pn->set("a", 55);
00191   EXPECT_STREQ(h.path.c_str(), "a");
00192   EXPECT_EQ(h.type, PropertyChanged);
00193   EXPECT_EQ(h.node, pn->getNode("a"));
00194 
00195   h.reset();
00196   pn->set(55);
00197   EXPECT_STREQ(h.path.c_str(), "");
00198   EXPECT_EQ(h.type, PropertyChanged);
00199   EXPECT_EQ(h.node, pn);
00200 }
00201 
00202 struct MultiChangeHelper
00203 {
00204   void cb(const PropertyNodePtr& n, const std::string& p, PropertyChangeType t)
00205   {
00206     //ROS_INFO_STREAM(p << "  " << (uint32_t)t);
00207     Change c;
00208     c.node = n;
00209     c.path = p;
00210     c.type = t;
00211     changes.push_back(c);
00212   }
00213 
00214   void reset()
00215   {
00216     changes.clear();
00217   }
00218 
00219   struct Change
00220   {
00221     std::string path;
00222     PropertyNodePtr node;
00223     PropertyChangeType type;
00224   };
00225   std::vector<Change> changes;
00226 };
00227 
00228 TEST(PropertyNode, propertyAdded)
00229 {
00230   PropertyNodePtr pn(new PropertyNode);
00231   MultiChangeHelper h;
00232   pn->addChangeCallback(boost::bind(&MultiChangeHelper::cb, &h, _1, _2, _3), &h, 0);
00233 
00234   pn->set("a/b/c", 5);
00235   ASSERT_EQ(h.changes.size(), 4U);
00236   EXPECT_STREQ(h.changes[0].path.c_str(), "a");
00237   EXPECT_EQ(h.changes[0].type, PropertyAdded);
00238   EXPECT_STREQ(h.changes[1].path.c_str(), "a/b");
00239   EXPECT_EQ(h.changes[1].type, PropertyAdded);
00240   EXPECT_STREQ(h.changes[2].path.c_str(), "a/b/c");
00241   EXPECT_EQ(h.changes[2].type, PropertyAdded);
00242   EXPECT_STREQ(h.changes[3].path.c_str(), "a/b/c");
00243   EXPECT_EQ(h.changes[3].type, PropertyChanged);
00244 }
00245 
00246 struct PropertyVisitor
00247 {
00248   PropertyVisitor()
00249   : inserted_twice(false)
00250   {}
00251 
00252   void operator()(const std::string& path, const PropertyNodePtr& node)
00253   {
00254     //ROS_INFO("%s\n", path.c_str());
00255     if (!nodes.insert(std::make_pair(path, node)).second)
00256     {
00257       inserted_twice = true;
00258     }
00259   }
00260 
00261   std::map<std::string, PropertyNodePtr> nodes;
00262   bool inserted_twice;
00263 };
00264 
00265 TEST(PropertyNode, visitChildrenRecursive)
00266 {
00267   PropertyNodePtr pn(new PropertyNode);
00268   pn->set("a/b/c/d/e/f/g/h", 5);
00269 
00270   PropertyVisitor pv;
00271   pn->visitChildren(pv);
00272   ASSERT_FALSE(pv.nodes.find("a") == pv.nodes.end());
00273   ASSERT_FALSE(pv.nodes.find("a/b") == pv.nodes.end());
00274   ASSERT_FALSE(pv.nodes.find("a/b/c") == pv.nodes.end());
00275   ASSERT_FALSE(pv.nodes.find("a/b/c/d") == pv.nodes.end());
00276   ASSERT_FALSE(pv.nodes.find("a/b/c/d/e") == pv.nodes.end());
00277   ASSERT_FALSE(pv.nodes.find("a/b/c/d/e/f") == pv.nodes.end());
00278   ASSERT_FALSE(pv.nodes.find("a/b/c/d/e/f/g") == pv.nodes.end());
00279 
00280   EXPECT_EQ(pv.nodes["a"], pn->getNode("a"));
00281   EXPECT_EQ(pv.nodes["a/b"], pn->getNode("a/b"));
00282   EXPECT_EQ(pv.nodes["a/b/c"], pn->getNode("a/b/c"));
00283   EXPECT_EQ(pv.nodes["a/b/c/d"], pn->getNode("a/b/c/d"));
00284   EXPECT_EQ(pv.nodes["a/b/c/d/e"], pn->getNode("a/b/c/d/e"));
00285   EXPECT_EQ(pv.nodes["a/b/c/d/e/f"], pn->getNode("a/b/c/d/e/f"));
00286   EXPECT_EQ(pv.nodes["a/b/c/d/e/f/g"], pn->getNode("a/b/c/d/e/f/g"));
00287 }
00288 
00289 TEST(PropertyNode, visitChildrenNonRecursive)
00290 {
00291   PropertyNodePtr pn(new PropertyNode);
00292   pn->set("a/b/c/d/e/f/g/h", 5);
00293   pn->set("z/b/c/d/e/f/g/h", 5);
00294 
00295   PropertyVisitor pv;
00296   pn->visitChildren(pv, false);
00297   ASSERT_FALSE(pv.nodes.find("a") == pv.nodes.end());
00298   ASSERT_FALSE(pv.nodes.find("z") == pv.nodes.end());
00299   ASSERT_TRUE(pv.nodes.find("a/b") == pv.nodes.end());
00300   ASSERT_TRUE(pv.nodes.find("a/b/c") == pv.nodes.end());
00301   ASSERT_TRUE(pv.nodes.find("a/b/c/d") == pv.nodes.end());
00302   ASSERT_TRUE(pv.nodes.find("a/b/c/d/e") == pv.nodes.end());
00303   ASSERT_TRUE(pv.nodes.find("a/b/c/d/e/f") == pv.nodes.end());
00304   ASSERT_TRUE(pv.nodes.find("a/b/c/d/e/f/g") == pv.nodes.end());
00305 
00306   EXPECT_EQ(pv.nodes["a"], pn->getNode("a"));
00307   EXPECT_EQ(pv.nodes["z"], pn->getNode("z"));
00308 }
00309 
00310 int main(int argc, char** argv)
00311 {
00312   std::cout << "sizeof(PropertyNode): " << sizeof(PropertyNode) << "\n";
00313 
00314   testing::InitGoogleTest(&argc, argv);
00315   return RUN_ALL_TESTS();
00316 }


rve_properties
Author(s): Josh Faust
autogenerated on Wed Dec 11 2013 14:31:27