source: trunk/contrib/cppunit-1.12.2/include/cppunit/TestAssert.h @ 876

Last change on this file since 876 was 876, checked in by sam, 9 years ago

contrib: add a precompiled Win32 version of CppUnit and update build system
accordingly.

File size: 16.2 KB
Line 
1#ifndef CPPUNIT_TESTASSERT_H
2#define CPPUNIT_TESTASSERT_H
3
4#include <cppunit/Portability.h>
5#include <cppunit/Exception.h>
6#include <cppunit/Asserter.h>
7#include <cppunit/portability/Stream.h>
8#include <stdio.h>
9#include <float.h> // For struct assertion_traits<double>
10
11
12CPPUNIT_NS_BEGIN
13
14
15/*! \brief Traits used by CPPUNIT_ASSERT_EQUAL().
16 *
17 * Here is an example of specialising these traits:
18 *
19 * \code
20 * template<>
21 * struct assertion_traits<std::string>   // specialization for the std::string type
22 * {
23 *   static bool equal( const std::string& x, const std::string& y )
24 *   {
25 *     return x == y;
26 *   }
27 *
28 *   static std::string toString( const std::string& x )
29 *   {
30 *     std::string text = '"' + x + '"';    // adds quote around the string to see whitespace
31 *     OStringStream ost;
32 *     ost << text;
33 *     return ost.str();
34 *   }
35 * };
36 * \endcode
37 */
38template <class T>
39struct assertion_traits
40
41    static bool equal( const T& x, const T& y )
42    {
43        return x == y;
44    }
45
46    static std::string toString( const T& x )
47    {
48        OStringStream ost;
49        ost << x;
50        return ost.str();
51    }
52};
53
54
55/*! \brief Traits used by CPPUNIT_ASSERT_DOUBLES_EQUAL().
56 *
57 * This specialisation from @c struct @c assertion_traits<> ensures that
58 * doubles are converted in full, instead of being rounded to the default
59 * 6 digits of precision. Use the system defined ISO C99 macro DBL_DIG
60 * within float.h is available to define the maximum precision, otherwise
61 * use the hard-coded maximum precision of 15.
62 */
63template <>
64struct assertion_traits<double>
65
66    static bool equal( double x, double y )
67    {
68        return x == y;
69    }
70
71    static std::string toString( double x )
72    {
73#ifdef DBL_DIG
74       const int precision = DBL_DIG;
75#else
76       const int precision = 15;
77#endif  // #ifdef DBL_DIG
78       char buffer[128];
79#ifdef __STDC_SECURE_LIB__ // Use secure version with visual studio 2005 to avoid warning.
80       sprintf_s(buffer, sizeof(buffer), "%.*g", precision, x);
81#else   
82       sprintf(buffer, "%.*g", precision, x);
83#endif
84       return buffer;
85    }
86};
87
88
89/*! \brief (Implementation) Asserts that two objects of the same type are equals.
90 * Use CPPUNIT_ASSERT_EQUAL instead of this function.
91 * \sa assertion_traits, Asserter::failNotEqual().
92 */
93template <class T>
94void assertEquals( const T& expected,
95                   const T& actual,
96                   SourceLine sourceLine,
97                   const std::string &message )
98{
99  if ( !assertion_traits<T>::equal(expected,actual) ) // lazy toString conversion...
100  {
101    Asserter::failNotEqual( assertion_traits<T>::toString(expected),
102                            assertion_traits<T>::toString(actual),
103                            sourceLine,
104                            message );
105  }
106}
107
108
109/*! \brief (Implementation) Asserts that two double are equals given a tolerance.
110 * Use CPPUNIT_ASSERT_DOUBLES_EQUAL instead of this function.
111 * \sa Asserter::failNotEqual().
112 * \sa CPPUNIT_ASSERT_DOUBLES_EQUAL for detailed semantic of the assertion.
113 */
114void CPPUNIT_API assertDoubleEquals( double expected,
115                                     double actual,
116                                     double delta,
117                                     SourceLine sourceLine,
118                                     const std::string &message );
119
120
121/* A set of macros which allow us to get the line number
122 * and file name at the point of an error.
123 * Just goes to show that preprocessors do have some
124 * redeeming qualities.
125 */
126#if CPPUNIT_HAVE_CPP_SOURCE_ANNOTATION
127/** Assertions that a condition is \c true.
128 * \ingroup Assertions
129 */
130#define CPPUNIT_ASSERT(condition)                                                 \
131  ( CPPUNIT_NS::Asserter::failIf( !(condition),                                   \
132                                 CPPUNIT_NS::Message( "assertion failed",         \
133                                                      "Expression: " #condition), \
134                                 CPPUNIT_SOURCELINE() ) )
135#else
136#define CPPUNIT_ASSERT(condition)                                            \
137  ( CPPUNIT_NS::Asserter::failIf( !(condition),                              \
138                                  CPPUNIT_NS::Message( "assertion failed" ), \
139                                  CPPUNIT_SOURCELINE() ) )
140#endif
141
142/** Assertion with a user specified message.
143 * \ingroup Assertions
144 * \param message Message reported in diagnostic if \a condition evaluates
145 *                to \c false.
146 * \param condition If this condition evaluates to \c false then the
147 *                  test failed.
148 */
149#define CPPUNIT_ASSERT_MESSAGE(message,condition)                          \
150  ( CPPUNIT_NS::Asserter::failIf( !(condition),                            \
151                                  CPPUNIT_NS::Message( "assertion failed", \
152                                                       "Expression: "      \
153                                                       #condition,         \
154                                                       message ),          \
155                                  CPPUNIT_SOURCELINE() ) )
156
157/** Fails with the specified message.
158 * \ingroup Assertions
159 * \param message Message reported in diagnostic.
160 */
161#define CPPUNIT_FAIL( message )                                         \
162  ( CPPUNIT_NS::Asserter::fail( CPPUNIT_NS::Message( "forced failure",  \
163                                                     message ),         \
164                                CPPUNIT_SOURCELINE() ) )
165
166#ifdef CPPUNIT_ENABLE_SOURCELINE_DEPRECATED
167/// Generalized macro for primitive value comparisons
168#define CPPUNIT_ASSERT_EQUAL(expected,actual)                     \
169  ( CPPUNIT_NS::assertEquals( (expected),             \
170                              (actual),               \
171                              __LINE__, __FILE__ ) )
172#else
173/** Asserts that two values are equals.
174 * \ingroup Assertions
175 *
176 * Equality and string representation can be defined with
177 * an appropriate CppUnit::assertion_traits class.
178 *
179 * A diagnostic is printed if actual and expected values disagree.
180 *
181 * Requirement for \a expected and \a actual parameters:
182 * - They are exactly of the same type
183 * - They are serializable into a std::strstream using operator <<.
184 * - They can be compared using operator ==.
185 *
186 * The last two requirements (serialization and comparison) can be
187 * removed by specializing the CppUnit::assertion_traits.
188 */
189#define CPPUNIT_ASSERT_EQUAL(expected,actual)          \
190  ( CPPUNIT_NS::assertEquals( (expected),              \
191                              (actual),                \
192                              CPPUNIT_SOURCELINE(),    \
193                              "" ) )
194
195/** Asserts that two values are equals, provides additional message on failure.
196 * \ingroup Assertions
197 *
198 * Equality and string representation can be defined with
199 * an appropriate assertion_traits class.
200 *
201 * A diagnostic is printed if actual and expected values disagree.
202 * The message is printed in addition to the expected and actual value
203 * to provide additional information.
204 *
205 * Requirement for \a expected and \a actual parameters:
206 * - They are exactly of the same type
207 * - They are serializable into a std::strstream using operator <<.
208 * - They can be compared using operator ==.
209 *
210 * The last two requirements (serialization and comparison) can be
211 * removed by specializing the CppUnit::assertion_traits.
212 */
213#define CPPUNIT_ASSERT_EQUAL_MESSAGE(message,expected,actual)      \
214  ( CPPUNIT_NS::assertEquals( (expected),              \
215                              (actual),                \
216                              CPPUNIT_SOURCELINE(),    \
217                              (message) ) )
218#endif
219
220/*! \brief Macro for primitive double value comparisons.
221 * \ingroup Assertions
222 *
223 * The assertion pass if both expected and actual are finite and
224 * \c fabs( \c expected - \c actual ) <= \c delta.
225 * If either \c expected or actual are infinite (+/- inf), the
226 * assertion pass if \c expected == \c actual.
227 * If either \c expected or \c actual is a NaN (not a number), then
228 * the assertion fails.
229 */
230#define CPPUNIT_ASSERT_DOUBLES_EQUAL(expected,actual,delta)        \
231  ( CPPUNIT_NS::assertDoubleEquals( (expected),            \
232                                    (actual),              \
233                                    (delta),               \
234                                    CPPUNIT_SOURCELINE(),  \
235                                    "" ) )
236
237
238/*! \brief Macro for primitive double value comparisons, setting a
239 * user-supplied message in case of failure.
240 * \ingroup Assertions
241 * \sa CPPUNIT_ASSERT_DOUBLES_EQUAL for detailed semantic of the assertion.
242 */
243#define CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(message,expected,actual,delta)  \
244  ( CPPUNIT_NS::assertDoubleEquals( (expected),            \
245                                    (actual),              \
246                                    (delta),               \
247                                    CPPUNIT_SOURCELINE(),  \
248                                    (message) ) )
249
250
251/** Asserts that the given expression throws an exception of the specified type.
252 * \ingroup Assertions
253 * Example of usage:
254 * \code
255 *   std::vector<int> v;
256 *  CPPUNIT_ASSERT_THROW( v.at( 50 ), std::out_of_range );
257 * \endcode
258 */
259# define CPPUNIT_ASSERT_THROW( expression, ExceptionType )              \
260   CPPUNIT_ASSERT_THROW_MESSAGE( CPPUNIT_NS::AdditionalMessage(),       \
261                                 expression,                            \
262                                 ExceptionType )
263
264
265// implementation detail
266#if CPPUNIT_USE_TYPEINFO_NAME
267#define CPPUNIT_EXTRACT_EXCEPTION_TYPE_( exception, no_rtti_message ) \
268   CPPUNIT_NS::TypeInfoHelper::getClassName( typeid(exception) )
269#else
270#define CPPUNIT_EXTRACT_EXCEPTION_TYPE_( exception, no_rtti_message ) \
271   std::string( no_rtti_message )
272#endif // CPPUNIT_USE_TYPEINFO_NAME
273
274// implementation detail
275#define CPPUNIT_GET_PARAMETER_STRING( parameter ) #parameter
276
277/** Asserts that the given expression throws an exception of the specified type,
278 * setting a user supplied message in case of failure.
279 * \ingroup Assertions
280 * Example of usage:
281 * \code
282 *   std::vector<int> v;
283 *  CPPUNIT_ASSERT_THROW_MESSAGE( "- std::vector<int> v;", v.at( 50 ), std::out_of_range );
284 * \endcode
285 */
286# define CPPUNIT_ASSERT_THROW_MESSAGE( message, expression, ExceptionType )   \
287   do {                                                                       \
288      bool cpputCorrectExceptionThrown_ = false;                              \
289      CPPUNIT_NS::Message cpputMsg_( "expected exception not thrown" );       \
290      cpputMsg_.addDetail( message );                                         \
291      cpputMsg_.addDetail( "Expected: "                                       \
292                           CPPUNIT_GET_PARAMETER_STRING( ExceptionType ) );   \
293                                                                              \
294      try {                                                                   \
295         expression;                                                          \
296      } catch ( const ExceptionType & ) {                                     \
297         cpputCorrectExceptionThrown_ = true;                                 \
298      } catch ( const std::exception &e) {                                    \
299         cpputMsg_.addDetail( "Actual  : " +                                  \
300                              CPPUNIT_EXTRACT_EXCEPTION_TYPE_( e,             \
301                                          "std::exception or derived") );     \
302         cpputMsg_.addDetail( std::string("What()  : ") + e.what() );         \
303      } catch ( ... ) {                                                       \
304         cpputMsg_.addDetail( "Actual  : unknown.");                          \
305      }                                                                       \
306                                                                              \
307      if ( cpputCorrectExceptionThrown_ )                                     \
308         break;                                                               \
309                                                                              \
310      CPPUNIT_NS::Asserter::fail( cpputMsg_,                                  \
311                                  CPPUNIT_SOURCELINE() );                     \
312   } while ( false )
313
314
315/** Asserts that the given expression does not throw any exceptions.
316 * \ingroup Assertions
317 * Example of usage:
318 * \code
319 *   std::vector<int> v;
320 *   v.push_back( 10 );
321 *  CPPUNIT_ASSERT_NO_THROW( v.at( 0 ) );
322 * \endcode
323 */
324# define CPPUNIT_ASSERT_NO_THROW( expression )                             \
325   CPPUNIT_ASSERT_NO_THROW_MESSAGE( CPPUNIT_NS::AdditionalMessage(),       \
326                                    expression )
327
328
329/** Asserts that the given expression does not throw any exceptions,
330 * setting a user supplied message in case of failure.
331 * \ingroup Assertions
332 * Example of usage:
333 * \code
334 *   std::vector<int> v;
335 *   v.push_back( 10 );
336 *  CPPUNIT_ASSERT_NO_THROW( "std::vector<int> v;", v.at( 0 ) );
337 * \endcode
338 */
339# define CPPUNIT_ASSERT_NO_THROW_MESSAGE( message, expression )               \
340   do {                                                                       \
341      CPPUNIT_NS::Message cpputMsg_( "unexpected exception caught" );         \
342      cpputMsg_.addDetail( message );                                         \
343                                                                              \
344      try {                                                                   \
345         expression;                                                          \
346      } catch ( const std::exception &e ) {                                   \
347         cpputMsg_.addDetail( "Caught: " +                                    \
348                              CPPUNIT_EXTRACT_EXCEPTION_TYPE_( e,             \
349                                          "std::exception or derived" ) );    \
350         cpputMsg_.addDetail( std::string("What(): ") + e.what() );           \
351         CPPUNIT_NS::Asserter::fail( cpputMsg_,                               \
352                                     CPPUNIT_SOURCELINE() );                  \
353      } catch ( ... ) {                                                       \
354         cpputMsg_.addDetail( "Caught: unknown." );                           \
355         CPPUNIT_NS::Asserter::fail( cpputMsg_,                               \
356                                     CPPUNIT_SOURCELINE() );                  \
357      }                                                                       \
358   } while ( false )
359
360
361/** Asserts that an assertion fail.
362 * \ingroup Assertions
363 * Use to test assertions.
364 * Example of usage:
365 * \code
366 *   CPPUNIT_ASSERT_ASSERTION_FAIL( CPPUNIT_ASSERT( 1 == 2 ) );
367 * \endcode
368 */
369# define CPPUNIT_ASSERT_ASSERTION_FAIL( assertion )                 \
370   CPPUNIT_ASSERT_THROW( assertion, CPPUNIT_NS::Exception )
371
372
373/** Asserts that an assertion fail, with a user-supplied message in
374 * case of error.
375 * \ingroup Assertions
376 * Use to test assertions.
377 * Example of usage:
378 * \code
379 *   CPPUNIT_ASSERT_ASSERTION_FAIL_MESSAGE( "1 == 2", CPPUNIT_ASSERT( 1 == 2 ) );
380 * \endcode
381 */
382# define CPPUNIT_ASSERT_ASSERTION_FAIL_MESSAGE( message, assertion )    \
383   CPPUNIT_ASSERT_THROW_MESSAGE( message, assertion, CPPUNIT_NS::Exception )
384
385
386/** Asserts that an assertion pass.
387 * \ingroup Assertions
388 * Use to test assertions.
389 * Example of usage:
390 * \code
391 *   CPPUNIT_ASSERT_ASSERTION_PASS( CPPUNIT_ASSERT( 1 == 1 ) );
392 * \endcode
393 */
394# define CPPUNIT_ASSERT_ASSERTION_PASS( assertion )                 \
395   CPPUNIT_ASSERT_NO_THROW( assertion )
396
397
398/** Asserts that an assertion pass, with a user-supplied message in
399 * case of failure.
400 * \ingroup Assertions
401 * Use to test assertions.
402 * Example of usage:
403 * \code
404 *   CPPUNIT_ASSERT_ASSERTION_PASS_MESSAGE( "1 != 1", CPPUNIT_ASSERT( 1 == 1 ) );
405 * \endcode
406 */
407# define CPPUNIT_ASSERT_ASSERTION_PASS_MESSAGE( message, assertion )    \
408   CPPUNIT_ASSERT_NO_THROW_MESSAGE( message, assertion )
409
410
411
412
413// Backwards compatibility
414
415#if CPPUNIT_ENABLE_NAKED_ASSERT
416
417#undef assert
418#define assert(c)                 CPPUNIT_ASSERT(c)
419#define assertEqual(e,a)          CPPUNIT_ASSERT_EQUAL(e,a)
420#define assertDoublesEqual(e,a,d) CPPUNIT_ASSERT_DOUBLES_EQUAL(e,a,d)
421#define assertLongsEqual(e,a)     CPPUNIT_ASSERT_EQUAL(e,a)
422
423#endif
424
425
426CPPUNIT_NS_END
427
428#endif  // CPPUNIT_TESTASSERT_H
Note: See TracBrowser for help on using the repository browser.