OpenWalnut
1.4.0
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #ifndef WPROPERTIES_TEST_H 00026 #define WPROPERTIES_TEST_H 00027 00028 #include <string> 00029 00030 #include <cxxtest/TestSuite.h> 00031 00032 #include "../WProperties.h" 00033 #include "../exceptions/WPropertyNotUnique.h" 00034 #include "../exceptions/WPropertyUnknown.h" 00035 #include "../exceptions/WPropertyNameMalformed.h" 00036 00037 /** 00038 * Test WProperties 00039 */ 00040 class WPropertiesTest : public CxxTest::TestSuite 00041 { 00042 public: 00043 /** 00044 * A temporary holder for some value. 00045 */ 00046 bool m_testTemporary1; 00047 00048 /** 00049 * A temporary holder for some value. 00050 */ 00051 bool m_testTemporary2; 00052 00053 /** 00054 * Helper function which simply sets the value above to true. It is used to test some conditions here. 00055 */ 00056 void setTemporary1() 00057 { 00058 m_testTemporary1 = true; 00059 } 00060 00061 /** 00062 * Helper function which simply sets the value above to true. It is used to test some conditions here. 00063 */ 00064 void setTemporary2() 00065 { 00066 m_testTemporary2 = true; 00067 } 00068 00069 /** 00070 * Test instantiation, also test name and description and type (from WPropertyBase) 00071 */ 00072 void testInstantiation( void ) 00073 { 00074 boost::shared_ptr< WProperties > p; 00075 TS_ASSERT_THROWS_NOTHING( p = boost::shared_ptr< WProperties >( new WProperties( "hey", "you" ) ) ); 00076 00077 // test names 00078 TS_ASSERT( p->getName() == "hey" ); 00079 TS_ASSERT( p->getDescription() == "you" ); 00080 TS_ASSERT( p->getType() == PV_GROUP ); 00081 00082 TS_ASSERT_THROWS_NOTHING( p.reset() ); 00083 } 00084 00085 /** 00086 * Test the add features, also tests the type of properties added 00087 */ 00088 void testAdd( void ) 00089 { 00090 WException::disableBacktrace(); // in tests, turn of backtrace globally 00091 00092 boost::shared_ptr< WProperties > p( new WProperties( "hey", "you" ) ); 00093 00094 // add some new properties 00095 boost::shared_ptr< WPropertyBase > p1 = p->addProperty( "1", "test1", true ); 00096 boost::shared_ptr< WPropertyBase > p2 = p->addProperty( "2", "test2", 1 ); 00097 boost::shared_ptr< WPropertyBase > p3 = p->addProperty( "3", "test3", 1.0 ); 00098 00099 // add a malformed (name) property 00100 // The name is malformed since the "/" is used as group separator 00101 TS_ASSERT_THROWS( p->addProperty( "4/5", "test4", 1.0 ), WPropertyNameMalformed ); 00102 00103 // this should have created 3 props 00104 TS_ASSERT( p->m_properties.getReadTicket()->get().size() == 3 ); 00105 00106 // ensure that it has created the correct types: 00107 TS_ASSERT( p1->getType() == PV_BOOL ); 00108 TS_ASSERT( p2->getType() == PV_INT ); 00109 TS_ASSERT( p3->getType() == PV_DOUBLE ); 00110 00111 // try to add another property with the same name ( regardless of actual type ) 00112 TS_ASSERT_THROWS( p->addProperty( "1", "test1", 1.0 ), WPropertyNotUnique ); 00113 } 00114 00115 /** 00116 * Test the clear() method 00117 */ 00118 void testClear( void ) 00119 { 00120 WException::disableBacktrace(); // in tests, turn of backtrace globally 00121 00122 boost::shared_ptr< WProperties > p( new WProperties( "hey", "you" ) ); 00123 00124 // add some new properties 00125 boost::shared_ptr< WPropertyBase > p1 = p->addProperty( "1", "test1", true ); 00126 boost::shared_ptr< WPropertyBase > p2 = p->addProperty( "2", "test2", 1 ); 00127 boost::shared_ptr< WPropertyBase > p3 = p->addProperty( "3", "test3", 1.0 ); 00128 00129 // this should have created 3 props 00130 TS_ASSERT( p->m_properties.getReadTicket()->get().size() == 3 ); 00131 00132 // clear 00133 TS_ASSERT_THROWS_NOTHING( p->clear() ); 00134 TS_ASSERT( p->m_properties.getReadTicket()->get().size() == 0 ); 00135 00136 // multiple clear should not cause any error 00137 TS_ASSERT_THROWS_NOTHING( p->clear() ); 00138 } 00139 00140 /** 00141 * Test the removeProperty() method 00142 */ 00143 void testRemove( void ) 00144 { 00145 WException::disableBacktrace(); // in tests, turn of backtrace globally 00146 00147 boost::shared_ptr< WProperties > p( new WProperties( "hey", "you" ) ); 00148 00149 // add some new properties 00150 boost::shared_ptr< WPropertyBase > p1 = p->addProperty( "1", "test1", true ); 00151 boost::shared_ptr< WPropertyBase > p2 = p->addProperty( "2", "test2", 1 ); 00152 boost::shared_ptr< WPropertyBase > p3 = p->addProperty( "3", "test3", 1.0 ); 00153 00154 // this should have created 3 props 00155 TS_ASSERT( p->m_properties.getReadTicket()->get().size() == 3 ); 00156 00157 // remove a property 00158 TS_ASSERT_THROWS_NOTHING( p->removeProperty( p2 ) ); 00159 TS_ASSERT( p->m_properties.getReadTicket()->get().size() == 2 ); 00160 00161 // remove a prop which is not in the list 00162 TS_ASSERT_THROWS_NOTHING( p->removeProperty( p2 ) ); 00163 TS_ASSERT( p->m_properties.getReadTicket()->get().size() == 2 ); 00164 } 00165 00166 /** 00167 * Tests whether the properties children can be set by the WProperties::set call using a other WProperties instance 00168 */ 00169 void testRecursiveSetByProperty( void ) 00170 { 00171 WException::disableBacktrace(); // in tests, turn of backtrace globally 00172 00173 // some props we can use as target 00174 boost::shared_ptr< WProperties > t( new WProperties( "hey", "you" ) ); 00175 00176 // add some new properties 00177 WPropBool tp1 = t->addProperty( "p1", "", true ); 00178 WPropInt tp2 = t->addProperty( "p2", "", 1 ); 00179 WPropGroup tg1 = t->addPropertyGroup( "g1", "" ); 00180 WPropDouble tp3 = tg1->addProperty( "p3", "", 1.0 ); 00181 WPropDouble tp4 = t->addProperty( "p4", "", 10.0 ); 00182 00183 // create a group we can use as source 00184 boost::shared_ptr< WProperties > s( new WProperties( "hey", "you" ) ); 00185 00186 // add some new properties 00187 WPropBool sp1 = s->addProperty( "p1", "", false ); 00188 WPropInt sp2 = s->addProperty( "p2__", "", 10 ); // NOTE: the name is different 00189 WPropGroup sg1 = s->addPropertyGroup( "g1", "" ); 00190 WPropDouble sp3 = sg1->addProperty( "p3", "", 2.0 ); 00191 WPropInt sp4 = s->addProperty( "p4", "", 2 ); 00192 00193 // let us set t using the values in s 00194 t->set( s ); 00195 00196 // lets check the values: 00197 // tp1 should be set to the value of sp1 00198 TS_ASSERT( tp1->get() == sp1->get() ); 00199 // tp2 should be untouched as no corresponding property exists in s 00200 TS_ASSERT( tp2->get() == 1 ); 00201 // the child of the group g1 should be set to sp3 00202 TS_ASSERT( tp3->get() == sp3->get() ); 00203 // tp4 must not be sp4 even if the names match. The type is a mismatch 00204 TS_ASSERT( tp4->get() == 10.0 ); 00205 } 00206 00207 /** 00208 * Test the features to find and get properties. 00209 */ 00210 void testGetAndExistsAndFind( void ) 00211 { 00212 WException::disableBacktrace(); // in tests, turn of backtrace globally 00213 00214 boost::shared_ptr< WProperties > p( new WProperties( "hey", "you" ) ); 00215 00216 // add some new properties 00217 boost::shared_ptr< WPropertyBase > p1 = p->addProperty( "1", "test1", true ); 00218 boost::shared_ptr< WPropertyBase > p2 = p->addProperty( "2", "test2", 1 ); 00219 boost::shared_ptr< WPropertyBase > p3 = p->addProperty( "3", "test3", 1.0 ); 00220 00221 ///////////// 00222 // exists 00223 00224 // now, try to check whether a property exists: 00225 TS_ASSERT( p->existsProperty( "1" ) ); 00226 TS_ASSERT( !p->existsProperty( "shouldNotBeInTheList" ) ); 00227 00228 ///////////// 00229 // find 00230 00231 // same for find. Find does not throw an exception if the property does not exist! It simply returns it or NULL 00232 boost::shared_ptr< WPropertyBase > someProp; 00233 TS_ASSERT_THROWS_NOTHING( someProp = p->findProperty( "1" ) ); 00234 // The property exists -> return value is not NULL 00235 TS_ASSERT( someProp ); 00236 00237 // now for an unexisting one 00238 TS_ASSERT_THROWS_NOTHING( someProp = p->findProperty( "shouldNotBeInTheList" ) ); 00239 // The property exists -> return value is not NULL 00240 TS_ASSERT( !someProp ); 00241 00242 ///////////// 00243 // get 00244 00245 // the getProperty method throws an exception if the property has not been found. 00246 00247 // this one exists -> no exception 00248 TS_ASSERT_THROWS_NOTHING( someProp = p->getProperty( "1" ) ); 00249 TS_ASSERT( someProp ); 00250 00251 // this one does not exist 00252 TS_ASSERT_THROWS( someProp = p->getProperty( "shouldNotBeInTheList" ), WPropertyUnknown ); 00253 } 00254 00255 /** 00256 * Test the recursive search mechanism. 00257 */ 00258 void testGetAndExistsAndFindRecursive( void ) 00259 { 00260 boost::shared_ptr< WProperties > p( new WProperties( "hey", "you" ) ); 00261 boost::shared_ptr< WProperties > psub = p->addPropertyGroup( "heySub", "you" ); 00262 00263 // add some new properties 00264 boost::shared_ptr< WPropertyBase > p1 = p->addProperty( "1", "test1", true ); 00265 boost::shared_ptr< WPropertyBase > p2 = p->addProperty( "2", "test2", 1 ); 00266 boost::shared_ptr< WPropertyBase > p3 = psub->addProperty( "3", "test3", 1.0 ); 00267 boost::shared_ptr< WPropertyBase > p4 = psub->addProperty( "4", "test4", std::string( "hello" ) ); 00268 00269 // insert a prop with the same name as a sub property 00270 TS_ASSERT_THROWS( p->addProperty( "heySub", "test1", true ), WPropertyNotUnique ); 00271 00272 ///////////// 00273 // exists 00274 00275 // try to find a property of a group in the parent: should fail 00276 TS_ASSERT( !p->existsProperty( "3" ) ); 00277 TS_ASSERT( !p->existsProperty( "4" ) ); 00278 TS_ASSERT( psub->existsProperty( "3" ) ); 00279 TS_ASSERT( psub->existsProperty( "4" ) ); 00280 TS_ASSERT( !psub->existsProperty( "1" ) ); 00281 TS_ASSERT( !psub->existsProperty( "2" ) ); 00282 00283 // search it with the proper name: 00284 TS_ASSERT( p->existsProperty( "heySub/3" ) ); 00285 TS_ASSERT( !p->existsProperty( "heySub/1" ) ); 00286 00287 ///////////// 00288 // find 00289 00290 // search it with the proper name: 00291 TS_ASSERT( p3 == p->findProperty( "heySub/3" ) ); 00292 TS_ASSERT( p4 == p->findProperty( "heySub/4" ) ); 00293 00294 // ensure nothing is found if wrong name is specified 00295 TS_ASSERT( boost::shared_ptr< WPropertyBase >() == p->findProperty( "heySub/1" ) ); 00296 00297 ///////////// 00298 // get 00299 00300 TS_ASSERT_THROWS_NOTHING( p->getProperty( "heySub/3" ) ); 00301 TS_ASSERT_THROWS_NOTHING( p->getProperty( "heySub/4" ) ); 00302 00303 // ensure nothing is found if wrong name is specified 00304 TS_ASSERT_THROWS( p->getProperty( "heySub/1" ), WPropertyUnknown ); 00305 } 00306 00307 /** 00308 * Tests the cloning functionality. 00309 */ 00310 void testClone() 00311 { 00312 ///////////////////// 00313 // Clone 00314 00315 boost::shared_ptr< WProperties > orig( new WProperties( "hey", "you" ) ); 00316 boost::shared_ptr< WProperties > clone = orig->clone()->toPropGroup(); 00317 00318 // test that toPropGroup worked and both are different 00319 TS_ASSERT( clone.get() ); 00320 TS_ASSERT( orig != clone ); 00321 00322 ///////////////////// 00323 // Conditions 00324 00325 // is there a new condition? This has to be the case, this mainly situated in WPropertyBase 00326 TS_ASSERT( orig->getUpdateCondition() != clone->getUpdateCondition() ); 00327 00328 // update of property list does not modify the original 00329 clone->addProperty( "1", "test1", 1.0 ); 00330 TS_ASSERT( clone->m_properties.getReadTicket()->get().size() == 1 ); 00331 TS_ASSERT( orig->m_properties.getReadTicket()->get().size() == 0 ); 00332 00333 // does the condition fire on add? 00334 // first, register some callbacks to test it 00335 m_testTemporary1 = false; 00336 m_testTemporary2 = false; 00337 orig->getUpdateCondition()->subscribeSignal( boost::bind( &WPropertiesTest::setTemporary1, this ) ); 00338 clone->getUpdateCondition()->subscribeSignal( boost::bind( &WPropertiesTest::setTemporary2, this ) ); 00339 00340 // add a bool property -> conditions fired? 00341 clone->addProperty( "2", "test2", false ); 00342 00343 // the first should not fire, but the condition of the clone 00344 TS_ASSERT( m_testTemporary1 == false ); 00345 TS_ASSERT( m_testTemporary2 == true ); 00346 00347 // the same thing but vice versa 00348 m_testTemporary1 = false; 00349 m_testTemporary2 = false; 00350 orig->addProperty( "1", "test1", false ); 00351 // this time, the first should fire but not the second 00352 TS_ASSERT( m_testTemporary2 == false ); 00353 TS_ASSERT( m_testTemporary1 == true ); 00354 00355 ///////////////////// 00356 // cloned list 00357 00358 // the clone now contains some properties -> clone it again and check the list of contained properties 00359 boost::shared_ptr< WProperties > cloneClone = clone->clone()->toPropGroup(); 00360 00361 // same size? 00362 TS_ASSERT( clone->m_properties.getReadTicket()->get().size() == 2 ); 00363 TS_ASSERT( cloneClone->m_properties.getReadTicket()->get().size() == 2 ); 00364 00365 WProperties::PropertySharedContainerType::ReadTicket t = clone->getProperties(); 00366 00367 // iterate the original and check that there exists a cloned property in the cloned one 00368 for( WProperties::PropertyConstIterator iter = t->get().begin(); iter != t->get().end(); ++iter ) 00369 { 00370 // ensure there is a corresponding property in cloneClone 00371 boost::shared_ptr< WPropertyBase > p = cloneClone->findProperty( ( *iter )->getName() ); 00372 TS_ASSERT( p ); // found? 00373 TS_ASSERT( p != ( *iter ) ); // is it really a clone? (the cloning functionality of WPropertyVariable is tested separately 00374 } 00375 } 00376 }; 00377 00378 #endif // WPROPERTIES_TEST_H 00379 00380