CoolProp  4.2.5
An open-source fluid property and humid air property database
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
catch.hpp
Go to the documentation of this file.
1 /*
2  * CATCH v1.0 build 25 (master branch)
3  * Generated: 2014-01-08 17:16:38.496390
4  * ----------------------------------------------------------
5  * This file has been merged from multiple headers. Please don't edit it directly
6  * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
7  *
8  * Distributed under the Boost Software License, Version 1.0. (See accompanying
9  * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10  */
11 #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
12 #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
13 
14 #define TWOBLUECUBES_CATCH_HPP_INCLUDED
15 
16 #ifdef __clang__
17 #pragma clang diagnostic ignored "-Wglobal-constructors"
18 #pragma clang diagnostic ignored "-Wvariadic-macros"
19 #pragma clang diagnostic ignored "-Wc99-extensions"
20 #pragma clang diagnostic push
21 #pragma clang diagnostic ignored "-Wpadded"
22 #endif
23 
24 // #included from: internal/catch_notimplemented_exception.h
25 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
26 
27 // #included from: catch_common.h
28 #define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
29 
30 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
31 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
32 #define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
33 
34 #define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
35 #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
36 
37 #include <sstream>
38 #include <stdexcept>
39 #include <algorithm>
40 
41 // #included from: catch_compiler_capabilities.h
42 #define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
43 
44 // Much of the following code is based on Boost (1.53)
45 
46 #ifdef __clang__
47 
48 #if __has_feature(cxx_nullptr)
49 
50 #define CATCH_CONFIG_CPP11_NULLPTR
51 
52 #endif
53 
54 #endif // __clang__
55 
57 // Borland
58 #ifdef __BORLANDC__
59 
60 #if (__BORLANDC__ > 0x582 )
61 //#define CATCH_CONFIG_SFINAE // Not confirmed
62 #endif
63 
64 #endif // __BORLANDC__
65 
67 // EDG
68 #ifdef __EDG_VERSION__
69 
70 #if (__EDG_VERSION__ > 238 )
71 //#define CATCH_CONFIG_SFINAE // Not confirmed
72 #endif
73 
74 #endif // __EDG_VERSION__
75 
77 // Digital Mars
78 #ifdef __DMC__
79 
80 #if (__DMC__ > 0x840 )
81 //#define CATCH_CONFIG_SFINAE // Not confirmed
82 #endif
83 
84 #endif // __DMC__
85 
87 // GCC
88 #ifdef __GNUC__
89 
90 #if __GNUC__ < 3
91 
92 #if (__GNUC_MINOR__ >= 96 )
93 //#define CATCH_CONFIG_SFINAE
94 #endif
95 
96 #elif __GNUC__ >= 3
97 
98 // #define CATCH_CONFIG_SFINAE // Taking this out completely for now
99 
100 #endif // __GNUC__ < 3
101 
102 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) )
103 
104 #define CATCH_CONFIG_CPP11_NULLPTR
105 #endif
106 
107 #endif // __GNUC__
108 
110 // Visual C++
111 #ifdef _MSC_VER
112 
113 #if (_MSC_VER >= 1310 ) // (VC++ 7.0+)
114 //#define CATCH_CONFIG_SFINAE // Not confirmed
115 #endif
116 
117 #endif // _MSC_VER
118 
119 // Use variadic macros if the compiler supports them
120 #if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
121  ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
122  ( defined __GNUC__ && __GNUC__ >= 3 ) || \
123  ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
124 
125 #ifndef CATCH_CONFIG_NO_VARIADIC_MACROS
126 #define CATCH_CONFIG_VARIADIC_MACROS
127 #endif
128 
129 #endif
130 
131 namespace Catch {
132 
133  class NonCopyable {
134  NonCopyable( NonCopyable const& );
135  void operator = ( NonCopyable const& );
136  protected:
138  virtual ~NonCopyable();
139  };
140 
141  class SafeBool {
142  public:
143  typedef void (SafeBool::*type)() const;
144 
145  static type makeSafe( bool value ) {
146  return value ? &SafeBool::trueValue : 0;
147  }
148  private:
149  void trueValue() const {}
150  };
151 
152  template<typename ContainerT>
153  inline void deleteAll( ContainerT& container ) {
154  typename ContainerT::const_iterator it = container.begin();
155  typename ContainerT::const_iterator itEnd = container.end();
156  for(; it != itEnd; ++it )
157  delete *it;
158  }
159  template<typename AssociativeContainerT>
160  inline void deleteAllValues( AssociativeContainerT& container ) {
161  typename AssociativeContainerT::const_iterator it = container.begin();
162  typename AssociativeContainerT::const_iterator itEnd = container.end();
163  for(; it != itEnd; ++it )
164  delete it->second;
165  }
166 
167  bool startsWith( std::string const& s, std::string const& prefix );
168  bool endsWith( std::string const& s, std::string const& suffix );
169  bool contains( std::string const& s, std::string const& infix );
170  void toLowerInPlace( std::string& s );
171  std::string toLower( std::string const& s );
172  std::string trim( std::string const& str );
173 
174  struct pluralise {
175  pluralise( std::size_t count, std::string const& label );
176 
177  friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
178 
179  std::size_t m_count;
180  std::string m_label;
181  };
182 
183  struct SourceLineInfo {
184 
185  SourceLineInfo();
186  SourceLineInfo( char const* _file, std::size_t _line );
187  SourceLineInfo( SourceLineInfo const& other );
188  bool empty() const;
189  bool operator == ( SourceLineInfo const& other ) const;
190 
191  std::string file;
192  std::size_t line;
193  };
194 
195  std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
196 
197  // This is just here to avoid compiler warnings with macro constants and boolean literals
198  inline bool isTrue( bool value ){ return value; }
199 
200  void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
201 
202  // Use this in variadic streaming macros to allow
203  // >> +StreamEndStop
204  // as well as
205  // >> stuff +StreamEndStop
206  struct StreamEndStop {
207  std::string operator+() {
208  return std::string();
209  }
210  };
211  template<typename T>
212  T const& operator + ( T const& value, StreamEndStop ) {
213  return value;
214  }
215 }
216 
217 #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
218 #define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
219 
220 #include <ostream>
221 
222 namespace Catch {
223 
224  class NotImplementedException : public std::exception
225  {
226  public:
227  NotImplementedException( SourceLineInfo const& lineInfo );
228 
229  virtual ~NotImplementedException() throw() {}
230 
231  virtual const char* what() const throw();
232 
233  private:
234  std::string m_what;
235  SourceLineInfo m_lineInfo;
236  };
237 
238 } // end namespace Catch
239 
241 #define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
242 
243 // #included from: internal/catch_context.h
244 #define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
245 
246 // #included from: catch_interfaces_generators.h
247 #define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
248 
249 #include <string>
250 
251 namespace Catch {
252 
253  struct IGeneratorInfo {
254  virtual ~IGeneratorInfo();
255  virtual bool moveNext() = 0;
256  virtual std::size_t getCurrentIndex() const = 0;
257  };
258 
260  virtual ~IGeneratorsForTest();
261 
262  virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
263  virtual bool moveNext() = 0;
264  };
265 
267 
268 } // end namespace Catch
269 
270 // #included from: catch_ptr.hpp
271 #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
272 
273 #ifdef __clang__
274 #pragma clang diagnostic push
275 #pragma clang diagnostic ignored "-Wpadded"
276 #endif
277 
278 namespace Catch {
279 
280  // An intrusive reference counting smart pointer.
281  // T must implement addRef() and release() methods
282  // typically implementing the IShared interface
283  template<typename T>
284  class Ptr {
285  public:
286  Ptr() : m_p( NULL ){}
287  Ptr( T* p ) : m_p( p ){
288  if( m_p )
289  m_p->addRef();
290  }
291  Ptr( Ptr const& other ) : m_p( other.m_p ){
292  if( m_p )
293  m_p->addRef();
294  }
295  ~Ptr(){
296  if( m_p )
297  m_p->release();
298  }
299  void reset() {
300  if( m_p )
301  m_p->release();
302  m_p = NULL;
303  }
304  Ptr& operator = ( T* p ){
305  Ptr temp( p );
306  swap( temp );
307  return *this;
308  }
309  Ptr& operator = ( Ptr const& other ){
310  Ptr temp( other );
311  swap( temp );
312  return *this;
313  }
314  void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
315  T* get() { return m_p; }
316  const T* get() const{ return m_p; }
317  T& operator*() const { return *m_p; }
318  T* operator->() const { return m_p; }
319  bool operator !() const { return m_p == NULL; }
320  operator SafeBool::type() const { return SafeBool::makeSafe( m_p != NULL ); }
321 
322  private:
323  T* m_p;
324  };
325 
326  struct IShared : NonCopyable {
327  virtual ~IShared();
328  virtual void addRef() const = 0;
329  virtual void release() const = 0;
330  };
331 
332  template<typename T = IShared>
333  struct SharedImpl : T {
334 
335  SharedImpl() : m_rc( 0 ){}
336 
337  virtual void addRef() const {
338  ++m_rc;
339  }
340  virtual void release() const {
341  if( --m_rc == 0 )
342  delete this;
343  }
344 
345  mutable unsigned int m_rc;
346  };
347 
348 } // end namespace Catch
349 
350 #ifdef __clang__
351 #pragma clang diagnostic pop
352 #endif
353 
354 #include <memory>
355 #include <vector>
356 #include <stdlib.h>
357 
358 namespace Catch {
359 
360  class TestCase;
361  class Stream;
362  struct IResultCapture;
363  struct IRunner;
364  struct IGeneratorsForTest;
365  struct IConfig;
366 
367  struct IContext
368  {
369  virtual ~IContext();
370 
371  virtual IResultCapture& getResultCapture() = 0;
372  virtual IRunner& getRunner() = 0;
373  virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
374  virtual bool advanceGeneratorsForCurrentTest() = 0;
375  virtual Ptr<IConfig const> getConfig() const = 0;
376  };
377 
379  {
380  virtual ~IMutableContext();
381  virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
382  virtual void setRunner( IRunner* runner ) = 0;
383  virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
384  };
385 
388  void cleanUpContext();
389  Stream createStream( std::string const& streamName );
390 
391 }
392 
393 // #included from: internal/catch_test_registry.hpp
394 #define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
395 
396 // #included from: catch_interfaces_testcase.h
397 #define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
398 
399 #include <vector>
400 
401 namespace Catch {
402 
403  class TestCaseFilters;
404 
405  struct ITestCase : IShared {
406  virtual void invoke () const = 0;
407  protected:
408  virtual ~ITestCase();
409  };
410 
411  class TestCase;
412 
414  virtual ~ITestCaseRegistry();
415  virtual std::vector<TestCase> const& getAllTests() const = 0;
416  virtual std::vector<TestCase> getMatchingTestCases( std::string const& rawTestSpec ) const = 0;
417  };
418 }
419 
420 namespace Catch {
421 
422 template<typename C>
423 class MethodTestCase : public SharedImpl<ITestCase> {
424 
425 public:
426  MethodTestCase( void (C::*method)() ) : m_method( method ) {}
427 
428  virtual void invoke() const {
429  C obj;
430  (obj.*m_method)();
431  }
432 
433 private:
434  virtual ~MethodTestCase() {}
435 
436  void (C::*m_method)();
437 };
438 
439 typedef void(*TestFunction)();
440 
441 struct NameAndDesc {
442  NameAndDesc( const char* _name = "", const char* _description= "" )
443  : name( _name ), description( _description )
444  {}
445 
446  const char* name;
447  const char* description;
448 };
449 
450 struct AutoReg {
451 
452  AutoReg( TestFunction function,
453  SourceLineInfo const& lineInfo,
454  NameAndDesc const& nameAndDesc );
455 
456  template<typename C>
457  AutoReg( void (C::*method)(),
458  char const* className,
459  NameAndDesc const& nameAndDesc,
460  SourceLineInfo const& lineInfo ) {
461  registerTestCase( new MethodTestCase<C>( method ),
462  className,
463  nameAndDesc,
464  lineInfo );
465  }
466 
467  void registerTestCase( ITestCase* testCase,
468  char const* className,
469  NameAndDesc const& nameAndDesc,
470  SourceLineInfo const& lineInfo );
471 
472  ~AutoReg();
473 
474 private:
475  AutoReg( AutoReg const& );
476  void operator= ( AutoReg const& );
477 };
478 
479 } // end namespace Catch
480 
481 #ifdef CATCH_CONFIG_VARIADIC_MACROS
482  #define INTERNAL_CATCH_TESTCASE( ... ) \
484  static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
485  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
486  static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
487 
489  #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
490  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
491 
493  #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\
494  namespace{ \
495  struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
496  void test(); \
497  }; \
498  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
499  } \
500  void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
501 
502 #else
503  #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
505  static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
506  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
507  static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
508 
510  #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
511  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
512 
514  #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
515  namespace{ \
516  struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
517  void test(); \
518  }; \
519  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
520  } \
521  void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
522 
523 #endif
524 
525 // #included from: internal/catch_capture.hpp
526 #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
527 
528 // #included from: catch_expression_decomposer.hpp
529 #define TWOBLUECUBES_CATCH_EXPRESSION_DECOMPOSER_HPP_INCLUDED
530 
531 // #included from: catch_expression_lhs.hpp
532 #define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
533 
534 // #included from: catch_expressionresult_builder.h
535 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_BUILDER_H_INCLUDED
536 
537 // #included from: catch_tostring.hpp
538 #define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
539 
540 // #included from: catch_sfinae.hpp
541 #define TWOBLUECUBES_CATCH_SFINAE_HPP_INCLUDED
542 
543 // Try to detect if the current compiler supports SFINAE
544 
545 namespace Catch {
546 
547  struct TrueType {
548  static const bool value = true;
549  typedef void Enable;
550  char sizer[1];
551  };
552  struct FalseType {
553  static const bool value = false;
554  typedef void Disable;
555  char sizer[2];
556  };
557 
558 #ifdef CATCH_CONFIG_SFINAE
559 
560  template<bool> struct NotABooleanExpression;
561 
562  template<bool c> struct If : NotABooleanExpression<c> {};
563  template<> struct If<true> : TrueType {};
564  template<> struct If<false> : FalseType {};
565 
566  template<int size> struct SizedIf;
567  template<> struct SizedIf<sizeof(TrueType)> : TrueType {};
568  template<> struct SizedIf<sizeof(FalseType)> : FalseType {};
569 
570 #endif // CATCH_CONFIG_SFINAE
571 
572 } // end namespace Catch
573 
574 #include <sstream>
575 #include <iomanip>
576 #include <limits>
577 #include <vector>
578 
579 #ifdef __OBJC__
580 // #included from: catch_objc_arc.hpp
581 #define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
582 
583 #import <Foundation/Foundation.h>
584 
585 #ifdef __has_feature
586 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
587 #else
588 #define CATCH_ARC_ENABLED 0
589 #endif
590 
591 void arcSafeRelease( NSObject* obj );
592 id performOptionalSelector( id obj, SEL sel );
593 
594 #if !CATCH_ARC_ENABLED
595 inline void arcSafeRelease( NSObject* obj ) {
596  [obj release];
597 }
598 inline id performOptionalSelector( id obj, SEL sel ) {
599  if( [obj respondsToSelector: sel] )
600  return [obj performSelector: sel];
601  return nil;
602 }
603 #define CATCH_UNSAFE_UNRETAINED
604 #define CATCH_ARC_STRONG
605 #else
606 inline void arcSafeRelease( NSObject* ){}
607 inline id performOptionalSelector( id obj, SEL sel ) {
608 #ifdef __clang__
609 #pragma clang diagnostic push
610 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
611 #endif
612  if( [obj respondsToSelector: sel] )
613  return [obj performSelector: sel];
614 #ifdef __clang__
615 #pragma clang diagnostic pop
616 #endif
617  return nil;
618 }
619 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
620 #define CATCH_ARC_STRONG __strong
621 #endif
622 
623 #endif
624 
625 namespace Catch {
626 namespace Detail {
627 
628 // SFINAE is currently disabled by default for all compilers.
629 // If the non SFINAE version of IsStreamInsertable is ambiguous for you
630 // and your compiler supports SFINAE, try #defining CATCH_CONFIG_SFINAE
631 #ifdef CATCH_CONFIG_SFINAE
632 
633  template<typename T>
634  class IsStreamInsertableHelper {
635  template<int N> struct TrueIfSizeable : TrueType {};
636 
637  template<typename T2>
638  static TrueIfSizeable<sizeof((*(std::ostream*)0) << *((T2 const*)0))> dummy(T2*);
639  static FalseType dummy(...);
640 
641  public:
642  typedef SizedIf<sizeof(dummy((T*)0))> type;
643  };
644 
645  template<typename T>
646  struct IsStreamInsertable : IsStreamInsertableHelper<T>::type {};
647 
648 #else
649 
650  struct BorgType {
651  template<typename T> BorgType( T const& );
652  };
653 
654  TrueType& testStreamable( std::ostream& );
656 
657  FalseType operator<<( std::ostream const&, BorgType const& );
658 
659  template<typename T>
661  static std::ostream &s;
662  static T const&t;
663  enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
664  };
665 
666 #endif
667 
668  template<bool C>
670  template<typename T>
671  static std::string convert( T const& ) { return "{?}"; }
672  };
673 
674  template<>
675  struct StringMakerBase<true> {
676  template<typename T>
677  static std::string convert( T const& _value ) {
678  std::ostringstream oss;
679  oss << _value;
680  return oss.str();
681  }
682  };
683 
684  // For display purposes only.
685  // Does not consider endian-ness
686  template<typename T>
687  std::string rawMemoryToString( T value ) {
688  union {
689  T typedValue;
690  unsigned char bytes[sizeof(T)];
691  };
692 
693  typedValue = value;
694 
695  std::ostringstream oss;
696  oss << "0x";
697  for( unsigned char* cp = bytes; cp < bytes+sizeof(T); ++cp )
698  oss << std::hex << std::setw(2) << std::setfill('0') << (unsigned int)*cp;
699  return oss.str();
700  }
701 
702 } // end namespace Detail
703 
704 template<typename T>
705 std::string toString( T const& value );
706 
707 template<typename T>
708 struct StringMaker :
709  Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
710 
711 template<typename T>
712 struct StringMaker<T*> {
713  template<typename U>
714  static std::string convert( U* p ) {
715  if( !p )
716  return INTERNAL_CATCH_STRINGIFY( NULL );
717  else
718  return Detail::rawMemoryToString( p );
719  }
720 };
721 
722 template<typename R, typename C>
723 struct StringMaker<R C::*> {
724  static std::string convert( R C::* p ) {
725  if( !p )
726  return INTERNAL_CATCH_STRINGIFY( NULL );
727  else
728  return Detail::rawMemoryToString( p );
729  }
730 };
731 
732 namespace Detail {
733  template<typename InputIterator>
734  std::string rangeToString( InputIterator first, InputIterator last );
735 }
736 
737 template<typename T, typename Allocator>
738 struct StringMaker<std::vector<T, Allocator> > {
739  static std::string convert( std::vector<T,Allocator> const& v ) {
740  return Detail::rangeToString( v.begin(), v.end() );
741  }
742 };
743 
744 namespace Detail {
745  template<typename T>
746  inline std::string makeString( T const& value ) {
747  return StringMaker<T>::convert( value );
748  }
749 } // end namespace Detail
750 
758 template<typename T>
759 std::string toString( T const& value ) {
760  return StringMaker<T>::convert( value );
761 }
762 
763 // Built in overloads
764 
765 inline std::string toString( std::string const& value ) {
766  return "\"" + value + "\"";
767 }
768 
769 inline std::string toString( std::wstring const& value ) {
770  std::ostringstream oss;
771  oss << "\"";
772  for(size_t i = 0; i < value.size(); ++i )
773  oss << static_cast<char>( value[i] <= 0xff ? value[i] : '?');
774  oss << "\"";
775  return oss.str();
776 }
777 
778 inline std::string toString( const char* const value ) {
779  return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
780 }
781 
782 inline std::string toString( char* const value ) {
783  return Catch::toString( static_cast<const char*>( value ) );
784 }
785 
786 inline std::string toString( int value ) {
787  std::ostringstream oss;
788  oss << value;
789  return oss.str();
790 }
791 
792 inline std::string toString( unsigned long value ) {
793  std::ostringstream oss;
794  if( value > 8192 )
795  oss << "0x" << std::hex << value;
796  else
797  oss << value;
798  return oss.str();
799 }
800 
801 inline std::string toString( unsigned int value ) {
802  return toString( static_cast<unsigned long>( value ) );
803 }
804 
805 inline std::string toString( const double value ) {
806  std::ostringstream oss;
807  oss << std::setprecision( 10 )
808  << std::fixed
809  << value;
810  std::string d = oss.str();
811  std::size_t i = d.find_last_not_of( '0' );
812  if( i != std::string::npos && i != d.size()-1 ) {
813  if( d[i] == '.' )
814  i++;
815  d = d.substr( 0, i+1 );
816  }
817  return d;
818 }
819 
820 inline std::string toString( bool value ) {
821  return value ? "true" : "false";
822 }
823 
824 inline std::string toString( char value ) {
825  return value < ' '
826  ? toString( static_cast<unsigned int>( value ) )
827  : Detail::makeString( value );
828 }
829 
830 inline std::string toString( signed char value ) {
831  return toString( static_cast<char>( value ) );
832 }
833 
834 inline std::string toString( unsigned char value ) {
835  return toString( static_cast<char>( value ) );
836 }
837 
838 #ifdef CATCH_CONFIG_CPP11_NULLPTR
839 inline std::string toString( std::nullptr_t ) {
840  return "nullptr";
841 }
842 #endif
843 
844 #ifdef __OBJC__
845  inline std::string toString( NSString const * const& nsstring ) {
846  if( !nsstring )
847  return "nil";
848  return std::string( "@\"" ) + [nsstring UTF8String] + "\"";
849  }
850  inline std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
851  if( !nsstring )
852  return "nil";
853  return std::string( "@\"" ) + [nsstring UTF8String] + "\"";
854  }
855  inline std::string toString( NSObject* const& nsObject ) {
856  return toString( [nsObject description] );
857  }
858 #endif
859 
860  namespace Detail {
861  template<typename InputIterator>
862  std::string rangeToString( InputIterator first, InputIterator last ) {
863  std::ostringstream oss;
864  oss << "{ ";
865  if( first != last ) {
866  oss << toString( *first );
867  for( ++first ; first != last ; ++first ) {
868  oss << ", " << toString( *first );
869  }
870  }
871  oss << " }";
872  return oss.str();
873  }
874 }
875 
876 } // end namespace Catch
877 
878 // #included from: catch_assertionresult.h
879 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
880 
881 #include <string>
882 // #included from: catch_result_type.h
883 #define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
884 
885 namespace Catch {
886 
887  // ResultWas::OfType enum
888  struct ResultWas { enum OfType {
889  Unknown = -1,
890  Ok = 0,
891  Info = 1,
892  Warning = 2,
893 
894  FailureBit = 0x10,
895 
896  ExpressionFailed = FailureBit | 1,
897  ExplicitFailure = FailureBit | 2,
898 
899  Exception = 0x100 | FailureBit,
900 
901  ThrewException = Exception | 1,
902  DidntThrowException = Exception | 2
903 
904  }; };
905 
906  inline bool isOk( ResultWas::OfType resultType ) {
907  return ( resultType & ResultWas::FailureBit ) == 0;
908  }
909  inline bool isJustInfo( int flags ) {
910  return flags == ResultWas::Info;
911  }
912 
913  // ResultAction::Value enum
914  struct ResultAction { enum Value {
916  Failed = 1, // Failure - but no debug break if Debug bit not set
917  Debug = 2, // If this bit is set, invoke the debugger
918  Abort = 4 // Test run should abort
919  }; };
920 
921  // ResultDisposition::Flags enum
922  struct ResultDisposition { enum Flags {
923  Normal = 0x00,
924 
925  ContinueOnFailure = 0x01, // Failures fail test, but execution continues
926  NegateResult = 0x02, // Prefix expressiom with !
927  SuppressFail = 0x04 // Failures are reported but do not fail the test
928  }; };
929 
931  return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
932  }
933 
934  inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
935  inline bool shouldNegate( int flags ) { return ( flags & ResultDisposition::NegateResult ) != 0; }
936  inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
937 
938 } // end namespace Catch
939 
940 
941 namespace Catch {
942 
944  {
946  AssertionInfo( std::string const& _macroName,
947  SourceLineInfo const& _lineInfo,
948  std::string const& _capturedExpression,
949  ResultDisposition::Flags _resultDisposition );
950 
951  std::string macroName;
953  std::string capturedExpression;
955  };
956 
958  {
959  AssertionResultData() : resultType( ResultWas::Unknown ) {}
960 
962  std::string message;
964  };
965 
967  public:
968  AssertionResult();
969  AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
970  ~AssertionResult();
971 
972  bool isOk() const;
973  bool succeeded() const;
974  ResultWas::OfType getResultType() const;
975  bool hasExpression() const;
976  bool hasMessage() const;
977  std::string getExpression() const;
978  std::string getExpressionInMacro() const;
979  bool hasExpandedExpression() const;
980  std::string getExpandedExpression() const;
981  std::string getMessage() const;
982  SourceLineInfo getSourceInfo() const;
983  std::string getTestMacroName() const;
984 
985  protected:
988  };
989 
990 } // end namespace Catch
991 
992 // #included from: catch_evaluate.hpp
993 #define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
994 
995 #ifdef _MSC_VER
996 #pragma warning(push)
997 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
998 #endif
999 
1000 namespace Catch {
1001 namespace Internal {
1002 
1003  enum Operator {
1010  };
1011 
1012  template<Operator Op> struct OperatorTraits { static const char* getName(){ return "*error*"; } };
1013  template<> struct OperatorTraits<IsEqualTo> { static const char* getName(){ return "=="; } };
1014  template<> struct OperatorTraits<IsNotEqualTo> { static const char* getName(){ return "!="; } };
1015  template<> struct OperatorTraits<IsLessThan> { static const char* getName(){ return "<"; } };
1016  template<> struct OperatorTraits<IsGreaterThan> { static const char* getName(){ return ">"; } };
1017  template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } };
1018  template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
1019 
1020  template<typename T>
1021  inline T& opCast(T const& t) { return const_cast<T&>(t); }
1022 
1023 // nullptr_t support based on pull request #154 from Konstantin Baumann
1024 #ifdef CATCH_CONFIG_CPP11_NULLPTR
1025  inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
1026 #endif // CATCH_CONFIG_CPP11_NULLPTR
1027 
1028  // So the compare overloads can be operator agnostic we convey the operator as a template
1029  // enum, which is used to specialise an Evaluator for doing the comparison.
1030  template<typename T1, typename T2, Operator Op>
1031  class Evaluator{};
1032 
1033  template<typename T1, typename T2>
1034  struct Evaluator<T1, T2, IsEqualTo> {
1035  static bool evaluate( T1 const& lhs, T2 const& rhs) {
1036  return opCast( lhs ) == opCast( rhs );
1037  }
1038  };
1039  template<typename T1, typename T2>
1040  struct Evaluator<T1, T2, IsNotEqualTo> {
1041  static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1042  return opCast( lhs ) != opCast( rhs );
1043  }
1044  };
1045  template<typename T1, typename T2>
1046  struct Evaluator<T1, T2, IsLessThan> {
1047  static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1048  return opCast( lhs ) < opCast( rhs );
1049  }
1050  };
1051  template<typename T1, typename T2>
1052  struct Evaluator<T1, T2, IsGreaterThan> {
1053  static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1054  return opCast( lhs ) > opCast( rhs );
1055  }
1056  };
1057  template<typename T1, typename T2>
1059  static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1060  return opCast( lhs ) >= opCast( rhs );
1061  }
1062  };
1063  template<typename T1, typename T2>
1064  struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
1065  static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1066  return opCast( lhs ) <= opCast( rhs );
1067  }
1068  };
1069 
1070  template<Operator Op, typename T1, typename T2>
1071  bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
1072  return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
1073  }
1074 
1075  // This level of indirection allows us to specialise for integer types
1076  // to avoid signed/ unsigned warnings
1077 
1078  // "base" overload
1079  template<Operator Op, typename T1, typename T2>
1080  bool compare( T1 const& lhs, T2 const& rhs ) {
1081  return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
1082  }
1083 
1084  // unsigned X to int
1085  template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
1086  return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1087  }
1088  template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
1089  return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1090  }
1091  template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
1092  return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1093  }
1094 
1095  // unsigned X to long
1096  template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
1097  return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1098  }
1099  template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
1100  return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1101  }
1102  template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
1103  return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1104  }
1105 
1106  // int to unsigned X
1107  template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
1108  return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1109  }
1110  template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
1111  return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1112  }
1113  template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
1114  return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1115  }
1116 
1117  // long to unsigned X
1118  template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
1119  return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1120  }
1121  template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
1122  return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1123  }
1124  template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
1125  return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1126  }
1127 
1128  // pointer to long (when comparing against NULL)
1129  template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
1130  return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
1131  }
1132  template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
1133  return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
1134  }
1135 
1136  // pointer to int (when comparing against NULL)
1137  template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
1138  return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
1139  }
1140  template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
1141  return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
1142  }
1143 
1144 #ifdef CATCH_CONFIG_CPP11_NULLPTR
1145  // pointer to nullptr_t (when comparing against nullptr)
1146  template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
1147  return Evaluator<T*, T*, Op>::evaluate( NULL, rhs );
1148  }
1149  template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
1150  return Evaluator<T*, T*, Op>::evaluate( lhs, NULL );
1151  }
1152 #endif // CATCH_CONFIG_CPP11_NULLPTR
1153 
1154 } // end of namespace Internal
1155 } // end of namespace Catch
1156 
1157 #ifdef _MSC_VER
1158 #pragma warning(pop)
1159 #endif
1160 
1161 namespace Catch {
1162 
1163 struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
1164 
1165 // Wraps the (stringised versions of) the lhs, operator and rhs of an expression - as well as
1166 // the result of evaluating it. This is used to build an AssertionResult object
1168 public:
1169 
1172  ExpressionResultBuilder& operator=(ExpressionResultBuilder const& other );
1173 
1174  ExpressionResultBuilder& setResultType( ResultWas::OfType result );
1175  ExpressionResultBuilder& setResultType( bool result );
1176  ExpressionResultBuilder& setLhs( std::string const& lhs );
1177  ExpressionResultBuilder& setRhs( std::string const& rhs );
1178  ExpressionResultBuilder& setOp( std::string const& op );
1179 
1180  ExpressionResultBuilder& endExpression( ResultDisposition::Flags resultDisposition );
1181 
1182  template<typename T>
1184  m_stream << value;
1185  return *this;
1186  }
1187 
1188  std::string reconstructExpression( AssertionInfo const& info ) const;
1189 
1190  AssertionResult buildResult( AssertionInfo const& info ) const;
1191 
1192  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
1193  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
1194 
1195 private:
1196  AssertionResultData m_data;
1197  struct ExprComponents {
1198  ExprComponents() : shouldNegate( false ) {}
1199  bool shouldNegate;
1200  std::string lhs, rhs, op;
1201  } m_exprComponents;
1202  std::ostringstream m_stream;
1203 };
1204 
1205 } // end namespace Catch
1206 
1207 namespace Catch {
1208 
1209 // Wraps the LHS of an expression and captures the operator and RHS (if any) - wrapping them all
1210 // in an ExpressionResultBuilder object
1211 template<typename T>
1213  void operator = ( ExpressionLhs const& );
1214 
1215 public:
1216  ExpressionLhs( T lhs ) : m_lhs( lhs ) {}
1217 
1218  template<typename RhsT>
1219  ExpressionResultBuilder& operator == ( RhsT const& rhs ) {
1220  return captureExpression<Internal::IsEqualTo>( rhs );
1221  }
1222 
1223  template<typename RhsT>
1224  ExpressionResultBuilder& operator != ( RhsT const& rhs ) {
1225  return captureExpression<Internal::IsNotEqualTo>( rhs );
1226  }
1227 
1228  template<typename RhsT>
1229  ExpressionResultBuilder& operator < ( RhsT const& rhs ) {
1230  return captureExpression<Internal::IsLessThan>( rhs );
1231  }
1232 
1233  template<typename RhsT>
1234  ExpressionResultBuilder& operator > ( RhsT const& rhs ) {
1235  return captureExpression<Internal::IsGreaterThan>( rhs );
1236  }
1237 
1238  template<typename RhsT>
1239  ExpressionResultBuilder& operator <= ( RhsT const& rhs ) {
1240  return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
1241  }
1242 
1243  template<typename RhsT>
1244  ExpressionResultBuilder& operator >= ( RhsT const& rhs ) {
1245  return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
1246  }
1247 
1248  ExpressionResultBuilder& operator == ( bool rhs ) {
1249  return captureExpression<Internal::IsEqualTo>( rhs );
1250  }
1251 
1252  ExpressionResultBuilder& operator != ( bool rhs ) {
1253  return captureExpression<Internal::IsNotEqualTo>( rhs );
1254  }
1255 
1257  bool value = m_lhs ? true : false;
1258  return m_result
1259  .setLhs( Catch::toString( value ) )
1260  .setResultType( value )
1261  .endExpression( resultDisposition );
1262  }
1263 
1264  // Only simple binary expressions are allowed on the LHS.
1265  // If more complex compositions are required then place the sub expression in parentheses
1266  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
1267  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
1268  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
1269  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
1270  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
1271  template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
1272 
1273 private:
1274  template<Internal::Operator Op, typename RhsT>
1275  ExpressionResultBuilder& captureExpression( RhsT const& rhs ) {
1276  return m_result
1277  .setResultType( Internal::compare<Op>( m_lhs, rhs ) )
1278  .setLhs( Catch::toString( m_lhs ) )
1279  .setRhs( Catch::toString( rhs ) )
1281  }
1282 
1283 private:
1284  ExpressionResultBuilder m_result;
1285  T m_lhs;
1286 };
1287 
1288 } // end namespace Catch
1289 
1290 namespace Catch {
1291 
1292 // Captures the LHS of the expression and wraps it in an Expression Lhs object
1294 public:
1295 
1296  template<typename T>
1297  ExpressionLhs<T const&> operator->* ( T const& operand ) {
1298  return ExpressionLhs<T const&>( operand );
1299  }
1300 
1301  ExpressionLhs<bool> operator->* ( bool value ) {
1302  return ExpressionLhs<bool>( value );
1303  }
1304 };
1305 
1306 } // end namespace Catch
1307 
1308 // #included from: catch_message.h
1309 #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
1310 
1311 #include <string>
1312 
1313 namespace Catch {
1314 
1315  struct MessageInfo {
1316  MessageInfo( std::string const& _macroName,
1317  SourceLineInfo const& _lineInfo,
1318  ResultWas::OfType _type );
1319 
1320  std::string macroName;
1323  std::string message;
1324  unsigned int sequence;
1325 
1326  bool operator == ( MessageInfo const& other ) const {
1327  return sequence == other.sequence;
1328  }
1329  bool operator < ( MessageInfo const& other ) const {
1330  return sequence < other.sequence;
1331  }
1332  private:
1333  static unsigned int globalCount;
1334  };
1335 
1337  MessageBuilder( std::string const& macroName,
1338  SourceLineInfo const& lineInfo,
1339  ResultWas::OfType type )
1340  : m_info( macroName, lineInfo, type )
1341  {}
1342 
1343  template<typename T>
1344  MessageBuilder& operator << ( T const& value ) {
1345  m_stream << value;
1346  return *this;
1347  }
1348 
1350  std::ostringstream m_stream;
1351  };
1352 
1354  public:
1355  ScopedMessage( MessageBuilder const& builder );
1356  ~ScopedMessage();
1357 
1359  };
1360 
1361 } // end namespace Catch
1362 
1363 // #included from: catch_interfaces_capture.h
1364 #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
1365 
1366 #include <string>
1367 
1368 namespace Catch {
1369 
1370  class TestCase;
1371  class ExpressionResultBuilder;
1372  class AssertionResult;
1373  struct AssertionInfo;
1374  struct SectionInfo;
1375  struct MessageInfo;
1376  class ScopedMessageBuilder;
1377  struct Counts;
1378 
1380 
1381  virtual ~IResultCapture();
1382 
1383  virtual void assertionEnded( AssertionResult const& result ) = 0;
1384  virtual bool sectionStarted( SectionInfo const& sectionInfo,
1385  Counts& assertions ) = 0;
1386  virtual void sectionEnded( SectionInfo const& name, Counts const& assertions, double _durationInSeconds ) = 0;
1387  virtual void pushScopedMessage( MessageInfo const& message ) = 0;
1388  virtual void popScopedMessage( MessageInfo const& message ) = 0;
1389 
1390  virtual bool shouldDebugBreak() const = 0;
1391 
1392  virtual ResultAction::Value acceptExpression( ExpressionResultBuilder const& assertionResult, AssertionInfo const& assertionInfo ) = 0;
1393 
1394  virtual std::string getCurrentTestName() const = 0;
1395  virtual const AssertionResult* getLastResult() const = 0;
1396  };
1397 }
1398 
1399 // #included from: catch_debugger.h
1400 #define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
1401 
1402 // #included from: catch_platform.h
1403 #define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
1404 
1405 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
1406 #define CATCH_PLATFORM_MAC
1407 #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
1408 #define CATCH_PLATFORM_IPHONE
1409 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
1410 #define CATCH_PLATFORM_WINDOWS
1411 #endif
1412 
1413 #include <string>
1414 
1415 namespace Catch{
1416 
1417  bool isDebuggerActive();
1418  void writeToDebugConsole( std::string const& text );
1419 }
1420 
1421 #ifdef CATCH_PLATFORM_MAC
1422 
1423  // The following code snippet based on:
1424  // http://cocoawithlove.com/2008/03/break-into-debugger.html
1425  #ifdef DEBUG
1426  #if defined(__ppc64__) || defined(__ppc__)
1427  #define CATCH_BREAK_INTO_DEBUGGER() \
1428  if( Catch::isDebuggerActive() ) { \
1429  __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
1430  : : : "memory","r0","r3","r4" ); \
1431  }
1432  #else
1433  #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
1434  #endif
1435  #endif
1436 
1437 #elif defined(_MSC_VER)
1438  #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
1439 #elif defined(__MINGW32__)
1440  extern "C" __declspec(dllimport) void __stdcall DebugBreak();
1441  #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
1442 #endif
1443 
1444 #ifndef CATCH_BREAK_INTO_DEBUGGER
1445 #define CATCH_BREAK_INTO_DEBUGGER() Catch::isTrue( true );
1446 #endif
1447 
1448 // #included from: catch_interfaces_registry_hub.h
1449 #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
1450 
1451 #include <string>
1452 
1453 namespace Catch {
1454 
1455  class TestCase;
1456  struct ITestCaseRegistry;
1457  struct IExceptionTranslatorRegistry;
1458  struct IExceptionTranslator;
1459  struct IReporterRegistry;
1460  struct IReporterFactory;
1461 
1462  struct IRegistryHub {
1463  virtual ~IRegistryHub();
1464 
1465  virtual IReporterRegistry const& getReporterRegistry() const = 0;
1466  virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
1467  virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
1468  };
1469 
1471  virtual ~IMutableRegistryHub();
1472  virtual void registerReporter( std::string const& name, IReporterFactory* factory ) = 0;
1473  virtual void registerTest( TestCase const& testInfo ) = 0;
1474  virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
1475  };
1476 
1479  void cleanUp();
1480  std::string translateActiveException();
1481 
1482 }
1483 
1484 // #included from: catch_interfaces_config.h
1485 #define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
1486 
1487 #include <iostream>
1488 #include <string>
1489 
1490 namespace Catch {
1491 
1492  struct Verbosity { enum Level {
1493  NoOutput = 0,
1495  Normal
1496  }; };
1497 
1498  struct WarnAbout { enum What {
1499  Nothing = 0x00,
1500  NoAssertions = 0x01
1501  }; };
1502 
1503  struct ShowDurations { enum OrNot {
1506  Never
1507  }; };
1508 
1509  struct IConfig : IShared {
1510 
1511  virtual ~IConfig();
1512 
1513  virtual bool allowThrows() const = 0;
1514  virtual std::ostream& stream() const = 0;
1515  virtual std::string name() const = 0;
1516  virtual bool includeSuccessfulResults() const = 0;
1517  virtual bool shouldDebugBreak() const = 0;
1518  virtual bool warnAboutMissingAssertions() const = 0;
1519  virtual int abortAfter() const = 0;
1520  virtual ShowDurations::OrNot showDurations() const = 0;
1521  };
1522 }
1523 
1524 #include <ostream>
1525 
1526 namespace Catch {
1527 
1530  }
1531 
1532  template<typename MatcherT>
1534  std::string const& matcherCallAsString ) {
1535  std::string matcherAsString = matcher.toString();
1536  if( matcherAsString == "{?}" )
1537  matcherAsString = matcherCallAsString;
1538  return ExpressionResultBuilder()
1539  .setRhs( matcherAsString )
1540  .setOp( "matches" );
1541  }
1542 
1543  template<typename MatcherT, typename ArgT>
1545  ArgT const& arg,
1546  std::string const& matcherCallAsString ) {
1547  return expressionResultBuilderFromMatcher( matcher, matcherCallAsString )
1548  .setLhs( Catch::toString( arg ) )
1549  .setResultType( matcher.match( arg ) );
1550  }
1551 
1552  template<typename MatcherT, typename ArgT>
1554  ArgT* arg,
1555  std::string const& matcherCallAsString ) {
1556  return expressionResultBuilderFromMatcher( matcher, matcherCallAsString )
1557  .setLhs( Catch::toString( arg ) )
1558  .setResultType( matcher.match( arg ) );
1559  }
1560 
1562 
1563 } // end namespace Catch
1564 
1566 #define INTERNAL_CATCH_ASSERTIONINFO_NAME INTERNAL_CATCH_UNIQUE_NAME( __assertionInfo )
1567 
1569 #define INTERNAL_CATCH_ACCEPT_EXPR( evaluatedExpr, resultDisposition, originalExpr ) \
1570  if( Catch::ResultAction::Value internal_catch_action = Catch::getResultCapture().acceptExpression( evaluatedExpr, INTERNAL_CATCH_ASSERTIONINFO_NAME ) ) { \
1571  if( internal_catch_action & Catch::ResultAction::Debug ) CATCH_BREAK_INTO_DEBUGGER(); \
1572  if( internal_catch_action & Catch::ResultAction::Abort ) throw Catch::TestFailureException(); \
1573  if( !Catch::shouldContinueOnFailure( resultDisposition ) ) throw Catch::TestFailureException(); \
1574  Catch::isTrue( false && originalExpr ); \
1575  }
1576 
1578 #define INTERNAL_CATCH_ACCEPT_INFO( expr, macroName, resultDisposition ) \
1579  Catch::AssertionInfo INTERNAL_CATCH_ASSERTIONINFO_NAME( macroName, CATCH_INTERNAL_LINEINFO, expr, resultDisposition );
1580 
1582 #define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
1583  do { \
1584  INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, resultDisposition ); \
1585  try { \
1586  INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionDecomposer()->*expr ).endExpression( resultDisposition ), resultDisposition, expr ); \
1587  } catch( Catch::TestFailureException& ) { \
1588  throw; \
1589  } catch( ... ) { \
1590  INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException(), \
1591  resultDisposition | Catch::ResultDisposition::ContinueOnFailure, expr ); \
1592  } \
1593  } while( Catch::isTrue( false ) )
1594 
1596 #define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
1597  INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
1598  if( Catch::getResultCapture().getLastResult()->succeeded() )
1599 
1601 #define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
1602  INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
1603  if( !Catch::getResultCapture().getLastResult()->succeeded() )
1604 
1606 #define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
1607  do { \
1608  INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, resultDisposition ); \
1609  try { \
1610  expr; \
1611  INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::Ok ), resultDisposition, false ); \
1612  } \
1613  catch( ... ) { \
1614  INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException(), resultDisposition, false ); \
1615  } \
1616 } while( Catch::isTrue( false ) )
1617 
1619 #define INTERNAL_CATCH_THROWS_IMPL( expr, exceptionType, resultDisposition ) \
1620  try { \
1621  if( Catch::getCurrentContext().getConfig()->allowThrows() ) { \
1622  expr; \
1623  INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::DidntThrowException ), resultDisposition, false ); \
1624  } \
1625  } \
1626  catch( Catch::TestFailureException& ) { \
1627  throw; \
1628  } \
1629  catch( exceptionType ) { \
1630  INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::Ok ), resultDisposition, false ); \
1631  }
1632 
1634 #define INTERNAL_CATCH_THROWS( expr, exceptionType, resultDisposition, macroName ) \
1635  do { \
1636  INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, resultDisposition ); \
1637  INTERNAL_CATCH_THROWS_IMPL( expr, exceptionType, resultDisposition ) \
1638  } while( Catch::isTrue( false ) )
1639 
1641 #define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
1642  do { \
1643  INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, resultDisposition ); \
1644  INTERNAL_CATCH_THROWS_IMPL( expr, exceptionType, resultDisposition ) \
1645  catch( ... ) { \
1646  INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException() ), \
1647  resultDisposition | Catch::ResultDisposition::ContinueOnFailure, false ); \
1648  } \
1649  } while( Catch::isTrue( false ) )
1650 
1652 #ifdef CATCH_CONFIG_VARIADIC_MACROS
1653  #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
1654  do { \
1655  INTERNAL_CATCH_ACCEPT_INFO( "", macroName, resultDisposition ); \
1656  INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( messageType ) << __VA_ARGS__ +::Catch::StreamEndStop(), resultDisposition, true ) \
1657  } while( Catch::isTrue( false ) )
1658 #else
1659  #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
1660  do { \
1661  INTERNAL_CATCH_ACCEPT_INFO( "", macroName, resultDisposition ); \
1662  INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( messageType ) << log, resultDisposition, true ) \
1663  } while( Catch::isTrue( false ) )
1664 #endif
1665 
1667 #define INTERNAL_CATCH_INFO( log, macroName ) \
1668  Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
1669 
1671 #define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
1672  do { \
1673  INTERNAL_CATCH_ACCEPT_INFO( #arg " " #matcher, macroName, resultDisposition ); \
1674  try { \
1675  INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::expressionResultBuilderFromMatcher( ::Catch::Matchers::matcher, arg, #matcher ) ), resultDisposition, false ); \
1676  } catch( Catch::TestFailureException& ) { \
1677  throw; \
1678  } catch( ... ) { \
1679  INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException() ), \
1680  resultDisposition | Catch::ResultDisposition::ContinueOnFailure, false ); \
1681  } \
1682  } while( Catch::isTrue( false ) )
1683 
1684 // #included from: internal/catch_section.h
1685 #define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
1686 
1687 // #included from: catch_section_info.h
1688 #define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
1689 
1690 namespace Catch {
1691 
1692  struct SectionInfo {
1693  SectionInfo( std::string const& _name,
1694  std::string const& _description,
1695  SourceLineInfo const& _lineInfo )
1696  : name( _name ),
1697  description( _description ),
1698  lineInfo( _lineInfo )
1699  {}
1700 
1701  std::string name;
1702  std::string description;
1704  };
1705 
1706 } // end namespace Catch
1707 
1708 // #included from: catch_totals.hpp
1709 #define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
1710 
1711 #include <cstddef>
1712 
1713 namespace Catch {
1714 
1715  struct Counts {
1716  Counts() : passed( 0 ), failed( 0 ) {}
1717 
1718  Counts operator - ( Counts const& other ) const {
1719  Counts diff;
1720  diff.passed = passed - other.passed;
1721  diff.failed = failed - other.failed;
1722  return diff;
1723  }
1724  Counts& operator += ( Counts const& other ) {
1725  passed += other.passed;
1726  failed += other.failed;
1727  return *this;
1728  }
1729 
1730  std::size_t total() const {
1731  return passed + failed;
1732  }
1733 
1734  std::size_t passed;
1735  std::size_t failed;
1736  };
1737 
1738  struct Totals {
1739 
1740  Totals operator - ( Totals const& other ) const {
1741  Totals diff;
1742  diff.assertions = assertions - other.assertions;
1743  diff.testCases = testCases - other.testCases;
1744  return diff;
1745  }
1746 
1747  Totals delta( Totals const& prevTotals ) const {
1748  Totals diff = *this - prevTotals;
1749  if( diff.assertions.failed > 0 )
1750  ++diff.testCases.failed;
1751  else
1752  ++diff.testCases.passed;
1753  return diff;
1754  }
1755 
1756  Totals& operator += ( Totals const& other ) {
1757  assertions += other.assertions;
1758  testCases += other.testCases;
1759  return *this;
1760  }
1761 
1764  };
1765 }
1766 
1767 // #included from: catch_timer.h
1768 #define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
1769 
1770 #ifdef CATCH_PLATFORM_WINDOWS
1771 typedef unsigned long long uint64_t;
1772 #else
1773 #include <stdint.h>
1774 #endif
1775 
1776 namespace Catch {
1777 
1778  class Timer {
1779  public:
1780  Timer() : m_ticks( 0 ) {}
1781  void start();
1782  unsigned int getElapsedNanoseconds() const;
1783  unsigned int getElapsedMilliseconds() const;
1784  double getElapsedSeconds() const;
1785 
1786  private:
1787  uint64_t m_ticks;
1788  };
1789 
1790 } // namespace Catch
1791 
1792 #include <string>
1793 
1794 namespace Catch {
1795 
1796  class Section {
1797  public:
1798  Section( SourceLineInfo const& lineInfo,
1799  std::string const& name,
1800  std::string const& description = "" );
1801  ~Section();
1802 
1803  // This indicates whether the section should be executed or not
1804  operator bool();
1805 
1806  private:
1807 
1808  SectionInfo m_info;
1809 
1810  std::string m_name;
1811  Counts m_assertions;
1812  bool m_sectionIncluded;
1813  Timer m_timer;
1814  };
1815 
1816 } // end namespace Catch
1817 
1818 #ifdef CATCH_CONFIG_VARIADIC_MACROS
1819  #define INTERNAL_CATCH_SECTION( ... ) \
1820  if( Catch::Section INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::Section( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
1821 #else
1822  #define INTERNAL_CATCH_SECTION( name, desc ) \
1823  if( Catch::Section INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::Section( CATCH_INTERNAL_LINEINFO, name, desc ) )
1824 #endif
1825 
1826 // #included from: internal/catch_generators.hpp
1827 #define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
1828 
1829 #include <iterator>
1830 #include <vector>
1831 #include <string>
1832 #include <stdlib.h>
1833 
1834 namespace Catch {
1835 
1836 template<typename T>
1837 struct IGenerator {
1838  virtual ~IGenerator() {}
1839  virtual T getValue( std::size_t index ) const = 0;
1840  virtual std::size_t size () const = 0;
1841 };
1842 
1843 template<typename T>
1844 class BetweenGenerator : public IGenerator<T> {
1845 public:
1846  BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
1847 
1848  virtual T getValue( std::size_t index ) const {
1849  return m_from+static_cast<int>( index );
1850  }
1851 
1852  virtual std::size_t size() const {
1853  return static_cast<std::size_t>( 1+m_to-m_from );
1854  }
1855 
1856 private:
1857 
1858  T m_from;
1859  T m_to;
1860 };
1861 
1862 template<typename T>
1863 class ValuesGenerator : public IGenerator<T> {
1864 public:
1866 
1867  void add( T value ) {
1868  m_values.push_back( value );
1869  }
1870 
1871  virtual T getValue( std::size_t index ) const {
1872  return m_values[index];
1873  }
1874 
1875  virtual std::size_t size() const {
1876  return m_values.size();
1877  }
1878 
1879 private:
1880  std::vector<T> m_values;
1881 };
1882 
1883 template<typename T>
1885 public:
1886  CompositeGenerator() : m_totalSize( 0 ) {}
1887 
1888  // *** Move semantics, similar to auto_ptr ***
1890  : m_fileInfo( other.m_fileInfo ),
1891  m_totalSize( 0 )
1892  {
1893  move( other );
1894  }
1895 
1896  CompositeGenerator& setFileInfo( const char* fileInfo ) {
1897  m_fileInfo = fileInfo;
1898  return *this;
1899  }
1900 
1902  deleteAll( m_composed );
1903  }
1904 
1905  operator T () const {
1906  size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
1907 
1908  typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
1909  typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
1910  for( size_t index = 0; it != itEnd; ++it )
1911  {
1912  const IGenerator<T>* generator = *it;
1913  if( overallIndex >= index && overallIndex < index + generator->size() )
1914  {
1915  return generator->getValue( overallIndex-index );
1916  }
1917  index += generator->size();
1918  }
1919  CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
1920  return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so
1921  }
1922 
1923  void add( const IGenerator<T>* generator ) {
1924  m_totalSize += generator->size();
1925  m_composed.push_back( generator );
1926  }
1927 
1929  move( other );
1930  return *this;
1931  }
1932 
1933  CompositeGenerator& then( T value ) {
1934  ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
1935  valuesGen->add( value );
1936  add( valuesGen );
1937  return *this;
1938  }
1939 
1940 private:
1941 
1942  void move( CompositeGenerator& other ) {
1943  std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
1944  m_totalSize += other.m_totalSize;
1945  other.m_composed.clear();
1946  }
1947 
1948  std::vector<const IGenerator<T>*> m_composed;
1949  std::string m_fileInfo;
1950  size_t m_totalSize;
1951 };
1952 
1953 namespace Generators
1954 {
1955  template<typename T>
1956  CompositeGenerator<T> between( T from, T to ) {
1957  CompositeGenerator<T> generators;
1958  generators.add( new BetweenGenerator<T>( from, to ) );
1959  return generators;
1960  }
1961 
1962  template<typename T>
1963  CompositeGenerator<T> values( T val1, T val2 ) {
1964  CompositeGenerator<T> generators;
1965  ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
1966  valuesGen->add( val1 );
1967  valuesGen->add( val2 );
1968  generators.add( valuesGen );
1969  return generators;
1970  }
1971 
1972  template<typename T>
1973  CompositeGenerator<T> values( T val1, T val2, T val3 ){
1974  CompositeGenerator<T> generators;
1975  ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
1976  valuesGen->add( val1 );
1977  valuesGen->add( val2 );
1978  valuesGen->add( val3 );
1979  generators.add( valuesGen );
1980  return generators;
1981  }
1982 
1983  template<typename T>
1984  CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
1985  CompositeGenerator<T> generators;
1986  ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
1987  valuesGen->add( val1 );
1988  valuesGen->add( val2 );
1989  valuesGen->add( val3 );
1990  valuesGen->add( val4 );
1991  generators.add( valuesGen );
1992  return generators;
1993  }
1994 
1995 } // end namespace Generators
1996 
1997 using namespace Generators;
1998 
1999 } // end namespace Catch
2000 
2001 #define INTERNAL_CATCH_LINESTR2( line ) #line
2002 #define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
2003 
2004 #define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
2005 
2006 // #included from: internal/catch_interfaces_exception.h
2007 #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
2008 
2009 #include <string>
2010 
2011 namespace Catch {
2012 
2013  typedef std::string(*exceptionTranslateFunction)();
2014 
2016  virtual ~IExceptionTranslator();
2017  virtual std::string translate() const = 0;
2018  };
2019 
2021  virtual ~IExceptionTranslatorRegistry();
2022 
2023  virtual std::string translateActiveException() const = 0;
2024  };
2025 
2027  template<typename T>
2028  class ExceptionTranslator : public IExceptionTranslator {
2029  public:
2030 
2031  ExceptionTranslator( std::string(*translateFunction)( T& ) )
2032  : m_translateFunction( translateFunction )
2033  {}
2034 
2035  virtual std::string translate() const {
2036  try {
2037  throw;
2038  }
2039  catch( T& ex ) {
2040  return m_translateFunction( ex );
2041  }
2042  }
2043 
2044  protected:
2045  std::string(*m_translateFunction)( T& );
2046  };
2047 
2048  public:
2049  template<typename T>
2050  ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
2052  ( new ExceptionTranslator<T>( translateFunction ) );
2053  }
2054  };
2055 }
2056 
2058 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \
2059  static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \
2060  namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\
2061  static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature )
2062 
2063 // #included from: internal/catch_approx.hpp
2064 #define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
2065 
2066 #include <cmath>
2067 #include <limits>
2068 
2069 namespace Catch {
2070 namespace Detail {
2071 
2072  class Approx {
2073  public:
2074  explicit Approx ( double value )
2075  : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
2076  m_scale( 1.0 ),
2077  m_value( value )
2078  {}
2079 
2080  Approx( Approx const& other )
2081  : m_epsilon( other.m_epsilon ),
2082  m_scale( other.m_scale ),
2083  m_value( other.m_value )
2084  {}
2085 
2086  static Approx custom() {
2087  return Approx( 0 );
2088  }
2089 
2090  Approx operator()( double value ) {
2091  Approx approx( value );
2092  approx.epsilon( m_epsilon );
2093  approx.scale( m_scale );
2094  return approx;
2095  }
2096 
2097  friend bool operator == ( double lhs, Approx const& rhs ) {
2098  // Thanks to Richard Harris for his help refining this formula
2099  return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
2100  }
2101 
2102  friend bool operator == ( Approx const& lhs, double rhs ) {
2103  return operator==( rhs, lhs );
2104  }
2105 
2106  friend bool operator != ( double lhs, Approx const& rhs ) {
2107  return !operator==( lhs, rhs );
2108  }
2109 
2110  friend bool operator != ( Approx const& lhs, double rhs ) {
2111  return !operator==( rhs, lhs );
2112  }
2113 
2114  Approx& epsilon( double newEpsilon ) {
2115  m_epsilon = newEpsilon;
2116  return *this;
2117  }
2118 
2119  Approx& scale( double newScale ) {
2120  m_scale = newScale;
2121  return *this;
2122  }
2123 
2124  std::string toString() const {
2125  std::ostringstream oss;
2126  oss << "Approx( " << Catch::toString( m_value ) << " )";
2127  return oss.str();
2128  }
2129 
2130  private:
2131  double m_epsilon;
2132  double m_scale;
2133  double m_value;
2134  };
2135 }
2136 
2137 template<>
2138 inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
2139  return value.toString();
2140 }
2141 
2142 } // end namespace Catch
2143 
2144 // #included from: internal/catch_matchers.hpp
2145 #define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
2146 
2147 namespace Catch {
2148 namespace Matchers {
2149  namespace Impl {
2150 
2151  template<typename ExpressionT>
2152  struct Matcher : SharedImpl<IShared>
2153  {
2154  typedef ExpressionT ExpressionType;
2155 
2156  virtual ~Matcher() {}
2157  virtual Ptr<Matcher> clone() const = 0;
2158  virtual bool match( ExpressionT const& expr ) const = 0;
2159  virtual std::string toString() const = 0;
2160  };
2161 
2162  template<typename DerivedT, typename ExpressionT>
2163  struct MatcherImpl : Matcher<ExpressionT> {
2164 
2165  virtual Ptr<Matcher<ExpressionT> > clone() const {
2166  return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
2167  }
2168  };
2169 
2170  namespace Generic {
2171 
2172  template<typename ExpressionT>
2173  class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
2174  public:
2175 
2176  AllOf() {}
2177  AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
2178 
2179  AllOf& add( Matcher<ExpressionT> const& matcher ) {
2180  m_matchers.push_back( matcher.clone() );
2181  return *this;
2182  }
2183  virtual bool match( ExpressionT const& expr ) const
2184  {
2185  for( std::size_t i = 0; i < m_matchers.size(); ++i )
2186  if( !m_matchers[i]->match( expr ) )
2187  return false;
2188  return true;
2189  }
2190  virtual std::string toString() const {
2191  std::ostringstream oss;
2192  oss << "( ";
2193  for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
2194  if( i != 0 )
2195  oss << " and ";
2196  oss << m_matchers[i]->toString();
2197  }
2198  oss << " )";
2199  return oss.str();
2200  }
2201 
2202  private:
2203  std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
2204  };
2205 
2206  template<typename ExpressionT>
2207  class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
2208  public:
2209 
2210  AnyOf() {}
2211  AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
2212 
2213  AnyOf& add( Matcher<ExpressionT> const& matcher ) {
2214  m_matchers.push_back( matcher.clone() );
2215  return *this;
2216  }
2217  virtual bool match( ExpressionT const& expr ) const
2218  {
2219  for( std::size_t i = 0; i < m_matchers.size(); ++i )
2220  if( m_matchers[i]->match( expr ) )
2221  return true;
2222  return false;
2223  }
2224  virtual std::string toString() const {
2225  std::ostringstream oss;
2226  oss << "( ";
2227  for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
2228  if( i != 0 )
2229  oss << " or ";
2230  oss << m_matchers[i]->toString();
2231  }
2232  oss << " )";
2233  return oss.str();
2234  }
2235 
2236  private:
2237  std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
2238  };
2239 
2240  }
2241 
2242  namespace StdString {
2243 
2244  inline std::string makeString( std::string const& str ) { return str; }
2245  inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
2246 
2247  struct Equals : MatcherImpl<Equals, std::string> {
2248  Equals( std::string const& str ) : m_str( str ){}
2249  Equals( Equals const& other ) : m_str( other.m_str ){}
2250 
2251  virtual ~Equals();
2252 
2253  virtual bool match( std::string const& expr ) const {
2254  return m_str == expr;
2255  }
2256  virtual std::string toString() const {
2257  return "equals: \"" + m_str + "\"";
2258  }
2259 
2260  std::string m_str;
2261  };
2262 
2263  struct Contains : MatcherImpl<Contains, std::string> {
2264  Contains( std::string const& substr ) : m_substr( substr ){}
2265  Contains( Contains const& other ) : m_substr( other.m_substr ){}
2266 
2267  virtual ~Contains();
2268 
2269  virtual bool match( std::string const& expr ) const {
2270  return expr.find( m_substr ) != std::string::npos;
2271  }
2272  virtual std::string toString() const {
2273  return "contains: \"" + m_substr + "\"";
2274  }
2275 
2276  std::string m_substr;
2277  };
2278 
2279  struct StartsWith : MatcherImpl<StartsWith, std::string> {
2280  StartsWith( std::string const& substr ) : m_substr( substr ){}
2281  StartsWith( StartsWith const& other ) : m_substr( other.m_substr ){}
2282 
2283  virtual ~StartsWith();
2284 
2285  virtual bool match( std::string const& expr ) const {
2286  return expr.find( m_substr ) == 0;
2287  }
2288  virtual std::string toString() const {
2289  return "starts with: \"" + m_substr + "\"";
2290  }
2291 
2292  std::string m_substr;
2293  };
2294 
2295  struct EndsWith : MatcherImpl<EndsWith, std::string> {
2296  EndsWith( std::string const& substr ) : m_substr( substr ){}
2297  EndsWith( EndsWith const& other ) : m_substr( other.m_substr ){}
2298 
2299  virtual ~EndsWith();
2300 
2301  virtual bool match( std::string const& expr ) const {
2302  return expr.find( m_substr ) == expr.size() - m_substr.size();
2303  }
2304  virtual std::string toString() const {
2305  return "ends with: \"" + m_substr + "\"";
2306  }
2307 
2308  std::string m_substr;
2309  };
2310  } // namespace StdString
2311  } // namespace Impl
2312 
2313  // The following functions create the actual matcher objects.
2314  // This allows the types to be inferred
2315  template<typename ExpressionT>
2317  Impl::Matcher<ExpressionT> const& m2 ) {
2318  return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
2319  }
2320  template<typename ExpressionT>
2322  Impl::Matcher<ExpressionT> const& m2,
2323  Impl::Matcher<ExpressionT> const& m3 ) {
2324  return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
2325  }
2326  template<typename ExpressionT>
2328  Impl::Matcher<ExpressionT> const& m2 ) {
2329  return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
2330  }
2331  template<typename ExpressionT>
2333  Impl::Matcher<ExpressionT> const& m2,
2334  Impl::Matcher<ExpressionT> const& m3 ) {
2335  return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
2336  }
2337 
2338  inline Impl::StdString::Equals Equals( std::string const& str ) {
2339  return Impl::StdString::Equals( str );
2340  }
2341  inline Impl::StdString::Equals Equals( const char* str ) {
2343  }
2344  inline Impl::StdString::Contains Contains( std::string const& substr ) {
2345  return Impl::StdString::Contains( substr );
2346  }
2347  inline Impl::StdString::Contains Contains( const char* substr ) {
2349  }
2350  inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) {
2351  return Impl::StdString::StartsWith( substr );
2352  }
2353  inline Impl::StdString::StartsWith StartsWith( const char* substr ) {
2355  }
2356  inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) {
2357  return Impl::StdString::EndsWith( substr );
2358  }
2359  inline Impl::StdString::EndsWith EndsWith( const char* substr ) {
2361  }
2362 
2363 } // namespace Matchers
2364 
2365 using namespace Matchers;
2366 
2367 } // namespace Catch
2368 
2369 // These files are included here so the single_include script doesn't put them
2370 // in the conditionally compiled sections
2371 // #included from: internal/catch_test_case_info.h
2372 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
2373 
2374 #include <string>
2375 #include <set>
2376 
2377 #ifdef __clang__
2378 #pragma clang diagnostic push
2379 #pragma clang diagnostic ignored "-Wpadded"
2380 #endif
2381 
2382 namespace Catch {
2383 
2384  struct ITestCase;
2385 
2386  struct TestCaseInfo {
2387  TestCaseInfo( std::string const& _name,
2388  std::string const& _className,
2389  std::string const& _description,
2390  std::set<std::string> const& _tags,
2391  bool _isHidden,
2392  SourceLineInfo const& _lineInfo );
2393 
2394  TestCaseInfo( TestCaseInfo const& other );
2395 
2396  std::string name;
2397  std::string className;
2398  std::string description;
2399  std::set<std::string> tags;
2400  std::string tagsAsString;
2402  bool isHidden;
2403  };
2404 
2405  class TestCase : protected TestCaseInfo {
2406  public:
2407 
2408  TestCase( ITestCase* testCase, TestCaseInfo const& info );
2409  TestCase( TestCase const& other );
2410 
2411  TestCase withName( std::string const& _newName ) const;
2412 
2413  void invoke() const;
2414 
2415  TestCaseInfo const& getTestCaseInfo() const;
2416 
2417  bool isHidden() const;
2418  bool hasTag( std::string const& tag ) const;
2419  bool matchesTags( std::string const& tagPattern ) const;
2420  std::set<std::string> const& getTags() const;
2421 
2422  void swap( TestCase& other );
2423  bool operator == ( TestCase const& other ) const;
2424  bool operator < ( TestCase const& other ) const;
2425  TestCase& operator = ( TestCase const& other );
2426 
2427  private:
2428  Ptr<ITestCase> test;
2429  };
2430 
2431  TestCase makeTestCase( ITestCase* testCase,
2432  std::string const& className,
2433  std::string const& name,
2434  std::string const& description,
2435  SourceLineInfo const& lineInfo );
2436 }
2437 
2438 #ifdef __clang__
2439 #pragma clang diagnostic pop
2440 #endif
2441 
2442 // #included from: internal/catch_interfaces_runner.h
2443 #define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
2444 
2445 namespace Catch {
2446  class TestCase;
2447 
2448  struct IRunner {
2449  virtual ~IRunner();
2450  };
2451 }
2452 
2453 
2454 #ifdef __OBJC__
2455 // #included from: internal/catch_objc.hpp
2456 #define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
2457 
2458 #import <objc/runtime.h>
2459 
2460 #include <string>
2461 
2462 // NB. Any general catch headers included here must be included
2463 // in catch.hpp first to make sure they are included by the single
2464 // header for non obj-usage
2465 
2467 // This protocol is really only here for (self) documenting purposes, since
2468 // all its methods are optional.
2469 @protocol OcFixture
2470 
2471 @optional
2472 
2473 -(void) setUp;
2474 -(void) tearDown;
2475 
2476 @end
2477 
2478 namespace Catch {
2479 
2480  class OcMethod : public SharedImpl<ITestCase> {
2481 
2482  public:
2483  OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
2484 
2485  virtual void invoke() const {
2486  id obj = [[m_cls alloc] init];
2487 
2488  performOptionalSelector( obj, @selector(setUp) );
2489  performOptionalSelector( obj, m_sel );
2490  performOptionalSelector( obj, @selector(tearDown) );
2491 
2492  arcSafeRelease( obj );
2493  }
2494  private:
2495  virtual ~OcMethod() {}
2496 
2497  Class m_cls;
2498  SEL m_sel;
2499  };
2500 
2501  namespace Detail{
2502 
2503  inline std::string getAnnotation( Class cls,
2504  std::string const& annotationName,
2505  std::string const& testCaseName ) {
2506  NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
2507  SEL sel = NSSelectorFromString( selStr );
2508  arcSafeRelease( selStr );
2509  id value = performOptionalSelector( cls, sel );
2510  if( value )
2511  return [(NSString*)value UTF8String];
2512  return "";
2513  }
2514  }
2515 
2516  inline size_t registerTestMethods() {
2517  size_t noTestMethods = 0;
2518  int noClasses = objc_getClassList( NULL, 0 );
2519 
2520  Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
2521  objc_getClassList( classes, noClasses );
2522 
2523  for( int c = 0; c < noClasses; c++ ) {
2524  Class cls = classes[c];
2525  {
2526  u_int count;
2527  Method* methods = class_copyMethodList( cls, &count );
2528  for( u_int m = 0; m < count ; m++ ) {
2529  SEL selector = method_getName(methods[m]);
2530  std::string methodName = sel_getName(selector);
2531  if( startsWith( methodName, "Catch_TestCase_" ) ) {
2532  std::string testCaseName = methodName.substr( 15 );
2533  std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
2534  std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
2535  const char* className = class_getName( cls );
2536 
2537  getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
2538  noTestMethods++;
2539  }
2540  }
2541  free(methods);
2542  }
2543  }
2544  return noTestMethods;
2545  }
2546 
2547  namespace Matchers {
2548  namespace Impl {
2549  namespace NSStringMatchers {
2550 
2551  template<typename MatcherT>
2552  struct StringHolder : MatcherImpl<MatcherT, NSString*>{
2553  StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
2554  StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
2555  StringHolder() {
2556  arcSafeRelease( m_substr );
2557  }
2558 
2559  NSString* m_substr;
2560  };
2561 
2562  struct Equals : StringHolder<Equals> {
2563  Equals( NSString* substr ) : StringHolder( substr ){}
2564 
2565  virtual bool match( ExpressionType const& str ) const {
2566  return (str != nil || m_substr == nil ) &&
2567  [str isEqualToString:m_substr];
2568  }
2569 
2570  virtual std::string toString() const {
2571  return "equals string: \"" + Catch::toString( m_substr ) + "\"";
2572  }
2573  };
2574 
2575  struct Contains : StringHolder<Contains> {
2576  Contains( NSString* substr ) : StringHolder( substr ){}
2577 
2578  virtual bool match( ExpressionType const& str ) const {
2579  return (str != nil || m_substr == nil ) &&
2580  [str rangeOfString:m_substr].location != NSNotFound;
2581  }
2582 
2583  virtual std::string toString() const {
2584  return "contains string: \"" + Catch::toString( m_substr ) + "\"";
2585  }
2586  };
2587 
2588  struct StartsWith : StringHolder<StartsWith> {
2589  StartsWith( NSString* substr ) : StringHolder( substr ){}
2590 
2591  virtual bool match( ExpressionType const& str ) const {
2592  return (str != nil || m_substr == nil ) &&
2593  [str rangeOfString:m_substr].location == 0;
2594  }
2595 
2596  virtual std::string toString() const {
2597  return "starts with: \"" + Catch::toString( m_substr ) + "\"";
2598  }
2599  };
2600  struct EndsWith : StringHolder<EndsWith> {
2601  EndsWith( NSString* substr ) : StringHolder( substr ){}
2602 
2603  virtual bool match( ExpressionType const& str ) const {
2604  return (str != nil || m_substr == nil ) &&
2605  [str rangeOfString:m_substr].location == [str length] - [m_substr length];
2606  }
2607 
2608  virtual std::string toString() const {
2609  return "ends with: \"" + Catch::toString( m_substr ) + "\"";
2610  }
2611  };
2612 
2613  } // namespace NSStringMatchers
2614  } // namespace Impl
2615 
2617  Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
2618 
2620  Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
2621 
2623  StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
2624 
2626  EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
2627 
2628  } // namespace Matchers
2629 
2630  using namespace Matchers;
2631 
2632 } // namespace Catch
2633 
2635 #define OC_TEST_CASE( name, desc )\
2636 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
2637 {\
2638 return @ name; \
2639 }\
2640 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
2641 { \
2642 return @ desc; \
2643 } \
2644 -(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
2645 
2646 #endif
2647 
2648 #if defined( CATCH_CONFIG_MAIN ) || defined( CATCH_CONFIG_RUNNER )
2649 // #included from: internal/catch_impl.hpp
2650 #define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
2651 
2652 // Collect all the implementation files together here
2653 // These are the equivalent of what would usually be cpp files
2654 
2655 #ifdef __clang__
2656 #pragma clang diagnostic push
2657 #pragma clang diagnostic ignored "-Wweak-vtables"
2658 #endif
2659 
2660 // #included from: catch_runner.hpp
2661 #define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
2662 
2663 // #included from: internal/catch_commandline.hpp
2664 #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
2665 
2666 // #included from: catch_config.hpp
2667 #define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
2668 
2669 // #included from: catch_test_spec.h
2670 #define TWOBLUECUBES_CATCH_TEST_SPEC_H_INCLUDED
2671 
2672 // #included from: catch_tags.h
2673 #define TWOBLUECUBES_CATCH_TAGS_H_INCLUDED
2674 
2675 #include <string>
2676 #include <set>
2677 #include <map>
2678 #include <vector>
2679 
2680 #ifdef __clang__
2681 #pragma clang diagnostic ignored "-Wpadded"
2682 #endif
2683 
2684 namespace Catch {
2685  class TagParser {
2686  public:
2687  virtual ~TagParser();
2688 
2689  void parse( std::string const& str );
2690 
2691  protected:
2692  virtual void acceptTag( std::string const& tag ) = 0;
2693  virtual void acceptChar( char c ) = 0;
2694  virtual void endParse() {}
2695 
2696  private:
2697  };
2698 
2699  class TagExtracter : public TagParser {
2700  public:
2701 
2702  TagExtracter( std::set<std::string>& tags );
2703  virtual ~TagExtracter();
2704 
2705  void parse( std::string& description );
2706 
2707  private:
2708  virtual void acceptTag( std::string const& tag );
2709  virtual void acceptChar( char c );
2710 
2711  TagExtracter& operator=(TagExtracter const&);
2712 
2713  std::set<std::string>& m_tags;
2714  std::string m_remainder;
2715  };
2716 
2717  class Tag {
2718  public:
2719  Tag();
2720  Tag( std::string const& name, bool isNegated );
2721  std::string getName() const;
2722  bool isNegated() const;
2723  bool operator ! () const;
2724 
2725  private:
2726  std::string m_name;
2727  bool m_isNegated;
2728  };
2729 
2730  class TagSet {
2731  typedef std::map<std::string, Tag> TagMap;
2732  public:
2733  void add( Tag const& tag );
2734  bool empty() const;
2735  bool matches( std::set<std::string> const& tags ) const;
2736 
2737  private:
2738  TagMap m_tags;
2739  };
2740 
2741  class TagExpression {
2742  public:
2743  bool matches( std::set<std::string> const& tags ) const;
2744 
2745  private:
2746  friend class TagExpressionParser;
2747 
2748  std::vector<TagSet> m_tagSets;
2749  };
2750 
2751  class TagExpressionParser : public TagParser {
2752  public:
2753  TagExpressionParser( TagExpression& exp );
2754  ~TagExpressionParser();
2755 
2756  private:
2757  virtual void acceptTag( std::string const& tag );
2758  virtual void acceptChar( char c );
2759  virtual void endParse();
2760 
2761  TagExpressionParser& operator=(TagExpressionParser const&);
2762 
2763  bool m_isNegated;
2764  TagSet m_currentTagSet;
2765  TagExpression& m_exp;
2766  };
2767 
2768 } // end namespace Catch
2769 
2770 #include <string>
2771 #include <vector>
2772 
2773 namespace Catch {
2774 
2775  class TestCase;
2776 
2777  struct IfFilterMatches{ enum DoWhat {
2778  AutoDetectBehaviour,
2779  IncludeTests,
2780  ExcludeTests
2781  }; };
2782 
2783  class TestCaseFilter {
2784  enum WildcardPosition {
2785  NoWildcard = 0,
2786  WildcardAtStart = 1,
2787  WildcardAtEnd = 2,
2788  WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
2789  };
2790 
2791  public:
2792  TestCaseFilter( std::string const& testSpec, IfFilterMatches::DoWhat matchBehaviour = IfFilterMatches::AutoDetectBehaviour );
2793 
2794  IfFilterMatches::DoWhat getFilterType() const;
2795  bool shouldInclude( TestCase const& testCase ) const;
2796 
2797  private:
2798  bool isMatch( TestCase const& testCase ) const;
2799 
2800  std::string m_stringToMatch;
2801  IfFilterMatches::DoWhat m_filterType;
2802  WildcardPosition m_wildcardPosition;
2803  };
2804 
2805  class TestCaseFilters {
2806  public:
2807  TestCaseFilters( std::string const& name );
2808  std::string getName() const;
2809  void addFilter( TestCaseFilter const& filter );
2810  void addTags( std::string const& tagPattern );
2811  bool shouldInclude( TestCase const& testCase ) const;
2812 
2813  private:
2814  std::vector<TagExpression> m_tagExpressions;
2815  std::vector<TestCaseFilter> m_inclusionFilters;
2816  std::vector<TestCaseFilter> m_exclusionFilters;
2817  std::string m_name;
2818  };
2819 
2820 }
2821 
2822 // #included from: catch_stream.h
2823 #define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
2824 
2825 #include <streambuf>
2826 
2827 #ifdef __clang__
2828 #pragma clang diagnostic ignored "-Wpadded"
2829 #endif
2830 
2831 namespace Catch {
2832 
2833  class Stream {
2834  public:
2835  Stream();
2836  Stream( std::streambuf* _streamBuf, bool _isOwned );
2837  void release();
2838 
2839  std::streambuf* streamBuf;
2840 
2841  private:
2842  bool isOwned;
2843  };
2844 }
2845 
2846 #include <memory>
2847 #include <vector>
2848 #include <string>
2849 #include <iostream>
2850 
2851 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
2852 #define CATCH_CONFIG_CONSOLE_WIDTH 80
2853 #endif
2854 
2855 namespace Catch {
2856 
2857  struct ConfigData {
2858 
2859  ConfigData()
2860  : listTests( false ),
2861  listTags( false ),
2862  listReporters( false ),
2863  listTestNamesOnly( false ),
2864  showSuccessfulTests( false ),
2865  shouldDebugBreak( false ),
2866  noThrow( false ),
2867  showHelp( false ),
2868  abortAfter( -1 ),
2869  verbosity( Verbosity::Normal ),
2870  warnings( WarnAbout::Nothing ),
2871  showDurations( ShowDurations::DefaultForReporter )
2872  {}
2873 
2874  bool listTests;
2875  bool listTags;
2876  bool listReporters;
2877  bool listTestNamesOnly;
2878 
2879  bool showSuccessfulTests;
2880  bool shouldDebugBreak;
2881  bool noThrow;
2882  bool showHelp;
2883 
2884  int abortAfter;
2885 
2886  Verbosity::Level verbosity;
2887  WarnAbout::What warnings;
2888  ShowDurations::OrNot showDurations;
2889 
2890  std::string reporterName;
2891  std::string outputFilename;
2892  std::string name;
2893  std::string processName;
2894 
2895  std::vector<std::string> testsOrTags;
2896  };
2897 
2898  class Config : public SharedImpl<IConfig> {
2899  private:
2900  Config( Config const& other );
2901  Config& operator = ( Config const& other );
2902  virtual void dummy();
2903  public:
2904 
2905  Config()
2906  : m_os( std::cout.rdbuf() )
2907  {}
2908 
2909  Config( ConfigData const& data )
2910  : m_data( data ),
2911  m_os( std::cout.rdbuf() )
2912  {
2913  if( !data.testsOrTags.empty() ) {
2914  std::string groupName;
2915  for( std::size_t i = 0; i < data.testsOrTags.size(); ++i ) {
2916  if( i != 0 )
2917  groupName += " ";
2918  groupName += data.testsOrTags[i];
2919  }
2920  TestCaseFilters filters( groupName );
2921  for( std::size_t i = 0; i < data.testsOrTags.size(); ++i ) {
2922  std::string filter = data.testsOrTags[i];
2923  if( startsWith( filter, "[" ) || startsWith( filter, "~[" ) )
2924  filters.addTags( filter );
2925  else
2926  filters.addFilter( TestCaseFilter( filter ) );
2927  }
2928  m_filterSets.push_back( filters );
2929  }
2930  }
2931 
2932  virtual ~Config() {
2933  m_os.rdbuf( std::cout.rdbuf() );
2934  m_stream.release();
2935  }
2936 
2937  void setFilename( std::string const& filename ) {
2938  m_data.outputFilename = filename;
2939  }
2940 
2941  std::string const& getFilename() const {
2942  return m_data.outputFilename ;
2943  }
2944 
2945  bool listTests() const { return m_data.listTests; }
2946  bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
2947  bool listTags() const { return m_data.listTags; }
2948  bool listReporters() const { return m_data.listReporters; }
2949 
2950  std::string getProcessName() const {
2951  return m_data.processName;
2952  }
2953 
2954  bool shouldDebugBreak() const {
2955  return m_data.shouldDebugBreak;
2956  }
2957 
2958  void setStreamBuf( std::streambuf* buf ) {
2959  m_os.rdbuf( buf ? buf : std::cout.rdbuf() );
2960  }
2961 
2962  void useStream( std::string const& streamName ) {
2963  Stream stream = createStream( streamName );
2964  setStreamBuf( stream.streamBuf );
2965  m_stream.release();
2966  m_stream = stream;
2967  }
2968 
2969  std::string getReporterName() const { return m_data.reporterName; }
2970 
2971  void addTestSpec( std::string const& testSpec ) {
2972  TestCaseFilters filters( testSpec );
2973  filters.addFilter( TestCaseFilter( testSpec ) );
2974  m_filterSets.push_back( filters );
2975  }
2976 
2977  int abortAfter() const {
2978  return m_data.abortAfter;
2979  }
2980 
2981  std::vector<TestCaseFilters> const& filters() const {
2982  return m_filterSets;
2983  }
2984 
2985  bool showHelp() const { return m_data.showHelp; }
2986 
2987  // IConfig interface
2988  virtual bool allowThrows() const { return !m_data.noThrow; }
2989  virtual std::ostream& stream() const { return m_os; }
2990  virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
2991  virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
2992  virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
2993  virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
2994 
2995  private:
2996  ConfigData m_data;
2997 
2998  Stream m_stream;
2999  mutable std::ostream m_os;
3000  std::vector<TestCaseFilters> m_filterSets;
3001  };
3002 
3003 } // end namespace Catch
3004 
3005 // #included from: clara.h
3006 #define TWOBLUECUBES_CLARA_H_INCLUDED
3007 
3008 // #included from: catch_text.h
3009 #define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
3010 
3011 #include <string>
3012 #include <vector>
3013 
3014 namespace Catch {
3015 
3016  struct TextAttributes {
3017  TextAttributes()
3018  : initialIndent( std::string::npos ),
3019  indent( 0 ),
3020  width( CATCH_CONFIG_CONSOLE_WIDTH-1 ),
3021  tabChar( '\t' )
3022  {}
3023 
3024  TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
3025  TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
3026  TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
3027  TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
3028 
3029  std::size_t initialIndent; // indent of first line, or npos
3030  std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
3031  std::size_t width; // maximum width of text, including indent. Longer text will wrap
3032  char tabChar; // If this char is seen the indent is changed to current pos
3033  };
3034 
3035  class Text {
3036  public:
3037  Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() );
3038  void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos );
3039 
3040  typedef std::vector<std::string>::const_iterator const_iterator;
3041 
3042  const_iterator begin() const { return lines.begin(); }
3043  const_iterator end() const { return lines.end(); }
3044  std::string const& last() const { return lines.back(); }
3045  std::size_t size() const { return lines.size(); }
3046  std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
3047  std::string toString() const;
3048 
3049  friend std::ostream& operator << ( std::ostream& _stream, Text const& _text );
3050 
3051  private:
3052  std::string str;
3053  TextAttributes attr;
3054  std::vector<std::string> lines;
3055  };
3056 
3057 } // end namespace Catch
3058 
3059 namespace Clara {
3060  namespace Detail {
3061  template<typename T> struct RemoveConstRef{ typedef T type; };
3062  template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
3063  template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
3064  template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
3065 
3066  template<typename T> struct IsBool { static const bool value = false; };
3067  template<> struct IsBool<bool> { static const bool value = true; };
3068 
3069  template<typename T>
3070  void convertInto( std::string const& _source, T& _dest ) {
3071  std::stringstream ss;
3072  ss << _source;
3073  ss >> _dest;
3074  if( ss.fail() )
3075  throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
3076  }
3077  inline void convertInto( std::string const& _source, std::string& _dest ) {
3078  _dest = _source;
3079  }
3080  inline void convertInto( std::string const& _source, bool& _dest ) {
3081  std::string sourceLC = _source;
3082  std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
3083  if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
3084  _dest = true;
3085  else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
3086  _dest = false;
3087  else
3088  throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" );
3089  }
3090  inline void convertInto( bool _source, bool& _dest ) {
3091  _dest = _source;
3092  }
3093  template<typename T>
3094  inline void convertInto( bool, T& ) {
3095  throw std::runtime_error( "Invalid conversion" );
3096  }
3097 
3098  template<typename ConfigT>
3099  struct IArgFunction {
3100  virtual ~IArgFunction() {}
3101  virtual void set( ConfigT& config, std::string const& value ) const = 0;
3102  virtual void setFlag( ConfigT& config ) const = 0;
3103  virtual bool takesArg() const = 0;
3104  virtual IArgFunction* clone() const = 0;
3105  };
3106 
3107  template<typename ConfigT>
3108  class BoundArgFunction {
3109  public:
3110  BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
3111  BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj->clone() ) {}
3112  BoundArgFunction& operator = ( BoundArgFunction const& other ) {
3113  IArgFunction<ConfigT>* newFunctionObj = other.functionObj->clone();
3114  delete functionObj;
3115  functionObj = newFunctionObj;
3116  return *this;
3117  }
3118  ~BoundArgFunction() { delete functionObj; }
3119 
3120  void set( ConfigT& config, std::string const& value ) const {
3121  functionObj->set( config, value );
3122  }
3123  void setFlag( ConfigT& config ) const {
3124  functionObj->setFlag( config );
3125  }
3126  bool takesArg() const { return functionObj->takesArg(); }
3127  private:
3128  IArgFunction<ConfigT>* functionObj;
3129  };
3130 
3131  template<typename C>
3132  struct NullBinder : IArgFunction<C>{
3133  virtual void set( C&, std::string const& ) const {}
3134  virtual void setFlag( C& ) const {}
3135  virtual bool takesArg() const { return true; }
3136  virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
3137  };
3138 
3139  template<typename C, typename M>
3140  struct BoundDataMember : IArgFunction<C>{
3141  BoundDataMember( M C::* _member ) : member( _member ) {}
3142  virtual void set( C& p, std::string const& stringValue ) const {
3143  convertInto( stringValue, p.*member );
3144  }
3145  virtual void setFlag( C& p ) const {
3146  convertInto( true, p.*member );
3147  }
3148  virtual bool takesArg() const { return !IsBool<M>::value; }
3149  virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
3150  M C::* member;
3151  };
3152  template<typename C, typename M>
3153  struct BoundUnaryMethod : IArgFunction<C>{
3154  BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
3155  virtual void set( C& p, std::string const& stringValue ) const {
3156  typename RemoveConstRef<M>::type value;
3157  convertInto( stringValue, value );
3158  (p.*member)( value );
3159  }
3160  virtual void setFlag( C& p ) const {
3161  typename RemoveConstRef<M>::type value;
3162  convertInto( true, value );
3163  (p.*member)( value );
3164  }
3165  virtual bool takesArg() const { return !IsBool<M>::value; }
3166  virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
3167  void (C::*member)( M );
3168  };
3169  template<typename C>
3170  struct BoundNullaryMethod : IArgFunction<C>{
3171  BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
3172  virtual void set( C& p, std::string const& stringValue ) const {
3173  bool value;
3174  convertInto( stringValue, value );
3175  if( value )
3176  (p.*member)();
3177  }
3178  virtual void setFlag( C& p ) const {
3179  (p.*member)();
3180  }
3181  virtual bool takesArg() const { return false; }
3182  virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
3183  void (C::*member)();
3184  };
3185 
3186  template<typename C>
3187  struct BoundUnaryFunction : IArgFunction<C>{
3188  BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
3189  virtual void set( C& obj, std::string const& stringValue ) const {
3190  bool value;
3191  convertInto( stringValue, value );
3192  if( value )
3193  function( obj );
3194  }
3195  virtual void setFlag( C& p ) const {
3196  function( p );
3197  }
3198  virtual bool takesArg() const { return false; }
3199  virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
3200  void (*function)( C& );
3201  };
3202 
3203  template<typename C, typename T>
3204  struct BoundBinaryFunction : IArgFunction<C>{
3205  BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
3206  virtual void set( C& obj, std::string const& stringValue ) const {
3207  typename RemoveConstRef<T>::type value;
3208  convertInto( stringValue, value );
3209  function( obj, value );
3210  }
3211  virtual void setFlag( C& obj ) const {
3212  typename RemoveConstRef<T>::type value;
3213  convertInto( true, value );
3214  function( obj, value );
3215  }
3216  virtual bool takesArg() const { return !IsBool<T>::value; }
3217  virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
3218  void (*function)( C&, T );
3219  };
3220 
3221  template<typename C, typename M>
3222  BoundArgFunction<C> makeBoundField( M C::* _member ) {
3223  return BoundArgFunction<C>( new BoundDataMember<C,M>( _member ) );
3224  }
3225  template<typename C, typename M>
3226  BoundArgFunction<C> makeBoundField( void (C::*_member)( M ) ) {
3227  return BoundArgFunction<C>( new BoundUnaryMethod<C,M>( _member ) );
3228  }
3229  template<typename C>
3230  BoundArgFunction<C> makeBoundField( void (C::*_member)() ) {
3231  return BoundArgFunction<C>( new BoundNullaryMethod<C>( _member ) );
3232  }
3233  template<typename C>
3234  BoundArgFunction<C> makeBoundField( void (*_function)( C& ) ) {
3235  return BoundArgFunction<C>( new BoundUnaryFunction<C>( _function ) );
3236  }
3237  template<typename C, typename T>
3238  BoundArgFunction<C> makeBoundField( void (*_function)( C&, T ) ) {
3239  return BoundArgFunction<C>( new BoundBinaryFunction<C, T>( _function ) );
3240  }
3241  } // namespace Detail
3242 
3243  struct Parser {
3244  Parser() : separators( " \t=:" ) {}
3245 
3246  struct Token {
3247  enum Type { Positional, ShortOpt, LongOpt };
3248  Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
3249  Type type;
3250  std::string data;
3251  };
3252 
3253  void parseIntoTokens( int argc, char const * const * argv, std::vector<Parser::Token>& tokens ) const {
3254  const std::string doubleDash = "--";
3255  for( int i = 1; i < argc && argv[i] != doubleDash; ++i )
3256  parseIntoTokens( argv[i] , tokens);
3257  }
3258  void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens ) const {
3259  while( !arg.empty() ) {
3260  Parser::Token token( Parser::Token::Positional, arg );
3261  arg = "";
3262  if( token.data[0] == '-' ) {
3263  if( token.data.size() > 1 && token.data[1] == '-' ) {
3264  token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) );
3265  }
3266  else {
3267  token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) );
3268  if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) {
3269  arg = "-" + token.data.substr( 1 );
3270  token.data = token.data.substr( 0, 1 );
3271  }
3272  }
3273  }
3274  if( token.type != Parser::Token::Positional ) {
3275  std::size_t pos = token.data.find_first_of( separators );
3276  if( pos != std::string::npos ) {
3277  arg = token.data.substr( pos+1 );
3278  token.data = token.data.substr( 0, pos );
3279  }
3280  }
3281  tokens.push_back( token );
3282  }
3283  }
3284  std::string separators;
3285  };
3286 
3287  template<typename ConfigT>
3288  class CommandLine {
3289 
3290  struct Arg {
3291  Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ), position( -1 ) {}
3292 
3293  bool hasShortName( std::string const& shortName ) const {
3294  for( std::vector<std::string>::const_iterator
3295  it = shortNames.begin(), itEnd = shortNames.end();
3296  it != itEnd;
3297  ++it )
3298  if( *it == shortName )
3299  return true;
3300  return false;
3301  }
3302  bool hasLongName( std::string const& _longName ) const {
3303  return _longName == longName;
3304  }
3305  bool takesArg() const {
3306  return !hint.empty();
3307  }
3308  bool isFixedPositional() const {
3309  return position != -1;
3310  }
3311  bool isAnyPositional() const {
3312  return position == -1 && shortNames.empty() && longName.empty();
3313  }
3314  std::string dbgName() const {
3315  if( !longName.empty() )
3316  return "--" + longName;
3317  if( !shortNames.empty() )
3318  return "-" + shortNames[0];
3319  return "positional args";
3320  }
3321  void validate() const {
3322  if( boundField.takesArg() && !takesArg() )
3323  throw std::logic_error( dbgName() + " must specify an arg name" );
3324  }
3325  std::string commands() const {
3326  std::ostringstream oss;
3327  bool first = true;
3328  std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
3329  for(; it != itEnd; ++it ) {
3330  if( first )
3331  first = false;
3332  else
3333  oss << ", ";
3334  oss << "-" << *it;
3335  }
3336  if( !longName.empty() ) {
3337  if( !first )
3338  oss << ", ";
3339  oss << "--" << longName;
3340  }
3341  if( !hint.empty() )
3342  oss << " <" << hint << ">";
3343  return oss.str();
3344  }
3345 
3346  Detail::BoundArgFunction<ConfigT> boundField;
3347  std::vector<std::string> shortNames;
3348  std::string longName;
3349  std::string description;
3350  std::string hint;
3351  int position;
3352  };
3353 
3354  // NOTE: std::auto_ptr is deprecated in c++11/c++0x
3355 #if defined(__cplusplus) && __cplusplus > 199711L
3356  typedef std::unique_ptr<Arg> ArgAutoPtr;
3357 #else
3358  typedef std::auto_ptr<Arg> ArgAutoPtr;
3359 #endif
3360 
3361  class ArgBinder {
3362  public:
3363  template<typename F>
3364  ArgBinder( CommandLine* cl, F f )
3365  : m_cl( cl ),
3366  m_arg( Detail::makeBoundField( f ) )
3367  {}
3368  ArgBinder( ArgBinder& other )
3369  : m_cl( other.m_cl ),
3370  m_arg( other.m_arg )
3371  {
3372  other.m_cl = NULL;
3373  }
3374  ~ArgBinder() {
3375  if( m_cl ) {
3376  m_arg.validate();
3377  if( m_arg.isFixedPositional() ) {
3378  m_cl->m_positionalArgs.insert( std::make_pair( m_arg.position, m_arg ) );
3379  if( m_arg.position > m_cl->m_highestSpecifiedArgPosition )
3380  m_cl->m_highestSpecifiedArgPosition = m_arg.position;
3381  }
3382  else if( m_arg.isAnyPositional() ) {
3383  if( m_cl->m_arg.get() )
3384  throw std::logic_error( "Only one unpositional argument can be added" );
3385  m_cl->m_arg = ArgAutoPtr( new Arg( m_arg ) );
3386  }
3387  else
3388  m_cl->m_options.push_back( m_arg );
3389  }
3390  }
3391  ArgBinder& shortOpt( std::string const& name ) {
3392  m_arg.shortNames.push_back( name );
3393  return *this;
3394  }
3395  ArgBinder& longOpt( std::string const& name ) {
3396  m_arg.longName = name;
3397  return *this;
3398  }
3399  ArgBinder& describe( std::string const& description ) {
3400  m_arg.description = description;
3401  return *this;
3402  }
3403  ArgBinder& hint( std::string const& hint ) {
3404  m_arg.hint = hint;
3405  return *this;
3406  }
3407  ArgBinder& position( int position ) {
3408  m_arg.position = position;
3409  return *this;
3410  }
3411  private:
3412  CommandLine* m_cl;
3413  Arg m_arg;
3414  };
3415 
3416  public:
3417 
3418  CommandLine()
3419  : m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
3420  m_highestSpecifiedArgPosition( 0 ),
3421  m_throwOnUnrecognisedTokens( false )
3422  {}
3423  CommandLine( CommandLine const& other )
3424  : m_boundProcessName( other.m_boundProcessName ),
3425  m_options ( other.m_options ),
3426  m_positionalArgs( other.m_positionalArgs ),
3427  m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
3428  m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
3429  {
3430  if( other.m_arg.get() )
3431  m_arg = ArgAutoPtr( new Arg( *other.m_arg ) );
3432  }
3433 
3434  CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {
3435  m_throwOnUnrecognisedTokens = shouldThrow;
3436  return *this;
3437  }
3438 
3439  template<typename F>
3440  ArgBinder bind( F f ) {
3441  ArgBinder binder( this, f );
3442  return binder;
3443  }
3444  template<typename F>
3445  void bindProcessName( F f ) {
3446  m_boundProcessName = Detail::makeBoundField( f );
3447  }
3448 
3449  void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = CATCH_CONFIG_CONSOLE_WIDTH ) const {
3450  typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
3451  std::size_t maxWidth = 0;
3452  for( it = itBegin; it != itEnd; ++it )
3453  maxWidth = (std::max)( maxWidth, it->commands().size() );
3454 
3455  for( it = itBegin; it != itEnd; ++it ) {
3456  Catch::Text usage( it->commands(), Catch::TextAttributes()
3457  .setWidth( maxWidth+indent )
3458  .setIndent( indent ) );
3459  // !TBD handle longer usage strings
3460  Catch::Text desc( it->description, Catch::TextAttributes()
3461  .setWidth( width - maxWidth -3 ) );
3462 
3463  for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
3464  std::string usageCol = i < usage.size() ? usage[i] : "";
3465  os << usageCol;
3466 
3467  if( i < desc.size() && !desc[i].empty() )
3468  os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
3469  << desc[i];
3470  os << "\n";
3471  }
3472  }
3473  }
3474  std::string optUsage() const {
3475  std::ostringstream oss;
3476  optUsage( oss );
3477  return oss.str();
3478  }
3479 
3480  void argSynopsis( std::ostream& os ) const {
3481  for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
3482  if( i > 1 )
3483  os << " ";
3484  typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
3485  if( it != m_positionalArgs.end() )
3486  os << "<" << it->second.hint << ">";
3487  else if( m_arg.get() )
3488  os << "<" << m_arg->hint << ">";
3489  else
3490  throw std::logic_error( "non consecutive positional arguments with no floating args" );
3491  }
3492  // !TBD No indication of mandatory args
3493  if( m_arg.get() ) {
3494  if( m_highestSpecifiedArgPosition > 1 )
3495  os << " ";
3496  os << "[<" << m_arg->hint << "> ...]";
3497  }
3498  }
3499  std::string argSynopsis() const {
3500  std::ostringstream oss;
3501  argSynopsis( oss );
3502  return oss.str();
3503  }
3504 
3505  void usage( std::ostream& os, std::string const& procName ) const {
3506  os << "usage:\n " << procName << " ";
3507  argSynopsis( os );
3508  if( !m_options.empty() ) {
3509  os << " [options]\n\nwhere options are: \n";
3510  optUsage( os, 2 );
3511  }
3512  os << "\n";
3513  }
3514  std::string usage( std::string const& procName ) const {
3515  std::ostringstream oss;
3516  usage( oss, procName );
3517  return oss.str();
3518  }
3519 
3520  std::vector<Parser::Token> parseInto( int argc, char const * const * argv, ConfigT& config ) const {
3521  std::string processName = argv[0];
3522  std::size_t lastSlash = processName.find_last_of( "/\\" );
3523  if( lastSlash != std::string::npos )
3524  processName = processName.substr( lastSlash+1 );
3525  m_boundProcessName.set( config, processName );
3526  std::vector<Parser::Token> tokens;
3527  Parser parser;
3528  parser.parseIntoTokens( argc, argv, tokens );
3529  return populate( tokens, config );
3530  }
3531 
3532  std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
3533  if( m_options.empty() && m_positionalArgs.empty() )
3534  throw std::logic_error( "No options or arguments specified" );
3535 
3536  std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
3537  unusedTokens = populateFixedArgs( unusedTokens, config );
3538  unusedTokens = populateFloatingArgs( unusedTokens, config );
3539  return unusedTokens;
3540  }
3541 
3542  std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
3543  std::vector<Parser::Token> unusedTokens;
3544  std::vector<std::string> errors;
3545  for( std::size_t i = 0; i < tokens.size(); ++i ) {
3546  Parser::Token const& token = tokens[i];
3547  typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
3548  for(; it != itEnd; ++it ) {
3549  Arg const& arg = *it;
3550 
3551  try {
3552  if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
3553  ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
3554  if( arg.takesArg() ) {
3555  if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
3556  errors.push_back( "Expected argument to option: " + token.data );
3557  else
3558  arg.boundField.set( config, tokens[++i].data );
3559  }
3560  else {
3561  arg.boundField.setFlag( config );
3562  }
3563  break;
3564  }
3565  }
3566  catch( std::exception& ex ) {
3567  errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
3568  }
3569  }
3570  if( it == itEnd ) {
3571  if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
3572  unusedTokens.push_back( token );
3573  else if( m_throwOnUnrecognisedTokens )
3574  errors.push_back( "unrecognised option: " + token.data );
3575  }
3576  }
3577  if( !errors.empty() ) {
3578  std::ostringstream oss;
3579  for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
3580  it != itEnd;
3581  ++it ) {
3582  if( it != errors.begin() )
3583  oss << "\n";
3584  oss << *it;
3585  }
3586  throw std::runtime_error( oss.str() );
3587  }
3588  return unusedTokens;
3589  }
3590  std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
3591  std::vector<Parser::Token> unusedTokens;
3592  int position = 1;
3593  for( std::size_t i = 0; i < tokens.size(); ++i ) {
3594  Parser::Token const& token = tokens[i];
3595  typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
3596  if( it != m_positionalArgs.end() )
3597  it->second.boundField.set( config, token.data );
3598  else
3599  unusedTokens.push_back( token );
3600  if( token.type == Parser::Token::Positional )
3601  position++;
3602  }
3603  return unusedTokens;
3604  }
3605  std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
3606  if( !m_arg.get() )
3607  return tokens;
3608  std::vector<Parser::Token> unusedTokens;
3609  for( std::size_t i = 0; i < tokens.size(); ++i ) {
3610  Parser::Token const& token = tokens[i];
3611  if( token.type == Parser::Token::Positional )
3612  m_arg->boundField.set( config, token.data );
3613  else
3614  unusedTokens.push_back( token );
3615  }
3616  return unusedTokens;
3617  }
3618 
3619  private:
3620  Detail::BoundArgFunction<ConfigT> m_boundProcessName;
3621  std::vector<Arg> m_options;
3622  std::map<int, Arg> m_positionalArgs;
3623  ArgAutoPtr m_arg;
3624  int m_highestSpecifiedArgPosition;
3625  bool m_throwOnUnrecognisedTokens;
3626  };
3627 
3628 } // end namespace Clara
3629 
3630 #include <fstream>
3631 
3632 namespace Catch {
3633 
3634  inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
3635  inline void abortAfterX( ConfigData& config, int x ) {
3636  if( x < 1 )
3637  throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
3638  config.abortAfter = x;
3639  }
3640  inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
3641 
3642  inline void addWarning( ConfigData& config, std::string const& _warning ) {
3643  if( _warning == "NoAssertions" )
3644  config.warnings = (WarnAbout::What)( config.warnings | WarnAbout::NoAssertions );
3645  else
3646  throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" );
3647 
3648  }
3649  inline void setVerbosity( ConfigData& config, int level ) {
3650  // !TBD: accept strings?
3651  config.verbosity = (Verbosity::Level)level;
3652  }
3653  inline void setShowDurations( ConfigData& config, bool _showDurations ) {
3654  config.showDurations = _showDurations
3657  }
3658  inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
3659  std::ifstream f( _filename.c_str() );
3660  if( !f.is_open() )
3661  throw std::domain_error( "Unable to load input file: " + _filename );
3662 
3663  std::string line;
3664  while( std::getline( f, line ) ) {
3665  line = trim(line);
3666  if( !line.empty() && !startsWith( line, "#" ) )
3667  addTestOrTags( config, line );
3668  }
3669  }
3670 
3671  inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
3672 
3673  Clara::CommandLine<ConfigData> cli;
3674 
3675  cli.bindProcessName( &ConfigData::processName );
3676 
3677  cli.bind( &ConfigData::showHelp )
3678  .describe( "display usage information" )
3679  .shortOpt( "?")
3680  .shortOpt( "h")
3681  .longOpt( "help" );
3682 
3683  cli.bind( &ConfigData::listTests )
3684  .describe( "list all/matching test cases" )
3685  .shortOpt( "l")
3686  .longOpt( "list-tests" );
3687 
3688  cli.bind( &ConfigData::listTags )
3689  .describe( "list all/matching tags" )
3690  .shortOpt( "t")
3691  .longOpt( "list-tags" );
3692 
3693  cli.bind( &ConfigData::showSuccessfulTests )
3694  .describe( "include successful tests in output" )
3695  .shortOpt( "s")
3696  .longOpt( "success" );
3697 
3698  cli.bind( &ConfigData::shouldDebugBreak )
3699  .describe( "break into debugger on failure" )
3700  .shortOpt( "b")
3701  .longOpt( "break" );
3702 
3703  cli.bind( &ConfigData::noThrow )
3704  .describe( "skip exception tests" )
3705  .shortOpt( "e")
3706  .longOpt( "nothrow" );
3707 
3708  cli.bind( &ConfigData::outputFilename )
3709  .describe( "output filename" )
3710  .shortOpt( "o")
3711  .longOpt( "out" )
3712  .hint( "filename" );
3713 
3714  cli.bind( &ConfigData::reporterName )
3715  .describe( "reporter to use (defaults to console)" )
3716  .shortOpt( "r")
3717  .longOpt( "reporter" )
3718 // .hint( "name[:filename]" );
3719  .hint( "name" );
3720 
3721  cli.bind( &ConfigData::name )
3722  .describe( "suite name" )
3723  .shortOpt( "n")
3724  .longOpt( "name" )
3725  .hint( "name" );
3726 
3727  cli.bind( &abortAfterFirst )
3728  .describe( "abort at first failure" )
3729  .shortOpt( "a")
3730  .longOpt( "abort" );
3731 
3732  cli.bind( &abortAfterX )
3733  .describe( "abort after x failures" )
3734  .shortOpt( "x")
3735  .longOpt( "abortx" )
3736  .hint( "number of failures" );
3737 
3738  cli.bind( &addWarning )
3739  .describe( "enable warnings" )
3740  .shortOpt( "w")
3741  .longOpt( "warn" )
3742  .hint( "warning name" );
3743 
3744 // cli.bind( &setVerbosity )
3745 // .describe( "level of verbosity (0=no output)" )
3746 // .shortOpt( "v")
3747 // .longOpt( "verbosity" )
3748 // .hint( "level" );
3749 
3750  cli.bind( &addTestOrTags )
3751  .describe( "which test or tests to use" )
3752  .hint( "test name, pattern or tags" );
3753 
3754  cli.bind( &setShowDurations )
3755  .describe( "show test durations" )
3756  .shortOpt( "d")
3757  .longOpt( "durations" )
3758  .hint( "yes/no" );
3759 
3760  cli.bind( &loadTestNamesFromFile )
3761  .describe( "load test names to run from a file" )
3762  .shortOpt( "f")
3763  .longOpt( "input-file" )
3764  .hint( "filename" );
3765 
3766  // Less common commands which don't have a short form
3767  cli.bind( &ConfigData::listTestNamesOnly )
3768  .describe( "list all/matching test cases names only" )
3769  .longOpt( "list-test-names-only" );
3770 
3771  cli.bind( &ConfigData::listReporters )
3772  .describe( "list all reporters" )
3773  .longOpt( "list-reporters" );
3774 
3775  return cli;
3776  }
3777 
3778 } // end namespace Catch
3779 
3780 // #included from: internal/catch_list.hpp
3781 #define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
3782 
3783 // #included from: catch_console_colour.hpp
3784 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
3785 
3786 namespace Catch {
3787 
3788  namespace Detail {
3789  struct IColourImpl;
3790  }
3791 
3792  struct Colour {
3793  enum Code {
3794  None = 0,
3795 
3796  White,
3797  Red,
3798  Green,
3799  Blue,
3800  Cyan,
3801  Yellow,
3802  Grey,
3803 
3804  Bright = 0x10,
3805 
3806  BrightRed = Bright | Red,
3807  BrightGreen = Bright | Green,
3808  LightGrey = Bright | Grey,
3809  BrightWhite = Bright | White,
3810 
3811  // By intention
3812  FileName = LightGrey,
3813  ResultError = BrightRed,
3814  ResultSuccess = BrightGreen,
3815 
3816  Error = BrightRed,
3817  Success = Green,
3818 
3819  OriginalExpression = Cyan,
3820  ReconstructedExpression = Yellow,
3821 
3822  SecondaryText = LightGrey,
3823  Headers = White
3824  };
3825 
3826  // Use constructed object for RAII guard
3827  Colour( Code _colourCode );
3828  ~Colour();
3829 
3830  // Use static method for one-shot changes
3831  static void use( Code _colourCode );
3832 
3833  private:
3834  static Detail::IColourImpl* impl;
3835  };
3836 
3837 } // end namespace Catch
3838 
3839 // #included from: catch_interfaces_reporter.h
3840 #define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
3841 
3842 // #included from: catch_option.hpp
3843 #define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
3844 
3845 namespace Catch {
3846 
3847  // An optional type
3848  template<typename T>
3849  class Option {
3850  public:
3851  Option() : nullableValue( NULL ) {}
3852  Option( T const& _value )
3853  : nullableValue( new( storage ) T( _value ) )
3854  {}
3855  Option( Option const& _other )
3856  : nullableValue( _other ? new( storage ) T( *_other ) : NULL )
3857  {}
3858 
3859  ~Option() {
3860  reset();
3861  }
3862 
3863  Option& operator= ( Option const& _other ) {
3864  reset();
3865  if( _other )
3866  nullableValue = new( storage ) T( *_other );
3867  return *this;
3868  }
3869  Option& operator = ( T const& _value ) {
3870  reset();
3871  nullableValue = new( storage ) T( _value );
3872  return *this;
3873  }
3874 
3875  void reset() {
3876  if( nullableValue )
3877  nullableValue->~T();
3878  nullableValue = NULL;
3879  }
3880 
3881  T& operator*() { return *nullableValue; }
3882  T const& operator*() const { return *nullableValue; }
3883  T* operator->() { return nullableValue; }
3884  const T* operator->() const { return nullableValue; }
3885 
3886  T valueOr( T const& defaultValue ) const {
3887  return nullableValue ? *nullableValue : defaultValue;
3888  }
3889 
3890  bool some() const { return nullableValue != NULL; }
3891  bool none() const { return nullableValue == NULL; }
3892 
3893  bool operator !() const { return nullableValue == NULL; }
3894  operator SafeBool::type() const {
3895  return SafeBool::makeSafe( some() );
3896  }
3897 
3898  private:
3899  T* nullableValue;
3900  char storage[sizeof(T)];
3901  };
3902 
3903 } // end namespace Catch
3904 
3905 #include <string>
3906 #include <ostream>
3907 #include <map>
3908 #include <assert.h>
3909 
3910 namespace Catch
3911 {
3912  struct ReporterConfig {
3913  explicit ReporterConfig( Ptr<IConfig> const& _fullConfig )
3914  : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
3915 
3916  ReporterConfig( Ptr<IConfig> const& _fullConfig, std::ostream& _stream )
3917  : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
3918 
3919  std::ostream& stream() const { return *m_stream; }
3920  Ptr<IConfig> fullConfig() const { return m_fullConfig; }
3921 
3922  private:
3923  std::ostream* m_stream;
3924  Ptr<IConfig> m_fullConfig;
3925  };
3926 
3927  struct ReporterPreferences {
3928  ReporterPreferences()
3929  : shouldRedirectStdOut( false )
3930  {}
3931 
3932  bool shouldRedirectStdOut;
3933  };
3934 
3935  template<typename T>
3936  struct LazyStat : Option<T> {
3937  LazyStat() : used( false ) {}
3938  LazyStat& operator=( T const& _value ) {
3939  Option<T>::operator=( _value );
3940  used = false;
3941  return *this;
3942  }
3943  void reset() {
3944  Option<T>::reset();
3945  used = false;
3946  }
3947  bool used;
3948  };
3949 
3950  struct TestRunInfo {
3951  TestRunInfo( std::string const& _name ) : name( _name ) {}
3952  std::string name;
3953  };
3954  struct GroupInfo {
3955  GroupInfo( std::string const& _name,
3956  std::size_t _groupIndex,
3957  std::size_t _groupsCount )
3958  : name( _name ),
3959  groupIndex( _groupIndex ),
3960  groupsCounts( _groupsCount )
3961  {}
3962 
3963  std::string name;
3964  std::size_t groupIndex;
3965  std::size_t groupsCounts;
3966  };
3967 
3968  struct AssertionStats {
3969  AssertionStats( AssertionResult const& _assertionResult,
3970  std::vector<MessageInfo> const& _infoMessages,
3971  Totals const& _totals )
3972  : assertionResult( _assertionResult ),
3973  infoMessages( _infoMessages ),
3974  totals( _totals )
3975  {
3976  if( assertionResult.hasMessage() ) {
3977  // Copy message into messages list.
3978  // !TBD This should have been done earlier, somewhere
3979  MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
3980  builder << assertionResult.getMessage();
3981  builder.m_info.message = builder.m_stream.str();
3982 
3983  infoMessages.push_back( builder.m_info );
3984  }
3985  }
3986  virtual ~AssertionStats();
3987 
3988  AssertionResult assertionResult;
3989  std::vector<MessageInfo> infoMessages;
3990  Totals totals;
3991  };
3992 
3993  struct SectionStats {
3994  SectionStats( SectionInfo const& _sectionInfo,
3995  Counts const& _assertions,
3996  double _durationInSeconds,
3997  bool _missingAssertions )
3998  : sectionInfo( _sectionInfo ),
3999  assertions( _assertions ),
4000  durationInSeconds( _durationInSeconds ),
4001  missingAssertions( _missingAssertions )
4002  {}
4003  virtual ~SectionStats();
4004 
4005  SectionInfo sectionInfo;
4006  Counts assertions;
4007  double durationInSeconds;
4008  bool missingAssertions;
4009  };
4010 
4011  struct TestCaseStats {
4012  TestCaseStats( TestCaseInfo const& _testInfo,
4013  Totals const& _totals,
4014  std::string const& _stdOut,
4015  std::string const& _stdErr,
4016  bool _aborting )
4017  : testInfo( _testInfo ),
4018  totals( _totals ),
4019  stdOut( _stdOut ),
4020  stdErr( _stdErr ),
4021  aborting( _aborting )
4022  {}
4023  virtual ~TestCaseStats();
4024 
4025  TestCaseInfo testInfo;
4026  Totals totals;
4027  std::string stdOut;
4028  std::string stdErr;
4029  bool aborting;
4030  };
4031 
4032  struct TestGroupStats {
4033  TestGroupStats( GroupInfo const& _groupInfo,
4034  Totals const& _totals,
4035  bool _aborting )
4036  : groupInfo( _groupInfo ),
4037  totals( _totals ),
4038  aborting( _aborting )
4039  {}
4040  TestGroupStats( GroupInfo const& _groupInfo )
4041  : groupInfo( _groupInfo ),
4042  aborting( false )
4043  {}
4044  virtual ~TestGroupStats();
4045 
4046  GroupInfo groupInfo;
4047  Totals totals;
4048  bool aborting;
4049  };
4050 
4051  struct TestRunStats {
4052  TestRunStats( TestRunInfo const& _runInfo,
4053  Totals const& _totals,
4054  bool _aborting )
4055  : runInfo( _runInfo ),
4056  totals( _totals ),
4057  aborting( _aborting )
4058  {}
4059  TestRunStats( TestRunStats const& _other )
4060  : runInfo( _other.runInfo ),
4061  totals( _other.totals ),
4062  aborting( _other.aborting )
4063  {}
4064  virtual ~TestRunStats();
4065 
4066  TestRunInfo runInfo;
4067  Totals totals;
4068  bool aborting;
4069  };
4070 
4071  struct IStreamingReporter : IShared {
4072  virtual ~IStreamingReporter();
4073 
4074  // Implementing class must also provide the following static method:
4075  // static std::string getDescription();
4076 
4077  virtual ReporterPreferences getPreferences() const = 0;
4078 
4079  virtual void noMatchingTestCases( std::string const& spec ) = 0;
4080 
4081  virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
4082  virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
4083 
4084  virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
4085  virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
4086 
4087  virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
4088 
4089  virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
4090  virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
4091  virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
4092  virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
4093  virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
4094  };
4095 
4096  struct IReporterFactory {
4097  virtual ~IReporterFactory();
4098  virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
4099  virtual std::string getDescription() const = 0;
4100  };
4101 
4102  struct IReporterRegistry {
4103  typedef std::map<std::string, IReporterFactory*> FactoryMap;
4104 
4105  virtual ~IReporterRegistry();
4106  virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const = 0;
4107  virtual FactoryMap const& getFactories() const = 0;
4108  };
4109 
4110 }
4111 
4112 #include <limits>
4113 #include <algorithm>
4114 
4115 namespace Catch {
4116  inline bool matchesFilters( std::vector<TestCaseFilters> const& filters, TestCase const& testCase ) {
4117  std::vector<TestCaseFilters>::const_iterator it = filters.begin();
4118  std::vector<TestCaseFilters>::const_iterator itEnd = filters.end();
4119  for(; it != itEnd; ++it )
4120  if( !it->shouldInclude( testCase ) )
4121  return false;
4122  return true;
4123  }
4124 
4125  inline std::size_t listTests( Config const& config ) {
4126  if( config.filters().empty() )
4127  std::cout << "All available test cases:\n";
4128  else
4129  std::cout << "Matching test cases:\n";
4130 
4131  std::size_t matchedTests = 0;
4132  TextAttributes nameAttr, tagsAttr;
4133  nameAttr.setInitialIndent( 2 ).setIndent( 4 );
4134  tagsAttr.setIndent( 6 );
4135 
4136  std::vector<TestCase> const& allTests = getRegistryHub().getTestCaseRegistry().getAllTests();
4137  for( std::vector<TestCase>::const_iterator it = allTests.begin(), itEnd = allTests.end();
4138  it != itEnd;
4139  ++it )
4140  if( matchesFilters( config.filters(), *it ) ) {
4141  matchedTests++;
4142  TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
4143  Colour::Code colour = testCaseInfo.isHidden
4144  ? Colour::SecondaryText
4145  : Colour::None;
4146  Colour colourGuard( colour );
4147 
4148  std::cout << Text( testCaseInfo.name, nameAttr ) << std::endl;
4149  if( !testCaseInfo.tags.empty() )
4150  std::cout << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
4151  }
4152 
4153  if( config.filters().empty() )
4154  std::cout << pluralise( matchedTests, "test case" ) << "\n" << std::endl;
4155  else
4156  std::cout << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl;
4157  return matchedTests;
4158  }
4159 
4160  inline std::size_t listTestsNamesOnly( Config const& config ) {
4161  std::size_t matchedTests = 0;
4162  std::vector<TestCase> const& allTests = getRegistryHub().getTestCaseRegistry().getAllTests();
4163  for( std::vector<TestCase>::const_iterator it = allTests.begin(), itEnd = allTests.end();
4164  it != itEnd;
4165  ++it )
4166  if( matchesFilters( config.filters(), *it ) ) {
4167  matchedTests++;
4168  TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
4169  std::cout << testCaseInfo.name << std::endl;
4170  }
4171  return matchedTests;
4172  }
4173 
4174  inline std::size_t listTags( Config const& config ) {
4175  if( config.filters().empty() )
4176  std::cout << "All available tags:\n";
4177  else
4178  std::cout << "Matching tags:\n";
4179 
4180  std::map<std::string, int> tagCounts;
4181 
4182  std::vector<TestCase> const& allTests = getRegistryHub().getTestCaseRegistry().getAllTests();
4183  for( std::vector<TestCase>::const_iterator it = allTests.begin(),
4184  itEnd = allTests.end();
4185  it != itEnd;
4186  ++it ) {
4187  if( matchesFilters( config.filters(), *it ) ) {
4188  for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(),
4189  tagItEnd = it->getTestCaseInfo().tags.end();
4190  tagIt != tagItEnd;
4191  ++tagIt ) {
4192  std::string tagName = *tagIt;
4193  std::map<std::string, int>::iterator countIt = tagCounts.find( tagName );
4194  if( countIt == tagCounts.end() )
4195  tagCounts.insert( std::make_pair( tagName, 1 ) );
4196  else
4197  countIt->second++;
4198  }
4199  }
4200  }
4201 
4202  for( std::map<std::string, int>::const_iterator countIt = tagCounts.begin(),
4203  countItEnd = tagCounts.end();
4204  countIt != countItEnd;
4205  ++countIt ) {
4206  std::ostringstream oss;
4207  oss << " " << countIt->second << " ";
4208  Text wrapper( "[" + countIt->first + "]", TextAttributes()
4209  .setInitialIndent( 0 )
4210  .setIndent( oss.str().size() )
4211  .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
4212  std::cout << oss.str() << wrapper << "\n";
4213  }
4214  std::cout << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl;
4215  return tagCounts.size();
4216  }
4217 
4218  inline std::size_t listReporters( Config const& /*config*/ ) {
4219  std::cout << "Available reports:\n";
4220  IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
4221  IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
4222  std::size_t maxNameLen = 0;
4223  for(it = itBegin; it != itEnd; ++it )
4224  maxNameLen = (std::max)( maxNameLen, it->first.size() );
4225 
4226  for(it = itBegin; it != itEnd; ++it ) {
4227  Text wrapper( it->second->getDescription(), TextAttributes()
4228  .setInitialIndent( 0 )
4229  .setIndent( 7+maxNameLen )
4230  .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
4231  std::cout << " "
4232  << it->first
4233  << ":"
4234  << std::string( maxNameLen - it->first.size() + 2, ' ' )
4235  << wrapper << "\n";
4236  }
4237  std::cout << std::endl;
4238  return factories.size();
4239  }
4240 
4241  inline Option<std::size_t> list( Config const& config ) {
4242  Option<std::size_t> listedCount;
4243  if( config.listTests() )
4244  listedCount = listedCount.valueOr(0) + listTests( config );
4245  if( config.listTestNamesOnly() )
4246  listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
4247  if( config.listTags() )
4248  listedCount = listedCount.valueOr(0) + listTags( config );
4249  if( config.listReporters() )
4250  listedCount = listedCount.valueOr(0) + listReporters( config );
4251  return listedCount;
4252  }
4253 
4254 } // end namespace Catch
4255 
4256 // #included from: internal/catch_runner_impl.hpp
4257 #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
4258 
4259 // #included from: catch_test_case_tracker.hpp
4260 #define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
4261 
4262 #include <map>
4263 #include <string>
4264 #include <assert.h>
4265 
4266 namespace Catch {
4267 namespace SectionTracking {
4268 
4269  class TrackedSection {
4270 
4271  typedef std::map<std::string, TrackedSection> TrackedSections;
4272 
4273  public:
4274  enum RunState {
4275  NotStarted,
4276  Executing,
4277  ExecutingChildren,
4278  Completed
4279  };
4280 
4281  TrackedSection( std::string const& name, TrackedSection* parent )
4282  : m_name( name ), m_runState( NotStarted ), m_parent( parent )
4283  {}
4284 
4285  RunState runState() const { return m_runState; }
4286 
4287  void addChild( std::string const& childName ) {
4288  m_children.insert( std::make_pair( childName, TrackedSection( childName, this ) ) );
4289  }
4290  TrackedSection* getChild( std::string const& childName ) {
4291  return &m_children.find( childName )->second;
4292  }
4293 
4294  void enter() {
4295  if( m_runState == NotStarted )
4296  m_runState = Executing;
4297  }
4298  void leave() {
4299  for( TrackedSections::const_iterator it = m_children.begin(), itEnd = m_children.end();
4300  it != itEnd;
4301  ++it )
4302  if( it->second.runState() != Completed ) {
4303  m_runState = ExecutingChildren;
4304  return;
4305  }
4306  m_runState = Completed;
4307  }
4308  TrackedSection* getParent() {
4309  return m_parent;
4310  }
4311  bool hasChildren() const {
4312  return !m_children.empty();
4313  }
4314 
4315  private:
4316  std::string m_name;
4317  RunState m_runState;
4318  TrackedSections m_children;
4319  TrackedSection* m_parent;
4320 
4321  };
4322 
4323  class TestCaseTracker {
4324  public:
4325  TestCaseTracker( std::string const& testCaseName )
4326  : m_testCase( testCaseName, NULL ),
4327  m_currentSection( &m_testCase ),
4328  m_completedASectionThisRun( false )
4329  {}
4330 
4331  bool enterSection( std::string const& name ) {
4332  if( m_completedASectionThisRun )
4333  return false;
4334  if( m_currentSection->runState() == TrackedSection::Executing ) {
4335  m_currentSection->addChild( name );
4336  return false;
4337  }
4338  else {
4339  TrackedSection* child = m_currentSection->getChild( name );
4340  if( child->runState() != TrackedSection::Completed ) {
4341  m_currentSection = child;
4342  m_currentSection->enter();
4343  return true;
4344  }
4345  return false;
4346  }
4347  }
4348  void leaveSection() {
4349  m_currentSection->leave();
4350  m_currentSection = m_currentSection->getParent();
4351  assert( m_currentSection != NULL );
4352  m_completedASectionThisRun = true;
4353  }
4354 
4355  bool currentSectionHasChildren() const {
4356  return m_currentSection->hasChildren();
4357  }
4358  bool isCompleted() const {
4359  return m_testCase.runState() == TrackedSection::Completed;
4360  }
4361 
4362  class Guard {
4363  public:
4364  Guard( TestCaseTracker& tracker )
4365  : m_tracker( tracker )
4366  {
4367  m_tracker.enterTestCase();
4368  }
4369  ~Guard() {
4370  m_tracker.leaveTestCase();
4371  }
4372  private:
4373  Guard( Guard const& );
4374  void operator = ( Guard const& );
4375  TestCaseTracker& m_tracker;
4376  };
4377 
4378  private:
4379  void enterTestCase() {
4380  m_currentSection = &m_testCase;
4381  m_completedASectionThisRun = false;
4382  m_testCase.enter();
4383  }
4384  void leaveTestCase() {
4385  m_testCase.leave();
4386  }
4387 
4388  TrackedSection m_testCase;
4389  TrackedSection* m_currentSection;
4390  bool m_completedASectionThisRun;
4391  };
4392 
4393 } // namespace SectionTracking
4394 
4395 using SectionTracking::TestCaseTracker;
4396 
4397 } // namespace Catch
4398 
4399 #include <set>
4400 #include <string>
4401 
4402 namespace Catch {
4403 
4404  class StreamRedirect {
4405 
4406  public:
4407  StreamRedirect( std::ostream& stream, std::string& targetString )
4408  : m_stream( stream ),
4409  m_prevBuf( stream.rdbuf() ),
4410  m_targetString( targetString )
4411  {
4412  stream.rdbuf( m_oss.rdbuf() );
4413  }
4414 
4415  ~StreamRedirect() {
4416  m_targetString += m_oss.str();
4417  m_stream.rdbuf( m_prevBuf );
4418  }
4419 
4420  private:
4421  std::ostream& m_stream;
4422  std::streambuf* m_prevBuf;
4423  std::ostringstream m_oss;
4424  std::string& m_targetString;
4425  };
4426 
4428 
4429  class RunContext : public IResultCapture, public IRunner {
4430 
4431  RunContext( RunContext const& );
4432  void operator =( RunContext const& );
4433 
4434  public:
4435 
4436  explicit RunContext( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> const& reporter )
4437  : m_runInfo( config->name() ),
4438  m_context( getCurrentMutableContext() ),
4439  m_activeTestCase( NULL ),
4440  m_config( config ),
4441  m_reporter( reporter ),
4442  m_prevRunner( &m_context.getRunner() ),
4443  m_prevResultCapture( &m_context.getResultCapture() ),
4444  m_prevConfig( m_context.getConfig() )
4445  {
4446  m_context.setRunner( this );
4447  m_context.setConfig( m_config );
4448  m_context.setResultCapture( this );
4449  m_reporter->testRunStarting( m_runInfo );
4450  }
4451 
4452  virtual ~RunContext() {
4453  m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
4454  m_context.setRunner( m_prevRunner );
4455  m_context.setConfig( NULL );
4456  m_context.setResultCapture( m_prevResultCapture );
4457  m_context.setConfig( m_prevConfig );
4458  }
4459 
4460  void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
4461  m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
4462  }
4463  void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
4464  m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
4465  }
4466 
4467  Totals runMatching( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
4468 
4469  std::vector<TestCase> matchingTests = getRegistryHub().getTestCaseRegistry().getMatchingTestCases( testSpec );
4470 
4471  Totals totals;
4472 
4473  testGroupStarting( testSpec, groupIndex, groupsCount );
4474 
4475  std::vector<TestCase>::const_iterator it = matchingTests.begin();
4476  std::vector<TestCase>::const_iterator itEnd = matchingTests.end();
4477  for(; it != itEnd; ++it )
4478  totals += runTest( *it );
4479 
4480  testGroupEnded( testSpec, totals, groupIndex, groupsCount );
4481  return totals;
4482  }
4483 
4484  Totals runTest( TestCase const& testCase ) {
4485  Totals prevTotals = m_totals;
4486 
4487  std::string redirectedCout;
4488  std::string redirectedCerr;
4489 
4490  TestCaseInfo testInfo = testCase.getTestCaseInfo();
4491 
4492  m_reporter->testCaseStarting( testInfo );
4493 
4494  m_activeTestCase = &testCase;
4495  m_testCaseTracker = TestCaseTracker( testInfo.name );
4496 
4497  do {
4498  do {
4499  runCurrentTest( redirectedCout, redirectedCerr );
4500  }
4501  while( !m_testCaseTracker->isCompleted() && !aborting() );
4502  }
4503  while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
4504 
4505  Totals deltaTotals = m_totals.delta( prevTotals );
4506  m_totals.testCases += deltaTotals.testCases;
4507  m_reporter->testCaseEnded( TestCaseStats( testInfo,
4508  deltaTotals,
4509  redirectedCout,
4510  redirectedCerr,
4511  aborting() ) );
4512 
4513  m_activeTestCase = NULL;
4514  m_testCaseTracker.reset();
4515 
4516  return deltaTotals;
4517  }
4518 
4519  Ptr<IConfig const> config() const {
4520  return m_config;
4521  }
4522 
4523  private: // IResultCapture
4524 
4525  virtual ResultAction::Value acceptExpression( ExpressionResultBuilder const& assertionResult, AssertionInfo const& assertionInfo ) {
4526  m_lastAssertionInfo = assertionInfo;
4527  return actOnCurrentResult( assertionResult.buildResult( assertionInfo ) );
4528  }
4529 
4530  virtual void assertionEnded( AssertionResult const& result ) {
4531  if( result.getResultType() == ResultWas::Ok ) {
4532  m_totals.assertions.passed++;
4533  }
4534  else if( !result.isOk() ) {
4535  m_totals.assertions.failed++;
4536  }
4537 
4538  if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
4539  m_messages.clear();
4540 
4541  // Reset working state
4542  m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
4543  }
4544 
4545  virtual bool sectionStarted (
4546  SectionInfo const& sectionInfo,
4547  Counts& assertions
4548  )
4549  {
4550  std::ostringstream oss;
4551  oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
4552 
4553  if( !m_testCaseTracker->enterSection( oss.str() ) )
4554  return false;
4555 
4556  m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
4557 
4558  m_reporter->sectionStarting( sectionInfo );
4559 
4560  assertions = m_totals.assertions;
4561 
4562  return true;
4563  }
4564  bool testForMissingAssertions( Counts& assertions ) {
4565  if( assertions.total() != 0 ||
4566  !m_config->warnAboutMissingAssertions() ||
4567  m_testCaseTracker->currentSectionHasChildren() )
4568  return false;
4569  m_totals.assertions.failed++;
4570  assertions.failed++;
4571  return true;
4572  }
4573 
4574  virtual void sectionEnded( SectionInfo const& info, Counts const& prevAssertions, double _durationInSeconds ) {
4575  if( std::uncaught_exception() ) {
4576  m_unfinishedSections.push_back( UnfinishedSections( info, prevAssertions, _durationInSeconds ) );
4577  return;
4578  }
4579 
4580  Counts assertions = m_totals.assertions - prevAssertions;
4581  bool missingAssertions = testForMissingAssertions( assertions );
4582 
4583  m_testCaseTracker->leaveSection();
4584 
4585  m_reporter->sectionEnded( SectionStats( info, assertions, _durationInSeconds, missingAssertions ) );
4586  m_messages.clear();
4587  }
4588 
4589  virtual void pushScopedMessage( MessageInfo const& message ) {
4590  m_messages.push_back( message );
4591  }
4592 
4593  virtual void popScopedMessage( MessageInfo const& message ) {
4594  m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
4595  }
4596 
4597  virtual bool shouldDebugBreak() const {
4598  return m_config->shouldDebugBreak();
4599  }
4600 
4601  virtual std::string getCurrentTestName() const {
4602  return m_activeTestCase
4603  ? m_activeTestCase->getTestCaseInfo().name
4604  : "";
4605  }
4606 
4607  virtual const AssertionResult* getLastResult() const {
4608  return &m_lastResult;
4609  }
4610 
4611  public:
4612  // !TBD We need to do this another way!
4613  bool aborting() const {
4614  return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
4615  }
4616 
4617  private:
4618 
4619  ResultAction::Value actOnCurrentResult( AssertionResult const& result ) {
4620  m_lastResult = result;
4621  assertionEnded( m_lastResult );
4622 
4624 
4625  if( !m_lastResult.isOk() ) {
4626  action = ResultAction::Failed;
4627  if( shouldDebugBreak() )
4628  action = (ResultAction::Value)( action | ResultAction::Debug );
4629  if( aborting() )
4630  action = (ResultAction::Value)( action | ResultAction::Abort );
4631  }
4632  return action;
4633  }
4634 
4635  void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
4636  TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
4637  SectionInfo testCaseSection( testCaseInfo.name, testCaseInfo.description, testCaseInfo.lineInfo );
4638  m_reporter->sectionStarting( testCaseSection );
4639  Counts prevAssertions = m_totals.assertions;
4640  double duration = 0;
4641  try {
4642  m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
4643  TestCaseTracker::Guard guard( *m_testCaseTracker );
4644 
4645  Timer timer;
4646  timer.start();
4647  if( m_reporter->getPreferences().shouldRedirectStdOut ) {
4648  StreamRedirect coutRedir( std::cout, redirectedCout );
4649  StreamRedirect cerrRedir( std::cerr, redirectedCerr );
4650  m_activeTestCase->invoke();
4651  }
4652  else {
4653  m_activeTestCase->invoke();
4654  }
4655  duration = timer.getElapsedSeconds();
4656  }
4657  catch( TestFailureException& ) {
4658  // This just means the test was aborted due to failure
4659  }
4660  catch(...) {
4661  ExpressionResultBuilder exResult( ResultWas::ThrewException );
4662  exResult << translateActiveException();
4663  actOnCurrentResult( exResult.buildResult( m_lastAssertionInfo ) );
4664  }
4665  // If sections ended prematurely due to an exception we stored their
4666  // infos here so we can tear them down outside the unwind process.
4667  for( std::vector<UnfinishedSections>::const_iterator it = m_unfinishedSections.begin(),
4668  itEnd = m_unfinishedSections.end();
4669  it != itEnd;
4670  ++it )
4671  sectionEnded( it->info, it->prevAssertions, it->durationInSeconds );
4672  m_unfinishedSections.clear();
4673  m_messages.clear();
4674 
4675  Counts assertions = m_totals.assertions - prevAssertions;
4676  bool missingAssertions = testForMissingAssertions( assertions );
4677 
4678  SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
4679  m_reporter->sectionEnded( testCaseSectionStats );
4680  }
4681 
4682  private:
4683  struct UnfinishedSections {
4684  UnfinishedSections( SectionInfo const& _info, Counts const& _prevAssertions, double _durationInSeconds )
4685  : info( _info ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
4686  {}
4687 
4688  SectionInfo info;
4689  Counts prevAssertions;
4690  double durationInSeconds;
4691  };
4692 
4693  TestRunInfo m_runInfo;
4694  IMutableContext& m_context;
4695  TestCase const* m_activeTestCase;
4696  Option<TestCaseTracker> m_testCaseTracker;
4697  AssertionResult m_lastResult;
4698 
4699  Ptr<IConfig const> m_config;
4700  Totals m_totals;
4701  Ptr<IStreamingReporter> m_reporter;
4702  std::vector<MessageInfo> m_messages;
4703  IRunner* m_prevRunner;
4704  IResultCapture* m_prevResultCapture;
4705  Ptr<IConfig const> m_prevConfig;
4706  AssertionInfo m_lastAssertionInfo;
4707  std::vector<UnfinishedSections> m_unfinishedSections;
4708  };
4709 
4710 } // end namespace Catch
4711 
4712 // #included from: internal/catch_version.h
4713 #define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
4714 
4715 namespace Catch {
4716 
4717  // Versioning information
4718  struct Version {
4719  Version( unsigned int _majorVersion,
4720  unsigned int _minorVersion,
4721  unsigned int _buildNumber,
4722  std::string const& _branchName )
4723  : majorVersion( _majorVersion ),
4724  minorVersion( _minorVersion ),
4725  buildNumber( _buildNumber ),
4726  branchName( _branchName )
4727  {}
4728 
4729  const unsigned int majorVersion;
4730  const unsigned int minorVersion;
4731  const unsigned int buildNumber;
4732  const std::string branchName;
4733 
4734  private:
4735  void operator=( Version const& );
4736  };
4737 
4738  extern Version libraryVersion;
4739 }
4740 
4741 #include <fstream>
4742 #include <stdlib.h>
4743 #include <limits>
4744 
4745 namespace Catch {
4746 
4747  class Runner {
4748 
4749  public:
4750  Runner( Ptr<Config> const& config )
4751  : m_config( config )
4752  {
4753  openStream();
4754  makeReporter();
4755  }
4756 
4757  Totals runTests() {
4758 
4759  std::vector<TestCaseFilters> filterGroups = m_config->filters();
4760  if( filterGroups.empty() ) {
4761  TestCaseFilters filterGroup( "" );
4762  filterGroups.push_back( filterGroup );
4763  }
4764 
4765  RunContext context( m_config.get(), m_reporter );
4766 
4767  Totals totals;
4768 
4769  for( std::size_t i=0; i < filterGroups.size() && !context.aborting(); ++i ) {
4770  context.testGroupStarting( filterGroups[i].getName(), i, filterGroups.size() );
4771  totals += runTestsForGroup( context, filterGroups[i] );
4772  context.testGroupEnded( filterGroups[i].getName(), totals, i, filterGroups.size() );
4773  }
4774  return totals;
4775  }
4776 
4777  Totals runTestsForGroup( RunContext& context, const TestCaseFilters& filterGroup ) {
4778  Totals totals;
4779  std::vector<TestCase>::const_iterator it = getRegistryHub().getTestCaseRegistry().getAllTests().begin();
4780  std::vector<TestCase>::const_iterator itEnd = getRegistryHub().getTestCaseRegistry().getAllTests().end();
4781  int testsRunForGroup = 0;
4782  for(; it != itEnd; ++it ) {
4783  if( filterGroup.shouldInclude( *it ) ) {
4784  testsRunForGroup++;
4785  if( m_testsAlreadyRun.find( *it ) == m_testsAlreadyRun.end() ) {
4786 
4787  if( context.aborting() )
4788  break;
4789 
4790  totals += context.runTest( *it );
4791  m_testsAlreadyRun.insert( *it );
4792  }
4793  }
4794  }
4795  if( testsRunForGroup == 0 && !filterGroup.getName().empty() )
4796  m_reporter->noMatchingTestCases( filterGroup.getName() );
4797  return totals;
4798 
4799  }
4800 
4801  private:
4802  void openStream() {
4803  // Open output file, if specified
4804  if( !m_config->getFilename().empty() ) {
4805  m_ofs.open( m_config->getFilename().c_str() );
4806  if( m_ofs.fail() ) {
4807  std::ostringstream oss;
4808  oss << "Unable to open file: '" << m_config->getFilename() << "'";
4809  throw std::domain_error( oss.str() );
4810  }
4811  m_config->setStreamBuf( m_ofs.rdbuf() );
4812  }
4813  }
4814  void makeReporter() {
4815  std::string reporterName = m_config->getReporterName().empty()
4816  ? "console"
4817  : m_config->getReporterName();
4818 
4819  m_reporter = getRegistryHub().getReporterRegistry().create( reporterName, m_config.get() );
4820  if( !m_reporter ) {
4821  std::ostringstream oss;
4822  oss << "No reporter registered with name: '" << reporterName << "'";
4823  throw std::domain_error( oss.str() );
4824  }
4825  }
4826 
4827  private:
4828  Ptr<Config> m_config;
4829  std::ofstream m_ofs;
4830  Ptr<IStreamingReporter> m_reporter;
4831  std::set<TestCase> m_testsAlreadyRun;
4832  };
4833 
4834  class Session {
4835  static bool alreadyInstantiated;
4836 
4837  public:
4838 
4839  struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
4840 
4841  Session()
4842  : m_cli( makeCommandLineParser() ) {
4843  if( alreadyInstantiated ) {
4844  std::string msg = "Only one instance of Catch::Session can ever be used";
4845  std::cerr << msg << std::endl;
4846  throw std::logic_error( msg );
4847  }
4848  alreadyInstantiated = true;
4849  }
4850  ~Session() {
4851  Catch::cleanUp();
4852  }
4853 
4854  void showHelp( std::string const& processName ) {
4855  std::cout << "\nCatch v" << libraryVersion.majorVersion << "."
4856  << libraryVersion.minorVersion << " build "
4857  << libraryVersion.buildNumber;
4858  if( libraryVersion.branchName != "master" )
4859  std::cout << " (" << libraryVersion.branchName << " branch)";
4860  std::cout << "\n";
4861 
4862  m_cli.usage( std::cout, processName );
4863  std::cout << "For more detail usage please see the project docs\n" << std::endl;
4864  }
4865 
4866  int applyCommandLine( int argc, char* const argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
4867  try {
4868  m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
4869  m_unusedTokens = m_cli.parseInto( argc, argv, m_configData );
4870  if( m_configData.showHelp )
4871  showHelp( m_configData.processName );
4872  m_config.reset();
4873  }
4874  catch( std::exception& ex ) {
4875  {
4876  Colour colourGuard( Colour::Red );
4877  std::cerr << "\nError(s) in input:\n"
4878  << Text( ex.what(), TextAttributes().setIndent(2) )
4879  << "\n\n";
4880  }
4881  m_cli.usage( std::cout, m_configData.processName );
4882  return (std::numeric_limits<int>::max)();
4883  }
4884  return 0;
4885  }
4886 
4887  void useConfigData( ConfigData const& _configData ) {
4888  m_configData = _configData;
4889  m_config.reset();
4890  }
4891 
4892  int run( int argc, char* const argv[] ) {
4893 
4894  int returnCode = applyCommandLine( argc, argv );
4895  if( returnCode == 0 )
4896  returnCode = run();
4897  return returnCode;
4898  }
4899 
4900  int run() {
4901  if( m_configData.showHelp )
4902  return 0;
4903 
4904  try
4905  {
4906  config(); // Force config to be constructed
4907  Runner runner( m_config );
4908 
4909  // Handle list request
4910  if( Option<std::size_t> listed = list( config() ) )
4911  return static_cast<int>( *listed );
4912 
4913  return static_cast<int>( runner.runTests().assertions.failed );
4914  }
4915  catch( std::exception& ex ) {
4916  std::cerr << ex.what() << std::endl;
4917  return (std::numeric_limits<int>::max)();
4918  }
4919  }
4920 
4921  Clara::CommandLine<ConfigData> const& cli() const {
4922  return m_cli;
4923  }
4924  std::vector<Clara::Parser::Token> const& unusedTokens() const {
4925  return m_unusedTokens;
4926  }
4927  ConfigData& configData() {
4928  return m_configData;
4929  }
4930  Config& config() {
4931  if( !m_config )
4932  m_config = new Config( m_configData );
4933  return *m_config;
4934  }
4935 
4936  private:
4937  Clara::CommandLine<ConfigData> m_cli;
4938  std::vector<Clara::Parser::Token> m_unusedTokens;
4939  ConfigData m_configData;
4940  Ptr<Config> m_config;
4941  };
4942 
4943  bool Session::alreadyInstantiated = false;
4944 
4945 } // end namespace Catch
4946 
4947 // #included from: catch_registry_hub.hpp
4948 #define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
4949 
4950 // #included from: catch_test_case_registry_impl.hpp
4951 #define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
4952 
4953 #include <vector>
4954 #include <set>
4955 #include <sstream>
4956 #include <iostream>
4957 
4958 namespace Catch {
4959 
4960  class TestRegistry : public ITestCaseRegistry {
4961  public:
4962  TestRegistry() : m_unnamedCount( 0 ) {}
4963  virtual ~TestRegistry();
4964 
4965  virtual void registerTest( TestCase const& testCase ) {
4966  std::string name = testCase.getTestCaseInfo().name;
4967  if( name == "" ) {
4968  std::ostringstream oss;
4969  oss << "Anonymous test case " << ++m_unnamedCount;
4970  return registerTest( testCase.withName( oss.str() ) );
4971  }
4972 
4973  if( m_functions.find( testCase ) == m_functions.end() ) {
4974  m_functions.insert( testCase );
4975  m_functionsInOrder.push_back( testCase );
4976  if( !testCase.isHidden() )
4977  m_nonHiddenFunctions.push_back( testCase );
4978  }
4979  else {
4980  TestCase const& prev = *m_functions.find( testCase );
4981  std::cerr << "error: TEST_CASE( \"" << name << "\" ) already defined.\n"
4982  << "\tFirst seen at " << prev.getTestCaseInfo().lineInfo << "\n"
4983  << "\tRedefined at " << testCase.getTestCaseInfo().lineInfo << std::endl;
4984  exit(1);
4985  }
4986  }
4987 
4988  virtual std::vector<TestCase> const& getAllTests() const {
4989  return m_functionsInOrder;
4990  }
4991 
4992  virtual std::vector<TestCase> const& getAllNonHiddenTests() const {
4993  return m_nonHiddenFunctions;
4994  }
4995 
4996  // !TBD deprecated
4997  virtual std::vector<TestCase> getMatchingTestCases( std::string const& rawTestSpec ) const {
4998  std::vector<TestCase> matchingTests;
4999  getMatchingTestCases( rawTestSpec, matchingTests );
5000  return matchingTests;
5001  }
5002 
5003  // !TBD deprecated
5004  virtual void getMatchingTestCases( std::string const& rawTestSpec, std::vector<TestCase>& matchingTestsOut ) const {
5005  TestCaseFilter filter( rawTestSpec );
5006 
5007  std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin();
5008  std::vector<TestCase>::const_iterator itEnd = m_functionsInOrder.end();
5009  for(; it != itEnd; ++it ) {
5010  if( filter.shouldInclude( *it ) ) {
5011  matchingTestsOut.push_back( *it );
5012  }
5013  }
5014  }
5015  virtual void getMatchingTestCases( TestCaseFilters const& filters, std::vector<TestCase>& matchingTestsOut ) const {
5016  std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin();
5017  std::vector<TestCase>::const_iterator itEnd = m_functionsInOrder.end();
5018  // !TBD: replace with algorithm
5019  for(; it != itEnd; ++it )
5020  if( filters.shouldInclude( *it ) )
5021  matchingTestsOut.push_back( *it );
5022  }
5023 
5024  private:
5025 
5026  std::set<TestCase> m_functions;
5027  std::vector<TestCase> m_functionsInOrder;
5028  std::vector<TestCase> m_nonHiddenFunctions;
5029  size_t m_unnamedCount;
5030  };
5031 
5033 
5034  class FreeFunctionTestCase : public SharedImpl<ITestCase> {
5035  public:
5036 
5037  FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
5038 
5039  virtual void invoke() const {
5040  m_fun();
5041  }
5042 
5043  private:
5044  virtual ~FreeFunctionTestCase();
5045 
5046  TestFunction m_fun;
5047  };
5048 
5049  inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
5050  std::string className = classOrQualifiedMethodName;
5051  if( startsWith( className, "&" ) )
5052  {
5053  std::size_t lastColons = className.rfind( "::" );
5054  std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
5055  if( penultimateColons == std::string::npos )
5056  penultimateColons = 1;
5057  className = className.substr( penultimateColons, lastColons-penultimateColons );
5058  }
5059  return className;
5060  }
5061 
5063 
5064  AutoReg::AutoReg( TestFunction function,
5065  SourceLineInfo const& lineInfo,
5066  NameAndDesc const& nameAndDesc ) {
5067  registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
5068  }
5069 
5070  AutoReg::~AutoReg() {}
5071 
5072  void AutoReg::registerTestCase( ITestCase* testCase,
5073  char const* classOrQualifiedMethodName,
5074  NameAndDesc const& nameAndDesc,
5075  SourceLineInfo const& lineInfo ) {
5076 
5078  ( makeTestCase( testCase,
5079  extractClassName( classOrQualifiedMethodName ),
5080  nameAndDesc.name,
5081  nameAndDesc.description,
5082  lineInfo ) );
5083  }
5084 
5085 } // end namespace Catch
5086 
5087 // #included from: catch_reporter_registry.hpp
5088 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
5089 
5090 #include <map>
5091 
5092 namespace Catch {
5093 
5094  class ReporterRegistry : public IReporterRegistry {
5095 
5096  public:
5097 
5098  virtual ~ReporterRegistry() {
5099  deleteAllValues( m_factories );
5100  }
5101 
5102  virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const {
5103  FactoryMap::const_iterator it = m_factories.find( name );
5104  if( it == m_factories.end() )
5105  return NULL;
5106  return it->second->create( ReporterConfig( config ) );
5107  }
5108 
5109  void registerReporter( std::string const& name, IReporterFactory* factory ) {
5110  m_factories.insert( std::make_pair( name, factory ) );
5111  }
5112 
5113  FactoryMap const& getFactories() const {
5114  return m_factories;
5115  }
5116 
5117  private:
5118  FactoryMap m_factories;
5119  };
5120 }
5121 
5122 // #included from: catch_exception_translator_registry.hpp
5123 #define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
5124 
5125 #ifdef __OBJC__
5126 #import "Foundation/Foundation.h"
5127 #endif
5128 
5129 namespace Catch {
5130 
5131  class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
5132  public:
5133  ~ExceptionTranslatorRegistry() {
5134  deleteAll( m_translators );
5135  }
5136 
5137  virtual void registerTranslator( const IExceptionTranslator* translator ) {
5138  m_translators.push_back( translator );
5139  }
5140 
5141  virtual std::string translateActiveException() const {
5142  try {
5143 #ifdef __OBJC__
5144  // In Objective-C try objective-c exceptions first
5145  @try {
5146  throw;
5147  }
5148  @catch (NSException *exception) {
5149  return toString( [exception description] );
5150  }
5151 #else
5152  throw;
5153 #endif
5154  }
5155  catch( std::exception& ex ) {
5156  return ex.what();
5157  }
5158  catch( std::string& msg ) {
5159  return msg;
5160  }
5161  catch( const char* msg ) {
5162  return msg;
5163  }
5164  catch(...) {
5165  return tryTranslators( m_translators.begin() );
5166  }
5167  }
5168 
5169  std::string tryTranslators( std::vector<const IExceptionTranslator*>::const_iterator it ) const {
5170  if( it == m_translators.end() )
5171  return "Unknown exception";
5172 
5173  try {
5174  return (*it)->translate();
5175  }
5176  catch(...) {
5177  return tryTranslators( it+1 );
5178  }
5179  }
5180 
5181  private:
5182  std::vector<const IExceptionTranslator*> m_translators;
5183  };
5184 }
5185 
5186 namespace Catch {
5187 
5188  namespace {
5189 
5190  class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
5191 
5192  RegistryHub( RegistryHub const& );
5193  void operator=( RegistryHub const& );
5194 
5195  public: // IRegistryHub
5196  RegistryHub() {
5197  }
5198  virtual IReporterRegistry const& getReporterRegistry() const {
5199  return m_reporterRegistry;
5200  }
5201  virtual ITestCaseRegistry const& getTestCaseRegistry() const {
5202  return m_testCaseRegistry;
5203  }
5204  virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() {
5205  return m_exceptionTranslatorRegistry;
5206  }
5207 
5208  public: // IMutableRegistryHub
5209  virtual void registerReporter( std::string const& name, IReporterFactory* factory ) {
5210  m_reporterRegistry.registerReporter( name, factory );
5211  }
5212  virtual void registerTest( TestCase const& testInfo ) {
5213  m_testCaseRegistry.registerTest( testInfo );
5214  }
5215  virtual void registerTranslator( const IExceptionTranslator* translator ) {
5216  m_exceptionTranslatorRegistry.registerTranslator( translator );
5217  }
5218 
5219  private:
5220  TestRegistry m_testCaseRegistry;
5221  ReporterRegistry m_reporterRegistry;
5222  ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
5223  };
5224 
5225  // Single, global, instance
5226  inline RegistryHub*& getTheRegistryHub() {
5227  static RegistryHub* theRegistryHub = NULL;
5228  if( !theRegistryHub )
5229  theRegistryHub = new RegistryHub();
5230  return theRegistryHub;
5231  }
5232  }
5233 
5234  IRegistryHub& getRegistryHub() {
5235  return *getTheRegistryHub();
5236  }
5237  IMutableRegistryHub& getMutableRegistryHub() {
5238  return *getTheRegistryHub();
5239  }
5240  void cleanUp() {
5241  delete getTheRegistryHub();
5242  getTheRegistryHub() = NULL;
5243  cleanUpContext();
5244  }
5245  std::string translateActiveException() {
5247  }
5248 
5249 } // end namespace Catch
5250 
5251 // #included from: catch_notimplemented_exception.hpp
5252 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
5253 
5254 #include <ostream>
5255 
5256 namespace Catch {
5257 
5258  NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
5259  : m_lineInfo( lineInfo ) {
5260  std::ostringstream oss;
5261  oss << lineInfo << ": function ";
5262  oss << "not implemented";
5263  m_what = oss.str();
5264  }
5265 
5266  const char* NotImplementedException::what() const throw() {
5267  return m_what.c_str();
5268  }
5269 
5270 } // end namespace Catch
5271 
5272 // #included from: catch_context_impl.hpp
5273 #define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
5274 
5275 // #included from: catch_stream.hpp
5276 #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
5277 
5278 // #included from: catch_streambuf.h
5279 #define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
5280 
5281 #include <streambuf>
5282 
5283 namespace Catch {
5284 
5285  class StreamBufBase : public std::streambuf {
5286  public:
5287  virtual ~StreamBufBase() throw();
5288  };
5289 }
5290 
5291 #include <stdexcept>
5292 #include <cstdio>
5293 
5294 namespace Catch {
5295 
5296  template<typename WriterF, size_t bufferSize=256>
5297  class StreamBufImpl : public StreamBufBase {
5298  char data[bufferSize];
5299  WriterF m_writer;
5300 
5301  public:
5302  StreamBufImpl() {
5303  setp( data, data + sizeof(data) );
5304  }
5305 
5306  ~StreamBufImpl() throw() {
5307  sync();
5308  }
5309 
5310  private:
5311  int overflow( int c ) {
5312  sync();
5313 
5314  if( c != EOF ) {
5315  if( pbase() == epptr() )
5316  m_writer( std::string( 1, static_cast<char>( c ) ) );
5317  else
5318  sputc( static_cast<char>( c ) );
5319  }
5320  return 0;
5321  }
5322 
5323  int sync() {
5324  if( pbase() != pptr() ) {
5325  m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
5326  setp( pbase(), epptr() );
5327  }
5328  return 0;
5329  }
5330  };
5331 
5333 
5334  struct OutputDebugWriter {
5335 
5336  void operator()( std::string const&str ) {
5337  writeToDebugConsole( str );
5338  }
5339  };
5340 
5341  Stream::Stream()
5342  : streamBuf( NULL ), isOwned( false )
5343  {}
5344 
5345  Stream::Stream( std::streambuf* _streamBuf, bool _isOwned )
5346  : streamBuf( _streamBuf ), isOwned( _isOwned )
5347  {}
5348 
5349  void Stream::release() {
5350  if( isOwned ) {
5351  delete streamBuf;
5352  streamBuf = NULL;
5353  isOwned = false;
5354  }
5355  }
5356 }
5357 
5358 namespace Catch {
5359 
5360  class Context : public IMutableContext {
5361 
5362  Context() : m_config( NULL ), m_runner( NULL ), m_resultCapture( NULL ) {}
5363  Context( Context const& );
5364  void operator=( Context const& );
5365 
5366  public: // IContext
5367  virtual IResultCapture& getResultCapture() {
5368  return *m_resultCapture;
5369  }
5370  virtual IRunner& getRunner() {
5371  return *m_runner;
5372  }
5373  virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
5374  return getGeneratorsForCurrentTest()
5375  .getGeneratorInfo( fileInfo, totalSize )
5376  .getCurrentIndex();
5377  }
5378  virtual bool advanceGeneratorsForCurrentTest() {
5379  IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
5380  return generators && generators->moveNext();
5381  }
5382 
5383  virtual Ptr<IConfig const> getConfig() const {
5384  return m_config;
5385  }
5386 
5387  public: // IMutableContext
5388  virtual void setResultCapture( IResultCapture* resultCapture ) {
5389  m_resultCapture = resultCapture;
5390  }
5391  virtual void setRunner( IRunner* runner ) {
5392  m_runner = runner;
5393  }
5394  virtual void setConfig( Ptr<IConfig const> const& config ) {
5395  m_config = config;
5396  }
5397 
5398  friend IMutableContext& getCurrentMutableContext();
5399 
5400  private:
5401  IGeneratorsForTest* findGeneratorsForCurrentTest() {
5402  std::string testName = getResultCapture().getCurrentTestName();
5403 
5404  std::map<std::string, IGeneratorsForTest*>::const_iterator it =
5405  m_generatorsByTestName.find( testName );
5406  return it != m_generatorsByTestName.end()
5407  ? it->second
5408  : NULL;
5409  }
5410 
5411  IGeneratorsForTest& getGeneratorsForCurrentTest() {
5412  IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
5413  if( !generators ) {
5414  std::string testName = getResultCapture().getCurrentTestName();
5415  generators = createGeneratorsForTest();
5416  m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
5417  }
5418  return *generators;
5419  }
5420 
5421  private:
5422  Ptr<IConfig const> m_config;
5423  IRunner* m_runner;
5424  IResultCapture* m_resultCapture;
5425  std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
5426  };
5427 
5428  namespace {
5429  Context* currentContext = NULL;
5430  }
5431  IMutableContext& getCurrentMutableContext() {
5432  if( !currentContext )
5433  currentContext = new Context();
5434  return *currentContext;
5435  }
5436  IContext& getCurrentContext() {
5437  return getCurrentMutableContext();
5438  }
5439 
5440  Stream createStream( std::string const& streamName ) {
5441  if( streamName == "stdout" ) return Stream( std::cout.rdbuf(), false );
5442  if( streamName == "stderr" ) return Stream( std::cerr.rdbuf(), false );
5443  if( streamName == "debug" ) return Stream( new StreamBufImpl<OutputDebugWriter>, true );
5444 
5445  throw std::domain_error( "Unknown stream: " + streamName );
5446  }
5447 
5448  void cleanUpContext() {
5449  delete currentContext;
5450  currentContext = NULL;
5451  }
5452 }
5453 
5454 // #included from: catch_console_colour_impl.hpp
5455 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
5456 
5457 namespace Catch { namespace Detail {
5458  struct IColourImpl {
5459  virtual ~IColourImpl() {}
5460  virtual void use( Colour::Code _colourCode ) = 0;
5461  };
5462 }}
5463 
5464 #if defined ( CATCH_PLATFORM_WINDOWS )
5465 
5466 #ifndef NOMINMAX
5467 #define NOMINMAX
5468 #endif
5469 
5470 #ifdef __AFXDLL
5471 #include <AfxWin.h>
5472 #else
5473 #include <windows.h>
5474 #endif
5475 
5476 namespace Catch {
5477 namespace {
5478 
5479  class Win32ColourImpl : public Detail::IColourImpl {
5480  public:
5481  Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
5482  {
5483  CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
5484  GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
5485  originalAttributes = csbiInfo.wAttributes;
5486  }
5487 
5488  virtual void use( Colour::Code _colourCode ) {
5489  switch( _colourCode ) {
5490  case Colour::None: return setTextAttribute( originalAttributes );
5491  case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
5492  case Colour::Red: return setTextAttribute( FOREGROUND_RED );
5493  case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
5494  case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
5495  case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
5496  case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
5497  case Colour::Grey: return setTextAttribute( 0 );
5498 
5499  case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
5500  case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
5501  case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
5502  case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
5503 
5504  case Colour::Bright: throw std::logic_error( "not a colour" );
5505  }
5506  }
5507 
5508  private:
5509  void setTextAttribute( WORD _textAttribute ) {
5510  SetConsoleTextAttribute( stdoutHandle, _textAttribute );
5511  }
5512  HANDLE stdoutHandle;
5513  WORD originalAttributes;
5514  };
5515 
5516  inline bool shouldUseColourForPlatform() {
5517  return true;
5518  }
5519 
5520  Win32ColourImpl platformColourImpl;
5521 
5522 } // end anon namespace
5523 } // end namespace Catch
5524 
5525 #else // Not Windows - assumed to be POSIX compatible
5526 
5527 #include <unistd.h>
5528 
5529 namespace Catch {
5530 namespace {
5531 
5532  // use POSIX/ ANSI console terminal codes
5533  // Thanks to Adam Strzelecki for original contribution
5534  // (http://github.com/nanoant)
5535  // https://github.com/philsquared/Catch/pull/131
5536  class PosixColourImpl : public Detail::IColourImpl {
5537  public:
5538  virtual void use( Colour::Code _colourCode ) {
5539  switch( _colourCode ) {
5540  case Colour::None:
5541  case Colour::White: return setColour( "[0m" );
5542  case Colour::Red: return setColour( "[0;31m" );
5543  case Colour::Green: return setColour( "[0;32m" );
5544  case Colour::Blue: return setColour( "[0:34m" );
5545  case Colour::Cyan: return setColour( "[0;36m" );
5546  case Colour::Yellow: return setColour( "[0;33m" );
5547  case Colour::Grey: return setColour( "[1;30m" );
5548 
5549  case Colour::LightGrey: return setColour( "[0;37m" );
5550  case Colour::BrightRed: return setColour( "[1;31m" );
5551  case Colour::BrightGreen: return setColour( "[1;32m" );
5552  case Colour::BrightWhite: return setColour( "[1;37m" );
5553 
5554  case Colour::Bright: throw std::logic_error( "not a colour" );
5555  }
5556  }
5557  private:
5558  void setColour( const char* _escapeCode ) {
5559  std::cout << '\033' << _escapeCode;
5560  }
5561  };
5562 
5563  inline bool shouldUseColourForPlatform() {
5564  return isatty(STDOUT_FILENO);
5565  }
5566 
5567  PosixColourImpl platformColourImpl;
5568 
5569 } // end anon namespace
5570 } // end namespace Catch
5571 
5572 #endif // not Windows
5573 
5574 namespace Catch {
5575 
5576  namespace {
5577  struct NoColourImpl : Detail::IColourImpl {
5578  void use( Colour::Code ) {}
5579  };
5580  NoColourImpl noColourImpl;
5581  static const bool shouldUseColour = shouldUseColourForPlatform() &&
5582  !isDebuggerActive();
5583  }
5584 
5585  Colour::Colour( Code _colourCode ){ use( _colourCode ); }
5586  Colour::~Colour(){ use( None ); }
5587  void Colour::use( Code _colourCode ) {
5588  impl->use( _colourCode );
5589  }
5590 
5591  Detail::IColourImpl* Colour::impl = shouldUseColour
5592  ? static_cast<Detail::IColourImpl*>( &platformColourImpl )
5593  : static_cast<Detail::IColourImpl*>( &noColourImpl );
5594 
5595 } // end namespace Catch
5596 
5597 // #included from: catch_generators_impl.hpp
5598 #define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
5599 
5600 #include <vector>
5601 #include <string>
5602 #include <map>
5603 
5604 namespace Catch {
5605 
5606  struct GeneratorInfo : IGeneratorInfo {
5607 
5608  GeneratorInfo( std::size_t size )
5609  : m_size( size ),
5610  m_currentIndex( 0 )
5611  {}
5612 
5613  bool moveNext() {
5614  if( ++m_currentIndex == m_size ) {
5615  m_currentIndex = 0;
5616  return false;
5617  }
5618  return true;
5619  }
5620 
5621  std::size_t getCurrentIndex() const {
5622  return m_currentIndex;
5623  }
5624 
5625  std::size_t m_size;
5626  std::size_t m_currentIndex;
5627  };
5628 
5630 
5631  class GeneratorsForTest : public IGeneratorsForTest {
5632 
5633  public:
5634  ~GeneratorsForTest() {
5635  deleteAll( m_generatorsInOrder );
5636  }
5637 
5638  IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
5639  std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
5640  if( it == m_generatorsByName.end() ) {
5641  IGeneratorInfo* info = new GeneratorInfo( size );
5642  m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
5643  m_generatorsInOrder.push_back( info );
5644  return *info;
5645  }
5646  return *it->second;
5647  }
5648 
5649  bool moveNext() {
5650  std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
5651  std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
5652  for(; it != itEnd; ++it ) {
5653  if( (*it)->moveNext() )
5654  return true;
5655  }
5656  return false;
5657  }
5658 
5659  private:
5660  std::map<std::string, IGeneratorInfo*> m_generatorsByName;
5661  std::vector<IGeneratorInfo*> m_generatorsInOrder;
5662  };
5663 
5664  IGeneratorsForTest* createGeneratorsForTest()
5665  {
5666  return new GeneratorsForTest();
5667  }
5668 
5669 } // end namespace Catch
5670 
5671 // #included from: catch_assertionresult.hpp
5672 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
5673 
5674 namespace Catch {
5675 
5676  AssertionInfo::AssertionInfo( std::string const& _macroName,
5677  SourceLineInfo const& _lineInfo,
5678  std::string const& _capturedExpression,
5679  ResultDisposition::Flags _resultDisposition )
5680  : macroName( _macroName ),
5681  lineInfo( _lineInfo ),
5682  capturedExpression( _capturedExpression ),
5683  resultDisposition( _resultDisposition )
5684  {}
5685 
5687 
5688  AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
5689  : m_info( info ),
5690  m_resultData( data )
5691  {}
5692 
5694 
5695  // Result was a success
5696  bool AssertionResult::succeeded() const {
5698  }
5699 
5700  // Result was a success, or failure is suppressed
5701  bool AssertionResult::isOk() const {
5703  }
5704 
5706  return m_resultData.resultType;
5707  }
5708 
5709  bool AssertionResult::hasExpression() const {
5710  return !m_info.capturedExpression.empty();
5711  }
5712 
5713  bool AssertionResult::hasMessage() const {
5714  return !m_resultData.message.empty();
5715  }
5716 
5717  std::string AssertionResult::getExpression() const {
5719  return "!" + m_info.capturedExpression;
5720  else
5721  return m_info.capturedExpression;
5722  }
5723  std::string AssertionResult::getExpressionInMacro() const {
5724  if( m_info.macroName.empty() )
5725  return m_info.capturedExpression;
5726  else
5727  return m_info.macroName + "( " + m_info.capturedExpression + " )";
5728  }
5729 
5732  }
5733 
5734  std::string AssertionResult::getExpandedExpression() const {
5736  }
5737 
5738  std::string AssertionResult::getMessage() const {
5739  return m_resultData.message;
5740  }
5741  SourceLineInfo AssertionResult::getSourceInfo() const {
5742  return m_info.lineInfo;
5743  }
5744 
5745  std::string AssertionResult::getTestMacroName() const {
5746  return m_info.macroName;
5747  }
5748 
5749 } // end namespace Catch
5750 
5751 // #included from: catch_expressionresult_builder.hpp
5752 #define TWOBLUECUBES_CATCH_EXPRESSIONRESULT_BUILDER_HPP_INCLUDED
5753 
5754 #include <assert.h>
5755 
5756 namespace Catch {
5757 
5759  m_data.resultType = resultType;
5760  }
5761  ExpressionResultBuilder::ExpressionResultBuilder( ExpressionResultBuilder const& other )
5762  : m_data( other.m_data ),
5763  m_exprComponents( other.m_exprComponents )
5764  {
5765  m_stream << other.m_stream.str();
5766  }
5767  ExpressionResultBuilder& ExpressionResultBuilder::operator=(ExpressionResultBuilder const& other ) {
5768  m_data = other.m_data;
5769  m_exprComponents = other.m_exprComponents;
5770  m_stream.str("");
5771  m_stream << other.m_stream.str();
5772  return *this;
5773  }
5774  ExpressionResultBuilder& ExpressionResultBuilder::setResultType( ResultWas::OfType result ) {
5775  m_data.resultType = result;
5776  return *this;
5777  }
5778  ExpressionResultBuilder& ExpressionResultBuilder::setResultType( bool result ) {
5780  return *this;
5781  }
5782  ExpressionResultBuilder& ExpressionResultBuilder::endExpression( ResultDisposition::Flags resultDisposition ) {
5783  m_exprComponents.shouldNegate = shouldNegate( resultDisposition );
5784  return *this;
5785  }
5786  ExpressionResultBuilder& ExpressionResultBuilder::setLhs( std::string const& lhs ) {
5787  m_exprComponents.lhs = lhs;
5788  return *this;
5789  }
5790  ExpressionResultBuilder& ExpressionResultBuilder::setRhs( std::string const& rhs ) {
5791  m_exprComponents.rhs = rhs;
5792  return *this;
5793  }
5794  ExpressionResultBuilder& ExpressionResultBuilder::setOp( std::string const& op ) {
5795  m_exprComponents.op = op;
5796  return *this;
5797  }
5798  AssertionResult ExpressionResultBuilder::buildResult( AssertionInfo const& info ) const
5799  {
5800  assert( m_data.resultType != ResultWas::Unknown );
5801 
5802  AssertionResultData data = m_data;
5803 
5804  // Flip bool results if shouldNegate is set
5805  if( m_exprComponents.shouldNegate && data.resultType == ResultWas::Ok )
5807  else if( m_exprComponents.shouldNegate && data.resultType == ResultWas::ExpressionFailed )
5808  data.resultType = ResultWas::Ok;
5809 
5810  data.message = m_stream.str();
5811  data.reconstructedExpression = reconstructExpression( info );
5812  if( m_exprComponents.shouldNegate ) {
5813  if( m_exprComponents.op == "" )
5814  data.reconstructedExpression = "!" + data.reconstructedExpression;
5815  else
5816  data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
5817  }
5818  return AssertionResult( info, data );
5819  }
5820  std::string ExpressionResultBuilder::reconstructExpression( AssertionInfo const& info ) const {
5821  if( m_exprComponents.op == "" )
5822  return m_exprComponents.lhs.empty() ? info.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
5823  else if( m_exprComponents.op == "matches" )
5824  return m_exprComponents.lhs + " " + m_exprComponents.rhs;
5825  else if( m_exprComponents.op != "!" ) {
5826  if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
5827  m_exprComponents.lhs.find("\n") == std::string::npos &&
5828  m_exprComponents.rhs.find("\n") == std::string::npos )
5829  return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs;
5830  else
5831  return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs;
5832  }
5833  else
5834  return "{can't expand - use " + info.macroName + "_FALSE( " + info.capturedExpression.substr(1) + " ) instead of " + info.macroName + "( " + info.capturedExpression + " ) for better diagnostics}";
5835  }
5836 
5837 } // end namespace Catch
5838 
5839 // #included from: catch_test_case_info.hpp
5840 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
5841 
5842 namespace Catch {
5843 
5844  TestCase makeTestCase( ITestCase* _testCase,
5845  std::string const& _className,
5846  std::string const& _name,
5847  std::string const& _descOrTags,
5848  SourceLineInfo const& _lineInfo )
5849  {
5850  std::string desc = _descOrTags;
5851  bool isHidden( startsWith( _name, "./" ) ); // Legacy support
5852  std::set<std::string> tags;
5853  TagExtracter( tags ).parse( desc );
5854  if( tags.find( "hide" ) != tags.end() || tags.find( "." ) != tags.end() )
5855  isHidden = true;
5856 
5857  if( isHidden ) {
5858  tags.insert( "hide" );
5859  tags.insert( "." );
5860  }
5861  TestCaseInfo info( _name, _className, desc, tags, isHidden, _lineInfo );
5862  return TestCase( _testCase, info );
5863  }
5864 
5865  TestCaseInfo::TestCaseInfo( std::string const& _name,
5866  std::string const& _className,
5867  std::string const& _description,
5868  std::set<std::string> const& _tags,
5869  bool _isHidden,
5870  SourceLineInfo const& _lineInfo )
5871  : name( _name ),
5872  className( _className ),
5873  description( _description ),
5874  tags( _tags ),
5875  lineInfo( _lineInfo ),
5876  isHidden( _isHidden )
5877  {
5878  std::ostringstream oss;
5879  for( std::set<std::string>::const_iterator it = _tags.begin(), itEnd = _tags.end(); it != itEnd; ++it )
5880  oss << "[" << *it << "]";
5881  tagsAsString = oss.str();
5882  }
5883 
5884  TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
5885  : name( other.name ),
5886  className( other.className ),
5887  description( other.description ),
5888  tags( other.tags ),
5889  tagsAsString( other.tagsAsString ),
5890  lineInfo( other.lineInfo ),
5891  isHidden( other.isHidden )
5892  {}
5893 
5894  TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
5895 
5896  TestCase::TestCase( TestCase const& other )
5897  : TestCaseInfo( other ),
5898  test( other.test )
5899  {}
5900 
5901  TestCase TestCase::withName( std::string const& _newName ) const {
5902  TestCase other( *this );
5903  other.name = _newName;
5904  return other;
5905  }
5906 
5907  void TestCase::invoke() const {
5908  test->invoke();
5909  }
5910 
5911  bool TestCase::isHidden() const {
5912  return TestCaseInfo::isHidden;
5913  }
5914 
5915  bool TestCase::hasTag( std::string const& tag ) const {
5916  return tags.find( toLower( tag ) ) != tags.end();
5917  }
5918  bool TestCase::matchesTags( std::string const& tagPattern ) const {
5919  TagExpression exp;
5920  TagExpressionParser( exp ).parse( tagPattern );
5921  return exp.matches( tags );
5922  }
5923  std::set<std::string> const& TestCase::getTags() const {
5924  return tags;
5925  }
5926 
5927  void TestCase::swap( TestCase& other ) {
5928  test.swap( other.test );
5929  className.swap( other.className );
5930  name.swap( other.name );
5931  description.swap( other.description );
5932  std::swap( lineInfo, other.lineInfo );
5933  }
5934 
5935  bool TestCase::operator == ( TestCase const& other ) const {
5936  return test.get() == other.test.get() &&
5937  name == other.name &&
5938  className == other.className;
5939  }
5940 
5941  bool TestCase::operator < ( TestCase const& other ) const {
5942  return name < other.name;
5943  }
5944  TestCase& TestCase::operator = ( TestCase const& other ) {
5945  TestCase temp( other );
5946  swap( temp );
5947  return *this;
5948  }
5949 
5950  TestCaseInfo const& TestCase::getTestCaseInfo() const
5951  {
5952  return *this;
5953  }
5954 
5955 } // end namespace Catch
5956 
5957 // #included from: catch_tags.hpp
5958 #define TWOBLUECUBES_CATCH_TAGS_HPP_INCLUDED
5959 
5960 namespace Catch {
5961  TagParser::~TagParser() {}
5962 
5963  void TagParser::parse( std::string const& str ) {
5964  std::size_t pos = 0;
5965  while( pos < str.size() ) {
5966  char c = str[pos];
5967  if( c == '[' ) {
5968  std::size_t end = str.find_first_of( ']', pos );
5969  if( end != std::string::npos ) {
5970  acceptTag( str.substr( pos+1, end-pos-1 ) );
5971  pos = end+1;
5972  }
5973  else {
5974  acceptChar( c );
5975  pos++;
5976  }
5977  }
5978  else {
5979  acceptChar( c );
5980  pos++;
5981  }
5982  }
5983  endParse();
5984  }
5985 
5986  TagExtracter::TagExtracter( std::set<std::string>& tags )
5987  : m_tags( tags )
5988  {}
5989 
5990  TagExtracter::~TagExtracter() {}
5991 
5992  void TagExtracter::parse( std::string& description ) {
5993  TagParser::parse( description );
5994  description = m_remainder;
5995  }
5996 
5997  void TagExtracter::acceptTag( std::string const& tag ) {
5998  m_tags.insert( toLower( tag ) );
5999  }
6000  void TagExtracter::acceptChar( char c ) {
6001  m_remainder += c;
6002  }
6003 
6004  Tag::Tag() : m_isNegated( false ) {}
6005  Tag::Tag( std::string const& name, bool isNegated )
6006  : m_name( name ),
6007  m_isNegated( isNegated )
6008  {}
6009 
6010  std::string Tag::getName() const {
6011  return m_name;
6012  }
6013  bool Tag::isNegated() const {
6014  return m_isNegated;
6015  }
6016 
6017  bool Tag::operator ! () const {
6018  return m_name.empty();
6019  }
6020 
6021  void TagSet::add( Tag const& tag ) {
6022  m_tags.insert( std::make_pair( toLower( tag.getName() ), tag ) );
6023  }
6024 
6025  bool TagSet::empty() const {
6026  return m_tags.empty();
6027  }
6028 
6029  bool TagSet::matches( std::set<std::string> const& tags ) const {
6030  for( TagMap::const_iterator
6031  it = m_tags.begin(), itEnd = m_tags.end();
6032  it != itEnd;
6033  ++it ) {
6034  bool found = tags.find( it->first ) != tags.end();
6035  if( found == it->second.isNegated() )
6036  return false;
6037  }
6038  return true;
6039  }
6040 
6041  bool TagExpression::matches( std::set<std::string> const& tags ) const {
6042  for( std::vector<TagSet>::const_iterator
6043  it = m_tagSets.begin(), itEnd = m_tagSets.end();
6044  it != itEnd;
6045  ++it )
6046  if( it->matches( tags ) )
6047  return true;
6048  return false;
6049  }
6050 
6051  TagExpressionParser::TagExpressionParser( TagExpression& exp )
6052  : m_isNegated( false ),
6053  m_exp( exp )
6054  {}
6055 
6056  TagExpressionParser::~TagExpressionParser() {}
6057 
6058  void TagExpressionParser::acceptTag( std::string const& tag ) {
6059  m_currentTagSet.add( Tag( tag, m_isNegated ) );
6060  m_isNegated = false;
6061  }
6062 
6063  void TagExpressionParser::acceptChar( char c ) {
6064  switch( c ) {
6065  case '~':
6066  m_isNegated = true;
6067  break;
6068  case ',':
6069  m_exp.m_tagSets.push_back( m_currentTagSet );
6070  m_currentTagSet = TagSet();
6071  break;
6072  }
6073  }
6074 
6075  void TagExpressionParser::endParse() {
6076  if( !m_currentTagSet.empty() )
6077  m_exp.m_tagSets.push_back( m_currentTagSet );
6078  }
6079 
6080 } // end namespace Catch
6081 
6082 // #included from: catch_test_spec.hpp
6083 #define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
6084 
6085 namespace Catch {
6086 
6087  TestCaseFilter::TestCaseFilter( std::string const& testSpec, IfFilterMatches::DoWhat matchBehaviour )
6088  : m_stringToMatch( toLower( testSpec ) ),
6089  m_filterType( matchBehaviour ),
6090  m_wildcardPosition( NoWildcard )
6091  {
6092  if( m_filterType == IfFilterMatches::AutoDetectBehaviour ) {
6093  if( startsWith( m_stringToMatch, "exclude:" ) ) {
6094  m_stringToMatch = m_stringToMatch.substr( 8 );
6095  m_filterType = IfFilterMatches::ExcludeTests;
6096  }
6097  else if( startsWith( m_stringToMatch, "~" ) ) {
6098  m_stringToMatch = m_stringToMatch.substr( 1 );
6099  m_filterType = IfFilterMatches::ExcludeTests;
6100  }
6101  else {
6102  m_filterType = IfFilterMatches::IncludeTests;
6103  }
6104  }
6105 
6106  if( startsWith( m_stringToMatch, "*" ) ) {
6107  m_stringToMatch = m_stringToMatch.substr( 1 );
6108  m_wildcardPosition = (WildcardPosition)( m_wildcardPosition | WildcardAtStart );
6109  }
6110  if( endsWith( m_stringToMatch, "*" ) ) {
6111  m_stringToMatch = m_stringToMatch.substr( 0, m_stringToMatch.size()-1 );
6112  m_wildcardPosition = (WildcardPosition)( m_wildcardPosition | WildcardAtEnd );
6113  }
6114  }
6115 
6116  IfFilterMatches::DoWhat TestCaseFilter::getFilterType() const {
6117  return m_filterType;
6118  }
6119 
6120  bool TestCaseFilter::shouldInclude( TestCase const& testCase ) const {
6121  return isMatch( testCase ) == (m_filterType == IfFilterMatches::IncludeTests);
6122  }
6123 
6124 #ifdef __clang__
6125 #pragma clang diagnostic push
6126 #pragma clang diagnostic ignored "-Wunreachable-code"
6127 #endif
6128 
6129  bool TestCaseFilter::isMatch( TestCase const& testCase ) const {
6130  std::string name = testCase.getTestCaseInfo().name;
6131  toLowerInPlace( name );
6132 
6133  switch( m_wildcardPosition ) {
6134  case NoWildcard:
6135  return m_stringToMatch == name;
6136  case WildcardAtStart:
6137  return endsWith( name, m_stringToMatch );
6138  case WildcardAtEnd:
6139  return startsWith( name, m_stringToMatch );
6140  case WildcardAtBothEnds:
6141  return contains( name, m_stringToMatch );
6142  }
6143  throw std::logic_error( "Unhandled wildcard type" );
6144  }
6145 
6146 #ifdef __clang__
6147 #pragma clang diagnostic pop
6148 #endif
6149 
6150  TestCaseFilters::TestCaseFilters( std::string const& name ) : m_name( name ) {}
6151 
6152  std::string TestCaseFilters::getName() const {
6153  return m_name;
6154  }
6155 
6156  void TestCaseFilters::addFilter( TestCaseFilter const& filter ) {
6157  if( filter.getFilterType() == IfFilterMatches::ExcludeTests )
6158  m_exclusionFilters.push_back( filter );
6159  else
6160  m_inclusionFilters.push_back( filter );
6161  }
6162 
6163  void TestCaseFilters::addTags( std::string const& tagPattern ) {
6164  TagExpression exp;
6165  TagExpressionParser( exp ).parse( tagPattern );
6166 
6167  m_tagExpressions.push_back( exp );
6168  }
6169 
6170  bool TestCaseFilters::shouldInclude( TestCase const& testCase ) const {
6171  if( !m_tagExpressions.empty() ) {
6172  std::vector<TagExpression>::const_iterator it = m_tagExpressions.begin();
6173  std::vector<TagExpression>::const_iterator itEnd = m_tagExpressions.end();
6174  for(; it != itEnd; ++it )
6175  if( it->matches( testCase.getTags() ) )
6176  break;
6177  if( it == itEnd )
6178  return false;
6179  }
6180 
6181  if( !m_inclusionFilters.empty() ) {
6182  std::vector<TestCaseFilter>::const_iterator it = m_inclusionFilters.begin();
6183  std::vector<TestCaseFilter>::const_iterator itEnd = m_inclusionFilters.end();
6184  for(; it != itEnd; ++it )
6185  if( it->shouldInclude( testCase ) )
6186  break;
6187  if( it == itEnd )
6188  return false;
6189  }
6190  else if( m_exclusionFilters.empty() && m_tagExpressions.empty() ) {
6191  return !testCase.isHidden();
6192  }
6193 
6194  std::vector<TestCaseFilter>::const_iterator it = m_exclusionFilters.begin();
6195  std::vector<TestCaseFilter>::const_iterator itEnd = m_exclusionFilters.end();
6196  for(; it != itEnd; ++it )
6197  if( !it->shouldInclude( testCase ) )
6198  return false;
6199  return true;
6200  }
6201 }
6202 
6203 // #included from: catch_version.hpp
6204 #define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
6205 
6206 namespace Catch {
6207 
6208  // These numbers are maintained by a script
6209  Version libraryVersion( 1, 0, 25, "master" );
6210 }
6211 
6212 // #included from: catch_text.hpp
6213 #define TWOBLUECUBES_CATCH_TEXT_HPP_INCLUDED
6214 
6215 #include <string>
6216 #include <vector>
6217 
6218 namespace Catch {
6219 
6220  Text::Text( std::string const& _str, TextAttributes const& _attr )
6221  : attr( _attr )
6222  {
6223  std::string wrappableChars = " [({.,/|\\-";
6224  std::size_t indent = _attr.initialIndent != std::string::npos
6225  ? _attr.initialIndent
6226  : _attr.indent;
6227  std::string remainder = _str;
6228 
6229  while( !remainder.empty() ) {
6230  if( lines.size() >= 1000 ) {
6231  lines.push_back( "... message truncated due to excessive size" );
6232  return;
6233  }
6234  std::size_t tabPos = std::string::npos;
6235  std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
6236  std::size_t pos = remainder.find_first_of( '\n' );
6237  if( pos <= width ) {
6238  width = pos;
6239  }
6240  pos = remainder.find_last_of( _attr.tabChar, width );
6241  if( pos != std::string::npos ) {
6242  tabPos = pos;
6243  if( remainder[width] == '\n' )
6244  width--;
6245  remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
6246  }
6247 
6248  if( width == remainder.size() ) {
6249  spliceLine( indent, remainder, width );
6250  }
6251  else if( remainder[width] == '\n' ) {
6252  spliceLine( indent, remainder, width );
6253  if( width <= 1 || remainder.size() != 1 )
6254  remainder = remainder.substr( 1 );
6255  indent = _attr.indent;
6256  }
6257  else {
6258  pos = remainder.find_last_of( wrappableChars, width );
6259  if( pos != std::string::npos && pos > 0 ) {
6260  spliceLine( indent, remainder, pos );
6261  if( remainder[0] == ' ' )
6262  remainder = remainder.substr( 1 );
6263  }
6264  else {
6265  spliceLine( indent, remainder, width-1 );
6266  lines.back() += "-";
6267  }
6268  if( lines.size() == 1 )
6269  indent = _attr.indent;
6270  if( tabPos != std::string::npos )
6271  indent += tabPos;
6272  }
6273  }
6274  }
6275 
6276  void Text::spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
6277  lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
6278  _remainder = _remainder.substr( _pos );
6279  }
6280 
6281  std::string Text::toString() const {
6282  std::ostringstream oss;
6283  oss << *this;
6284  return oss.str();
6285  }
6286 
6287  std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
6288  for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
6289  it != itEnd; ++it ) {
6290  if( it != _text.begin() )
6291  _stream << "\n";
6292  _stream << *it;
6293  }
6294  return _stream;
6295  }
6296 
6297 } // end namespace Catch
6298 
6299 // #included from: catch_message.hpp
6300 #define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
6301 
6302 namespace Catch {
6303 
6304  MessageInfo::MessageInfo( std::string const& _macroName,
6305  SourceLineInfo const& _lineInfo,
6306  ResultWas::OfType _type )
6307  : macroName( _macroName ),
6308  lineInfo( _lineInfo ),
6309  type( _type ),
6310  sequence( ++globalCount )
6311  {}
6312 
6313  // This may need protecting if threading support is added
6314  unsigned int MessageInfo::globalCount = 0;
6315 
6317 
6318  ScopedMessage::ScopedMessage( MessageBuilder const& builder )
6319  : m_info( builder.m_info )
6320  {
6321  m_info.message = builder.m_stream.str();
6322  getResultCapture().pushScopedMessage( m_info );
6323  }
6326  }
6327 
6328 } // end namespace Catch
6329 
6330 // #included from: catch_legacy_reporter_adapter.hpp
6331 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
6332 
6333 // #included from: catch_legacy_reporter_adapter.h
6334 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
6335 
6336 namespace Catch
6337 {
6338  // Deprecated
6339  struct IReporter : IShared {
6340  virtual ~IReporter();
6341 
6342  virtual bool shouldRedirectStdout() const = 0;
6343 
6344  virtual void StartTesting() = 0;
6345  virtual void EndTesting( Totals const& totals ) = 0;
6346  virtual void StartGroup( std::string const& groupName ) = 0;
6347  virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
6348  virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
6349  virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
6350  virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
6351  virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
6352  virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
6353  virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
6354  virtual void Aborted() = 0;
6355  virtual void Result( AssertionResult const& result ) = 0;
6356  };
6357 
6358  class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
6359  {
6360  public:
6361  LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
6362  virtual ~LegacyReporterAdapter();
6363 
6364  virtual ReporterPreferences getPreferences() const;
6365  virtual void noMatchingTestCases( std::string const& );
6366  virtual void testRunStarting( TestRunInfo const& );
6367  virtual void testGroupStarting( GroupInfo const& groupInfo );
6368  virtual void testCaseStarting( TestCaseInfo const& testInfo );
6369  virtual void sectionStarting( SectionInfo const& sectionInfo );
6370  virtual void assertionStarting( AssertionInfo const& );
6371  virtual bool assertionEnded( AssertionStats const& assertionStats );
6372  virtual void sectionEnded( SectionStats const& sectionStats );
6373  virtual void testCaseEnded( TestCaseStats const& testCaseStats );
6374  virtual void testGroupEnded( TestGroupStats const& testGroupStats );
6375  virtual void testRunEnded( TestRunStats const& testRunStats );
6376 
6377  private:
6378  Ptr<IReporter> m_legacyReporter;
6379  };
6380 }
6381 
6382 namespace Catch
6383 {
6384  LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
6385  : m_legacyReporter( legacyReporter )
6386  {}
6387  LegacyReporterAdapter::~LegacyReporterAdapter() {}
6388 
6389  ReporterPreferences LegacyReporterAdapter::getPreferences() const {
6390  ReporterPreferences prefs;
6391  prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
6392  return prefs;
6393  }
6394 
6395  void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
6396  void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
6397  m_legacyReporter->StartTesting();
6398  }
6399  void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
6400  m_legacyReporter->StartGroup( groupInfo.name );
6401  }
6402  void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
6403  m_legacyReporter->StartTestCase( testInfo );
6404  }
6405  void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
6406  m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
6407  }
6408  void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
6409  // Not on legacy interface
6410  }
6411 
6412  bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
6413  if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
6414  for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
6415  it != itEnd;
6416  ++it ) {
6417  if( it->type == ResultWas::Info ) {
6418  ExpressionResultBuilder expressionBuilder( it->type );
6419  expressionBuilder << it->message;
6420  AssertionInfo info( it->macroName, it->lineInfo, "", ResultDisposition::Normal );
6421  AssertionResult result = expressionBuilder.buildResult( info );
6422  m_legacyReporter->Result( result );
6423  }
6424  }
6425  }
6426  m_legacyReporter->Result( assertionStats.assertionResult );
6427  return true;
6428  }
6429  void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
6430  if( sectionStats.missingAssertions )
6431  m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
6432  m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
6433  }
6434  void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
6435  m_legacyReporter->EndTestCase
6436  ( testCaseStats.testInfo,
6437  testCaseStats.totals,
6438  testCaseStats.stdOut,
6439  testCaseStats.stdErr );
6440  }
6441  void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
6442  if( testGroupStats.aborting )
6443  m_legacyReporter->Aborted();
6444  m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
6445  }
6446  void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
6447  m_legacyReporter->EndTesting( testRunStats.totals );
6448  }
6449 }
6450 
6451 // #included from: catch_timer.hpp
6452 
6453 #ifdef __clang__
6454 #pragma clang diagnostic push
6455 #pragma clang diagnostic ignored "-Wc++11-long-long"
6456 #endif
6457 
6458 #ifdef CATCH_PLATFORM_WINDOWS
6459 #include <windows.h>
6460 #else
6461 #include <sys/time.h>
6462 #endif
6463 
6464 namespace Catch {
6465 
6466  namespace {
6467 #ifdef CATCH_PLATFORM_WINDOWS
6468  uint64_t getCurrentTicks() {
6469  static uint64_t hz=0, hzo=0;
6470  if (!hz) {
6471  QueryPerformanceFrequency((LARGE_INTEGER*)&hz);
6472  QueryPerformanceCounter((LARGE_INTEGER*)&hzo);
6473  }
6474  uint64_t t;
6475  QueryPerformanceCounter((LARGE_INTEGER*)&t);
6476  return ((t-hzo)*1000000)/hz;
6477  }
6478 #else
6479  uint64_t getCurrentTicks() {
6480  timeval t;
6481  gettimeofday(&t,NULL);
6482  return (uint64_t)t.tv_sec * 1000000ull + (uint64_t)t.tv_usec;
6483  }
6484 #endif
6485  }
6486 
6487  void Timer::start() {
6488  m_ticks = getCurrentTicks();
6489  }
6490  unsigned int Timer::getElapsedNanoseconds() const {
6491  return (unsigned int)(getCurrentTicks() - m_ticks);
6492  }
6493  unsigned int Timer::getElapsedMilliseconds() const {
6494  return (unsigned int)((getCurrentTicks() - m_ticks)/1000);
6495  }
6496  double Timer::getElapsedSeconds() const {
6497  return (getCurrentTicks() - m_ticks)/1000000.0;
6498  }
6499 
6500 } // namespace Catch
6501 
6502 #ifdef __clang__
6503 #pragma clang diagnostic pop
6504 #endif
6505 // #included from: catch_common.hpp
6506 #define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
6507 
6508 namespace Catch {
6509 
6510  bool startsWith( std::string const& s, std::string const& prefix ) {
6511  return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
6512  }
6513  bool endsWith( std::string const& s, std::string const& suffix ) {
6514  return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
6515  }
6516  bool contains( std::string const& s, std::string const& infix ) {
6517  return s.find( infix ) != std::string::npos;
6518  }
6519  void toLowerInPlace( std::string& s ) {
6520  std::transform( s.begin(), s.end(), s.begin(), ::tolower );
6521  }
6522  std::string toLower( std::string const& s ) {
6523  std::string lc = s;
6524  toLowerInPlace( lc );
6525  return lc;
6526  }
6527  std::string trim( std::string const& str ) {
6528  static char const* whitespaceChars = "\n\r\t ";
6529  std::string::size_type start = str.find_first_not_of( whitespaceChars );
6530  std::string::size_type end = str.find_last_not_of( whitespaceChars );
6531 
6532  return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
6533  }
6534 
6535  pluralise::pluralise( std::size_t count, std::string const& label )
6536  : m_count( count ),
6537  m_label( label )
6538  {}
6539 
6540  std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
6541  os << pluraliser.m_count << " " << pluraliser.m_label;
6542  if( pluraliser.m_count != 1 )
6543  os << "s";
6544  return os;
6545  }
6546 
6547  SourceLineInfo::SourceLineInfo() : line( 0 ){}
6548  SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
6549  : file( _file ),
6550  line( _line )
6551  {}
6552  SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )
6553  : file( other.file ),
6554  line( other.line )
6555  {}
6556  bool SourceLineInfo::empty() const {
6557  return file.empty();
6558  }
6559  bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
6560  return line == other.line && file == other.file;
6561  }
6562 
6563  std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
6564 #ifndef __GNUG__
6565  os << info.file << "(" << info.line << ")";
6566 #else
6567  os << info.file << ":" << info.line;
6568 #endif
6569  return os;
6570  }
6571 
6572  void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
6573  std::ostringstream oss;
6574  oss << locationInfo << ": Internal Catch error: '" << message << "'";
6575  if( isTrue( true ))
6576  throw std::logic_error( oss.str() );
6577  }
6578 }
6579 
6580 // #included from: catch_section.hpp
6581 #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
6582 
6583 namespace Catch {
6584 
6585  Section::Section( SourceLineInfo const& lineInfo,
6586  std::string const& name,
6587  std::string const& description )
6588  : m_info( name, description, lineInfo ),
6589  m_sectionIncluded( getCurrentContext().getResultCapture().sectionStarted( m_info, m_assertions ) )
6590  {
6591  m_timer.start();
6592  }
6593 
6594  Section::~Section() {
6595  if( m_sectionIncluded )
6596  getCurrentContext().getResultCapture().sectionEnded( m_info, m_assertions, m_timer.getElapsedSeconds() );
6597  }
6598 
6599  // This indicates whether the section should be executed or not
6600  Section::operator bool() {
6601  return m_sectionIncluded;
6602  }
6603 
6604 } // end namespace Catch
6605 
6606 // #included from: catch_debugger.hpp
6607 #define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
6608 
6609 #include <iostream>
6610 
6611 #ifdef CATCH_PLATFORM_MAC
6612 
6613  #include <assert.h>
6614  #include <stdbool.h>
6615  #include <sys/types.h>
6616  #include <unistd.h>
6617  #include <sys/sysctl.h>
6618 
6619  namespace Catch{
6620 
6621  // The following function is taken directly from the following technical note:
6622  // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
6623 
6624  // Returns true if the current process is being debugged (either
6625  // running under the debugger or has a debugger attached post facto).
6626  bool isDebuggerActive(){
6627 
6628  int mib[4];
6629  struct kinfo_proc info;
6630  size_t size;
6631 
6632  // Initialize the flags so that, if sysctl fails for some bizarre
6633  // reason, we get a predictable result.
6634 
6635  info.kp_proc.p_flag = 0;
6636 
6637  // Initialize mib, which tells sysctl the info we want, in this case
6638  // we're looking for information about a specific process ID.
6639 
6640  mib[0] = CTL_KERN;
6641  mib[1] = KERN_PROC;
6642  mib[2] = KERN_PROC_PID;
6643  mib[3] = getpid();
6644 
6645  // Call sysctl.
6646 
6647  size = sizeof(info);
6648  if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0) != 0 ) {
6649  std::cerr << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
6650  return false;
6651  }
6652 
6653  // We're being debugged if the P_TRACED flag is set.
6654 
6655  return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
6656  }
6657  } // namespace Catch
6658 
6659 #elif defined(_MSC_VER)
6660  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
6661  namespace Catch {
6662  bool isDebuggerActive() {
6663  return IsDebuggerPresent() != 0;
6664  }
6665  }
6666 #elif defined(__MINGW32__)
6667  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
6668  namespace Catch {
6669  bool isDebuggerActive() {
6670  return IsDebuggerPresent() != 0;
6671  }
6672  }
6673 #else
6674  namespace Catch {
6675  inline bool isDebuggerActive() { return false; }
6676  }
6677 #endif // Platform
6678 
6679 #ifdef CATCH_PLATFORM_WINDOWS
6680  extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
6681  namespace Catch {
6682  void writeToDebugConsole( std::string const& text ) {
6683  ::OutputDebugStringA( text.c_str() );
6684  }
6685  }
6686 #else
6687  namespace Catch {
6688  void writeToDebugConsole( std::string const& text ) {
6689  // !TBD: Need a version for Mac/ XCode and other IDEs
6690  std::cout << text;
6691  }
6692  }
6693 #endif // Platform
6694 
6695 // #included from: ../reporters/catch_reporter_xml.hpp
6696 #define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
6697 
6698 // #included from: catch_reporter_bases.hpp
6699 #define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
6700 
6701 namespace Catch {
6702 
6703  struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
6704 
6705  StreamingReporterBase( ReporterConfig const& _config )
6706  : m_config( _config.fullConfig() ),
6707  stream( _config.stream() )
6708  {}
6709 
6710  virtual ~StreamingReporterBase();
6711 
6712  virtual void noMatchingTestCases( std::string const& ) {}
6713 
6714  virtual void testRunStarting( TestRunInfo const& _testRunInfo ) {
6715  currentTestRunInfo = _testRunInfo;
6716  }
6717  virtual void testGroupStarting( GroupInfo const& _groupInfo ) {
6718  currentGroupInfo = _groupInfo;
6719  }
6720 
6721  virtual void testCaseStarting( TestCaseInfo const& _testInfo ) {
6722  currentTestCaseInfo = _testInfo;
6723  }
6724  virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
6725  m_sectionStack.push_back( _sectionInfo );
6726  }
6727 
6728  virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) {
6729  m_sectionStack.pop_back();
6730  }
6731  virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) {
6732  currentTestCaseInfo.reset();
6733  assert( m_sectionStack.empty() );
6734  }
6735  virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) {
6736  currentGroupInfo.reset();
6737  }
6738  virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) {
6739  currentTestCaseInfo.reset();
6740  currentGroupInfo.reset();
6741  currentTestRunInfo.reset();
6742  }
6743 
6744  Ptr<IConfig> m_config;
6745  std::ostream& stream;
6746 
6747  LazyStat<TestRunInfo> currentTestRunInfo;
6748  LazyStat<GroupInfo> currentGroupInfo;
6749  LazyStat<TestCaseInfo> currentTestCaseInfo;
6750 
6751  std::vector<SectionInfo> m_sectionStack;
6752  };
6753 
6754  struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
6755  template<typename T, typename ChildNodeT>
6756  struct Node : SharedImpl<> {
6757  explicit Node( T const& _value ) : value( _value ) {}
6758  virtual ~Node() {}
6759 
6760  typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
6761  T value;
6762  ChildNodes children;
6763  };
6764  struct SectionNode : SharedImpl<> {
6765  explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
6766  virtual ~SectionNode();
6767 
6768  bool operator == ( SectionNode const& other ) const {
6769  return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
6770  }
6771  bool operator == ( Ptr<SectionNode> const& other ) const {
6772  return operator==( *other );
6773  }
6774 
6775  SectionStats stats;
6776  typedef std::vector<Ptr<SectionNode> > ChildSections;
6777  typedef std::vector<AssertionStats> Assertions;
6778  ChildSections childSections;
6779  Assertions assertions;
6780  std::string stdOut;
6781  std::string stdErr;
6782  };
6783 
6784  struct BySectionInfo {
6785  BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
6786  bool operator() ( Ptr<SectionNode> const& node ) const {
6787  return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
6788  }
6789  private:
6790  SectionInfo const& m_other;
6791  };
6792 
6793  typedef Node<TestCaseStats, SectionNode> TestCaseNode;
6794  typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
6795  typedef Node<TestRunStats, TestGroupNode> TestRunNode;
6796 
6797  CumulativeReporterBase( ReporterConfig const& _config )
6798  : m_config( _config.fullConfig() ),
6799  stream( _config.stream() )
6800  {}
6801  ~CumulativeReporterBase();
6802 
6803  virtual void testRunStarting( TestRunInfo const& ) {}
6804  virtual void testGroupStarting( GroupInfo const& ) {}
6805 
6806  virtual void testCaseStarting( TestCaseInfo const& ) {}
6807 
6808  virtual void sectionStarting( SectionInfo const& sectionInfo ) {
6809  SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
6810  Ptr<SectionNode> node;
6811  if( m_sectionStack.empty() ) {
6812  if( !m_rootSection )
6813  m_rootSection = new SectionNode( incompleteStats );
6814  node = m_rootSection;
6815  }
6816  else {
6817  SectionNode& parentNode = *m_sectionStack.back();
6818  SectionNode::ChildSections::const_iterator it =
6819  std::find_if( parentNode.childSections.begin(),
6820  parentNode.childSections.end(),
6821  BySectionInfo( sectionInfo ) );
6822  if( it == parentNode.childSections.end() ) {
6823  node = new SectionNode( incompleteStats );
6824  parentNode.childSections.push_back( node );
6825  }
6826  else
6827  node = *it;
6828  }
6829  m_sectionStack.push_back( node );
6830  m_deepestSection = node;
6831  }
6832 
6833  virtual void assertionStarting( AssertionInfo const& ) {}
6834 
6835  virtual bool assertionEnded( AssertionStats const& assertionStats ) {
6836  assert( !m_sectionStack.empty() );
6837  SectionNode& sectionNode = *m_sectionStack.back();
6838  sectionNode.assertions.push_back( assertionStats );
6839  return true;
6840  }
6841  virtual void sectionEnded( SectionStats const& sectionStats ) {
6842  assert( !m_sectionStack.empty() );
6843  SectionNode& node = *m_sectionStack.back();
6844  node.stats = sectionStats;
6845  m_sectionStack.pop_back();
6846  }
6847  virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
6848  Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
6849  assert( m_sectionStack.size() == 0 );
6850  node->children.push_back( m_rootSection );
6851  m_testCases.push_back( node );
6852  m_rootSection.reset();
6853 
6854  assert( m_deepestSection );
6855  m_deepestSection->stdOut = testCaseStats.stdOut;
6856  m_deepestSection->stdErr = testCaseStats.stdErr;
6857  }
6858  virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
6859  Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
6860  node->children.swap( m_testCases );
6861  m_testGroups.push_back( node );
6862  }
6863  virtual void testRunEnded( TestRunStats const& testRunStats ) {
6864  Ptr<TestRunNode> node = new TestRunNode( testRunStats );
6865  node->children.swap( m_testGroups );
6866  m_testRuns.push_back( node );
6867  testRunEndedCumulative();
6868  }
6869  virtual void testRunEndedCumulative() = 0;
6870 
6871  Ptr<IConfig> m_config;
6872  std::ostream& stream;
6873  std::vector<AssertionStats> m_assertions;
6874  std::vector<std::vector<Ptr<SectionNode> > > m_sections;
6875  std::vector<Ptr<TestCaseNode> > m_testCases;
6876  std::vector<Ptr<TestGroupNode> > m_testGroups;
6877 
6878  std::vector<Ptr<TestRunNode> > m_testRuns;
6879 
6880  Ptr<SectionNode> m_rootSection;
6881  Ptr<SectionNode> m_deepestSection;
6882  std::vector<Ptr<SectionNode> > m_sectionStack;
6883 
6884  };
6885 
6886 } // end namespace Catch
6887 
6888 // #included from: ../internal/catch_reporter_registrars.hpp
6889 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
6890 
6891 namespace Catch {
6892 
6893  template<typename T>
6894  class LegacyReporterRegistrar {
6895 
6896  class ReporterFactory : public IReporterFactory {
6897  virtual IStreamingReporter* create( ReporterConfig const& config ) const {
6898  return new LegacyReporterAdapter( new T( config ) );
6899  }
6900 
6901  virtual std::string getDescription() const {
6902  return T::getDescription();
6903  }
6904  };
6905 
6906  public:
6907 
6908  LegacyReporterRegistrar( std::string const& name ) {
6909  getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
6910  }
6911  };
6912 
6913  template<typename T>
6914  class ReporterRegistrar {
6915 
6916  class ReporterFactory : public IReporterFactory {
6917 
6918  // *** Please Note ***:
6919  // - If you end up here looking at a compiler error because it's trying to register
6920  // your custom reporter class be aware that the native reporter interface has changed
6921  // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via
6922  // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.
6923  // However please consider updating to the new interface as the old one is now
6924  // deprecated and will probably be removed quite soon!
6925  // Please contact me via github if you have any questions at all about this.
6926  // In fact, ideally, please contact me anyway to let me know you've hit this - as I have
6927  // no idea who is actually using custom reporters at all (possibly no-one!).
6928  // The new interface is designed to minimise exposure to interface changes in the future.
6929  virtual IStreamingReporter* create( ReporterConfig const& config ) const {
6930  return new T( config );
6931  }
6932 
6933  virtual std::string getDescription() const {
6934  return T::getDescription();
6935  }
6936  };
6937 
6938  public:
6939 
6940  ReporterRegistrar( std::string const& name ) {
6941  getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
6942  }
6943  };
6944 }
6945 
6946 #define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
6947  namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
6948 #define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
6949  namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
6950 
6951 // #included from: ../internal/catch_xmlwriter.hpp
6952 #define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
6953 
6954 #include <sstream>
6955 #include <iostream>
6956 #include <string>
6957 #include <vector>
6958 
6959 namespace Catch {
6960 
6961  class XmlWriter {
6962  public:
6963 
6964  class ScopedElement {
6965  public:
6966  ScopedElement( XmlWriter* writer )
6967  : m_writer( writer )
6968  {}
6969 
6970  ScopedElement( ScopedElement const& other )
6971  : m_writer( other.m_writer ){
6972  other.m_writer = NULL;
6973  }
6974 
6975  ~ScopedElement() {
6976  if( m_writer )
6977  m_writer->endElement();
6978  }
6979 
6980  ScopedElement& writeText( std::string const& text, bool indent = true ) {
6981  m_writer->writeText( text, indent );
6982  return *this;
6983  }
6984 
6985  template<typename T>
6986  ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
6987  m_writer->writeAttribute( name, attribute );
6988  return *this;
6989  }
6990 
6991  private:
6992  mutable XmlWriter* m_writer;
6993  };
6994 
6995  XmlWriter()
6996  : m_tagIsOpen( false ),
6997  m_needsNewline( false ),
6998  m_os( &std::cout )
6999  {}
7000 
7001  XmlWriter( std::ostream& os )
7002  : m_tagIsOpen( false ),
7003  m_needsNewline( false ),
7004  m_os( &os )
7005  {}
7006 
7007  ~XmlWriter() {
7008  while( !m_tags.empty() )
7009  endElement();
7010  }
7011 
7012  XmlWriter& operator = ( XmlWriter const& other ) {
7013  XmlWriter temp( other );
7014  swap( temp );
7015  return *this;
7016  }
7017 
7018  void swap( XmlWriter& other ) {
7019  std::swap( m_tagIsOpen, other.m_tagIsOpen );
7020  std::swap( m_needsNewline, other.m_needsNewline );
7021  std::swap( m_tags, other.m_tags );
7022  std::swap( m_indent, other.m_indent );
7023  std::swap( m_os, other.m_os );
7024  }
7025 
7026  XmlWriter& startElement( std::string const& name ) {
7027  ensureTagClosed();
7028  newlineIfNecessary();
7029  stream() << m_indent << "<" << name;
7030  m_tags.push_back( name );
7031  m_indent += " ";
7032  m_tagIsOpen = true;
7033  return *this;
7034  }
7035 
7036  ScopedElement scopedElement( std::string const& name ) {
7037  ScopedElement scoped( this );
7038  startElement( name );
7039  return scoped;
7040  }
7041 
7042  XmlWriter& endElement() {
7043  newlineIfNecessary();
7044  m_indent = m_indent.substr( 0, m_indent.size()-2 );
7045  if( m_tagIsOpen ) {
7046  stream() << "/>\n";
7047  m_tagIsOpen = false;
7048  }
7049  else {
7050  stream() << m_indent << "</" << m_tags.back() << ">\n";
7051  }
7052  m_tags.pop_back();
7053  return *this;
7054  }
7055 
7056  XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
7057  if( !name.empty() && !attribute.empty() ) {
7058  stream() << " " << name << "=\"";
7059  writeEncodedText( attribute );
7060  stream() << "\"";
7061  }
7062  return *this;
7063  }
7064 
7065  XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
7066  stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\"";
7067  return *this;
7068  }
7069 
7070  template<typename T>
7071  XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
7072  if( !name.empty() )
7073  stream() << " " << name << "=\"" << attribute << "\"";
7074  return *this;
7075  }
7076 
7077  XmlWriter& writeText( std::string const& text, bool indent = true ) {
7078  if( !text.empty() ){
7079  bool tagWasOpen = m_tagIsOpen;
7080  ensureTagClosed();
7081  if( tagWasOpen && indent )
7082  stream() << m_indent;
7083  writeEncodedText( text );
7084  m_needsNewline = true;
7085  }
7086  return *this;
7087  }
7088 
7089  XmlWriter& writeComment( std::string const& text ) {
7090  ensureTagClosed();
7091  stream() << m_indent << "<!--" << text << "-->";
7092  m_needsNewline = true;
7093  return *this;
7094  }
7095 
7096  XmlWriter& writeBlankLine() {
7097  ensureTagClosed();
7098  stream() << "\n";
7099  return *this;
7100  }
7101 
7102  private:
7103 
7104  std::ostream& stream() {
7105  return *m_os;
7106  }
7107 
7108  void ensureTagClosed() {
7109  if( m_tagIsOpen ) {
7110  stream() << ">\n";
7111  m_tagIsOpen = false;
7112  }
7113  }
7114 
7115  void newlineIfNecessary() {
7116  if( m_needsNewline ) {
7117  stream() << "\n";
7118  m_needsNewline = false;
7119  }
7120  }
7121 
7122  void writeEncodedText( std::string const& text ) {
7123  static const char* charsToEncode = "<&\"";
7124  std::string mtext = text;
7125  std::string::size_type pos = mtext.find_first_of( charsToEncode );
7126  while( pos != std::string::npos ) {
7127  stream() << mtext.substr( 0, pos );
7128 
7129  switch( mtext[pos] ) {
7130  case '<':
7131  stream() << "&lt;";
7132  break;
7133  case '&':
7134  stream() << "&amp;";
7135  break;
7136  case '\"':
7137  stream() << "&quot;";
7138  break;
7139  }
7140  mtext = mtext.substr( pos+1 );
7141  pos = mtext.find_first_of( charsToEncode );
7142  }
7143  stream() << mtext;
7144  }
7145 
7146  bool m_tagIsOpen;
7147  bool m_needsNewline;
7148  std::vector<std::string> m_tags;
7149  std::string m_indent;
7150  std::ostream* m_os;
7151  };
7152 
7153 }
7154 namespace Catch {
7155  class XmlReporter : public SharedImpl<IReporter> {
7156  public:
7157  XmlReporter( ReporterConfig const& config ) : m_config( config ), m_sectionDepth( 0 ) {}
7158 
7159  static std::string getDescription() {
7160  return "Reports test results as an XML document";
7161  }
7162  virtual ~XmlReporter();
7163 
7164  private: // IReporter
7165 
7166  virtual bool shouldRedirectStdout() const {
7167  return true;
7168  }
7169 
7170  virtual void StartTesting() {
7171  m_xml = XmlWriter( m_config.stream() );
7172  m_xml.startElement( "Catch" );
7173  if( !m_config.fullConfig()->name().empty() )
7174  m_xml.writeAttribute( "name", m_config.fullConfig()->name() );
7175  }
7176 
7177  virtual void EndTesting( const Totals& totals ) {
7178  m_xml.scopedElement( "OverallResults" )
7179  .writeAttribute( "successes", totals.assertions.passed )
7180  .writeAttribute( "failures", totals.assertions.failed );
7181  m_xml.endElement();
7182  }
7183 
7184  virtual void StartGroup( const std::string& groupName ) {
7185  m_xml.startElement( "Group" )
7186  .writeAttribute( "name", groupName );
7187  }
7188 
7189  virtual void EndGroup( const std::string&, const Totals& totals ) {
7190  m_xml.scopedElement( "OverallResults" )
7191  .writeAttribute( "successes", totals.assertions.passed )
7192  .writeAttribute( "failures", totals.assertions.failed );
7193  m_xml.endElement();
7194  }
7195 
7196  virtual void StartSection( const std::string& sectionName, const std::string& description ) {
7197  if( m_sectionDepth++ > 0 ) {
7198  m_xml.startElement( "Section" )
7199  .writeAttribute( "name", trim( sectionName ) )
7200  .writeAttribute( "description", description );
7201  }
7202  }
7203  virtual void NoAssertionsInSection( const std::string& ) {}
7204  virtual void NoAssertionsInTestCase( const std::string& ) {}
7205 
7206  virtual void EndSection( const std::string& /*sectionName*/, const Counts& assertions ) {
7207  if( --m_sectionDepth > 0 ) {
7208  m_xml.scopedElement( "OverallResults" )
7209  .writeAttribute( "successes", assertions.passed )
7210  .writeAttribute( "failures", assertions.failed );
7211  m_xml.endElement();
7212  }
7213  }
7214 
7215  virtual void StartTestCase( const Catch::TestCaseInfo& testInfo ) {
7216  m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
7217  m_currentTestSuccess = true;
7218  }
7219 
7220  virtual void Result( const Catch::AssertionResult& assertionResult ) {
7221  if( !m_config.fullConfig()->includeSuccessfulResults() && assertionResult.getResultType() == ResultWas::Ok )
7222  return;
7223 
7224  if( assertionResult.hasExpression() ) {
7225  m_xml.startElement( "Expression" )
7226  .writeAttribute( "success", assertionResult.succeeded() )
7227  .writeAttribute( "filename", assertionResult.getSourceInfo().file )
7228  .writeAttribute( "line", assertionResult.getSourceInfo().line );
7229 
7230  m_xml.scopedElement( "Original" )
7231  .writeText( assertionResult.getExpression() );
7232  m_xml.scopedElement( "Expanded" )
7233  .writeText( assertionResult.getExpandedExpression() );
7234  m_currentTestSuccess &= assertionResult.succeeded();
7235  }
7236 
7237  switch( assertionResult.getResultType() ) {
7239  m_xml.scopedElement( "Exception" )
7240  .writeAttribute( "filename", assertionResult.getSourceInfo().file )
7241  .writeAttribute( "line", assertionResult.getSourceInfo().line )
7242  .writeText( assertionResult.getMessage() );
7243  m_currentTestSuccess = false;
7244  break;
7245  case ResultWas::Info:
7246  m_xml.scopedElement( "Info" )
7247  .writeText( assertionResult.getMessage() );
7248  break;
7249  case ResultWas::Warning:
7250  m_xml.scopedElement( "Warning" )
7251  .writeText( assertionResult.getMessage() );
7252  break;
7254  m_xml.scopedElement( "Failure" )
7255  .writeText( assertionResult.getMessage() );
7256  m_currentTestSuccess = false;
7257  break;
7258  case ResultWas::Unknown:
7259  case ResultWas::Ok:
7260  case ResultWas::FailureBit:
7262  case ResultWas::Exception:
7264  break;
7265  }
7266  if( assertionResult.hasExpression() )
7267  m_xml.endElement();
7268  }
7269 
7270  virtual void Aborted() {
7271  // !TBD
7272  }
7273 
7274  virtual void EndTestCase( const Catch::TestCaseInfo&, const Totals&, const std::string&, const std::string& ) {
7275  m_xml.scopedElement( "OverallResult" ).writeAttribute( "success", m_currentTestSuccess );
7276  m_xml.endElement();
7277  }
7278 
7279  private:
7280  ReporterConfig m_config;
7281  bool m_currentTestSuccess;
7282  XmlWriter m_xml;
7283  int m_sectionDepth;
7284  };
7285 
7286 } // end namespace Catch
7287 
7288 // #included from: ../reporters/catch_reporter_junit.hpp
7289 #define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
7290 
7291 #include <assert.h>
7292 
7293 namespace Catch {
7294 
7295  class JunitReporter : public CumulativeReporterBase {
7296  public:
7297  JunitReporter( ReporterConfig const& _config )
7298  : CumulativeReporterBase( _config ),
7299  xml( _config.stream() )
7300  {}
7301 
7302  ~JunitReporter();
7303 
7304  static std::string getDescription() {
7305  return "Reports test results in an XML format that looks like Ant's junitreport target";
7306  }
7307 
7308  virtual void noMatchingTestCases( std::string const& /*spec*/ ) {}
7309 
7310  virtual ReporterPreferences getPreferences() const {
7311  ReporterPreferences prefs;
7312  prefs.shouldRedirectStdOut = true;
7313  return prefs;
7314  }
7315 
7316  virtual void testRunStarting( TestRunInfo const& runInfo ) {
7317  CumulativeReporterBase::testRunStarting( runInfo );
7318  xml.startElement( "testsuites" );
7319  }
7320 
7321  virtual void testGroupStarting( GroupInfo const& groupInfo ) {
7322  suiteTimer.start();
7323  stdOutForSuite.str("");
7324  stdErrForSuite.str("");
7325  unexpectedExceptions = 0;
7326  CumulativeReporterBase::testGroupStarting( groupInfo );
7327  }
7328 
7329  virtual bool assertionEnded( AssertionStats const& assertionStats ) {
7330  if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
7331  unexpectedExceptions++;
7332  return CumulativeReporterBase::assertionEnded( assertionStats );
7333  }
7334 
7335  virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
7336  stdOutForSuite << testCaseStats.stdOut;
7337  stdErrForSuite << testCaseStats.stdErr;
7338  CumulativeReporterBase::testCaseEnded( testCaseStats );
7339  }
7340 
7341  virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
7342  double suiteTime = suiteTimer.getElapsedSeconds();
7343  CumulativeReporterBase::testGroupEnded( testGroupStats );
7344  writeGroup( *m_testGroups.back(), suiteTime );
7345  }
7346 
7347  virtual void testRunEndedCumulative() {
7348  xml.endElement();
7349  }
7350 
7351  void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
7352  XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
7353  TestGroupStats const& stats = groupNode.value;
7354  xml.writeAttribute( "name", stats.groupInfo.name );
7355  xml.writeAttribute( "errors", unexpectedExceptions );
7356  xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
7357  xml.writeAttribute( "tests", stats.totals.assertions.total() );
7358  xml.writeAttribute( "hostname", "tbd" ); // !TBD
7359  if( m_config->showDurations() == ShowDurations::Never )
7360  xml.writeAttribute( "time", "" );
7361  else
7362  xml.writeAttribute( "time", suiteTime );
7363  xml.writeAttribute( "timestamp", "tbd" ); // !TBD
7364 
7365  // Write test cases
7366  for( TestGroupNode::ChildNodes::const_iterator
7367  it = groupNode.children.begin(), itEnd = groupNode.children.end();
7368  it != itEnd;
7369  ++it )
7370  writeTestCase( **it );
7371 
7372  xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
7373  xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
7374  }
7375 
7376  void writeTestCase( TestCaseNode const& testCaseNode ) {
7377  TestCaseStats const& stats = testCaseNode.value;
7378 
7379  // All test cases have exactly one section - which represents the
7380  // test case itself. That section may have 0-n nested sections
7381  assert( testCaseNode.children.size() == 1 );
7382  SectionNode const& rootSection = *testCaseNode.children.front();
7383 
7384  std::string className = stats.testInfo.className;
7385 
7386  if( className.empty() ) {
7387  if( rootSection.childSections.empty() )
7388  className = "global";
7389  }
7390  writeSection( className, "", rootSection );
7391  }
7392 
7393  void writeSection( std::string const& className,
7394  std::string const& rootName,
7395  SectionNode const& sectionNode ) {
7396  std::string name = trim( sectionNode.stats.sectionInfo.name );
7397  if( !rootName.empty() )
7398  name = rootName + "/" + name;
7399 
7400  if( !sectionNode.assertions.empty() ||
7401  !sectionNode.stdOut.empty() ||
7402  !sectionNode.stdErr.empty() ) {
7403  XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
7404  if( className.empty() ) {
7405  xml.writeAttribute( "classname", name );
7406  xml.writeAttribute( "name", "root" );
7407  }
7408  else {
7409  xml.writeAttribute( "classname", className );
7410  xml.writeAttribute( "name", name );
7411  }
7412  xml.writeAttribute( "time", toString( sectionNode.stats.durationInSeconds ) );
7413 
7414  writeAssertions( sectionNode );
7415 
7416  if( !sectionNode.stdOut.empty() )
7417  xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
7418  if( !sectionNode.stdErr.empty() )
7419  xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
7420  }
7421  for( SectionNode::ChildSections::const_iterator
7422  it = sectionNode.childSections.begin(),
7423  itEnd = sectionNode.childSections.end();
7424  it != itEnd;
7425  ++it )
7426  if( className.empty() )
7427  writeSection( name, "", **it );
7428  else
7429  writeSection( className, name, **it );
7430  }
7431 
7432  void writeAssertions( SectionNode const& sectionNode ) {
7433  for( SectionNode::Assertions::const_iterator
7434  it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
7435  it != itEnd;
7436  ++it )
7437  writeAssertion( *it );
7438  }
7439  void writeAssertion( AssertionStats const& stats ) {
7440  AssertionResult const& result = stats.assertionResult;
7441  if( !result.isOk() ) {
7442  std::string elementName;
7443  switch( result.getResultType() ) {
7445  elementName = "error";
7446  break;
7448  elementName = "failure";
7449  break;
7451  elementName = "failure";
7452  break;
7454  elementName = "failure";
7455  break;
7456 
7457  // We should never see these here:
7458  case ResultWas::Info:
7459  case ResultWas::Warning:
7460  case ResultWas::Ok:
7461  case ResultWas::Unknown:
7462  case ResultWas::FailureBit:
7463  case ResultWas::Exception:
7464  elementName = "internalError";
7465  break;
7466  }
7467 
7468  XmlWriter::ScopedElement e = xml.scopedElement( elementName );
7469 
7470  xml.writeAttribute( "message", result.getExpandedExpression() );
7471  xml.writeAttribute( "type", result.getTestMacroName() );
7472 
7473  std::ostringstream oss;
7474  if( !result.getMessage().empty() )
7475  oss << result.getMessage() << "\n";
7476  for( std::vector<MessageInfo>::const_iterator
7477  it = stats.infoMessages.begin(),
7478  itEnd = stats.infoMessages.end();
7479  it != itEnd;
7480  ++it )
7481  if( it->type == ResultWas::Info )
7482  oss << it->message << "\n";
7483 
7484  oss << "at " << result.getSourceInfo();
7485  xml.writeText( oss.str(), false );
7486  }
7487  }
7488 
7489  XmlWriter xml;
7490  Timer suiteTimer;
7491  std::ostringstream stdOutForSuite;
7492  std::ostringstream stdErrForSuite;
7493  unsigned int unexpectedExceptions;
7494  };
7495 
7496  INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
7497 
7498 } // end namespace Catch
7499 
7500 // #included from: ../reporters/catch_reporter_console.hpp
7501 #define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
7502 
7503 namespace Catch {
7504 
7505  struct ConsoleReporter : StreamingReporterBase {
7506  ConsoleReporter( ReporterConfig const& _config )
7507  : StreamingReporterBase( _config ),
7508  m_headerPrinted( false ),
7509  m_atLeastOneTestCasePrinted( false )
7510  {}
7511 
7512  virtual ~ConsoleReporter();
7513  static std::string getDescription() {
7514  return "Reports test results as plain lines of text";
7515  }
7516  virtual ReporterPreferences getPreferences() const {
7517  ReporterPreferences prefs;
7518  prefs.shouldRedirectStdOut = false;
7519  return prefs;
7520  }
7521 
7522  virtual void noMatchingTestCases( std::string const& spec ) {
7523  stream << "No test cases matched '" << spec << "'" << std::endl;
7524  }
7525 
7526  virtual void assertionStarting( AssertionInfo const& ) {
7527  }
7528 
7529  virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
7530  AssertionResult const& result = _assertionStats.assertionResult;
7531 
7532  bool printInfoMessages = true;
7533 
7534  // Drop out if result was successful and we're not printing those
7535  if( !m_config->includeSuccessfulResults() && result.isOk() ) {
7536  if( result.getResultType() != ResultWas::Warning )
7537  return false;
7538  printInfoMessages = false;
7539  }
7540 
7541  lazyPrint();
7542 
7543  AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
7544  printer.print();
7545  stream << std::endl;
7546  return true;
7547  }
7548 
7549  virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
7550  m_headerPrinted = false;
7551  StreamingReporterBase::sectionStarting( _sectionInfo );
7552  }
7553  virtual void sectionEnded( SectionStats const& _sectionStats ) {
7554  if( _sectionStats.missingAssertions ) {
7555  lazyPrint();
7556  Colour colour( Colour::ResultError );
7557  if( m_sectionStack.size() > 1 )
7558  stream << "\nNo assertions in section";
7559  else
7560  stream << "\nNo assertions in test case";
7561  stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
7562  }
7563  if( m_headerPrinted ) {
7564  if( m_config->showDurations() == ShowDurations::Always )
7565  stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
7566  m_headerPrinted = false;
7567  }
7568  else {
7569  if( m_config->showDurations() == ShowDurations::Always )
7570  stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
7571  }
7572  StreamingReporterBase::sectionEnded( _sectionStats );
7573  }
7574 
7575  virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) {
7576  StreamingReporterBase::testCaseEnded( _testCaseStats );
7577  m_headerPrinted = false;
7578  }
7579  virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) {
7580  if( currentGroupInfo.used ) {
7581  printSummaryDivider();
7582  stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
7583  printTotals( _testGroupStats.totals );
7584  stream << "\n" << std::endl;
7585  }
7586  StreamingReporterBase::testGroupEnded( _testGroupStats );
7587  }
7588  virtual void testRunEnded( TestRunStats const& _testRunStats ) {
7589  if( m_atLeastOneTestCasePrinted )
7590  printTotalsDivider();
7591  printTotals( _testRunStats.totals );
7592  stream << "\n" << std::endl;
7593  StreamingReporterBase::testRunEnded( _testRunStats );
7594  }
7595 
7596  private:
7597 
7598  class AssertionPrinter {
7599  void operator= ( AssertionPrinter const& );
7600  public:
7601  AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
7602  : stream( _stream ),
7603  stats( _stats ),
7604  result( _stats.assertionResult ),
7605  colour( Colour::None ),
7606  message( result.getMessage() ),
7607  messages( _stats.infoMessages ),
7608  printInfoMessages( _printInfoMessages )
7609  {
7610  switch( result.getResultType() ) {
7611  case ResultWas::Ok:
7612  colour = Colour::Success;
7613  passOrFail = "PASSED";
7614  //if( result.hasMessage() )
7615  if( _stats.infoMessages.size() == 1 )
7616  messageLabel = "with message";
7617  if( _stats.infoMessages.size() > 1 )
7618  messageLabel = "with messages";
7619  break;
7621  if( result.isOk() ) {
7622  colour = Colour::Success;
7623  passOrFail = "FAILED - but was ok";
7624  }
7625  else {
7626  colour = Colour::Error;
7627  passOrFail = "FAILED";
7628  }
7629  if( _stats.infoMessages.size() == 1 )
7630  messageLabel = "with message";
7631  if( _stats.infoMessages.size() > 1 )
7632  messageLabel = "with messages";
7633  break;
7635  colour = Colour::Error;
7636  passOrFail = "FAILED";
7637  messageLabel = "due to unexpected exception with message";
7638  break;
7640  colour = Colour::Error;
7641  passOrFail = "FAILED";
7642  messageLabel = "because no exception was thrown where one was expected";
7643  break;
7644  case ResultWas::Info:
7645  messageLabel = "info";
7646  break;
7647  case ResultWas::Warning:
7648  messageLabel = "warning";
7649  break;
7651  passOrFail = "FAILED";
7652  colour = Colour::Error;
7653  if( _stats.infoMessages.size() == 1 )
7654  messageLabel = "explicitly with message";
7655  if( _stats.infoMessages.size() > 1 )
7656  messageLabel = "explicitly with messages";
7657  break;
7658  // These cases are here to prevent compiler warnings
7659  case ResultWas::Unknown:
7660  case ResultWas::FailureBit:
7661  case ResultWas::Exception:
7662  passOrFail = "** internal error **";
7663  colour = Colour::Error;
7664  break;
7665  }
7666  }
7667 
7668  void print() const {
7669  printSourceInfo();
7670  if( stats.totals.assertions.total() > 0 ) {
7671  if( result.isOk() )
7672  stream << "\n";
7673  printResultType();
7674  printOriginalExpression();
7675  printReconstructedExpression();
7676  }
7677  else {
7678  stream << "\n";
7679  }
7680  printMessage();
7681  }
7682 
7683  private:
7684  void printResultType() const {
7685  if( !passOrFail.empty() ) {
7686  Colour colourGuard( colour );
7687  stream << passOrFail << ":\n";
7688  }
7689  }
7690  void printOriginalExpression() const {
7691  if( result.hasExpression() ) {
7692  Colour colourGuard( Colour::OriginalExpression );
7693  stream << " ";
7694  stream << result.getExpressionInMacro();
7695  stream << "\n";
7696  }
7697  }
7698  void printReconstructedExpression() const {
7699  if( result.hasExpandedExpression() ) {
7700  stream << "with expansion:\n";
7701  Colour colourGuard( Colour::ReconstructedExpression );
7702  stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n";
7703  }
7704  }
7705  void printMessage() const {
7706  if( !messageLabel.empty() )
7707  stream << messageLabel << ":" << "\n";
7708  for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
7709  it != itEnd;
7710  ++it ) {
7711  // If this assertion is a warning ignore any INFO messages
7712  if( printInfoMessages || it->type != ResultWas::Info )
7713  stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n";
7714  }
7715  }
7716  void printSourceInfo() const {
7717  Colour colourGuard( Colour::FileName );
7718  stream << result.getSourceInfo() << ": ";
7719  }
7720 
7721  std::ostream& stream;
7722  AssertionStats const& stats;
7723  AssertionResult const& result;
7724  Colour::Code colour;
7725  std::string passOrFail;
7726  std::string messageLabel;
7727  std::string message;
7728  std::vector<MessageInfo> messages;
7729  bool printInfoMessages;
7730  };
7731 
7732  void lazyPrint() {
7733 
7734  if( !currentTestRunInfo.used )
7735  lazyPrintRunInfo();
7736  if( !currentGroupInfo.used )
7737  lazyPrintGroupInfo();
7738 
7739  if( !m_headerPrinted ) {
7740  printTestCaseAndSectionHeader();
7741  m_headerPrinted = true;
7742  }
7743  m_atLeastOneTestCasePrinted = true;
7744  }
7745  void lazyPrintRunInfo() {
7746  stream << "\n" << getTildes() << "\n";
7747  Colour colour( Colour::SecondaryText );
7748  stream << currentTestRunInfo->name
7749  << " is a Catch v" << libraryVersion.majorVersion << "."
7750  << libraryVersion.minorVersion << " b"
7751  << libraryVersion.buildNumber;
7752  if( libraryVersion.branchName != "master" )
7753  stream << " (" << libraryVersion.branchName << ")";
7754  stream << " host application.\n"
7755  << "Run with -? for options\n\n";
7756 
7757  currentTestRunInfo.used = true;
7758  }
7759  void lazyPrintGroupInfo() {
7760  if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
7761  printClosedHeader( "Group: " + currentGroupInfo->name );
7762  currentGroupInfo.used = true;
7763  }
7764  }
7765  void printTestCaseAndSectionHeader() {
7766  assert( !m_sectionStack.empty() );
7767  printOpenHeader( currentTestCaseInfo->name );
7768 
7769  if( m_sectionStack.size() > 1 ) {
7770  Colour colourGuard( Colour::Headers );
7771 
7772  std::vector<SectionInfo>::const_iterator
7773  it = m_sectionStack.begin()+1, // Skip first section (test case)
7774  itEnd = m_sectionStack.end();
7775  for( ; it != itEnd; ++it )
7776  printHeaderString( it->name, 2 );
7777  }
7778 
7779  SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
7780 
7781  if( !lineInfo.empty() ){
7782  stream << getDashes() << "\n";
7783  Colour colourGuard( Colour::FileName );
7784  stream << lineInfo << "\n";
7785  }
7786  stream << getDots() << "\n" << std::endl;
7787  }
7788 
7789  void printClosedHeader( std::string const& _name ) {
7790  printOpenHeader( _name );
7791  stream << getDots() << "\n";
7792  }
7793  void printOpenHeader( std::string const& _name ) {
7794  stream << getDashes() << "\n";
7795  {
7796  Colour colourGuard( Colour::Headers );
7797  printHeaderString( _name );
7798  }
7799  }
7800 
7801  // if string has a : in first line will set indent to follow it on
7802  // subsequent lines
7803  void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
7804  std::size_t i = _string.find( ": " );
7805  if( i != std::string::npos )
7806  i+=2;
7807  else
7808  i = 0;
7809  stream << Text( _string, TextAttributes()
7810  .setIndent( indent+i)
7811  .setInitialIndent( indent ) ) << "\n";
7812  }
7813 
7814  void printTotals( const Totals& totals ) {
7815  if( totals.testCases.total() == 0 ) {
7816  stream << "No tests ran";
7817  }
7818  else if( totals.assertions.total() == 0 ) {
7819  Colour colour( Colour::Yellow );
7820  printCounts( "test case", totals.testCases );
7821  stream << " (no assertions)";
7822  }
7823  else if( totals.assertions.failed ) {
7824  Colour colour( Colour::ResultError );
7825  printCounts( "test case", totals.testCases );
7826  if( totals.testCases.failed > 0 ) {
7827  stream << " (";
7828  printCounts( "assertion", totals.assertions );
7829  stream << ")";
7830  }
7831  }
7832  else {
7833  Colour colour( Colour::ResultSuccess );
7834  stream << "All tests passed ("
7835  << pluralise( totals.assertions.passed, "assertion" ) << " in "
7836  << pluralise( totals.testCases.passed, "test case" ) << ")";
7837  }
7838  }
7839  void printCounts( std::string const& label, Counts const& counts ) {
7840  if( counts.total() == 1 ) {
7841  stream << "1 " << label << " - ";
7842  if( counts.failed )
7843  stream << "failed";
7844  else
7845  stream << "passed";
7846  }
7847  else {
7848  stream << counts.total() << " " << label << "s ";
7849  if( counts.passed ) {
7850  if( counts.failed )
7851  stream << "- " << counts.failed << " failed";
7852  else if( counts.passed == 2 )
7853  stream << "- both passed";
7854  else
7855  stream << "- all passed";
7856  }
7857  else {
7858  if( counts.failed == 2 )
7859  stream << "- both failed";
7860  else
7861  stream << "- all failed";
7862  }
7863  }
7864  }
7865 
7866  void printTotalsDivider() {
7867  stream << getDoubleDashes() << "\n";
7868  }
7869  void printSummaryDivider() {
7870  stream << getDashes() << "\n";
7871  }
7872  static std::string const& getDashes() {
7873  static const std::string dashes( CATCH_CONFIG_CONSOLE_WIDTH-1, '-' );
7874  return dashes;
7875  }
7876  static std::string const& getDots() {
7877  static const std::string dots( CATCH_CONFIG_CONSOLE_WIDTH-1, '.' );
7878  return dots;
7879  }
7880  static std::string const& getDoubleDashes() {
7881  static const std::string doubleDashes( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
7882  return doubleDashes;
7883  }
7884  static std::string const& getTildes() {
7885  static const std::string dots( CATCH_CONFIG_CONSOLE_WIDTH-1, '~' );
7886  return dots;
7887  }
7888 
7889  private:
7890  bool m_headerPrinted;
7891  bool m_atLeastOneTestCasePrinted;
7892  };
7893 
7894  INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
7895 
7896 } // end namespace Catch
7897 
7898 namespace Catch {
7900  IShared::~IShared() {}
7901  StreamBufBase::~StreamBufBase() throw() {}
7902  IContext::~IContext() {}
7910  IReporter::~IReporter() {}
7911  IReporterFactory::~IReporterFactory() {}
7912  IReporterRegistry::~IReporterRegistry() {}
7913  IStreamingReporter::~IStreamingReporter() {}
7914  AssertionStats::~AssertionStats() {}
7915  SectionStats::~SectionStats() {}
7916  TestCaseStats::~TestCaseStats() {}
7917  TestGroupStats::~TestGroupStats() {}
7918  TestRunStats::~TestRunStats() {}
7919  CumulativeReporterBase::SectionNode::~SectionNode() {}
7920  CumulativeReporterBase::~CumulativeReporterBase() {}
7921 
7922  StreamingReporterBase::~StreamingReporterBase() {}
7923  ConsoleReporter::~ConsoleReporter() {}
7924  IRunner::~IRunner() {}
7926  IConfig::~IConfig() {}
7927  XmlReporter::~XmlReporter() {}
7928  JunitReporter::~JunitReporter() {}
7929  TestRegistry::~TestRegistry() {}
7930  FreeFunctionTestCase::~FreeFunctionTestCase() {}
7933 
7938 
7939  void Config::dummy() {}
7940 
7941  INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( "xml", XmlReporter )
7942 }
7943 
7944 #ifdef __clang__
7945 #pragma clang diagnostic pop
7946 #endif
7947 
7948 #endif // CATCH_CONFIG_MAIN || CATCH_CONFIG_RUNNER
7949 
7950 #ifdef CATCH_CONFIG_MAIN
7951 // #included from: internal/catch_default_main.hpp
7952 #define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
7953 
7954 #ifndef __OBJC__
7955 
7956 // Standard C/C++ main entry point
7957 int main (int argc, char * const argv[]) {
7958  return Catch::Session().run( argc, argv );
7959 }
7960 
7961 #else // __OBJC__
7962 
7963 // Objective-C entry point
7964 int main (int argc, char * const argv[]) {
7965 #if !CATCH_ARC_ENABLED
7966  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
7967 #endif
7968 
7969  Catch::registerTestMethods();
7970  int result = Catch::Session().run( argc, (char* const*)argv );
7971 
7972 #if !CATCH_ARC_ENABLED
7973  [pool drain];
7974 #endif
7975 
7976  return result;
7977 }
7978 
7979 #endif // __OBJC__
7980 
7981 #endif // CATCH_CONFIG_MAIN
7982 
7984 
7985 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
7986 #ifdef CATCH_CONFIG_PREFIX_ALL
7987 
7988 #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
7989 #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::NegateResult, "CATCH_REQUIRE_FALSE" )
7990 
7991 #define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, ..., Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS" )
7992 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" )
7993 #define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" )
7994 
7995 #define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" )
7996 #define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::NegateResult, "CATCH_CHECK_FALSE" )
7997 #define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" )
7998 #define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" )
7999 #define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" )
8000 
8001 #define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, ..., Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" )
8002 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" )
8003 #define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
8004 
8005 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
8006 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
8007 
8008 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
8009 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
8010 #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
8011 #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
8012 #define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
8013 
8014 #ifdef CATCH_CONFIG_VARIADIC_MACROS
8015  #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
8016  #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
8017  #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
8018  #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
8019  #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
8020  #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
8021 #else
8022  #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
8023  #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
8024  #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
8025  #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
8026  #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
8027  #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
8028 #endif
8029 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
8030 
8031 #define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
8032 #define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
8033 
8034 #define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
8035 
8036 // "BDD-style" convenience wrappers
8037 #ifdef CATCH_CONFIG_VARIADIC_MACROS
8038 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
8039 #else
8040 #define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
8041 #endif
8042 #define CATCH_GIVEN( desc ) CATCH_SECTION( "Given: " desc, "" )
8043 #define CATCH_WHEN( desc ) CATCH_SECTION( " When: " desc, "" )
8044 #define CATCH_AND_WHEN( desc ) CATCH_SECTION( " And: " desc, "" )
8045 #define CATCH_THEN( desc ) CATCH_SECTION( " Then: " desc, "" )
8046 #define CATCH_AND_THEN( desc ) CATCH_SECTION( " And: " desc, "" )
8047 
8048 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
8049 #else
8050 
8051 #define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
8052 #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::NegateResult, "REQUIRE_FALSE" )
8053 
8054 #define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, ..., Catch::ResultDisposition::Normal, "REQUIRE_THROWS" )
8055 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" )
8056 #define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" )
8057 
8058 #define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" )
8059 #define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::NegateResult, "CHECK_FALSE" )
8060 #define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" )
8061 #define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" )
8062 #define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" )
8063 
8064 #define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, ..., Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS" )
8065 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
8066 #define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
8067 
8068 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" )
8069 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
8070 
8071 #define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
8072 #define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
8073 #define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
8074 #define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
8075 #define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
8076 
8077 #ifdef CATCH_CONFIG_VARIADIC_MACROS
8078  #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
8079  #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
8080  #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
8081  #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
8082  #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
8083  #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
8084 #else
8085  #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
8086  #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
8087  #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
8088  #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
8089  #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
8090  #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
8091 #endif
8092 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
8093 
8094 #define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
8095 #define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
8096 
8097 #define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
8098 
8099 #endif
8100 
8101 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
8102 
8103 // "BDD-style" convenience wrappers
8104 #ifdef CATCH_CONFIG_VARIADIC_MACROS
8105 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
8106 #else
8107 #define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
8108 #endif
8109 #define GIVEN( desc ) SECTION( " Given: " desc, "" )
8110 #define WHEN( desc ) SECTION( " When: " desc, "" )
8111 #define AND_WHEN( desc ) SECTION( "And when: " desc, "" )
8112 #define THEN( desc ) SECTION( " Then: " desc, "" )
8113 #define AND_THEN( desc ) SECTION( " And: " desc, "" )
8114 
8115 using Catch::Detail::Approx;
8116 
8117 #ifdef __clang__
8118 #pragma clang diagnostic pop
8119 #endif
8120 
8121 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
8122 
virtual ~IRegistryHub()
std::string getExpandedExpression() const
CompositeGenerator< T > between(T from, T to)
Definition: catch.hpp:1956
Approx operator()(double value)
Definition: catch.hpp:2090
friend std::ostream & operator<<(std::ostream &os, pluralise const &pluraliser)
bool isTrue(bool value)
Definition: catch.hpp:198
T & opCast(T const &t)
Definition: catch.hpp:1021
StartsWith(std::string const &substr)
Definition: catch.hpp:2280
unsigned int sequence
Definition: catch.hpp:1324
MessageInfo m_info
Definition: catch.hpp:1349
EndsWith(std::string const &substr)
Definition: catch.hpp:2296
virtual bool match(ExpressionT const &expr) const
Definition: catch.hpp:2183
virtual std::size_t size() const
Definition: catch.hpp:1852
ExpressionResultBuilder & setRhs(std::string const &rhs)
ExpressionResultBuilder & setResultType(ResultWas::OfType result)
SourceLineInfo getSourceInfo() const
static bool evaluate(T1 const &lhs, T2 const &rhs)
Definition: catch.hpp:1059
virtual bool match(ExpressionT const &expr) const
Definition: catch.hpp:2217
bool hasExpandedExpression() const
void throwLogicError(std::string const &message, SourceLineInfo const &locationInfo)
CompositeGenerator & then(CompositeGenerator &other)
Definition: catch.hpp:1928
MethodTestCase(void(C::*method)())
Definition: catch.hpp:426
std::size_t passed
Definition: catch.hpp:1734
static std::string convert(T const &_value)
Definition: catch.hpp:677
void(SafeBool::* type)() const
Definition: catch.hpp:143
ResultDisposition::Flags operator|(ResultDisposition::Flags lhs, ResultDisposition::Flags rhs)
Definition: catch.hpp:930
ExpressionResultBuilder & endExpression(ResultDisposition::Flags resultDisposition)
Definition: catch.hpp:1256
Equals(std::string const &str)
Definition: catch.hpp:2248
virtual T getValue(std::size_t index) const
Definition: catch.hpp:1871
Section(SourceLineInfo const &lineInfo, std::string const &name, std::string const &description="")
CompositeGenerator< T > values(T val1, T val2, T val3, T val4)
Definition: catch.hpp:1984
T * operator->() const
Definition: catch.hpp:318
std::string description
Definition: catch.hpp:1702
std::string getExpression() const
bool isHidden() const
MessageBuilder(std::string const &macroName, SourceLineInfo const &lineInfo, ResultWas::OfType type)
Definition: catch.hpp:1337
virtual ~IRunner()
std::string toString(T const &value)
converts any type to a string
Definition: catch.hpp:759
bool shouldNegate(int flags)
Definition: catch.hpp:935
virtual IResultCapture & getResultCapture()=0
static std::string convert(U *p)
Definition: catch.hpp:714
std::size_t line
Definition: catch.hpp:192
void swap(Ptr &other)
Definition: catch.hpp:314
SourceLineInfo lineInfo
Definition: catch.hpp:1703
std::string toString(unsigned char value)
Definition: catch.hpp:834
AssertionResult buildResult(AssertionInfo const &info) const
ExceptionTranslatorRegistrar(std::string(*translateFunction)(T &))
Definition: catch.hpp:2050
std::string capturedExpression
Definition: catch.hpp:953
std::string toString() const
Definition: catch.hpp:2124
std::string trim(std::string const &str)
ExpressionResultBuilder expressionResultBuilderFromMatcher(MatcherT const &matcher, std::string const &matcherCallAsString)
Definition: catch.hpp:1533
bool hasMessage() const
virtual std::string toString() const
Definition: catch.hpp:2288
SectionInfo(std::string const &_name, std::string const &_description, SourceLineInfo const &_lineInfo)
Definition: catch.hpp:1693
bool hasExpression() const
std::string reconstructedExpression
Definition: catch.hpp:961
TestCaseInfo const & getTestCaseInfo() const
Counts assertions
Definition: catch.hpp:1762
void deleteAllValues(AssociativeContainerT &container)
Definition: catch.hpp:160
Totals delta(Totals const &prevTotals) const
Definition: catch.hpp:1747
void swap(TestCase &other)
IContext & getCurrentContext()
Contains(std::string const &substr)
Definition: catch.hpp:2264
virtual T getValue(std::size_t index) const
Definition: catch.hpp:1848
std::set< std::string > tags
Definition: catch.hpp:2399
virtual ~IGenerator()
Definition: catch.hpp:1838
std::string getTestMacroName() const
IGeneratorsForTest * createGeneratorsForTest()
virtual Ptr< Matcher< ExpressionT > > clone() const
Definition: catch.hpp:2165
NotImplementedException(SourceLineInfo const &lineInfo)
bool hasTag(std::string const &tag) const
ResultDisposition::Flags resultDisposition
Definition: catch.hpp:954
#define CATCH_INTERNAL_ERROR(msg)
Definition: catch.hpp:218
virtual void popScopedMessage(MessageInfo const &message)=0
T & operator*() const
Definition: catch.hpp:317
virtual ~NonCopyable()
virtual IExceptionTranslatorRegistry & getExceptionTranslatorRegistry()=0
void writeToDebugConsole(std::string const &text)
virtual void registerTest(TestCase const &testInfo)=0
AllOf & add(Matcher< ExpressionT > const &matcher)
Definition: catch.hpp:2179
TestCaseInfo(std::string const &_name, std::string const &_className, std::string const &_description, std::set< std::string > const &_tags, bool _isHidden, SourceLineInfo const &_lineInfo)
std::string macroName
Definition: catch.hpp:1320
virtual void invoke() const
Definition: catch.hpp:428
AnyOf & add(Matcher< ExpressionT > const &matcher)
Definition: catch.hpp:2213
pluralise(std::size_t count, std::string const &label)
std::size_t total() const
Definition: catch.hpp:1730
bool applyEvaluator(T1 const &lhs, T2 const &rhs)
Definition: catch.hpp:1071
const char * name
Definition: catch.hpp:446
bool isJustInfo(int flags)
Definition: catch.hpp:909
ScopedMessage(MessageBuilder const &builder)
std::string getExpressionInMacro() const
std::string name
Definition: catch.hpp:2396
Stream createStream(std::string const &streamName)
void reset()
Definition: catch.hpp:299
Approx & scale(double newScale)
Definition: catch.hpp:2119
std::string(* exceptionTranslateFunction)()
Definition: catch.hpp:2013
virtual void registerTranslator(const IExceptionTranslator *translator)=0
std::size_t failed
Definition: catch.hpp:1735
NameAndDesc(const char *_name="", const char *_description="")
Definition: catch.hpp:442
bool operator==(TestCase const &other) const
virtual std::string toString() const
Definition: catch.hpp:2272
static bool evaluate(T1 const &lhs, T2 const &rhs)
Definition: catch.hpp:1047
std::string className
Definition: catch.hpp:2397
std::string description
Definition: catch.hpp:2398
static const char * getName()
Definition: catch.hpp:1012
IRegistryHub & getRegistryHub()
SourceLineInfo lineInfo
Definition: catch.hpp:2401
virtual ~IContext()
std::string message
Definition: catch.hpp:1323
MessageInfo(std::string const &_macroName, SourceLineInfo const &_lineInfo, ResultWas::OfType _type)
bool operator==(SourceLineInfo const &other) const
static std::string convert(R C::*p)
Definition: catch.hpp:724
static Approx custom()
Definition: catch.hpp:2086
virtual T getValue(std::size_t index) const =0
bool compare(T *lhs, int rhs)
Definition: catch.hpp:1140
void add(const IGenerator< T > *generator)
Definition: catch.hpp:1923
Approx(Approx const &other)
Definition: catch.hpp:2080
IMutableRegistryHub & getMutableRegistryHub()
std::vector< double > x(ncmax, 0)
virtual bool match(std::string const &expr) const
Definition: catch.hpp:2285
ExpressionResultBuilder & setOp(std::string const &op)
FalseType testStreamable(FalseType)
CompositeGenerator(CompositeGenerator &other)
Definition: catch.hpp:1889
virtual std::string toString() const
Definition: catch.hpp:2256
virtual std::string getCurrentTestName() const =0
std::string operator+()
Definition: catch.hpp:207
bool shouldContinueOnFailure(int flags)
Definition: catch.hpp:934
static std::string convert(T const &)
Definition: catch.hpp:671
Type
Type of JSON value.
Definition: rapidjson.h:513
virtual ~ITestCase()
SourceLineInfo lineInfo
Definition: catch.hpp:1321
std::string reconstructExpression(AssertionInfo const &info) const
TestCase withName(std::string const &_newName) const
Ptr(T *p)
Definition: catch.hpp:287
static bool evaluate(T1 const &lhs, T2 const &rhs)
Definition: catch.hpp:1065
ExpressionResultBuilder & endExpression(ResultDisposition::Flags resultDisposition)
virtual Ptr< Matcher > clone() const =0
virtual std::string toString() const
Definition: catch.hpp:2224
std::string rangeToString(InputIterator first, InputIterator last)
Definition: catch.hpp:862
virtual std::string toString() const
Definition: catch.hpp:2190
std::string makeString(const char *str)
Definition: catch.hpp:2245
virtual ITestCaseRegistry const & getTestCaseRegistry() const =0
ResultWas::OfType getResultType() const
virtual bool match(std::string const &expr) const
Definition: catch.hpp:2301
void toLowerInPlace(std::string &s)
virtual IReporterRegistry const & getReporterRegistry() const =0
void invoke() const
std::string name
Definition: catch.hpp:1701
#define INTERNAL_CATCH_STRINGIFY(expr)
Definition: catch.hpp:35
virtual bool match(std::string const &expr) const
Definition: catch.hpp:2269
void cleanUp()
const char * description
Definition: catch.hpp:447
std::string m_label
Definition: catch.hpp:180
double getElapsedSeconds() const
IResultCapture & getResultCapture()
Definition: catch.hpp:1528
std::size_t m_count
Definition: catch.hpp:179
std::string toLower(std::string const &s)
Impl::StdString::StartsWith StartsWith(const char *substr)
Definition: catch.hpp:2353
Impl::StdString::EndsWith EndsWith(const char *substr)
Definition: catch.hpp:2359
std::string getMessage() const
virtual std::string toString() const
Definition: catch.hpp:2304
virtual const char * what() const
bool operator<(TestCase const &other) const
ResultWas::OfType resultType
Definition: catch.hpp:963
unsigned int getElapsedNanoseconds() const
Impl::StdString::Equals Equals(const char *str)
Definition: catch.hpp:2341
virtual void addRef() const
Definition: catch.hpp:337
bool startsWith(std::string const &s, std::string const &prefix)
double double double *typedef void(CALLCONV AGdll_TYPE)(double *
Definition: REFPROP_lib.h:580
virtual std::vector< TestCase > getMatchingTestCases(std::string const &rawTestSpec) const =0
static bool evaluate(T1 const &lhs, T2 const &rhs)
Definition: catch.hpp:1041
virtual size_t getGeneratorIndex(std::string const &fileInfo, size_t totalSize)=0
Ptr(Ptr const &other)
Definition: catch.hpp:291
std::set< std::string > const & getTags() const
virtual void release() const
Definition: catch.hpp:340
BetweenGenerator(T from, T to)
Definition: catch.hpp:1846
MessageInfo m_info
Definition: catch.hpp:1358
bool matchesTags(std::string const &tagPattern) const
CompositeGenerator & then(T value)
Definition: catch.hpp:1933
CompositeGenerator & setFileInfo(const char *fileInfo)
Definition: catch.hpp:1896
virtual std::vector< TestCase > const & getAllTests() const =0
TestCase makeTestCase(ITestCase *testCase, std::string const &className, std::string const &name, std::string const &description, SourceLineInfo const &lineInfo)
static std::string convert(std::vector< T, Allocator > const &v)
Definition: catch.hpp:739
std::string tagsAsString
Definition: catch.hpp:2400
std::string makeString(T const &value)
Definition: catch.hpp:746
static bool evaluate(T1 const &lhs, T2 const &rhs)
Definition: catch.hpp:1035
void cleanUpContext()
IMutableContext & getCurrentMutableContext()
unsigned int m_rc
Definition: catch.hpp:345
AssertionInfo m_info
Definition: catch.hpp:986
std::string macroName
Definition: catch.hpp:951
Impl::StdString::Contains Contains(const char *substr)
Definition: catch.hpp:2347
virtual bool match(std::string const &expr) const
Definition: catch.hpp:2253
bool endsWith(std::string const &s, std::string const &suffix)
bool contains(std::string const &s, std::string const &infix)
TestCase(ITestCase *testCase, TestCaseInfo const &info)
ExpressionResultBuilder & setLhs(std::string const &lhs)
std::string file
Definition: catch.hpp:191
void(* TestFunction)()
Definition: catch.hpp:439
ExpressionResultBuilder & operator=(ExpressionResultBuilder const &other)
unsigned int getElapsedMilliseconds() const
virtual ~IConfig()
T const & operator+(T const &value, StreamEndStop)
Definition: catch.hpp:212
Impl::Generic::AnyOf< ExpressionT > AnyOf(Impl::Matcher< ExpressionT > const &m1, Impl::Matcher< ExpressionT > const &m2, Impl::Matcher< ExpressionT > const &m3)
Definition: catch.hpp:2332
Counts testCases
Definition: catch.hpp:1763
ExpressionResultBuilder(ResultWas::OfType resultType=ResultWas::Unknown)
std::string translateActiveException()
static bool evaluate(T1 const &lhs, T2 const &rhs)
Definition: catch.hpp:1053
static std::ostream & s
Definition: catch.hpp:661
StartsWith(StartsWith const &other)
Definition: catch.hpp:2281
AssertionResultData m_resultData
Definition: catch.hpp:987
Approx & epsilon(double newEpsilon)
Definition: catch.hpp:2114
SourceLineInfo lineInfo
Definition: catch.hpp:952
bool isDebuggerActive()
std::string rawMemoryToString(T value)
Definition: catch.hpp:687
virtual std::size_t size() const =0
ResultWas::OfType type
Definition: catch.hpp:1322
bool shouldSuppressFailure(int flags)
Definition: catch.hpp:936
virtual void sectionEnded(SectionInfo const &name, Counts const &assertions, double _durationInSeconds)=0
virtual bool advanceGeneratorsForCurrentTest()=0
bool empty() const
Impl::Generic::AllOf< ExpressionT > AllOf(Impl::Matcher< ExpressionT > const &m1, Impl::Matcher< ExpressionT > const &m2, Impl::Matcher< ExpressionT > const &m3)
Definition: catch.hpp:2321
TestCase & operator=(TestCase const &other)
std::ostringstream m_stream
Definition: catch.hpp:1350
std::ostream & operator<<(std::ostream &os, SourceLineInfo const &info)
virtual void pushScopedMessage(MessageInfo const &message)=0
static type makeSafe(bool value)
Definition: catch.hpp:145
AutoReg(void(C::*method)(), char const *className, NameAndDesc const &nameAndDesc, SourceLineInfo const &lineInfo)
Definition: catch.hpp:457
virtual std::size_t size() const
Definition: catch.hpp:1875
void deleteAll(ContainerT &container)
Definition: catch.hpp:153
bool isOk(ResultWas::OfType resultType)
Definition: catch.hpp:906
void add(T value)
Definition: catch.hpp:1867
virtual ~NotImplementedException()
Definition: catch.hpp:229
bool succeeded() const
virtual std::string translateActiveException() const =0
virtual ~IShared()
Approx(double value)
Definition: catch.hpp:2074
virtual void registerReporter(std::string const &name, IReporterFactory *factory)=0