OpenWalnut
1.2.5
|
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 /** 00045 * A temporary holder for some value. 00046 */ 00047 bool m_testTemporary1; 00048 00049 /** 00050 * A temporary holder for some value. 00051 */ 00052 bool m_testTemporary2; 00053 00054 /** 00055 * Helper function which simply sets the value above to true. It is used to test some conditions here. 00056 */ 00057 void setTemporary1() 00058 { 00059 m_testTemporary1 = true; 00060 } 00061 00062 /** 00063 * Helper function which simply sets the value above to true. It is used to test some conditions here. 00064 */ 00065 void setTemporary2() 00066 { 00067 m_testTemporary2 = true; 00068 } 00069 00070 /** 00071 * Test instantiation, also test name and description and type (from WPropertyBase) 00072 */ 00073 void testInstantiation( void ) 00074 { 00075 boost::shared_ptr< WProperties > p; 00076 TS_ASSERT_THROWS_NOTHING( p = boost::shared_ptr< WProperties >( new WProperties( "hey", "you" ) ) ); 00077 00078 // test names 00079 TS_ASSERT( p->getName() == "hey" ); 00080 TS_ASSERT( p->getDescription() == "you" ); 00081 TS_ASSERT( p->getType() == PV_GROUP ); 00082 00083 TS_ASSERT_THROWS_NOTHING( p.reset() ); 00084 } 00085 00086 /** 00087 * Test the add features, also tests the type of properties added 00088 */ 00089 void testAdd( void ) 00090 { 00091 WException::disableBacktrace(); // in tests, turn of backtrace globally 00092 00093 boost::shared_ptr< WProperties > p = boost::shared_ptr< WProperties >( new WProperties( "hey", "you" ) ); 00094 00095 // add some new properties 00096 boost::shared_ptr< WPropertyBase > p1 = p->addProperty( "1", "test1", true ); 00097 boost::shared_ptr< WPropertyBase > p2 = p->addProperty( "2", "test2", 1 ); 00098 boost::shared_ptr< WPropertyBase > p3 = p->addProperty( "3", "test3", 1.0 ); 00099 00100 // add a malformed (name) property 00101 // The name is malformed since the "/" is used as group separator 00102 TS_ASSERT_THROWS( p->addProperty( "4/5", "test4", 1.0 ), WPropertyNameMalformed ); 00103 00104 // this should have created 3 props 00105 TS_ASSERT( p->m_properties.getReadTicket()->get().size() == 3 ); 00106 00107 // ensure that it has created the correct types: 00108 TS_ASSERT( p1->getType() == PV_BOOL ); 00109 TS_ASSERT( p2->getType() == PV_INT ); 00110 TS_ASSERT( p3->getType() == PV_DOUBLE ); 00111 00112 // try to add another property with the same name ( regardless of actual type ) 00113 TS_ASSERT_THROWS( p->addProperty( "1", "test1", 1.0 ), WPropertyNotUnique ); 00114 } 00115 00116 /** 00117 * Test the clear() method 00118 */ 00119 void testClear( void ) 00120 { 00121 WException::disableBacktrace(); // in tests, turn of backtrace globally 00122 00123 boost::shared_ptr< WProperties > p = boost::shared_ptr< WProperties >( new WProperties( "hey", "you" ) ); 00124 00125 // add some new properties 00126 boost::shared_ptr< WPropertyBase > p1 = p->addProperty( "1", "test1", true ); 00127 boost::shared_ptr< WPropertyBase > p2 = p->addProperty( "2", "test2", 1 ); 00128 boost::shared_ptr< WPropertyBase > p3 = p->addProperty( "3", "test3", 1.0 ); 00129 00130 // this should have created 3 props 00131 TS_ASSERT( p->m_properties.getReadTicket()->get().size() == 3 ); 00132 00133 // clear 00134 TS_ASSERT_THROWS_NOTHING( p->clear() ); 00135 TS_ASSERT( p->m_properties.getReadTicket()->get().size() == 0 ); 00136 00137 // multiple clear should not cause any error 00138 TS_ASSERT_THROWS_NOTHING( p->clear() ); 00139 } 00140 00141 /** 00142 * Test the removeProperty() method 00143 */ 00144 void testRemove( void ) 00145 { 00146 WException::disableBacktrace(); // in tests, turn of backtrace globally 00147 00148 boost::shared_ptr< WProperties > p = boost::shared_ptr< WProperties >( new WProperties( "hey", "you" ) ); 00149 00150 // add some new properties 00151 boost::shared_ptr< WPropertyBase > p1 = p->addProperty( "1", "test1", true ); 00152 boost::shared_ptr< WPropertyBase > p2 = p->addProperty( "2", "test2", 1 ); 00153 boost::shared_ptr< WPropertyBase > p3 = p->addProperty( "3", "test3", 1.0 ); 00154 00155 // this should have created 3 props 00156 TS_ASSERT( p->m_properties.getReadTicket()->get().size() == 3 ); 00157 00158 // remove a property 00159 TS_ASSERT_THROWS_NOTHING( p->removeProperty( p2 ) ); 00160 TS_ASSERT( p->m_properties.getReadTicket()->get().size() == 2 ); 00161 00162 // remove a prop which is not in the list 00163 TS_ASSERT_THROWS_NOTHING( p->removeProperty( p2 ) ); 00164 TS_ASSERT( p->m_properties.getReadTicket()->get().size() == 2 ); 00165 } 00166 00167 00168 /** 00169 * Test the features to find and get properties. 00170 */ 00171 void testGetAndExistsAndFind( void ) 00172 { 00173 WException::disableBacktrace(); // in tests, turn of backtrace globally 00174 00175 boost::shared_ptr< WProperties > p = boost::shared_ptr< WProperties >( new WProperties( "hey", "you" ) ); 00176 00177 // add some new properties 00178 boost::shared_ptr< WPropertyBase > p1 = p->addProperty( "1", "test1", true ); 00179 boost::shared_ptr< WPropertyBase > p2 = p->addProperty( "2", "test2", 1 ); 00180 boost::shared_ptr< WPropertyBase > p3 = p->addProperty( "3", "test3", 1.0 ); 00181 00182 ///////////// 00183 // exists 00184 00185 // now, try to check whether a property exists: 00186 TS_ASSERT( p->existsProperty( "1" ) ); 00187 TS_ASSERT( !p->existsProperty( "shouldNotBeInTheList" ) ); 00188 00189 ///////////// 00190 // find 00191 00192 // same for find. Find does not throw an exception if the property does not exist! It simply returns it or NULL 00193 boost::shared_ptr< WPropertyBase > someProp; 00194 TS_ASSERT_THROWS_NOTHING( someProp = p->findProperty( "1" ) ); 00195 // The property exists -> return value is not NULL 00196 TS_ASSERT( someProp ); 00197 00198 // now for an unexisting one 00199 TS_ASSERT_THROWS_NOTHING( someProp = p->findProperty( "shouldNotBeInTheList" ) ); 00200 // The property exists -> return value is not NULL 00201 TS_ASSERT( !someProp ); 00202 00203 ///////////// 00204 // get 00205 00206 // the getProperty method throws an exception if the property has not been found. 00207 00208 // this one exists -> no exception 00209 TS_ASSERT_THROWS_NOTHING( someProp = p->getProperty( "1" ) ); 00210 TS_ASSERT( someProp ); 00211 00212 // this one does not exist 00213 TS_ASSERT_THROWS( someProp = p->getProperty( "shouldNotBeInTheList" ), WPropertyUnknown ); 00214 } 00215 00216 /** 00217 * Test the recursive search mechanism. 00218 */ 00219 void testGetAndExistsAndFindRecursive( void ) 00220 { 00221 boost::shared_ptr< WProperties > p = boost::shared_ptr< WProperties >( new WProperties( "hey", "you" ) ); 00222 boost::shared_ptr< WProperties > psub = p->addPropertyGroup( "heySub", "you" ); 00223 00224 // add some new properties 00225 boost::shared_ptr< WPropertyBase > p1 = p->addProperty( "1", "test1", true ); 00226 boost::shared_ptr< WPropertyBase > p2 = p->addProperty( "2", "test2", 1 ); 00227 boost::shared_ptr< WPropertyBase > p3 = psub->addProperty( "3", "test3", 1.0 ); 00228 boost::shared_ptr< WPropertyBase > p4 = psub->addProperty( "4", "test4", std::string( "hello" ) ); 00229 00230 // insert a prop with the same name as a sub property 00231 TS_ASSERT_THROWS( p->addProperty( "heySub", "test1", true ), WPropertyNotUnique ); 00232 00233 ///////////// 00234 // exists 00235 00236 // try to find a property of a group in the parent: should fail 00237 TS_ASSERT( !p->existsProperty( "3" ) ); 00238 TS_ASSERT( !p->existsProperty( "4" ) ); 00239 TS_ASSERT( psub->existsProperty( "3" ) ); 00240 TS_ASSERT( psub->existsProperty( "4" ) ); 00241 TS_ASSERT( !psub->existsProperty( "1" ) ); 00242 TS_ASSERT( !psub->existsProperty( "2" ) ); 00243 00244 // search it with the proper name: 00245 TS_ASSERT( p->existsProperty( "heySub/3" ) ); 00246 TS_ASSERT( !p->existsProperty( "heySub/1" ) ); 00247 00248 ///////////// 00249 // find 00250 00251 // search it with the proper name: 00252 TS_ASSERT( p3 == p->findProperty( "heySub/3" ) ); 00253 TS_ASSERT( p4 == p->findProperty( "heySub/4" ) ); 00254 00255 // ensure nothing is found if wrong name is specified 00256 TS_ASSERT( boost::shared_ptr< WPropertyBase >() == p->findProperty( "heySub/1" ) ); 00257 00258 ///////////// 00259 // get 00260 00261 TS_ASSERT_THROWS_NOTHING( p->getProperty( "heySub/3" ) ); 00262 TS_ASSERT_THROWS_NOTHING( p->getProperty( "heySub/4" ) ); 00263 00264 // ensure nothing is found if wrong name is specified 00265 TS_ASSERT_THROWS( p->getProperty( "heySub/1" ), WPropertyUnknown ); 00266 } 00267 00268 /** 00269 * Tests the cloning functionality. 00270 */ 00271 void testClone() 00272 { 00273 ///////////////////// 00274 // Clone 00275 00276 boost::shared_ptr< WProperties > orig = boost::shared_ptr< WProperties >( new WProperties( "hey", "you" ) ); 00277 boost::shared_ptr< WProperties > clone = orig->clone()->toPropGroup(); 00278 00279 // test that toPropGroup worked and both are different 00280 TS_ASSERT( clone.get() ); 00281 TS_ASSERT( orig != clone ); 00282 00283 ///////////////////// 00284 // Conditions 00285 00286 // is there a new condition? This has to be the case, this mainly situated in WPropertyBase 00287 TS_ASSERT( orig->getUpdateCondition() != clone->getUpdateCondition() ); 00288 00289 // update of property list does not modify the original 00290 clone->addProperty( "1", "test1", 1.0 ); 00291 TS_ASSERT( clone->m_properties.getReadTicket()->get().size() == 1 ); 00292 TS_ASSERT( orig->m_properties.getReadTicket()->get().size() == 0 ); 00293 00294 // does the condition fire on add? 00295 // first, register some callbacks to test it 00296 m_testTemporary1 = false; 00297 m_testTemporary2 = false; 00298 orig->getUpdateCondition()->subscribeSignal( boost::bind( &WPropertiesTest::setTemporary1, this ) ); 00299 clone->getUpdateCondition()->subscribeSignal( boost::bind( &WPropertiesTest::setTemporary2, this ) ); 00300 00301 // add a bool property -> conditions fired? 00302 clone->addProperty( "2", "test2", false ); 00303 00304 // the first should not fire, but the condition of the clone 00305 TS_ASSERT( m_testTemporary1 == false ); 00306 TS_ASSERT( m_testTemporary2 == true ); 00307 00308 // the same thing but vice versa 00309 m_testTemporary1 = false; 00310 m_testTemporary2 = false; 00311 orig->addProperty( "1", "test1", false ); 00312 // this time, the first should fire but not the second 00313 TS_ASSERT( m_testTemporary2 == false ); 00314 TS_ASSERT( m_testTemporary1 == true ); 00315 00316 ///////////////////// 00317 // cloned list 00318 00319 // the clone now contains some properties -> clone it again and check the list of contained properties 00320 boost::shared_ptr< WProperties > cloneClone = clone->clone()->toPropGroup(); 00321 00322 // same size? 00323 TS_ASSERT( clone->m_properties.getReadTicket()->get().size() == 2 ); 00324 TS_ASSERT( cloneClone->m_properties.getReadTicket()->get().size() == 2 ); 00325 00326 WProperties::PropertySharedContainerType::ReadTicket t = clone->getProperties(); 00327 00328 // iterate the original and check that there exists a cloned property in the cloned one 00329 for( WProperties::PropertyConstIterator iter = t->get().begin(); iter != t->get().end(); ++iter ) 00330 { 00331 // ensure there is a corresponding property in cloneClone 00332 boost::shared_ptr< WPropertyBase > p = cloneClone->findProperty( ( *iter )->getName() ); 00333 TS_ASSERT( p ); // found? 00334 TS_ASSERT( p != ( *iter ) ); // is it really a clone? (the cloning functionality of WPropertyVariable is tested separately 00335 } 00336 } 00337 }; 00338 00339 #endif // WPROPERTIES_TEST_H 00340 00341