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