OpenWalnut  1.2.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
WProperties_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 WPROPERTIES_TEST_H
26 #define WPROPERTIES_TEST_H
27 
28 #include <string>
29 
30 #include <cxxtest/TestSuite.h>
31 
32 #include "../WProperties.h"
33 #include "../exceptions/WPropertyNotUnique.h"
34 #include "../exceptions/WPropertyUnknown.h"
35 #include "../exceptions/WPropertyNameMalformed.h"
36 
37 /**
38  * Test WProperties
39  */
40 class WPropertiesTest : public CxxTest::TestSuite
41 {
42 public:
43 
44  /**
45  * A temporary holder for some value.
46  */
48 
49  /**
50  * A temporary holder for some value.
51  */
53 
54  /**
55  * Helper function which simply sets the value above to true. It is used to test some conditions here.
56  */
58  {
59  m_testTemporary1 = true;
60  }
61 
62  /**
63  * Helper function which simply sets the value above to true. It is used to test some conditions here.
64  */
66  {
67  m_testTemporary2 = true;
68  }
69 
70  /**
71  * Test instantiation, also test name and description and type (from WPropertyBase)
72  */
73  void testInstantiation( void )
74  {
75  boost::shared_ptr< WProperties > p;
76  TS_ASSERT_THROWS_NOTHING( p = boost::shared_ptr< WProperties >( new WProperties( "hey", "you" ) ) );
77 
78  // test names
79  TS_ASSERT( p->getName() == "hey" );
80  TS_ASSERT( p->getDescription() == "you" );
81  TS_ASSERT( p->getType() == PV_GROUP );
82 
83  TS_ASSERT_THROWS_NOTHING( p.reset() );
84  }
85 
86  /**
87  * Test the add features, also tests the type of properties added
88  */
89  void testAdd( void )
90  {
91  WException::disableBacktrace(); // in tests, turn of backtrace globally
92 
93  boost::shared_ptr< WProperties > p = boost::shared_ptr< WProperties >( new WProperties( "hey", "you" ) );
94 
95  // add some new properties
96  boost::shared_ptr< WPropertyBase > p1 = p->addProperty( "1", "test1", true );
97  boost::shared_ptr< WPropertyBase > p2 = p->addProperty( "2", "test2", 1 );
98  boost::shared_ptr< WPropertyBase > p3 = p->addProperty( "3", "test3", 1.0 );
99 
100  // add a malformed (name) property
101  // The name is malformed since the "/" is used as group separator
102  TS_ASSERT_THROWS( p->addProperty( "4/5", "test4", 1.0 ), WPropertyNameMalformed );
103 
104  // this should have created 3 props
105  TS_ASSERT( p->m_properties.getReadTicket()->get().size() == 3 );
106 
107  // ensure that it has created the correct types:
108  TS_ASSERT( p1->getType() == PV_BOOL );
109  TS_ASSERT( p2->getType() == PV_INT );
110  TS_ASSERT( p3->getType() == PV_DOUBLE );
111 
112  // try to add another property with the same name ( regardless of actual type )
113  TS_ASSERT_THROWS( p->addProperty( "1", "test1", 1.0 ), WPropertyNotUnique );
114  }
115 
116  /**
117  * Test the clear() method
118  */
119  void testClear( void )
120  {
121  WException::disableBacktrace(); // in tests, turn of backtrace globally
122 
123  boost::shared_ptr< WProperties > p = boost::shared_ptr< WProperties >( new WProperties( "hey", "you" ) );
124 
125  // add some new properties
126  boost::shared_ptr< WPropertyBase > p1 = p->addProperty( "1", "test1", true );
127  boost::shared_ptr< WPropertyBase > p2 = p->addProperty( "2", "test2", 1 );
128  boost::shared_ptr< WPropertyBase > p3 = p->addProperty( "3", "test3", 1.0 );
129 
130  // this should have created 3 props
131  TS_ASSERT( p->m_properties.getReadTicket()->get().size() == 3 );
132 
133  // clear
134  TS_ASSERT_THROWS_NOTHING( p->clear() );
135  TS_ASSERT( p->m_properties.getReadTicket()->get().size() == 0 );
136 
137  // multiple clear should not cause any error
138  TS_ASSERT_THROWS_NOTHING( p->clear() );
139  }
140 
141  /**
142  * Test the removeProperty() method
143  */
144  void testRemove( void )
145  {
146  WException::disableBacktrace(); // in tests, turn of backtrace globally
147 
148  boost::shared_ptr< WProperties > p = boost::shared_ptr< WProperties >( new WProperties( "hey", "you" ) );
149 
150  // add some new properties
151  boost::shared_ptr< WPropertyBase > p1 = p->addProperty( "1", "test1", true );
152  boost::shared_ptr< WPropertyBase > p2 = p->addProperty( "2", "test2", 1 );
153  boost::shared_ptr< WPropertyBase > p3 = p->addProperty( "3", "test3", 1.0 );
154 
155  // this should have created 3 props
156  TS_ASSERT( p->m_properties.getReadTicket()->get().size() == 3 );
157 
158  // remove a property
159  TS_ASSERT_THROWS_NOTHING( p->removeProperty( p2 ) );
160  TS_ASSERT( p->m_properties.getReadTicket()->get().size() == 2 );
161 
162  // remove a prop which is not in the list
163  TS_ASSERT_THROWS_NOTHING( p->removeProperty( p2 ) );
164  TS_ASSERT( p->m_properties.getReadTicket()->get().size() == 2 );
165  }
166 
167 
168  /**
169  * Test the features to find and get properties.
170  */
172  {
173  WException::disableBacktrace(); // in tests, turn of backtrace globally
174 
175  boost::shared_ptr< WProperties > p = boost::shared_ptr< WProperties >( new WProperties( "hey", "you" ) );
176 
177  // add some new properties
178  boost::shared_ptr< WPropertyBase > p1 = p->addProperty( "1", "test1", true );
179  boost::shared_ptr< WPropertyBase > p2 = p->addProperty( "2", "test2", 1 );
180  boost::shared_ptr< WPropertyBase > p3 = p->addProperty( "3", "test3", 1.0 );
181 
182  /////////////
183  // exists
184 
185  // now, try to check whether a property exists:
186  TS_ASSERT( p->existsProperty( "1" ) );
187  TS_ASSERT( !p->existsProperty( "shouldNotBeInTheList" ) );
188 
189  /////////////
190  // find
191 
192  // same for find. Find does not throw an exception if the property does not exist! It simply returns it or NULL
193  boost::shared_ptr< WPropertyBase > someProp;
194  TS_ASSERT_THROWS_NOTHING( someProp = p->findProperty( "1" ) );
195  // The property exists -> return value is not NULL
196  TS_ASSERT( someProp );
197 
198  // now for an unexisting one
199  TS_ASSERT_THROWS_NOTHING( someProp = p->findProperty( "shouldNotBeInTheList" ) );
200  // The property exists -> return value is not NULL
201  TS_ASSERT( !someProp );
202 
203  /////////////
204  // get
205 
206  // the getProperty method throws an exception if the property has not been found.
207 
208  // this one exists -> no exception
209  TS_ASSERT_THROWS_NOTHING( someProp = p->getProperty( "1" ) );
210  TS_ASSERT( someProp );
211 
212  // this one does not exist
213  TS_ASSERT_THROWS( someProp = p->getProperty( "shouldNotBeInTheList" ), WPropertyUnknown );
214  }
215 
216  /**
217  * Test the recursive search mechanism.
218  */
220  {
221  boost::shared_ptr< WProperties > p = boost::shared_ptr< WProperties >( new WProperties( "hey", "you" ) );
222  boost::shared_ptr< WProperties > psub = p->addPropertyGroup( "heySub", "you" );
223 
224  // add some new properties
225  boost::shared_ptr< WPropertyBase > p1 = p->addProperty( "1", "test1", true );
226  boost::shared_ptr< WPropertyBase > p2 = p->addProperty( "2", "test2", 1 );
227  boost::shared_ptr< WPropertyBase > p3 = psub->addProperty( "3", "test3", 1.0 );
228  boost::shared_ptr< WPropertyBase > p4 = psub->addProperty( "4", "test4", std::string( "hello" ) );
229 
230  // insert a prop with the same name as a sub property
231  TS_ASSERT_THROWS( p->addProperty( "heySub", "test1", true ), WPropertyNotUnique );
232 
233  /////////////
234  // exists
235 
236  // try to find a property of a group in the parent: should fail
237  TS_ASSERT( !p->existsProperty( "3" ) );
238  TS_ASSERT( !p->existsProperty( "4" ) );
239  TS_ASSERT( psub->existsProperty( "3" ) );
240  TS_ASSERT( psub->existsProperty( "4" ) );
241  TS_ASSERT( !psub->existsProperty( "1" ) );
242  TS_ASSERT( !psub->existsProperty( "2" ) );
243 
244  // search it with the proper name:
245  TS_ASSERT( p->existsProperty( "heySub/3" ) );
246  TS_ASSERT( !p->existsProperty( "heySub/1" ) );
247 
248  /////////////
249  // find
250 
251  // search it with the proper name:
252  TS_ASSERT( p3 == p->findProperty( "heySub/3" ) );
253  TS_ASSERT( p4 == p->findProperty( "heySub/4" ) );
254 
255  // ensure nothing is found if wrong name is specified
256  TS_ASSERT( boost::shared_ptr< WPropertyBase >() == p->findProperty( "heySub/1" ) );
257 
258  /////////////
259  // get
260 
261  TS_ASSERT_THROWS_NOTHING( p->getProperty( "heySub/3" ) );
262  TS_ASSERT_THROWS_NOTHING( p->getProperty( "heySub/4" ) );
263 
264  // ensure nothing is found if wrong name is specified
265  TS_ASSERT_THROWS( p->getProperty( "heySub/1" ), WPropertyUnknown );
266  }
267 
268  /**
269  * Tests the cloning functionality.
270  */
271  void testClone()
272  {
273  /////////////////////
274  // Clone
275 
276  boost::shared_ptr< WProperties > orig = boost::shared_ptr< WProperties >( new WProperties( "hey", "you" ) );
277  boost::shared_ptr< WProperties > clone = orig->clone()->toPropGroup();
278 
279  // test that toPropGroup worked and both are different
280  TS_ASSERT( clone.get() );
281  TS_ASSERT( orig != clone );
282 
283  /////////////////////
284  // Conditions
285 
286  // is there a new condition? This has to be the case, this mainly situated in WPropertyBase
287  TS_ASSERT( orig->getUpdateCondition() != clone->getUpdateCondition() );
288 
289  // update of property list does not modify the original
290  clone->addProperty( "1", "test1", 1.0 );
291  TS_ASSERT( clone->m_properties.getReadTicket()->get().size() == 1 );
292  TS_ASSERT( orig->m_properties.getReadTicket()->get().size() == 0 );
293 
294  // does the condition fire on add?
295  // first, register some callbacks to test it
296  m_testTemporary1 = false;
297  m_testTemporary2 = false;
298  orig->getUpdateCondition()->subscribeSignal( boost::bind( &WPropertiesTest::setTemporary1, this ) );
299  clone->getUpdateCondition()->subscribeSignal( boost::bind( &WPropertiesTest::setTemporary2, this ) );
300 
301  // add a bool property -> conditions fired?
302  clone->addProperty( "2", "test2", false );
303 
304  // the first should not fire, but the condition of the clone
305  TS_ASSERT( m_testTemporary1 == false );
306  TS_ASSERT( m_testTemporary2 == true );
307 
308  // the same thing but vice versa
309  m_testTemporary1 = false;
310  m_testTemporary2 = false;
311  orig->addProperty( "1", "test1", false );
312  // this time, the first should fire but not the second
313  TS_ASSERT( m_testTemporary2 == false );
314  TS_ASSERT( m_testTemporary1 == true );
315 
316  /////////////////////
317  // cloned list
318 
319  // the clone now contains some properties -> clone it again and check the list of contained properties
320  boost::shared_ptr< WProperties > cloneClone = clone->clone()->toPropGroup();
321 
322  // same size?
323  TS_ASSERT( clone->m_properties.getReadTicket()->get().size() == 2 );
324  TS_ASSERT( cloneClone->m_properties.getReadTicket()->get().size() == 2 );
325 
326  WProperties::PropertySharedContainerType::ReadTicket t = clone->getProperties();
327 
328  // iterate the original and check that there exists a cloned property in the cloned one
329  for( WProperties::PropertyConstIterator iter = t->get().begin(); iter != t->get().end(); ++iter )
330  {
331  // ensure there is a corresponding property in cloneClone
332  boost::shared_ptr< WPropertyBase > p = cloneClone->findProperty( ( *iter )->getName() );
333  TS_ASSERT( p ); // found?
334  TS_ASSERT( p != ( *iter ) ); // is it really a clone? (the cloning functionality of WPropertyVariable is tested separately
335  }
336  }
337 };
338 
339 #endif // WPROPERTIES_TEST_H
340 
341