OpenWalnut  1.5.0dev
WPropertyVariable_test.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WPROPERTYVARIABLE_TEST_H
26 #define WPROPERTYVARIABLE_TEST_H
27 
28 #include <memory>
29 #include <string>
30 
31 #include <cxxtest/TestSuite.h>
32 
33 #include "../WPropertyVariable.h"
34 #include "../constraints/WPropertyConstraintMax.h"
35 #include "../constraints/WPropertyConstraintMin.h"
36 #include "../exceptions/WPropertyNameMalformed.h"
37 #include "../exceptions/WPropertyNotUnique.h"
38 #include "../exceptions/WPropertyUnknown.h"
39 
40 /**
41  * Test WPropertyVariable
42  */
43 class WPropertyVariableTest : public CxxTest::TestSuite
44 {
45 public:
46  /**
47  * A temporary holder for some value.
48  */
50 
51  /**
52  * A temporary holder for some value.
53  */
55 
56  /**
57  * Helper function which simply sets the value above to true. It is used to test some conditions here.
58  */
60  {
61  m_testTemporary1 = true;
62  }
63 
64  /**
65  * Helper function which simply sets the value above to true. It is used to test some conditions here.
66  */
68  {
69  m_testTemporary2 = true;
70  }
71 
72  /**
73  * Test instantiation, also test name and description and type (from WPropertyBase)
74  */
75  void testInstantiation( void )
76  {
77  std::shared_ptr< WPropertyVariable< bool > > p;
78  TS_ASSERT_THROWS_NOTHING( p = std::shared_ptr< WPropertyVariable< bool > >( new WPropertyVariable< bool >( "hey", "you", false ) ) );
79 
80  // test names
81  TS_ASSERT( p->getName() == "hey" );
82  TS_ASSERT( p->getDescription() == "you" );
83  TS_ASSERT( p->getType() == PV_BOOL );
84 
85  TS_ASSERT_THROWS_NOTHING( p.reset() );
86  }
87 
88  /**
89  * Tests that only properties with proper names can be created
90  */
91  void testNameConvention( void )
92  {
93  WException::disableBacktrace(); // in tests, turn of backtrace globally
94 
95  std::shared_ptr< WPropertyVariable< bool > > p;
96  TS_ASSERT_THROWS( p = std::shared_ptr< WPropertyVariable< bool > >( new WPropertyVariable< bool >( "hey/you", "you", false ) ),
97  const WPropertyNameMalformed& );
98  }
99 
100  /**
101  * Tests the cloning functionality.
102  */
103  void testClone()
104  {
105  WException::disableBacktrace(); // in tests, turn of backtrace globally
106 
107  /////////////////////////
108  // Create an original
109 
110  // create an int property
111  std::shared_ptr< WPropertyVariable< int > > p =
112  std::shared_ptr< WPropertyVariable< int > >( new WPropertyVariable< int >( "hey", "you", false ) );
113  // add a min/max prop
116  p->set( 5 );
117 
118  /////////////////////////
119  // Clone it
120 
121  std::shared_ptr< WPropertyVariable< int > > clone = p->clone()->toPropInt();
122 
123  // some rudimentary tests (from WPropertyBase)
124  TS_ASSERT( clone );
125  TS_ASSERT( clone->getType() == PV_INT );
126  TS_ASSERT( clone->getName() == p->getName() );
127  TS_ASSERT( clone->getDescription() == p->getDescription() );
128  TS_ASSERT( clone->getPurpose() == p->getPurpose() );
129 
130  // equal value?
131  TS_ASSERT( p->get() == clone->get() );
132 
133  // different conditions?
134  TS_ASSERT( p->getContraintsChangedCondition() != clone->getContraintsChangedCondition() );
135  TS_ASSERT( p->getUpdateCondition() != clone->getUpdateCondition() ); // this is from WPropertyBase
136 
137  // cloned constraints?
138  TS_ASSERT( p->getMin() != clone->getMin() ); // the constraints of course need to be cloned too
139  TS_ASSERT( p->getMax() != clone->getMax() ); // the constraints of course need to be cloned too
140 
141  TS_ASSERT( p->getMin()->getMin() == clone->getMin()->getMin() ); // but their values need to be the same. This somehow tests the clone
142  // feature of WPropertyConstrainMin and Max
143  TS_ASSERT( p->getMax()->getMax() == clone->getMax()->getMax() ); // but their values need to be the same. This somehow tests the clone
144  // feature of WPropertyConstrainMin and Max
145 
146  // check independence of both update conditions
147  p->getUpdateCondition()->subscribeSignal( boost::bind( &WPropertyVariableTest::setTemporary1, this ) );
148  clone->getUpdateCondition()->subscribeSignal( boost::bind( &WPropertyVariableTest::setTemporary2, this ) );
149 
150  // set the value of the clone -> fire condition of clone but not of original
151  m_testTemporary1 = false;
152  m_testTemporary2 = false;
153  clone->set( 4 );
154  TS_ASSERT( !m_testTemporary1 );
155  TS_ASSERT( m_testTemporary2 );
156 
157  // and test vice versa
158  m_testTemporary1 = false;
159  m_testTemporary2 = false;
160  p->set( 2 );
161  TS_ASSERT( m_testTemporary1 );
162  TS_ASSERT( !m_testTemporary2 );
163 
164  // do the same for constraints
165  m_testTemporary1 = false;
166  m_testTemporary2 = false;
167  clone->removeConstraint( PC_MIN );
168  TS_ASSERT( !m_testTemporary1 );
169  TS_ASSERT( m_testTemporary2 );
170 
171  // and vice versa
172  m_testTemporary1 = false;
173  m_testTemporary2 = false;
174  p->removeConstraint( PC_MIN );
175  TS_ASSERT( m_testTemporary1 );
176  TS_ASSERT( !m_testTemporary2 );
177  }
178 
179  /**
180  * Test min/max functionality, including tests for set(), accept() and ensureValidity.
181  */
183  {
184  WException::disableBacktrace(); // in tests, turn of backtrace globally
185 
186  // create an int property
187  std::shared_ptr< WPropertyVariable< int > > p =
188  std::shared_ptr< WPropertyVariable< int > >( new WPropertyVariable< int >( "hey", "you", false ) );
189 
190  // by default there should be no min/max property set. Only IF the property was created using a WProperties::addProperty.
193  TS_ASSERT( !cmin );
194  TS_ASSERT( !cmax );
195 
196  // does set() and accept work if no constraints are there?
197  TS_ASSERT( p->set( 123 ) );
198  TS_ASSERT( p->get() == 123 );
199  TS_ASSERT( p->accept( 12345 ) );
200 
201  // add a min prop
202  cmin = p->setMin( 10 );
203  cmax = p->setMax( 15 );
204  TS_ASSERT( cmin );
205  TS_ASSERT( cmax );
206 
207  // compare that getMin/max returns the correct ones
208  TS_ASSERT( cmin == p->getMin() );
209  TS_ASSERT( cmax == p->getMax() );
210 
211  // try to set a valid value
212  TS_ASSERT( p->set( 10 ) );
213  TS_ASSERT( p->get() == 10 );
214 
215  // try to set an invalid value
216  TS_ASSERT( !p->set( 9 ) );
217  TS_ASSERT( p->get() == 10 );
218  TS_ASSERT( !p->set( 16 ) );
219  TS_ASSERT( p->get() == 10 );
220 
221  // add another min value. Is the first one removed?
222  p->setMin( 5 );
223  p->setMax( 20 );
224  p->m_constraints->getReadTicket()->get().size();
225 
226  // try to set a valid value, which was invalid previously
227  TS_ASSERT( p->set( 9 ) );
228  TS_ASSERT( p->get() == 9 );
229  TS_ASSERT( p->set( 16 ) );
230  TS_ASSERT( p->get() == 16 );
231 
232  // finally, test ensureValidity
233  // this function helps to restore a property to a valid state after a constraint change
234 
235  // currently, the state of p is valid. So ensureValidity should do nothing
236  TS_ASSERT( p->ensureValidity( 10 ) );
237  TS_ASSERT( p->get() == 16 );
238 
239  // change the min constraint so that 16 gets invalid
240  TS_ASSERT( p->isValid() );
241  p->setMin( 17 );
242  TS_ASSERT( !p->isValid() );
243  TS_ASSERT( p->get() == 16 ); // setting a new constraint should NOT modify the current value
244 
245  // use ensureValidity
246  TS_ASSERT( p->ensureValidity( 18 ) );
247  TS_ASSERT( p->get() == 18 );
248  TS_ASSERT( p->isValid() );
249 
250  // what happens if the ensureValidity parameter itself is invalid? It should return false
251  p->setMin( 19 );
252  TS_ASSERT( !p->ensureValidity( 16 ) ); // 16 is invalid since minimum is 19
253  TS_ASSERT( !p->isValid() ); // the value should stay invalid
254  TS_ASSERT( p->get() == 18 );
255  }
256 
257  /**
258  * Tests constraint management. Especially add,replace,remove,count,getFirst.
259  */
261  {
262  WException::disableBacktrace(); // in tests, turn of backtrace globally
263 
264  // create an int property
265  std::shared_ptr< WPropertyVariable< int > > p =
266  std::shared_ptr< WPropertyVariable< int > >( new WPropertyVariable< int >( "hey", "you", false ) );
267 
268  // register a condition callback
269  p->getUpdateCondition()->subscribeSignal( boost::bind( &WPropertyVariableTest::setTemporary1, this ) );
270 
271  ////////////////////////////////////
272  // add
273 
274  // add a constraint
275  m_testTemporary1 = false;
277  std::shared_ptr< WPropertyConstraintMin< int > >( new WPropertyConstraintMin< int >( 10 ) );
278  p->addConstraint( cmin );
279  TS_ASSERT( p->m_constraints->getReadTicket()->get().size() == 1 );
280  TS_ASSERT( m_testTemporary1 ); // the update condition has to be fired on constraint updates
281 
282  ////////////////////////////////////
283  // count, getFirst
284 
285  // count constraints
286  m_testTemporary1 = false;
287  TS_ASSERT( p->countConstraint( PC_MIN ) == 1 );
288  TS_ASSERT( p->countConstraint( PC_MAX ) == 0 );
289 
290  // get first constraint should return the first constraint of a specified type
291  TS_ASSERT( cmin == p->getFirstConstraint( PC_MIN ) );
292  TS_ASSERT( !p->getFirstConstraint( PC_MAX ) ); // there is no max constraint
293  TS_ASSERT( !m_testTemporary1 ); // these operations should not fire the condition
294 
295  ////////////////////////////////////
296  // replace
297 
298  // replace a constraint
299  m_testTemporary1 = false;
301  std::shared_ptr< WPropertyConstraintMax< int > >( new WPropertyConstraintMax< int >( 15 ) );
302 
303  // replace non existent type
304  TS_ASSERT_THROWS_NOTHING( p->replaceConstraint( cmax, PC_MAX ) ); // since there is no max constraint, replace acts like addConstraint
305  TS_ASSERT( m_testTemporary1 );
306 
307  // replace existent type ( note: there is now a min and a max constraint )
308  m_testTemporary1 = false;
310  std::shared_ptr< WPropertyConstraintMax< int > >( new WPropertyConstraintMax< int >( 20 ) );
311  p->replaceConstraint( cmax2, PC_MAX );
312  TS_ASSERT( m_testTemporary1 );
313  TS_ASSERT( cmax2 == p->getFirstConstraint( PC_MAX ) );
314 
315  ////////////////////////////////////
316  // remove
317 
318  // removeConstraints should not fire the condition if nothing is removed
319  m_testTemporary1 = false;
320  p->removeConstraint( PC_NOTEMPTY );
321  TS_ASSERT( !m_testTemporary1 );
322 
323  // remove max constraint
324  m_testTemporary1 = false;
325  TS_ASSERT( p->countConstraint( PC_MAX ) == 1 );
326  p->removeConstraint( PC_MAX );
327  TS_ASSERT( p->countConstraint( PC_MAX ) == 0 );
328  TS_ASSERT( m_testTemporary1 ); // should have fired
329 
330  // remove min constraint with pointer
331  m_testTemporary1 = false;
332  TS_ASSERT( p->countConstraint( PC_MIN ) == 1 );
333  p->removeConstraint( cmin );
334  TS_ASSERT( p->countConstraint( PC_MIN ) == 0 );
335  TS_ASSERT( m_testTemporary1 ); // should have fired
336  }
337 };
338 
339 #endif // WPROPERTYVARIABLE_TEST_H
340 
static void disableBacktrace()
Function disables backtraces.
Definition: WException.cpp:200
This class allows constraining properties using a maximum value and the corresponding <= operator.
This class allows constraining properties using a minimum value and the corresponding >= operator.
Indicates invalid property name.
Test WPropertyVariable.
bool m_testTemporary2
A temporary holder for some value.
void testClone()
Tests the cloning functionality.
void testInstantiation(void)
Test instantiation, also test name and description and type (from WPropertyBase)
void testMinMaxWithSetAndAccept()
Test min/max functionality, including tests for set(), accept() and ensureValidity.
bool m_testTemporary1
A temporary holder for some value.
void setTemporary1()
Helper function which simply sets the value above to true.
void testNameConvention(void)
Tests that only properties with proper names can be created.
void setTemporary2()
Helper function which simply sets the value above to true.
void testConstraintManagement(void)
Tests constraint management.
A named property class with a concrete type.
PropertyConstraintMax setMax(const T &max)
Set a maximum constraint.
std::shared_ptr< WPropertyConstraintMin< T > > PropertyConstraintMin
Alias for min constraints.
std::shared_ptr< WPropertyConstraintMax< T > > PropertyConstraintMax
Alias for max constraints.
PropertyConstraintMax getMax()
Gets the current maximum constraint value.
std::shared_ptr< PropertyConstraint > getFirstConstraint(PROPERTYCONSTRAINT_TYPE type)
Method searching the first appearance of a constrained with the specified type.