OpenWalnut 1.2.5
WProperties_test.h
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 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends