00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
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
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
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 }