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 WPROPERTYVARIABLE_TEST_H 00026 #define WPROPERTYVARIABLE_TEST_H 00027 00028 #include <string> 00029 00030 #include <cxxtest/TestSuite.h> 00031 00032 #include "../WPropertyVariable.h" 00033 #include "../constraints/WPropertyConstraintMin.h" 00034 #include "../constraints/WPropertyConstraintMax.h" 00035 00036 #include "../exceptions/WPropertyNotUnique.h" 00037 #include "../exceptions/WPropertyUnknown.h" 00038 #include "../exceptions/WPropertyNameMalformed.h" 00039 00040 /** 00041 * Test WPropertyVariable 00042 */ 00043 class WPropertyVariableTest : public CxxTest::TestSuite 00044 { 00045 public: 00046 00047 /** 00048 * A temporary holder for some value. 00049 */ 00050 bool m_testTemporary1; 00051 00052 /** 00053 * A temporary holder for some value. 00054 */ 00055 bool m_testTemporary2; 00056 00057 /** 00058 * Helper function which simply sets the value above to true. It is used to test some conditions here. 00059 */ 00060 void setTemporary1() 00061 { 00062 m_testTemporary1 = true; 00063 } 00064 00065 /** 00066 * Helper function which simply sets the value above to true. It is used to test some conditions here. 00067 */ 00068 void setTemporary2() 00069 { 00070 m_testTemporary2 = true; 00071 } 00072 00073 /** 00074 * Test instantiation, also test name and description and type (from WPropertyBase) 00075 */ 00076 void testInstantiation( void ) 00077 { 00078 boost::shared_ptr< WPropertyVariable< bool > > p; 00079 TS_ASSERT_THROWS_NOTHING( p = boost::shared_ptr< WPropertyVariable< bool > >( new WPropertyVariable< bool >( "hey", "you", false ) ) ); 00080 00081 // test names 00082 TS_ASSERT( p->getName() == "hey" ); 00083 TS_ASSERT( p->getDescription() == "you" ); 00084 TS_ASSERT( p->getType() == PV_BOOL ); 00085 00086 TS_ASSERT_THROWS_NOTHING( p.reset() ); 00087 } 00088 00089 /** 00090 * Tests that only properties with proper names can be created 00091 */ 00092 void testNameConvention( void ) 00093 { 00094 WException::disableBacktrace(); // in tests, turn of backtrace globally 00095 00096 boost::shared_ptr< WPropertyVariable< bool > > p; 00097 TS_ASSERT_THROWS( p = boost::shared_ptr< WPropertyVariable< bool > >( new WPropertyVariable< bool >( "hey/you", "you", false ) ), 00098 WPropertyNameMalformed ); 00099 } 00100 00101 /** 00102 * Tests the cloning functionality. 00103 */ 00104 void testClone() 00105 { 00106 WException::disableBacktrace(); // in tests, turn of backtrace globally 00107 00108 ///////////////////////// 00109 // Create an original 00110 00111 // create an int property 00112 boost::shared_ptr< WPropertyVariable< int > > p = 00113 boost::shared_ptr< WPropertyVariable< int > >( new WPropertyVariable< int >( "hey", "you", false ) ); 00114 // add a min/max prop 00115 WPropertyVariable< int >::PropertyConstraintMin cmin = p->setMin( 0 ); 00116 WPropertyVariable< int >::PropertyConstraintMax cmax = p->setMax( 9 ); 00117 p->set( 5 ); 00118 00119 ///////////////////////// 00120 // Clone it 00121 00122 boost::shared_ptr< WPropertyVariable< int > > clone = p->clone()->toPropInt(); 00123 00124 // some rudimentary tests (from WPropertyBase) 00125 TS_ASSERT( clone ); 00126 TS_ASSERT( clone->getType() == PV_INT ); 00127 TS_ASSERT( clone->getName() == p->getName() ); 00128 TS_ASSERT( clone->getDescription() == p->getDescription() ); 00129 TS_ASSERT( clone->getPurpose() == p->getPurpose() ); 00130 00131 // equal value? 00132 TS_ASSERT( p->get() == clone->get() ); 00133 00134 // different conditions? 00135 TS_ASSERT( p->getContraintsChangedCondition() != clone->getContraintsChangedCondition() ); 00136 TS_ASSERT( p->getUpdateCondition() != clone->getUpdateCondition() ); // this is from WPropertyBase 00137 00138 // cloned constraints? 00139 TS_ASSERT( p->getMin() != clone->getMin() ); // the constraints of course need to be cloned too 00140 TS_ASSERT( p->getMax() != clone->getMax() ); // the constraints of course need to be cloned too 00141 00142 TS_ASSERT( p->getMin()->getMin() == clone->getMin()->getMin() ); // but their values need to be the same. This somehow tests the clone 00143 // feature of WPropertyConstrainMin and Max 00144 TS_ASSERT( p->getMax()->getMax() == clone->getMax()->getMax() ); // but their values need to be the same. This somehow tests the clone 00145 // feature of WPropertyConstrainMin and Max 00146 00147 // check independence of both update conditions 00148 p->getUpdateCondition()->subscribeSignal( boost::bind( &WPropertyVariableTest::setTemporary1, this ) ); 00149 clone->getUpdateCondition()->subscribeSignal( boost::bind( &WPropertyVariableTest::setTemporary2, this ) ); 00150 00151 // set the value of the clone -> fire condition of clone but not of original 00152 m_testTemporary1 = false; 00153 m_testTemporary2 = false; 00154 clone->set( 4 ); 00155 TS_ASSERT( !m_testTemporary1 ); 00156 TS_ASSERT( m_testTemporary2 ); 00157 00158 // and test vice versa 00159 m_testTemporary1 = false; 00160 m_testTemporary2 = false; 00161 p->set( 2 ); 00162 TS_ASSERT( m_testTemporary1 ); 00163 TS_ASSERT( !m_testTemporary2 ); 00164 00165 // do the same for constraints 00166 m_testTemporary1 = false; 00167 m_testTemporary2 = false; 00168 clone->removeConstraint( PC_MIN ); 00169 TS_ASSERT( !m_testTemporary1 ); 00170 TS_ASSERT( m_testTemporary2 ); 00171 00172 // and vice versa 00173 m_testTemporary1 = false; 00174 m_testTemporary2 = false; 00175 p->removeConstraint( PC_MIN ); 00176 TS_ASSERT( m_testTemporary1 ); 00177 TS_ASSERT( !m_testTemporary2 ); 00178 } 00179 00180 /** 00181 * Test min/max functionality, including tests for set(), accept() and ensureValidity. 00182 */ 00183 void testMinMaxWithSetAndAccept() 00184 { 00185 WException::disableBacktrace(); // in tests, turn of backtrace globally 00186 00187 // create an int property 00188 boost::shared_ptr< WPropertyVariable< int > > p = 00189 boost::shared_ptr< WPropertyVariable< int > >( new WPropertyVariable< int >( "hey", "you", false ) ); 00190 00191 // by default there should be no min/max property set. Only IF the property was created using a WProperties::addProperty. 00192 WPropertyVariable< int >::PropertyConstraintMin cmin = p->getMin(); 00193 WPropertyVariable< int >::PropertyConstraintMax cmax = p->getMax(); 00194 TS_ASSERT( !cmin ); 00195 TS_ASSERT( !cmax ); 00196 00197 // does set() and accept work if no constraints are there? 00198 TS_ASSERT( p->set( 123 ) ); 00199 TS_ASSERT( p->get() == 123 ); 00200 TS_ASSERT( p->accept( 12345 ) ); 00201 00202 // add a min prop 00203 cmin = p->setMin( 10 ); 00204 cmax = p->setMax( 15 ); 00205 TS_ASSERT( cmin ); 00206 TS_ASSERT( cmax ); 00207 00208 // compare that getMin/max returns the correct ones 00209 TS_ASSERT( cmin == p->getMin() ); 00210 TS_ASSERT( cmax == p->getMax() ); 00211 00212 // try to set a valid value 00213 TS_ASSERT( p->set( 10 ) ); 00214 TS_ASSERT( p->get() == 10 ); 00215 00216 // try to set an invalid value 00217 TS_ASSERT( !p->set( 9 ) ); 00218 TS_ASSERT( p->get() == 10 ); 00219 TS_ASSERT( !p->set( 16 ) ); 00220 TS_ASSERT( p->get() == 10 ); 00221 00222 // add another min value. Is the first one removed? 00223 p->setMin( 5 ); 00224 p->setMax( 20 ); 00225 p->m_constraints->getReadTicket()->get().size(); 00226 00227 // try to set a valid value, which was invalid previously 00228 TS_ASSERT( p->set( 9 ) ); 00229 TS_ASSERT( p->get() == 9 ); 00230 TS_ASSERT( p->set( 16 ) ); 00231 TS_ASSERT( p->get() == 16 ); 00232 00233 // finally, test ensureValidity 00234 // this function helps to restore a property to a valid state after a constraint change 00235 00236 // currently, the state of p is valid. So ensureValidity should do nothing 00237 TS_ASSERT( p->ensureValidity( 10 ) ); 00238 TS_ASSERT( p->get() == 16 ); 00239 00240 // change the min constraint so that 16 gets invalid 00241 TS_ASSERT( p->isValid() ); 00242 p->setMin( 17 ); 00243 TS_ASSERT( !p->isValid() ); 00244 TS_ASSERT( p->get() == 16 ); // setting a new constraint should NOT modify the current value 00245 00246 // use ensureValidity 00247 TS_ASSERT( p->ensureValidity( 18 ) ); 00248 TS_ASSERT( p->get() == 18 ); 00249 TS_ASSERT( p->isValid() ); 00250 00251 // what happens if the ensureValidity parameter itself is invalid? It should return false 00252 p->setMin( 19 ); 00253 TS_ASSERT( !p->ensureValidity( 16 ) ); // 16 is invalid since minimum is 19 00254 TS_ASSERT( !p->isValid() ); // the value should stay invalid 00255 TS_ASSERT( p->get() == 18 ); 00256 } 00257 00258 /** 00259 * Tests constraint management. Especially add,replace,remove,count,getFirst. 00260 */ 00261 void testConstraintManagement( void ) 00262 { 00263 WException::disableBacktrace(); // in tests, turn of backtrace globally 00264 00265 // create an int property 00266 boost::shared_ptr< WPropertyVariable< int > > p = 00267 boost::shared_ptr< WPropertyVariable< int > >( new WPropertyVariable< int >( "hey", "you", false ) ); 00268 00269 // register a condition callback 00270 p->getUpdateCondition()->subscribeSignal( boost::bind( &WPropertyVariableTest::setTemporary1, this ) ); 00271 00272 //////////////////////////////////// 00273 // add 00274 00275 // add a constraint 00276 m_testTemporary1 = false; 00277 WPropertyVariable< int >::PropertyConstraintMin cmin = 00278 boost::shared_ptr< WPropertyConstraintMin< int > >( new WPropertyConstraintMin< int >( 10 ) ); 00279 p->addConstraint( cmin ); 00280 TS_ASSERT( p->m_constraints->getReadTicket()->get().size() == 1 ); 00281 TS_ASSERT( m_testTemporary1 ); // the update condition has to be fired on constraint updates 00282 00283 //////////////////////////////////// 00284 // count, getFirst 00285 00286 // count constraints 00287 m_testTemporary1 = false; 00288 TS_ASSERT( p->countConstraint( PC_MIN ) == 1 ); 00289 TS_ASSERT( p->countConstraint( PC_MAX ) == 0 ); 00290 00291 // get first constraint should return the first constraint of a specified type 00292 TS_ASSERT( cmin == p->getFirstConstraint( PC_MIN ) ); 00293 TS_ASSERT( !p->getFirstConstraint( PC_MAX ) ); // there is no max constraint 00294 TS_ASSERT( !m_testTemporary1 ); // these operations should not fire the condition 00295 00296 //////////////////////////////////// 00297 // replace 00298 00299 // replace a constraint 00300 m_testTemporary1 = false; 00301 WPropertyVariable< int >::PropertyConstraintMax cmax = 00302 boost::shared_ptr< WPropertyConstraintMax< int > >( new WPropertyConstraintMax< int >( 15 ) ); 00303 00304 // replace non existent type 00305 TS_ASSERT_THROWS_NOTHING( p->replaceConstraint( cmax, PC_MAX ) ); // since there is no max constraint, replace acts like addConstraint 00306 TS_ASSERT( m_testTemporary1 ); 00307 00308 // replace existent type ( note: there is now a min and a max constraint ) 00309 m_testTemporary1 = false; 00310 WPropertyVariable< int >::PropertyConstraintMax cmax2 = 00311 boost::shared_ptr< WPropertyConstraintMax< int > >( new WPropertyConstraintMax< int >( 20 ) ); 00312 p->replaceConstraint( cmax2, PC_MAX ); 00313 TS_ASSERT( m_testTemporary1 ); 00314 TS_ASSERT( cmax2 == p->getFirstConstraint( PC_MAX ) ); 00315 00316 //////////////////////////////////// 00317 // remove 00318 00319 // removeConstraints should not fire the condition if nothing is removed 00320 m_testTemporary1 = false; 00321 p->removeConstraint( PC_NOTEMPTY ); 00322 TS_ASSERT( !m_testTemporary1 ); 00323 00324 // remove max constraint 00325 m_testTemporary1 = false; 00326 TS_ASSERT( p->countConstraint( PC_MAX ) == 1 ); 00327 p->removeConstraint( PC_MAX ); 00328 TS_ASSERT( p->countConstraint( PC_MAX ) == 0 ); 00329 TS_ASSERT( m_testTemporary1 ); // should have fired 00330 00331 // remove min constraint with pointer 00332 m_testTemporary1 = false; 00333 TS_ASSERT( p->countConstraint( PC_MIN ) == 1 ); 00334 p->removeConstraint( cmin ); 00335 TS_ASSERT( p->countConstraint( PC_MIN ) == 0 ); 00336 TS_ASSERT( m_testTemporary1 ); // should have fired 00337 } 00338 }; 00339 00340 #endif // WPROPERTYVARIABLE_TEST_H 00341