OpenMesh
TestingFramework.hh
Go to the documentation of this file.
1 /*===========================================================================*\
2  * *
3  * OpenMesh *
4  * Copyright (C) 2001-2014 by Computer Graphics Group, RWTH Aachen *
5  * www.openmesh.org *
6  * *
7  *---------------------------------------------------------------------------*
8  * This file is part of OpenMesh. *
9  * *
10  * OpenMesh is free software: you can redistribute it and/or modify *
11  * it under the terms of the GNU Lesser General Public License as *
12  * published by the Free Software Foundation, either version 3 of *
13  * the License, or (at your option) any later version with the *
14  * following exceptions: *
15  * *
16  * If other files instantiate templates or use macros *
17  * or inline functions from this file, or you compile this file and *
18  * link it with other files to produce an executable, this file does *
19  * not by itself cause the resulting executable to be covered by the *
20  * GNU Lesser General Public License. This exception does not however *
21  * invalidate any other reasons why the executable file might be *
22  * covered by the GNU Lesser General Public License. *
23  * *
24  * OpenMesh is distributed in the hope that it will be useful, *
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
27  * GNU Lesser General Public License for more details. *
28  * *
29  * You should have received a copy of the GNU LesserGeneral Public *
30  * License along with OpenMesh. If not, *
31  * see <http://www.gnu.org/licenses/>. *
32  * *
33 \*===========================================================================*/
34 
35 /*===========================================================================*\
36  * *
37  * $Revision: 990 $ *
38  * $Date: 2014-02-05 10:01:07 +0100 (Mi, 05 Feb 2014) $ *
39  * *
40 \*===========================================================================*/
41 
42 #ifndef TESTINGFRAMEWORK_HH
43 #define TESTINGFRAMEWORK_HH
44 // ----------------------------------------------------------------------------
45 
51 // ----------------------------------------------------------------------------
52 
53 #include "Config.hh"
54 #include <iosfwd>
55 #include <sstream>
56 #include <vector>
57 #include <algorithm>
58 #include <stdexcept>
59 #include <OpenMesh/Core/Utils/Noncopyable.hh>
60 
61 // ------------------------------------------------------------- namespace ----
62 
63 namespace OpenMesh { // BEGIN_NS_OPENMESH
64 namespace Utils { // BEGIN_NS_UTILS
65 
66 
67 // ----------------------------------------------------------------- class ----
68 //
69 // Usage Example
70 //
71 // #include <iostream>
72 // #include <.../TestingFramework.hh>
73 //
74 // struct test_func : public TestingFramework::TestFunc
75 // {
76 // typedef test_func Self;
77 //
78 // // define ctor and copy-ctor
79 // test_func( TestingFramework& _th, std::string _n ) : TestingFramework::TestFunc( _th, _n ) { }
80 // test_func( Self& _cpy ) : TestingFramework::TestFunc(_cpy) { }
81 //
82 // // overload body()
83 // void body()
84 // {
85 //
86 // // Do the tests
87 // // direct call to verify
88 // verify( testResult, expectedResult, "additional information" );
89 //
90 // // or use the define TH_VERIFY. The test-expression will be used as the message string
91 // TH_VERIFY( testResult, expectedResult );
92 //
93 // ...
94 // }
95 // };
96 //
97 // int main(...)
98 // {
99 // TestingFramework testSuite(std::cout); // send output to stdout
100 //
101 // new test_func(testSuite); // create new test instance. It registers with testSuite.
102 // return testSuite.run();
103 // }
104 //
105 
106 //
107 #define TH_VERIFY( expr, expt ) \
108  verify( expr, expt, #expr )
109 
110 //
111 #define TH_VERIFY_X( expr, expt ) \
112  verify_x( expr, expt, #expr )
113 
118 {
119 public:
120 
121  typedef TestingFramework Self;
122  typedef std::logic_error verify_error;
123 
124 #ifndef DOXY_IGNORE_THIS
125  class TestFunc
126  {
127  public:
128  TestFunc( TestingFramework& _th, const std::string& _n )
129  : th_(_th), name_(_n)
130  {
131  th_.reg(this);
132  }
133 
134  virtual ~TestFunc()
135  { }
136 
137  void operator() ( void )
138  {
139  prolog();
140  try
141  {
142  body();
143  }
144  catch( std::exception& x )
145  {
146  std::cerr << "<<Error>>: Cannot proceed test due to failure of last"
147  << " test: " << x.what() << std::endl;
148  }
149  catch(...)
150  {
151  std::cerr << "Fatal: cannot proceed test due to unknown error!"
152  << std::endl;
153  }
154  epilog();
155  }
156 
157  const TestingFramework& testHelper() const { return th_; }
158 
159  protected:
160 
161  virtual void prolog(void)
162  {
163  begin(name_);
164  }
165 
166  virtual void body(void) = 0;
167 
168  virtual void epilog(void)
169  {
170  end();
171  }
172 
173  protected:
174 
175  TestingFramework& testHelper() { return th_; }
176 
177  TestFunc( const TestFunc& _cpy ) : th_(_cpy.th_), name_(_cpy.name_) { }
178 
179 
180  // Use the following method in prolog()
181  TestFunc& begin(std::string _title, const std::string& _info = "")
182  { th_.begin(_title,_info); return *this; }
183 
184 
185  // Use the following method in epilog()
186  TestFunc& end(void)
187  { th_.end(); return *this; }
188 
189 
190  // Use the followin methods in body()
191 
192  template <typename ValueType>
193  bool
194  verify( const ValueType& _rc, const ValueType& _expected,
195  std::string _info )
196  { return th_.verify( _rc, _expected, _info ); }
197 
198  template <typename ValueType>
199  void
200  verify_x( const ValueType& _rc, const ValueType& _expected,
201  std::string _info )
202  {
203  if ( !verify(_rc, _expected, _info) )
204  throw verify_error(_info);
205  }
206 
207  TestFunc& info(const std::string& _info)
208  { th_.info(_info); return *this; }
209 
210  TestFunc& info(const std::ostringstream& _ostr)
211  { th_.info(_ostr); return *this; }
212 
213  private:
214  TestFunc();
215 
216  protected:
217  TestingFramework& th_;
218  std::string name_;
219  };
220 #endif
221 
222  typedef TestFunc* TestFuncPtr;
223  typedef std::vector<TestFuncPtr> TestSet;
224 
225 public:
226 
227  TestingFramework(std::ostream& _os)
228  : errTotal_(0), errCount_(0),
229  verifyTotal_(0), verifyCount_(0),
230  testTotal_(0), testCount_(0),
231  os_(_os)
232  { }
233 
234 protected:
235 
236 #ifndef DOXY_IGNORE_THIS
237  struct TestDeleter
238  {
239  void operator() (TestFuncPtr _tfptr) { delete _tfptr; }
240  };
241 #endif
242 
243 public:
244 
245  virtual ~TestingFramework()
246  {
247  std::for_each(tests_.begin(), tests_.end(), TestDeleter() );
248  }
249 
250 public:
251 
252  template <typename ValueType>
253  bool verify(const ValueType& _rc,
254  const ValueType& _expected,
255  const std::string& _info)
256  {
257  ++verifyTotal_;
258  if ( _rc == _expected )
259  {
260  os_ << " " << _info << ", result: " << _rc << ", OK!" << std::endl;
261  return true;
262  }
263  ++errTotal_;
264  os_ << " " << _info << ", result: " << _rc << " != " << _expected
265  << " <<ERROR>>" << std::endl;
266  return false;
267  }
268 
269  Self& begin(std::string _title, const std::string& _info = "")
270  {
271  std::ostringstream ostr;
272 
273  testTitle_ = _title;
274  errCount_ = errTotal_;
275  ++testTotal_;
276 
277  ostr << _title;
278  if ( !_info.empty() )
279  ostr << " ["<< _info << "]";
280  testTitle_ = ostr.str();
281  os_ << "Begin " << testTitle_ << std::endl;
282  return *this;
283  }
284 
285  Self& end()
286  {
287  if (errorCount()==0)
288  ++testCount_;
289 
290  os_ << "End " << testTitle_ << ": " << errorCount() << " Error(s)." << std::endl;
291  return *this;
292  }
293 
294  Self& info(const std::string& _info)
295  {
296  os_ << " + " << _info << std::endl;
297  return *this;
298  }
299 
300  Self& info(const std::ostringstream& _ostr)
301  {
302  os_ << " + " << _ostr.str() << std::endl;
303  return *this;
304  }
305 
306  size_t errorTotal() const { return errTotal_; }
307  size_t errorCount() const { return errTotal_ - errCount_; }
308  size_t verifyTotal() const { return verifyTotal_; }
309  size_t verifyCount() const { return verifyTotal_ - verifyCount_; }
310  size_t goodTotal() const { return verifyTotal() - errorTotal(); }
311  size_t goodCount() const { return verifyCount() - errorCount(); }
312 
313  size_t testTotal() const { return testTotal_; }
314  size_t testCount() const { return testCount_; }
315 
316 public:
317 
318  int run(void)
319  {
320  os_ << "Test started\n";
321  TestRunner executer;
322  std::for_each(tests_.begin(), tests_.end(), executer );
323  os_ << std::endl;
324  os_ << "All tests completed" << std::endl
325  << " #Tests: " << testCount() << "/" << testTotal() << std::endl
326  << " #Errors: " << errorTotal() << "/" << verifyTotal() << std::endl;
327  return errorTotal();
328  }
329 
330 protected:
331 
332 #ifndef DOXY_IGNORE_THIS
333  struct TestRunner
334  {
335  void operator() (TestFuncPtr _tfptr) { (*_tfptr)(); }
336  };
337 #endif
338 
339  int reg(TestFuncPtr _tfptr)
340  {
341  tests_.push_back(_tfptr);
342  return true;
343  }
344 
345  friend class TestFunc;
346 
347 private:
348 
349  size_t errTotal_;
350  size_t errCount_;
351  size_t verifyTotal_;
352  size_t verifyCount_;
353  size_t testTotal_; // #Tests
354  size_t testCount_; // #Tests ohne Fehler
355 
356  std::string testTitle_;
357  std::ostream& os_;
358 
359  TestSet tests_;
360 
361 };
362 
363 // ============================================================================
364 } // END_NS_UTILS
365 } // END_NS_OPENMESH
366 // ============================================================================
367 #endif // TESTINGFRMEWORK_HH
368 // ============================================================================
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:56
Helper class for test programms.
Definition: TestingFramework.hh:117
This class demonstrates the non copyable idiom.
Definition: Noncopyable.hh:69

acg pic Project OpenMesh, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .