property_test.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: Peter Soetens Tue Apr 5 16:53:26 CEST 2005 property_test.cpp
3 
4  property_test.cpp - description
5  -------------------
6  begin : Tue April 05 2005
7  copyright : (C) 2005 Peter Soetens
8  email : peter.soetens@mech.kuleuven.ac.be
9 
10  ***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 
19 #include <typeinfo>
23 #include <Property.hpp>
24 #include <PropertyBag.hpp>
25 
26 #include "unit.hpp"
27 
29 {
30 public:
38  int intref;
39 
49 
52 
54  : pf("pf","pfd", -1.0),pd("pd","pdd", +1.0),
55  ps("ps","psd", "std::string"),
56  pc("pc","pcd", 'c'),
57  pc1("pc1","pcd1", 'a'),
58  pc2("pc2","pcd1", 'b'),
59  subbag1("s1", "s1d"),subbag2("s2", "s2d")
60  {
61  intref = 99;
62  pi1 = new Property<int>("pi1","pi1d", 0 );
63  pi2 = new Property<int>("pi2","pi2d", 0 );
64  pi1ref = dynamic_cast< Property<int>* >( pi1->clone() );
65  pi2ref = dynamic_cast< Property<int>* >( pi2->clone() );
66 
67  pc1ref = pc1;
68  pc2ref = pc2;
69 
70  bag.add( pi1 );
71  bag.add( pi2 );
72  bag.add( &subbag1 );
73  subbag1.set().add( &subbag2 );
74  subbag1.set().add( &pf );
75  subbag1.set().add( &pd );
76 
77  subbag2.set().add( &ps );
78  subbag2.set().add( &pc );
79 
80  }
82  {
83  delete pi1;
84  delete pi2;
85  delete pi1ref;
86  delete pi2ref;
87  }
88 };
89 
90 bool operator==(const std::vector<double>& a, const std::vector<double>& b)
91 {
92  if ( a.size() != b.size() ) {
93  log(Error) << "Wrong vector sizes : " << a.size() <<" "<< b.size()<<endlog();
94  return false;
95  }
96  for(unsigned int i =0; i != a.size(); ++i)
97  {
98  if (a[i] != b[i]) {
99  log(Error) << "Wrong vector element: "<<a[i]<<" != "<<b[i]<<" i:" << i<<endlog();
100  return false;
101  }
102  }
103  return true;
104 }
105 
106 
107 BOOST_FIXTURE_TEST_SUITE( PropertyTestSuite, PropertyTest )
108 
109 BOOST_AUTO_TEST_CASE( testCopyUpdateLink )
110 {
112 
113  *pi1 = intref;
114  *pi2 = 0;
115 
116  // update semantics
117  pi1->update( *pi2 );
118  BOOST_REQUIRE_EQUAL( pi2->get(), pi1->get() );
119  BOOST_REQUIRE_EQUAL( pi1ref->getName(), pi1->getName() );
120  BOOST_REQUIRE_EQUAL( pi1ref->getDescription(), pi1->getDescription() );
121  BOOST_REQUIRE_NE( pi2->getDataSource().get(), pi1->getDataSource().get() );
122  *pi1 = intref;
123 
124  // update with PropertyBase pointer
125  BOOST_CHECK( pi1->update( static_cast< PropertyBase* >(pi2) ) );
126  BOOST_REQUIRE_EQUAL( pi2->get(), pi1->get() );
127  BOOST_REQUIRE_EQUAL( pi1ref->getName(), pi1->getName() );
128  BOOST_REQUIRE_EQUAL( pi1ref->getDescription(), pi1->getDescription() );
129  BOOST_REQUIRE_NE( pi2->getDataSource().get(), pi1->getDataSource().get() );
130  *pi1 = intref;
131 
132  // copy semantics
133  pi1->copy( *pi2 );
134  BOOST_REQUIRE_EQUAL( pi2->get(), pi1->get() );
135  BOOST_REQUIRE_EQUAL( pi2ref->getName(), pi1->getName() );
136  BOOST_REQUIRE_EQUAL( pi2ref->getDescription(), pi1->getDescription() );
137  BOOST_REQUIRE_NE( pi2->getDataSource().get(), pi1->getDataSource().get() );
138  pi1->copy( *pi1ref );
139 
140  // copy with PropertyBase pointer
141  BOOST_CHECK( pi1->copy( pib2 ) );
142  BOOST_REQUIRE_EQUAL( pi2->get(), pi1->get() );
143  BOOST_REQUIRE_EQUAL( pi2ref->getName(), pi1->getName() );
144  BOOST_REQUIRE_EQUAL( pi2ref->getDescription(), pi1->getDescription() );
145  BOOST_REQUIRE_NE( pi2->getDataSource().get(), pi1->getDataSource().get() );
146  pi1->copy( pi1ref );
147 
148  RTT::Property<int> pi1orig = pi1;
149  BOOST_REQUIRE_EQUAL( pi1orig.getDataSource().get(), pi1->getDataSource().get() );
150 
151  // link semantics with PropertyBase pointer assignment
152  *pi1 = pib2;
153  BOOST_CHECK( pi1->ready() );
154  BOOST_REQUIRE_EQUAL( pi2->get(), pi1->get() );
155  BOOST_REQUIRE_EQUAL( pi2ref->getName(), pi1->getName() );
156  BOOST_REQUIRE_EQUAL( pi2ref->getDescription(), pi1->getDescription() );
157  BOOST_REQUIRE_EQUAL( pi2->getDataSource().get(), pi1->getDataSource().get() );
158  *pi1 = pi1orig;
159 
160  // link semantics with setDataSource() method (value only)
161  BOOST_CHECK( pi1->setDataSource( pi2->getDataSource() ) );
162  BOOST_REQUIRE_EQUAL( pi2->get(), pi1->get() );
163  BOOST_REQUIRE_EQUAL( pi1ref->getName(), pi1->getName() );
164  BOOST_REQUIRE_EQUAL( pi1ref->getDescription(), pi1->getDescription() );
165  BOOST_REQUIRE_EQUAL( pi2->getDataSource().get(), pi1->getDataSource().get() );
166  BOOST_CHECK( pi1->setDataSource( pi1orig.getDataSource() ) );
167 }
168 
169 BOOST_AUTO_TEST_CASE( testCopyUpdateLinkChar )
170 {
171  PropertyBase* pcb2 = &pc2;
172 
173  pc2 = 'H';
174 
175  // update semantics
176  pc1.update( pc2 );
177  BOOST_REQUIRE_EQUAL( pc2.get(), pc1.get() );
178  BOOST_REQUIRE_EQUAL( pc1ref.getName(), pc1.getName() );
179  BOOST_REQUIRE_EQUAL( pc1ref.getDescription(), pc1.getDescription() );
180  BOOST_REQUIRE_NE( pc2.getDataSource().get(), pc1.getDataSource().get() );
181  pc1 = 'e';
182 
183  // update with PropertyBase pointer
184  BOOST_CHECK( pc1.update( pcb2 ) );
185  BOOST_REQUIRE_EQUAL( pc2.get(), pc1.get() );
186  BOOST_REQUIRE_EQUAL( pc1ref.getName(), pc1.getName() );
187  BOOST_REQUIRE_EQUAL( pc1ref.getDescription(), pc1.getDescription() );
188  BOOST_REQUIRE_NE( pc2.getDataSource().get(), pc1.getDataSource().get() );
189  pc1 = 'l';
190 
191  // copy semantics
192  pc1.copy( pc2 );
193  BOOST_REQUIRE_EQUAL( pc2.get(), pc1.get() );
194  BOOST_REQUIRE_EQUAL( pc2ref.getName(), pc1.getName() );
195  BOOST_REQUIRE_EQUAL( pc2ref.getDescription(), pc1.getDescription() );
196  BOOST_REQUIRE_NE( pc2.getDataSource().get(), pc1.getDataSource().get() );
197  pc1.copy( pc1ref );
198 
199  // copy with PropertyBase pointer
200  BOOST_CHECK( pc1.copy( pcb2 ) );
201  BOOST_REQUIRE_EQUAL( pc2.get(), pc1.get() );
202  BOOST_REQUIRE_EQUAL( pc2ref.getName(), pc1.getName() );
203  BOOST_REQUIRE_EQUAL( pc2ref.getDescription(), pc1.getDescription() );
204  BOOST_REQUIRE_NE( pc2.getDataSource().get(), pc1.getDataSource().get() );
205  pc1.copy( pc1ref );
206 
207  RTT::Property<char> pc1orig = &pc1;
208  BOOST_REQUIRE_EQUAL( pc1orig.getDataSource().get(), pc1.getDataSource().get() );
209 
210  // link semantics with PropertyBase pointer assignment
211  pc1 = pcb2;
212  BOOST_CHECK( pc1.ready() );
213  BOOST_REQUIRE_EQUAL( pc2.get(), pc1.get() );
214  BOOST_REQUIRE_EQUAL( pc2ref.getName(), pc1.getName() );
215  BOOST_REQUIRE_EQUAL( pc2ref.getDescription(), pc1.getDescription() );
216  BOOST_REQUIRE_EQUAL( pc2.getDataSource().get(), pc1.getDataSource().get() );
217  pc1 = &pc1orig;
218 
219  // link semantics with setDataSource() method (value only)
220  BOOST_CHECK( pc1.setDataSource( pc2.getDataSource() ) );
221  BOOST_REQUIRE_EQUAL( pc2.get(), pc1.get() );
222  BOOST_REQUIRE_EQUAL( pc1ref.getName(), pc1.getName() );
223  BOOST_REQUIRE_EQUAL( pc1ref.getDescription(), pc1.getDescription() );
224  BOOST_REQUIRE_EQUAL( pc2.getDataSource().get(), pc1.getDataSource().get() );
225  BOOST_CHECK( pc1.setDataSource( pc1orig.getDataSource() ) );
226 }
227 
228 BOOST_AUTO_TEST_CASE( testCreateUpdateChar )
229 {
230  PropertyBag target;
231  // step 1 : create a new instance (non deep copy)
232  PropertyBase* temp = pc1.create();
233  // step 2 : deep copy clone with original, will never fail.
234  BOOST_CHECK( temp->update( &pc1 ) );
235  // step 3 : add result to target bag.
236  target.add( temp );
237 }
238 
239 BOOST_AUTO_TEST_CASE( testfindProperty )
240 {
241  // non recursive search :
242  BOOST_CHECK( bag.find( "pf" ) == 0 );
243  BOOST_CHECK( bag.find( "s1" ) == &subbag1 );
244  BOOST_CHECK( bag.find( "pi1" ) == pi1 );
245 
246  // recursive search :
247  BOOST_CHECK( findProperty( bag, "/pf", "/" ) == 0 );
248  BOOST_CHECK( findProperty( bag, ".pi1" ) == pi1 ); // default is "."
249  BOOST_CHECK( findProperty( bag, "s1" ) == &subbag1 );
250  BOOST_CHECK( findProperty( bag, "pi1" ) == pi1 );
251  BOOST_CHECK( findProperty( bag, "/s1/s2", "/" ) == &subbag2 );
252  BOOST_CHECK( findProperty( bag, "/s1/s2/ps", "/" ) == &ps );
253  BOOST_CHECK( findProperty( bag, "s1.s2.pc" ) == &pc );
254 
255 }
256 
257 // listProperties( bag, separator )
258 BOOST_AUTO_TEST_CASE( testlistProperties )
259 {
260  vector<string> result = listProperties( bag );
261  BOOST_CHECK_EQUAL( result.size(), 8);
262  // this test assumes this order, which is actually not
263  // guaranteed by PropertyBag:
264  BOOST_CHECK_EQUAL( result[0], string("pi1"));
265  BOOST_CHECK_EQUAL( result[1], string("pi2"));
266  BOOST_CHECK_EQUAL( result[2], string("s1"));
267  BOOST_CHECK_EQUAL( result[3], string("s1.s2"));
268  BOOST_CHECK_EQUAL( result[4], string("s1.s2.ps"));
269  BOOST_CHECK_EQUAL( result[5], string("s1.s2.pc"));
270  BOOST_CHECK_EQUAL( result[6], string("s1.pf"));
271  BOOST_CHECK_EQUAL( result[7], string("s1.pd"));
272 }
273 
274 // storeProperty( bag, path, item, separator )
275 BOOST_AUTO_TEST_CASE( teststoreProperty )
276 {
277  Property<int>* int1 = new Property<int>("int1","",3);
278  Property<int>* int2 = new Property<int>("int2","",6);
279  Property<int>* int3 = new Property<int>("int3","",9);
280  BOOST_CHECK( storeProperty(bag, "pp1", int1 ));
281  BOOST_CHECK_EQUAL( findProperty(bag, "pp1.int1"), int1 );
282 
283  BOOST_CHECK( storeProperty(bag, "pp1.pp2", int2) );
284  BOOST_CHECK_EQUAL( findProperty(bag, "pp1.pp2.int2"), int2 );
285 
286  BOOST_CHECK( removeProperty( bag, "pp1.pp2.int2") );
287  int2 = new Property<int>("int2","",6);
288 
289  // re-add int2, but with different separator, and lots of them
290  BOOST_CHECK( storeProperty(bag, "##pp1###pp3##", int2, "#") );
291  BOOST_CHECK_EQUAL( findProperty(bag, "pp1#pp3#int2", "#"), int2 );
292 
293  // top level store is equivalent to ownProperty:
294  BOOST_CHECK( storeProperty(bag, "", int3) );
295  BOOST_CHECK( findProperty(bag, "int3") );
296  BOOST_CHECK_EQUAL( bag.find("int3"), int3 );
297  BOOST_CHECK( bag.ownsProperty( int3 ) );
298 
299  bag.removeProperty( int3 );
300  int3 = new Property<int>("int3","",9);
301 
302  // same but with separator as path:
303  BOOST_CHECK( storeProperty(bag, "#", int3,"#") );
304  BOOST_CHECK( findProperty(bag, "int3") );
305  BOOST_CHECK_EQUAL( bag.find("int3"), int3 );
306  BOOST_CHECK( bag.ownsProperty( int3 ) );
307 }
308 
309 // removeProperty( bag, path, item, separator )
310 BOOST_AUTO_TEST_CASE( testremoveProperty )
311 {
312  // check for wrong input:
313  BOOST_CHECK( removeProperty( bag, "qwerty" ) == false );
314  BOOST_CHECK( removeProperty( bag, "." ) == false );
315 
316  // remove top level prop:
317  BOOST_CHECK( removeProperty( bag, "pi1" ) );
318  BOOST_CHECK( findProperty( bag, "pi1" ) == 0 );
319 
320  // remove a leaf prop:
321  BOOST_CHECK( removeProperty( bag, "s1.s2.pc" ) );
322  BOOST_CHECK( findProperty( bag, "s1.s2.pc" ) == 0 );
323 
324  // remove a bag:
325  BOOST_CHECK( removeProperty( bag, "s1.s2" ) );
326  BOOST_CHECK( findProperty( bag, "s1.s2" ) == 0 );
327 }
328 
329 BOOST_AUTO_TEST_CASE( testRepository )
330 {
334  BOOST_TEST_MESSAGE("----- Testing testRep");
335  std::vector<string> names = TypeInfoRepository::Instance()->getTypes();
336  for (std::vector<string>::iterator it = names.begin(); it != names.end(); ++it) {
337  BOOST_TEST_MESSAGE("----------- loop names: " << *it);
338  PropertyBase* target;
339  Property<PropertyBag> bag("Result","D");
340  BOOST_REQUIRE( TypeInfoRepository::Instance()->type( *it ) );
341  target = TypeInfoRepository::Instance()->type( *it )->buildProperty("Result", "D");
342  if ( target && typeDecomposition( target->getDataSource(), bag.value() ) )
343  BOOST_CHECK_MESSAGE( target->getTypeInfo()->composeType( bag.getDataSource() , target->getDataSource() ), "Failed composition for type "+target->getTypeInfo()->getTypeName() );
344  deletePropertyBag( bag.value() );
345  delete target;
346  }
347 
348 }
349 
350 BOOST_AUTO_TEST_CASE( testComposition )
351 {
355  std::vector<double> init(33, 1.0);
356  Property<std::vector<double> > pvd("pvd","pvd desc", init);
357 
358  //std::cout << "\n\n\n "<< std::string( typeid(init).name() ) << "\n\n\n "<<std::endl;
359 
360  Property<std::vector<double> > pvd2("pvd 2","pvd desc 2");
361 
362  BOOST_CHECK( pvd.get() == init );
363  BOOST_CHECK( pvd.set() == init );
364 
365  BOOST_REQUIRE( pvd.getTypeInfo() );
367 
368  Property<PropertyBag> bag("Result","Rd");
369  // Decompose to property bag and back:
370  BOOST_CHECK( typeDecomposition( pvd.getDataSource(), bag.value() ) );
371  BOOST_CHECK( pvd.getTypeInfo()->composeType( bag.getDataSource(), pvd2.getDataSource() ) );
372  BOOST_CHECK( pvd == pvd2 );
373  pvd2.value().clear();
374  deletePropertyBag( bag.value() );
375 }
376 
378 BOOST_AUTO_TEST_CASE( testNewDecomposition )
379 {
383  std::vector<double> init(33, 1.0);
384  // these are the original sources:
385  Property<std::vector<double> > pvd("pvd","pvd desc", init);
386 
387  BOOST_CHECK( pvd.get() == init );
388  BOOST_CHECK( pvd.set() == init );
389 
390  BOOST_REQUIRE( pvd.getTypeInfo() );
392 
393  Property<PropertyBag> bag("Result","Rd");
394  // Decompose to property bag and check refs:
395  BOOST_CHECK( propertyDecomposition( &pvd, bag.value() ) );
396 
397  Property<double> pvalue = bag.value().getItem(3);
398  BOOST_REQUIRE( pvalue.ready() );
399  pvalue.set( 42 );
400 
401  BOOST_CHECK( pvd.rvalue()[3] == 42 );
402 
403  deletePropertyBag( bag.value() );
404 }
405 
406 
408 {
409  // See if this compiles fine:
410  // detects collisions with other constructors...
411  Property<unsigned int> pui("PUI","", 0 );
412  Property<int> pi("PI","", 0 );
413  Property<bool> pb("PB","", false );
414 
415  // Test null assignment
416  PropertyBase* pbase = 0;
417  Property<int> p2 = pbase;
418  BOOST_CHECK( !p2.ready() );
419  Property<int> p3;
420  BOOST_CHECK( !p3.ready() );
421 
422  p3 = pbase;
423  BOOST_CHECK( !p3.ready() );
424 
425  p2 = p3;
426  BOOST_CHECK( !p2.ready() );
427 
428  p2 = pi;
429  BOOST_CHECK( p2.ready() );
430 
431  BOOST_CHECK(true);
432 }
433 
434 
435 BOOST_AUTO_TEST_CASE( testUpdate )
436 {
437  PropertyBag source;
438  PropertyBag target;
439 
440  Property<PropertyBag> b1("b1","");
441  Property<PropertyBag> b2("b2","");
442  Property<int> p1("p1","",-1);
443 
444  Property<PropertyBag> b1c("b1","");
445  Property<PropertyBag> b2c("b2","");
446  Property<int> p1c("p1","",0);
447 
448  // setup source tree
449  source.addProperty( b1 );
450  b1.value().addProperty( b2 );
451  b2.value().addProperty( p1 );
452 
453  // update case:
454  // setup target tree
455  target.addProperty( b1c );
456  b1c.value().addProperty( b2c );
457  b2c.value().addProperty( p1c );
458 
459  BOOST_CHECK( p1.get() != p1c.get() );
460 
461  BOOST_CHECK( updateProperty(target, source, "b1/b2/p1", "/") );
462 
463  BOOST_CHECK( p1.get() == -1 );
464  BOOST_CHECK( p1c.get() == -1 );
465 
466  // creation case:
467  target.removeProperty(&b1);
468  BOOST_CHECK( updateProperty(target, source, "b1/b2/p1", "/") );
469 
471  BOOST_CHECK( bag );
472  BOOST_CHECK( bag->getName() == "b1" );
473  bag = bag->get().getPropertyType<PropertyBag>("b2");
474  BOOST_CHECK( bag );
475  BOOST_CHECK( bag->getName() == "b2" );
476 
477  Property<int>* res = bag->get().getPropertyType<int>("p1");
478  BOOST_CHECK( res );
479  BOOST_CHECK( res->getName() == "p1" );
480  BOOST_CHECK( res->get() == -1 );
481 
482 }
483 
virtual base::DataSourceBase::shared_ptr getDataSource() const
Definition: Property.hpp:393
Property< char > pc2
bool removeProperty(PropertyBag &bag, const std::string &path, const std::string &separator)
#define BOOST_FIXTURE_TEST_SUITE(suite_name, F)
DataSourceType get() const
Definition: Property.hpp:246
PropertyBag bag1
Property< char > pc
bool composeType(base::DataSourceBase::shared_ptr source, base::DataSourceBase::shared_ptr target) const
Definition: TypeInfo.hpp:386
PropertyBag bag
bool updateProperty(PropertyBag &target, const PropertyBag &source, const std::string &name, const std::string &separator)
void add(base::PropertyBase *p)
Definition: PropertyBag.cpp:75
Property< T > * getPropertyType(const std::string &name) const
Property< PropertyBag > subbag1
const std::string & getTypeName() const
Definition: TypeInfo.hpp:83
bool propertyDecomposition(base::PropertyBase *source, PropertyBag &targetbag, bool recurse)
virtual bool copy(const base::PropertyBase *other)
Definition: Property.hpp:323
virtual Property< T > * clone() const
Definition: Property.hpp:371
#define BOOST_AUTO_TEST_SUITE_END()
Property< float > pf
const_reference_t rvalue() const
Definition: Property.hpp:285
A container for holding references to properties.
Definition: PropertyBag.hpp:96
reference_t value()
Definition: Property.hpp:277
PropertyBase * findProperty(const PropertyBag &bag, const std::string &nameSequence, const std::string &separator)
Property< PropertyBag > subbag2
Property< char > pc1ref
void deletePropertyBag(PropertyBag &target)
Property< T > & addProperty(const std::string &name, T &attr)
Property< char > pc2ref
Property< std::string > ps
base::PropertyBase * find(const std::string &name) const
bool removeProperty(base::PropertyBase *p)
virtual bool setDataSource(const base::DataSourceBase::shared_ptr &dsb)
Definition: Property.hpp:406
const std::string & getDescription() const
virtual const types::TypeInfo * getTypeInfo() const
Definition: Property.hpp:421
PropertyBase * pb
bool typeDecomposition(base::DataSourceBase::shared_ptr dsb, PropertyBag &targetbag, bool recurse)
BOOST_AUTO_TEST_CASE(testCopyUpdateLink)
static const types::TypeInfo * getTypeInfo()
vector< string > listProperties(const PropertyBag &source, const std::string &separator)
bool storeProperty(PropertyBag &bag, const std::string &path, base::PropertyBase *item, const std::string &separator)
bool operator==(const std::vector< double > &a, const std::vector< double > &b)
virtual bool update(const base::PropertyBase *other)
Definition: Property.hpp:305
Property< int > * pi1ref
const std::string & getName() const
Property< int > * pi2
PropertyBag bag2
Property< char > pc1
reference_t set()
Definition: Property.hpp:257
Property< int > * pi1
virtual Property< T > * create() const
Definition: Property.hpp:376
static Logger & log()
Definition: Logger.hpp:350
Property< int > * pi2ref
virtual bool update(const PropertyBase *other)=0
bool ownsProperty(base::PropertyBase *p) const
Definition: PropertyBag.cpp:97
static Logger::LogFunction endlog()
Definition: Logger.hpp:362
virtual DataSourceBase::shared_ptr getDataSource() const =0
Property< double > pd
virtual const types::TypeInfo * getTypeInfo() const =0


rtt
Author(s): RTT Developers
autogenerated on Tue Jun 25 2019 19:33:26