The Winamp Remote Control suite
a remote control client and plugin for Winamp 2.x, 5.x
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
catch.hpp
Go to the documentation of this file.
1 /*
2  * Generated: 2012-08-31 18:50:03.965736
3  * ----------------------------------------------------------
4  * This file has been merged from multiple headers. Please don't edit it directly
5  * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
6  *
7  * Distributed under the Boost Software License, Version 1.0. (See accompanying
8  * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9  */
10 #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
11 #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
12 
13 #define TWOBLUECUBES_CATCH_HPP_INCLUDED
14 
15 #ifdef __clang__
16 #pragma clang diagnostic ignored "-Wno-global-constructors"
17 
18 #pragma clang diagnostic push
19 #pragma clang diagnostic ignored "-Wpadded"
20 #endif
21 
22 // #included from: internal/catch_notimplemented_exception.h
23 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
24 
25 // #included from: catch_common.h
26 #define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
27 
28 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
29 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
30 #define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
31 
32 #define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
33 #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
34 
35 #ifdef __GNUC__
36 #define CATCH_ATTRIBUTE_NORETURN __attribute__ ((noreturn))
37 #else
38 #define CATCH_ATTRIBUTE_NORETURN
39 #endif
40 
41 #include <sstream>
42 #include <stdexcept>
43 #include <algorithm>
44 
45 namespace Catch {
46 
47  class NonCopyable {
48  NonCopyable( const NonCopyable& );
49  void operator = ( const NonCopyable& );
50  protected:
51  NonCopyable() {}
52  virtual ~NonCopyable();
53  };
54 
55  class SafeBool {
56  public:
57  typedef void (SafeBool::*type)() const;
58 
59  static type makeSafe( bool value ) {
60  return value ? &SafeBool::trueValue : 0;
61  }
62  private:
63  void trueValue() const {}
64  };
65 
66  template<typename ContainerT>
67  inline void deleteAll( ContainerT& container ) {
68  typename ContainerT::const_iterator it = container.begin();
69  typename ContainerT::const_iterator itEnd = container.end();
70  for(; it != itEnd; ++it )
71  {
72  delete *it;
73  }
74  }
75  template<typename AssociativeContainerT>
76  inline void deleteAllValues( AssociativeContainerT& container ) {
77  typename AssociativeContainerT::const_iterator it = container.begin();
78  typename AssociativeContainerT::const_iterator itEnd = container.end();
79  for(; it != itEnd; ++it )
80  {
81  delete it->second;
82  }
83  }
84 
85  template<typename ContainerT, typename Function>
86  inline void forEach( ContainerT& container, Function function ) {
87  std::for_each( container.begin(), container.end(), function );
88  }
89 
90  template<typename ContainerT, typename Function>
91  inline void forEach( const ContainerT& container, Function function ) {
92  std::for_each( container.begin(), container.end(), function );
93  }
94 
95  inline bool startsWith( const std::string& s, const std::string& prefix ) {
96  return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
97  }
98  inline bool endsWith( const std::string& s, const std::string& suffix ) {
99  return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
100  }
101  inline bool contains( const std::string& s, const std::string& infix ) {
102  return s.find( infix ) != std::string::npos;
103  }
104 
105  struct pluralise {
106  pluralise( std::size_t count, const std::string& label )
107  : m_count( count ),
108  m_label( label )
109  {}
110 
111  friend std::ostream& operator << ( std::ostream& os, const pluralise& pluraliser ) {
112  os << pluraliser.m_count << " " << pluraliser.m_label;
113  if( pluraliser.m_count != 1 )
114  os << "s";
115  return os;
116  }
117 
118  std::size_t m_count;
119  std::string m_label;
120  };
121 
122  struct SourceLineInfo {
123 
124  SourceLineInfo() : line( 0 ){}
125  SourceLineInfo( const std::string& _file, std::size_t _line )
126  : file( _file ),
127  line( _line )
128  {}
129  SourceLineInfo( const std::string& _function, const std::string& _file, std::size_t _line )
130  : function( _function ),
131  file( _file ),
132  line( _line )
133  {}
134  SourceLineInfo( const SourceLineInfo& other )
135  : file( other.file ),
136  line( other.line )
137  {}
138  void swap( SourceLineInfo& other ){
139  file.swap( other.file );
140  std::swap( line, other.line );
141  }
142 
143  std::string function;
144  std::string file;
145  std::size_t line;
146  };
147 
148  inline std::ostream& operator << ( std::ostream& os, const SourceLineInfo& info ) {
149 #ifndef __GNUG__
150  os << info.file << "(" << info.line << "): ";
151 #else
152  os << info.file << ":" << info.line << ": ";
153 #endif
154  return os;
155  }
156 
158  inline void throwLogicError( const std::string& message, const SourceLineInfo& locationInfo ) {
159  std::ostringstream oss;
160  oss << "Internal Catch error: '" << message << "' at: " << locationInfo;
161  throw std::logic_error( oss.str() );
162  }
163 }
164 
165 #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
166 #define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
167 
168 #include <ostream>
169 
170 namespace Catch {
171 
172  class NotImplementedException : public std::exception
173  {
174  public:
175  NotImplementedException( const SourceLineInfo& lineInfo );
176 
177  virtual ~NotImplementedException() throw() {}
178 
179  virtual const char* what() const throw();
180 
181  private:
182  std::string m_what;
183  SourceLineInfo m_lineInfo;
184  };
185 
186 } // end namespace Catch
187 
189 #define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
190 
191 // #included from: internal/catch_context.h
192 #define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
193 
194 // #included from: catch_interfaces_generators.h
195 #define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
196 
197 #include <string>
198 
199 namespace Catch {
200 
201  struct IGeneratorInfo {
202  virtual ~IGeneratorInfo();
203  virtual bool moveNext() = 0;
204  virtual std::size_t getCurrentIndex() const = 0;
205  };
206 
207  struct IGeneratorsForTest {
208  virtual ~IGeneratorsForTest();
209 
210  virtual IGeneratorInfo& getGeneratorInfo( const std::string& fileInfo, std::size_t size ) = 0;
211  virtual bool moveNext() = 0;
212  };
213 
214  IGeneratorsForTest* createGeneratorsForTest();
215 
216 } // end namespace Catch
217 
218 #include <memory>
219 #include <vector>
220 #include <stdlib.h>
221 
222 namespace Catch {
223 
224  class TestCaseInfo;
225  struct IResultCapture;
226  struct IRunner;
227  struct IGeneratorsForTest;
228  struct IConfig;
229 
230  class StreamBufBase : public std::streambuf {
231  public:
232  virtual ~StreamBufBase();
233  };
234 
235  struct IContext
236  {
237  virtual ~IContext();
238 
239  virtual IResultCapture& getResultCapture() = 0;
240  virtual IRunner& getRunner() = 0;
241  virtual size_t getGeneratorIndex( const std::string& fileInfo, size_t totalSize ) = 0;
242  virtual bool advanceGeneratorsForCurrentTest() = 0;
243  virtual const IConfig* getConfig() const = 0;
244  };
245 
246  struct IMutableContext : IContext
247  {
248  virtual ~IMutableContext();
249  virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
250  virtual void setRunner( IRunner* runner ) = 0;
251  virtual void setConfig( const IConfig* config ) = 0;
252  };
253 
254  IContext& getCurrentContext();
255  IMutableContext& getCurrentMutableContext();
256  void cleanUpContext();
257  std::streambuf* createStreamBuf( const std::string& streamName );
258 
259 }
260 
261 // #included from: internal/catch_test_registry.hpp
262 #define TWOBLUECUBES_CATCH_REGISTRY_HPP_INCLUDED
263 
264 // #included from: catch_interfaces_testcase.h
265 #define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
266 
267 // #included from: catch_ptr.hpp
268 #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
269 
270 namespace Catch {
271 
272  // An intrusive reference counting smart pointer.
273  // T must implement addRef() and release() methods
274  // typically implementing the IShared interface
275  template<typename T>
276  class Ptr {
277  public:
278  Ptr() : m_p( NULL ){}
279  Ptr( T* p ) : m_p( p ){
280  if( m_p )
281  m_p->addRef();
282  }
283  Ptr( const Ptr& other ) : m_p( other.m_p ){
284  if( m_p )
285  m_p->addRef();
286  }
287  ~Ptr(){
288  if( m_p )
289  m_p->release();
290  }
291  Ptr& operator = ( T* p ){
292  Ptr temp( p );
293  swap( temp );
294  return *this;
295  }
296  Ptr& operator = ( const Ptr& other ){
297  Ptr temp( other );
298  swap( temp );
299  return *this;
300  }
301  void swap( Ptr& other ){
302  std::swap( m_p, other.m_p );
303  }
304 
305  T* get(){
306  return m_p;
307  }
308  const T* get() const{
309  return m_p;
310  }
311 
312  T& operator*() const {
313  return *m_p;
314  }
315 
316  T* operator->() const {
317  return m_p;
318  }
319 
320  bool operator !() const {
321  return m_p == NULL;
322  }
323 
324  private:
325  T* m_p;
326  };
327 
328  struct IShared : NonCopyable {
329  virtual ~IShared();
330  virtual void addRef() = 0;
331  virtual void release() = 0;
332  };
333 
334  template<typename T>
335  struct SharedImpl : T {
336 
337  SharedImpl() : m_rc( 0 ){}
338 
339  virtual void addRef(){
340  ++m_rc;
341  }
342  virtual void release(){
343  if( --m_rc == 0 )
344  delete this;
345  }
346 
347  int m_rc;
348  };
349 
350 } // end namespace Catch
351 
352 #include <vector>
353 
354 namespace Catch {
355 
356  class TestCaseFilters;
357 
358  struct ITestCase : IShared {
359  virtual void invoke () const = 0;
360  protected:
361  virtual ~ITestCase();
362  };
363 
364  class TestCaseInfo;
365 
366  struct ITestCaseRegistry {
367  virtual ~ITestCaseRegistry();
368  virtual const std::vector<TestCaseInfo>& getAllTests() const = 0;
369  virtual std::vector<TestCaseInfo> getMatchingTestCases( const std::string& rawTestSpec ) const = 0;
370  };
371 }
372 
373 namespace Catch {
374 
375 template<typename C>
376 class MethodTestCase : public SharedImpl<ITestCase> {
377 
378 public:
379  MethodTestCase( void (C::*method)() ) : m_method( method ) {}
380 
381  virtual void invoke() const {
382  C obj;
383  (obj.*m_method)();
384  }
385 
386 private:
387  virtual ~MethodTestCase() {}
388 
389  void (C::*m_method)();
390 };
391 
392 typedef void(*TestFunction)();
393 
394 struct AutoReg {
395 
396  AutoReg( TestFunction function,
397  const char* name,
398  const char* description,
399  const SourceLineInfo& lineInfo );
400 
401  template<typename C>
402  AutoReg( void (C::*method)(),
403  const char* name,
404  const char* description,
405  const SourceLineInfo& lineInfo ) {
406  registerTestCase( new MethodTestCase<C>( method ), name, description, lineInfo );
407  }
408 
409  void registerTestCase( ITestCase* testCase,
410  const char* name,
411  const char* description,
412  const SourceLineInfo& lineInfo );
413 
414  ~AutoReg();
415 
416 private:
417  AutoReg( const AutoReg& );
418  void operator= ( const AutoReg& );
419 };
420 
421 } // end namespace Catch
422 
424 #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
425  static void INTERNAL_CATCH_UNIQUE_NAME( TestCaseFunction_catch_internal_ )(); \
426  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( TestCaseFunction_catch_internal_ ), Name, Desc, CATCH_INTERNAL_LINEINFO ); }\
427  static void INTERNAL_CATCH_UNIQUE_NAME( TestCaseFunction_catch_internal_ )()
428 
430 #define INTERNAL_CATCH_TESTCASE_NORETURN( Name, Desc ) \
431  static void INTERNAL_CATCH_UNIQUE_NAME( TestCaseFunction_catch_internal_ )() CATCH_ATTRIBUTE_NORETURN; \
432  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( TestCaseFunction_catch_internal_ ), Name, Desc, CATCH_INTERNAL_LINEINFO ); }\
433  static void INTERNAL_CATCH_UNIQUE_NAME( TestCaseFunction_catch_internal_ )()
434 
436 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
437  namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, Name, Desc, CATCH_INTERNAL_LINEINFO ); }
438 
440 #define TEST_CASE_METHOD( ClassName, TestName, Desc )\
441  namespace{ \
442  struct INTERNAL_CATCH_UNIQUE_NAME( TestCaseMethod_catch_internal_ ) : ClassName{ \
443  void test(); \
444  }; \
445  Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( TestCaseMethod_catch_internal_ )::test, TestName, Desc, CATCH_INTERNAL_LINEINFO ); \
446  } \
447  void INTERNAL_CATCH_UNIQUE_NAME( TestCaseMethod_catch_internal_ )::test()
448 
449 // #included from: internal/catch_capture.hpp
450 #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
451 
452 // #included from: catch_expression_builder.hpp
453 #define TWOBLUECUBES_CATCH_EXPRESSION_BUILDER_HPP_INCLUDED
454 
455 // #included from: catch_expression.hpp
456 #define TWOBLUECUBES_CATCH_EXPRESSION_HPP_INCLUDED
457 
458 // #included from: catch_resultinfo_builder.h
459 #define TWOBLUECUBES_CATCH_RESULTINFO_BUILDER_H_INCLUDED
460 
461 // #included from: catch_tostring.hpp
462 #define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
463 
464 #include <sstream>
465 
466 #ifdef __OBJC__
467 // #included from: catch_objc_arc.hpp
468 #define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
469 
470 #import <Foundation/Foundation.h>
471 
472 #ifdef __has_feature
473 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
474 #else
475 #define CATCH_ARC_ENABLED 0
476 #endif
477 
478 void arcSafeRelease( NSObject* obj );
479 id performOptionalSelector( id obj, SEL sel );
480 
481 #if !CATCH_ARC_ENABLED
482 inline void arcSafeRelease( NSObject* obj ) {
483  [obj release];
484 }
485 inline id performOptionalSelector( id obj, SEL sel ) {
486  if( [obj respondsToSelector: sel] )
487  return [obj performSelector: sel];
488  return nil;
489 }
490 #define CATCH_UNSAFE_UNRETAINED
491 #define CATCH_ARC_STRONG
492 #else
493 inline void arcSafeRelease( NSObject* ){}
494 inline id performOptionalSelector( id obj, SEL sel ) {
495 #ifdef __clang__
496 #pragma clang diagnostic push
497 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
498 #endif
499  if( [obj respondsToSelector: sel] )
500  return [obj performSelector: sel];
501 #ifdef __clang__
502 #pragma clang diagnostic pop
503 #endif
504  return nil;
505 }
506 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
507 #define CATCH_ARC_STRONG __strong
508 #endif
509 
510 #endif
511 
512 namespace Catch {
513 namespace Detail {
514 
515  struct NonStreamable {
516  template<typename T> NonStreamable( const T& ){}
517  };
518 
519  // If the type does not have its own << overload for ostream then
520  // this one will be used instead
521  inline std::ostream& operator << ( std::ostream& ss, NonStreamable ){
522  return ss << "{?}";
523  }
524 
525  template<typename T>
526  inline std::string makeString( const T& value ) {
527  std::ostringstream oss;
528  oss << value;
529  return oss.str();
530  }
531 
532  template<typename T>
533  inline std::string makeString( T* p ) {
534  if( !p )
535  return INTERNAL_CATCH_STRINGIFY( NULL );
536  std::ostringstream oss;
537  oss << p;
538  return oss.str();
539  }
540 
541  template<typename T>
542  inline std::string makeString( const T* p ) {
543  if( !p )
544  return INTERNAL_CATCH_STRINGIFY( NULL );
545  std::ostringstream oss;
546  oss << p;
547  return oss.str();
548  }
549 
550 } // end namespace Detail
551 
559 template<typename T>
560 std::string toString( const T& value ) {
561  return Detail::makeString( value );
562 }
563 
564 // Built in overloads
565 
566 inline std::string toString( const std::string& value ) {
567  return "\"" + value + "\"";
568 }
569 
570 inline std::string toString( const std::wstring& value ) {
571  std::ostringstream oss;
572  oss << "\"";
573  for(size_t i = 0; i < value.size(); ++i )
574  oss << static_cast<char>( value[i] <= 0xff ? value[i] : '?');
575  oss << "\"";
576  return oss.str();
577 }
578 
579 inline std::string toString( const char* const value ) {
580  return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
581 }
582 
583 inline std::string toString( char* const value ) {
584  return Catch::toString( static_cast<const char*>( value ) );
585 }
586 
587 inline std::string toString( int value ) {
588  std::ostringstream oss;
589  oss << value;
590  return oss.str();
591 }
592 
593 inline std::string toString( unsigned long value ) {
594  std::ostringstream oss;
595  if( value > 8192 )
596  oss << "0x" << std::hex << value;
597  else
598  oss << value;
599  return oss.str();
600 }
601 
602 inline std::string toString( unsigned int value ) {
603  return toString( static_cast<unsigned long>( value ) );
604 }
605 
606 inline std::string toString( const double value ) {
607  std::ostringstream oss;
608  oss << value;
609  return oss.str();
610 }
611 
612 inline std::string toString( bool value ) {
613  return value ? "true" : "false";
614 }
615 
616 inline std::string toString( char value ) {
617  return value < ' '
618  ? toString( (unsigned int)value )
619  : Detail::makeString( value );
620 }
621 
622 inline std::string toString( signed char value ) {
623  return toString( static_cast<char>( value ) );
624 }
625 
626 #ifdef CATCH_CONFIG_CPP11_NULLPTR
627 inline std::string toString( std::nullptr_t ) {
628  return "nullptr";
629 }
630 #endif
631 
632 #ifdef __OBJC__
633  inline std::string toString( NSString const * const& nsstring ) {
634  return std::string( "@\"" ) + [nsstring UTF8String] + "\"";
635  }
636  inline std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
637  return std::string( "@\"" ) + [nsstring UTF8String] + "\"";
638  }
639  inline std::string toString( NSObject* const& nsObject ) {
640  return toString( [nsObject description] );
641  }
642 #endif
643 
644 } // end namespace Catch
645 
646 // #included from: catch_resultinfo.h
647 #define TWOBLUECUBES_CATCH_RESULT_INFO_H_INCLUDED
648 
649 #include <string>
650 // #included from: catch_result_type.h
651 #define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
652 
653 namespace Catch {
654 
655 struct ResultWas { enum OfType {
656  Unknown = -1,
657  Ok = 0,
658  Info = 1,
659  Warning = 2,
660 
661  FailureBit = 0x10,
662 
663  ExpressionFailed = FailureBit | 1,
664  ExplicitFailure = FailureBit | 2,
665 
666  Exception = 0x100 | FailureBit,
667 
668  ThrewException = Exception | 1,
669  DidntThrowException = Exception | 2
670 
671 }; };
672 
673 struct ResultAction { enum Value {
674  None,
675  Failed = 1, // Failure - but no debug break if Debug bit not set
676  Debug = 2, // If this bit is set, invoke the debugger
677  Abort = 4 // Test run should abort
678 }; };
679 
680 }
681 
682 
683 namespace Catch {
684 
685  class ResultInfo {
686  public:
687  ResultInfo();
688  ResultInfo( const char* expr,
689  ResultWas::OfType result,
690  bool isNot,
691  const SourceLineInfo& lineInfo,
692  const char* macroName,
693  const char* message );
694  ~ResultInfo();
695 
696  bool ok() const;
697  ResultWas::OfType getResultType() const;
698  bool hasExpression() const;
699  bool hasMessage() const;
700  std::string getExpression() const;
701  bool hasExpandedExpression() const;
702  std::string getExpandedExpression() const;
703  std::string getMessage() const;
704  std::string getFilename() const;
705  std::size_t getLine() const;
706  std::string getTestMacroName() const;
707 
708  protected:
709 
710  std::string getExpandedExpressionInternal() const;
711  bool isNotExpression( const char* expr );
712 
713  protected:
714  std::string m_macroName;
715  SourceLineInfo m_lineInfo;
716  std::string m_expr, m_lhs, m_rhs, m_op;
717  std::string m_message;
718  ResultWas::OfType m_result;
719  bool m_isNot;
720  };
721 
722 } // end namespace Catch
723 
724 // #included from: catch_evaluate.hpp
725 #define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
726 
727 namespace Catch {
728 namespace Internal {
729 
730  enum Operator {
731  IsEqualTo,
732  IsNotEqualTo,
733  IsLessThan,
734  IsGreaterThan,
735  IsLessThanOrEqualTo,
736  IsGreaterThanOrEqualTo
737  };
738 
739  template<Operator Op> struct OperatorTraits { static const char* getName(){ return "*error*"; } };
740  template<> struct OperatorTraits<IsEqualTo> { static const char* getName(){ return "=="; } };
741  template<> struct OperatorTraits<IsNotEqualTo> { static const char* getName(){ return "!="; } };
742  template<> struct OperatorTraits<IsLessThan> { static const char* getName(){ return "<"; } };
743  template<> struct OperatorTraits<IsGreaterThan> { static const char* getName(){ return ">"; } };
744  template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } };
745  template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
746 
747  // So the compare overloads can be operator agnostic we convey the operator as a template
748  // enum, which is used to specialise an Evaluator for doing the comparison.
749  template<typename T1, typename T2, Operator Op>
750  class Evaluator{};
751 
752  template<typename T1, typename T2>
753  struct Evaluator<T1, T2, IsEqualTo> {
754  static bool evaluate( const T1& lhs, const T2& rhs) {
755  return const_cast<T1&>( lhs ) == const_cast<T2&>( rhs );
756  }
757  };
758  template<typename T1, typename T2>
759  struct Evaluator<T1, T2, IsNotEqualTo> {
760  static bool evaluate( const T1& lhs, const T2& rhs ) {
761  return const_cast<T1&>( lhs ) != const_cast<T2&>( rhs );
762  }
763  };
764  template<typename T1, typename T2>
765  struct Evaluator<T1, T2, IsLessThan> {
766  static bool evaluate( const T1& lhs, const T2& rhs ) {
767  return const_cast<T1&>( lhs ) < const_cast<T2&>( rhs );
768  }
769  };
770  template<typename T1, typename T2>
771  struct Evaluator<T1, T2, IsGreaterThan> {
772  static bool evaluate( const T1& lhs, const T2& rhs ) {
773  return const_cast<T1&>( lhs ) > const_cast<T2&>( rhs );
774  }
775  };
776  template<typename T1, typename T2>
777  struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
778  static bool evaluate( const T1& lhs, const T2& rhs ) {
779  return const_cast<T1&>( lhs ) >= const_cast<T2&>( rhs );
780  }
781  };
782  template<typename T1, typename T2>
783  struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
784  static bool evaluate( const T1& lhs, const T2& rhs ) {
785  return const_cast<T1&>( lhs ) <= const_cast<T2&>( rhs );
786  }
787  };
788 
789  template<Operator Op, typename T1, typename T2>
790  bool applyEvaluator( const T1& lhs, const T2& rhs ) {
791  return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
792  }
793 
794  // "base" overload
795  template<Operator Op, typename T1, typename T2>
796  bool compare( const T1& lhs, const T2& rhs ) {
797  return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
798  }
799 
800  // unsigned X to int
801  template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
802  return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
803  }
804  template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
805  return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
806  }
807  template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
808  return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
809  }
810 
811  // unsigned X to long
812  template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
813  return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
814  }
815  template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
816  return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
817  }
818  template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
819  return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
820  }
821 
822  // int to unsigned X
823  template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
824  return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
825  }
826  template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
827  return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
828  }
829  template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
830  return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
831  }
832 
833  // long to unsigned X
834  template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
835  return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
836  }
837  template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
838  return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
839  }
840  template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
841  return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
842  }
843 
844  // pointer to long (when comparing against NULL)
845  template<Operator Op, typename T>
846  bool compare( long lhs, const T* rhs ) {
847  return Evaluator<const T*, const T*, Op>::evaluate( reinterpret_cast<const T*>( lhs ), rhs );
848  }
849 
850  template<Operator Op, typename T>
851  bool compare( long lhs, T* rhs ) {
852  return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
853  }
854 
855  template<Operator Op, typename T>
856  bool compare( const T* lhs, long rhs ) {
857  return Evaluator<const T*, const T*, Op>::evaluate( lhs, reinterpret_cast<const T*>( rhs ) );
858  }
859 
860  template<Operator Op, typename T>
861  bool compare( T* lhs, long rhs ) {
862  return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
863  }
864 
865  // pointer to int (when comparing against NULL)
866  template<Operator Op, typename T>
867  bool compare( int lhs, const T* rhs ) {
868  return Evaluator<const T*, const T*, Op>::evaluate( reinterpret_cast<const T*>( lhs ), rhs );
869  }
870 
871  template<Operator Op, typename T>
872  bool compare( int lhs, T* rhs ) {
873  return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
874  }
875 
876  template<Operator Op, typename T>
877  bool compare( const T* lhs, int rhs ) {
878  return Evaluator<const T*, const T*, Op>::evaluate( lhs, reinterpret_cast<const T*>( rhs ) );
879  }
880 
881  template<Operator Op, typename T>
882  bool compare( T* lhs, int rhs ) {
883  return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
884  }
885 
886 } // end of namespace Internal
887 } // end of namespace Catch
888 
889 namespace Catch {
890 
891 struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
892 
893 class ResultInfoBuilder : public ResultInfo {
894 
895 public:
896 
897  ResultInfoBuilder();
898 
899  ResultInfoBuilder( const char* expr,
900  bool isNot,
901  const SourceLineInfo& lineInfo,
902  const char* macroName,
903  const char* message = "" );
904 
905  void setResultType( ResultWas::OfType result );
906  void setMessage( const std::string& message );
907  void setLineInfo( const SourceLineInfo& lineInfo );
908  void setLhs( const std::string& lhs );
909  void setRhs( const std::string& rhs );
910  void setOp( const std::string& op );
911 
912  template<typename RhsT>
913  STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator ||
914  (
915  const RhsT&
916  );
917 
918  template<typename RhsT>
919  STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator &&
920  (
921  const RhsT&
922  );
923 
924 private:
925  friend class ExpressionBuilder;
926  template<typename T> friend class Expression;
927 
928  template<typename T> friend class PtrExpression;
929 
930  ResultInfoBuilder& captureBoolExpression( bool result );
931 
932  template<Internal::Operator Op, typename T1, typename T2>
933  ResultInfoBuilder& captureExpression( const T1& lhs, const T2& rhs ) {
934  setResultType( Internal::compare<Op>( lhs, rhs ) ? ResultWas::Ok : ResultWas::ExpressionFailed );
935  m_lhs = Catch::toString( lhs );
936  m_rhs = Catch::toString( rhs );
937  m_op = Internal::OperatorTraits<Op>::getName();
938  return *this;
939  }
940 
941  template<Internal::Operator Op, typename T>
942  ResultInfoBuilder& captureExpression( const T* lhs, int rhs ) {
943  return captureExpression<Op>( lhs, reinterpret_cast<const T*>( rhs ) );
944  }
945 };
946 
947 } // end namespace Catch
948 
949 namespace Catch {
950 
951 template<typename T>
952 class Expression {
953  void operator = ( const Expression& );
954 
955 public:
956  Expression( ResultInfoBuilder& result, T lhs )
957  : m_result( result ),
958  m_lhs( lhs )
959  {}
960 
961  template<typename RhsT>
962  ResultInfoBuilder& operator == ( const RhsT& rhs ) {
963  return m_result.captureExpression<Internal::IsEqualTo>( m_lhs, rhs );
964  }
965 
966  template<typename RhsT>
967  ResultInfoBuilder& operator != ( const RhsT& rhs ) {
968  return m_result.captureExpression<Internal::IsNotEqualTo>( m_lhs, rhs );
969  }
970 
971  template<typename RhsT>
972  ResultInfoBuilder& operator < ( const RhsT& rhs ) {
973  return m_result.captureExpression<Internal::IsLessThan>( m_lhs, rhs );
974  }
975 
976  template<typename RhsT>
977  ResultInfoBuilder& operator > ( const RhsT& rhs ) {
978  return m_result.captureExpression<Internal::IsGreaterThan>( m_lhs, rhs );
979  }
980 
981  template<typename RhsT>
982  ResultInfoBuilder& operator <= ( const RhsT& rhs ) {
983  return m_result.captureExpression<Internal::IsLessThanOrEqualTo>( m_lhs, rhs );
984  }
985 
986  template<typename RhsT>
987  ResultInfoBuilder& operator >= ( const RhsT& rhs ) {
988  return m_result.captureExpression<Internal::IsGreaterThanOrEqualTo>( m_lhs, rhs );
989  }
990 
991  ResultInfoBuilder& operator == ( bool rhs ) {
992  return m_result.captureExpression<Internal::IsEqualTo>( m_lhs, rhs );
993  }
994 
995  ResultInfoBuilder& operator != ( bool rhs ) {
996  return m_result.captureExpression<Internal::IsNotEqualTo>( m_lhs, rhs );
997  }
998 
999  operator ResultInfoBuilder& () {
1000  return m_result.captureBoolExpression( m_lhs );
1001  }
1002 
1003  template<typename RhsT>
1004  STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( const RhsT& );
1005 
1006  template<typename RhsT>
1007  STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( const RhsT& );
1008 
1009 private:
1010  ResultInfoBuilder& m_result;
1011  T m_lhs;
1012 };
1013 
1014 } // end namespace Catch
1015 
1016 #include <sstream>
1017 
1018 namespace Catch {
1019 
1020 class ExpressionBuilder {
1021 public:
1022 
1023  ExpressionBuilder( const SourceLineInfo& lineInfo,
1024  const char* macroName,
1025  const char* expr = "",
1026  bool isNot = false )
1027  : m_result( expr, isNot, lineInfo, macroName ),
1028  m_messageStream()
1029  {}
1030 
1031  template<typename T>
1032  Expression<const T&> operator->* ( const T & operand ) {
1033  Expression<const T&> expr( m_result, operand );
1034  return expr;
1035  }
1036 
1037  Expression<bool> operator->* ( bool value ) {
1038  Expression<bool> expr( m_result, value );
1039  return expr;
1040  }
1041 
1042  template<typename T>
1043  ExpressionBuilder& operator << ( const T & value ) {
1044  m_messageStream << Catch::toString( value );
1045  return *this;
1046  }
1047 
1048  template<typename MatcherT, typename ArgT>
1049  ExpressionBuilder& acceptMatcher( const MatcherT& matcher,
1050  const ArgT& arg,
1051  const std::string& matcherCallAsString ) {
1052  std::string matcherAsString = Catch::toString( matcher );
1053  if( matcherAsString == "{?}" )
1054  matcherAsString = matcherCallAsString;
1055  m_result.setLhs( Catch::toString( arg ) );
1056  m_result.setRhs( matcherAsString );
1057  m_result.setOp( "matches" );
1058  m_result.setResultType( matcher( arg ) ? ResultWas::Ok : ResultWas::ExpressionFailed );
1059  return *this;
1060  }
1061 
1062  template<typename MatcherT, typename ArgT>
1063  ExpressionBuilder& acceptMatcher( const MatcherT& matcher,
1064  ArgT* arg,
1065  const std::string& matcherCallAsString ) {
1066  std::string matcherAsString = Catch::toString( matcher );
1067  if( matcherAsString == "{?}" )
1068  matcherAsString = matcherCallAsString;
1069  m_result.setLhs( Catch::toString( arg ) );
1070  m_result.setRhs( matcherAsString );
1071  m_result.setOp( "matches" );
1072  m_result.setResultType( matcher( arg ) ? ResultWas::Ok : ResultWas::ExpressionFailed );
1073  return *this;
1074  }
1075 
1076  ExpressionBuilder& setResultType( ResultWas::OfType resultType ) {
1077  m_result.setResultType( resultType );
1078  return *this;
1079  }
1080 
1081  operator ResultInfoBuilder&() {
1082  m_result.setMessage( m_messageStream.str() );
1083  return m_result;
1084  }
1085 
1086 private:
1087  ResultInfoBuilder m_result;
1088  std::ostringstream m_messageStream;
1089 };
1090 
1091 } // end namespace Catch
1092 
1093 // #included from: catch_interfaces_capture.h
1094 #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
1095 
1096 #include <string>
1097 // #included from: catch_totals.hpp
1098 #define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
1099 
1100 namespace Catch {
1101 
1102  struct Counts {
1103  Counts() : passed( 0 ), failed( 0 ) {}
1104 
1105  Counts operator - ( const Counts& other ) const {
1106  Counts diff;
1107  diff.passed = passed - other.passed;
1108  diff.failed = failed - other.failed;
1109  return diff;
1110  }
1111  Counts& operator += ( const Counts& other ) {
1112  passed += other.passed;
1113  failed += other.failed;
1114  return *this;
1115  }
1116 
1117  std::size_t total() const {
1118  return passed + failed;
1119  }
1120 
1121  std::size_t passed;
1122  std::size_t failed;
1123  };
1124 
1125  struct Totals {
1126 
1127  Totals operator - ( const Totals& other ) const {
1128  Totals diff;
1129  diff.assertions = assertions - other.assertions;
1130  diff.testCases = testCases - other.testCases;
1131  return diff;
1132  }
1133 
1134  Totals delta( const Totals& prevTotals ) const {
1135  Totals diff = *this - prevTotals;
1136  if( diff.assertions.failed > 0 )
1137  ++diff.testCases.failed;
1138  else
1139  ++diff.testCases.passed;
1140  return diff;
1141  }
1142 
1143  Totals& operator += ( const Totals& other ) {
1144  assertions += other.assertions;
1145  testCases += other.testCases;
1146  return *this;
1147  }
1148 
1149  Counts assertions;
1150  Counts testCases;
1151  };
1152 }
1153 
1154 
1155 namespace Catch {
1156 
1157  class TestCaseInfo;
1158  class ScopedInfo;
1159  class ResultInfoBuilder;
1160  class ResultInfo;
1161 
1162  struct IResultCapture {
1163 
1164  virtual ~IResultCapture();
1165 
1166  virtual void testEnded( const ResultInfo& result ) = 0;
1167  virtual bool sectionStarted( const std::string& name,
1168  const std::string& description,
1169  const SourceLineInfo& lineInfo,
1170  Counts& assertions ) = 0;
1171  virtual void sectionEnded( const std::string& name, const Counts& assertions ) = 0;
1172  virtual void pushScopedInfo( ScopedInfo* scopedInfo ) = 0;
1173  virtual void popScopedInfo( ScopedInfo* scopedInfo ) = 0;
1174  virtual bool shouldDebugBreak() const = 0;
1175 
1176  virtual ResultAction::Value acceptResult( bool result ) = 0;
1177  virtual ResultAction::Value acceptResult( ResultWas::OfType result ) = 0;
1178  virtual ResultAction::Value acceptExpression( const ResultInfoBuilder& resultInfo ) = 0;
1179  virtual void acceptMessage( const std::string& msg ) = 0;
1180 
1181  virtual std::string getCurrentTestName() const = 0;
1182  virtual const ResultInfo* getLastResult() const = 0;
1183  };
1184 }
1185 
1186 // #included from: catch_debugger.hpp
1187 #define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
1188 
1189 #include <iostream>
1190 
1191 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
1192 #define CATCH_PLATFORM_MAC
1193 #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
1194 #define CATCH_PLATFORM_IPHONE
1195 #elif defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
1196 #define CATCH_PLATFORM_WINDOWS
1197 #endif
1198 
1199 #ifdef CATCH_PLATFORM_MAC
1200 
1201  #include <assert.h>
1202  #include <stdbool.h>
1203  #include <sys/types.h>
1204  #include <unistd.h>
1205  #include <sys/sysctl.h>
1206 
1207  namespace Catch{
1208 
1209  // The following function is taken directly from the following technical note:
1210  // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
1211 
1212  // Returns true if the current process is being debugged (either
1213  // running under the debugger or has a debugger attached post facto).
1214  inline bool isDebuggerActive(){
1215 
1216  int junk;
1217  int mib[4];
1218  struct kinfo_proc info;
1219  size_t size;
1220 
1221  // Initialize the flags so that, if sysctl fails for some bizarre
1222  // reason, we get a predictable result.
1223 
1224  info.kp_proc.p_flag = 0;
1225 
1226  // Initialize mib, which tells sysctl the info we want, in this case
1227  // we're looking for information about a specific process ID.
1228 
1229  mib[0] = CTL_KERN;
1230  mib[1] = KERN_PROC;
1231  mib[2] = KERN_PROC_PID;
1232  mib[3] = getpid();
1233 
1234  // Call sysctl.
1235 
1236  size = sizeof(info);
1237  junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0);
1238  assert(junk == 0);
1239 
1240  // We're being debugged if the P_TRACED flag is set.
1241 
1242  return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
1243  }
1244  }
1245 
1246  // The following code snippet taken from:
1247  // http://cocoawithlove.com/2008/03/break-into-debugger.html
1248  #ifdef DEBUG
1249  #if defined(__ppc64__) || defined(__ppc__)
1250  #define BreakIntoDebugger() \
1251  if( Catch::isDebuggerActive() ) { \
1252  __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
1253  : : : "memory","r0","r3","r4" ); \
1254  }
1255  #else
1256  #define BreakIntoDebugger() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
1257  #endif
1258  #else
1259  inline void BreakIntoDebugger(){}
1260  #endif
1261 
1262 #elif defined(_MSC_VER)
1263  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
1264  #define BreakIntoDebugger() if (IsDebuggerPresent() ) { __debugbreak(); }
1265  inline bool isDebuggerActive() {
1266  return IsDebuggerPresent() != 0;
1267  }
1268 #elif defined(__MINGW32__)
1269  extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
1270  extern "C" __declspec(dllimport) void __stdcall DebugBreak();
1271  #define BreakIntoDebugger() if (IsDebuggerPresent() ) { DebugBreak(); }
1272  inline bool isDebuggerActive() {
1273  return IsDebuggerPresent() != 0;
1274  }
1275 #else
1276  inline void BreakIntoDebugger(){}
1277  inline bool isDebuggerActive() { return false; }
1278 #endif
1279 
1280 #ifdef CATCH_PLATFORM_WINDOWS
1281 extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
1282 inline void writeToDebugConsole( const std::string& text ) {
1283  ::OutputDebugStringA( text.c_str() );
1284 }
1285 #else
1286 inline void writeToDebugConsole( const std::string& text ) {
1287  // !TBD: Need a version for Mac/ XCode and other IDEs
1288  std::cout << text;
1289 }
1290 #endif // CATCH_PLATFORM_WINDOWS
1291 
1292 #include <ostream>
1293 
1294 namespace Catch {
1295 
1296 struct TestFailureException{};
1297 
1298 class ScopedInfo {
1299 public:
1300  ScopedInfo() : m_oss() {
1301  getCurrentContext().getResultCapture().pushScopedInfo( this );
1302  }
1303 
1304  ~ScopedInfo() {
1305  getCurrentContext().getResultCapture().popScopedInfo( this );
1306  }
1307 
1308  template<typename T>
1309  ScopedInfo& operator << ( const T& value ) {
1310  m_oss << value;
1311  return *this;
1312  }
1313 
1314  std::string getInfo () const {
1315  return m_oss.str();
1316  }
1317 
1318 private:
1319  std::ostringstream m_oss;
1320 };
1321 
1322 // This is just here to avoid compiler warnings with macro constants
1323 inline bool isTrue( bool value ){ return value; }
1324 
1325 } // end namespace Catch
1326 
1328 #define INTERNAL_CATCH_ACCEPT_EXPR( expr, stopOnFailure, originalExpr ) \
1329  if( Catch::ResultAction::Value internal_catch_action = Catch::getCurrentContext().getResultCapture().acceptExpression( expr ) ) { \
1330  if( internal_catch_action & Catch::ResultAction::Debug ) BreakIntoDebugger(); \
1331  if( internal_catch_action & Catch::ResultAction::Abort ) throw Catch::TestFailureException(); \
1332  if( Catch::isTrue( stopOnFailure ) ) throw Catch::TestFailureException(); \
1333  if( Catch::isTrue( false ) ){ bool this_is_here_to_invoke_warnings = ( originalExpr ); Catch::isTrue( this_is_here_to_invoke_warnings ); } \
1334  }
1335 
1337 #define INTERNAL_CATCH_TEST( expr, isNot, stopOnFailure, macroName ) \
1338  do { try { \
1339  INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionBuilder( CATCH_INTERNAL_LINEINFO, macroName, #expr, isNot )->*expr ), stopOnFailure, expr ); \
1340  } catch( Catch::TestFailureException& ) { \
1341  throw; \
1342  } catch( ... ) { \
1343  INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionBuilder( CATCH_INTERNAL_LINEINFO, macroName, #expr ) << Catch::getRegistryHub().getExceptionTranslatorRegistry().translateActiveException() ).setResultType( Catch::ResultWas::ThrewException ), false, expr ); \
1344  throw; \
1345  } } while( Catch::isTrue( false ) )
1346 
1348 #define INTERNAL_CATCH_IF( expr, isNot, stopOnFailure, macroName ) \
1349  INTERNAL_CATCH_TEST( expr, isNot, stopOnFailure, macroName ); \
1350  if( Catch::getCurrentContext().getResultCapture().getLastResult()->ok() )
1351 
1353 #define INTERNAL_CATCH_ELSE( expr, isNot, stopOnFailure, macroName ) \
1354  INTERNAL_CATCH_TEST( expr, isNot, stopOnFailure, macroName ); \
1355  if( !Catch::getCurrentContext().getResultCapture().getLastResult()->ok() )
1356 
1358 #define INTERNAL_CATCH_NO_THROW( expr, stopOnFailure, macroName ) \
1359  try { \
1360  expr; \
1361  INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionBuilder( CATCH_INTERNAL_LINEINFO, macroName, #expr ).setResultType( Catch::ResultWas::Ok ), stopOnFailure, false ); \
1362  } \
1363  catch( ... ) { \
1364  INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionBuilder( CATCH_INTERNAL_LINEINFO, macroName, #expr ) << Catch::getRegistryHub().getExceptionTranslatorRegistry().translateActiveException() ).setResultType( Catch::ResultWas::ThrewException ), stopOnFailure, false ); \
1365  }
1366 
1368 #define INTERNAL_CATCH_THROWS( expr, exceptionType, stopOnFailure, macroName ) \
1369  try { \
1370  if( Catch::getCurrentContext().getConfig()->allowThrows() ) { \
1371  expr; \
1372  INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionBuilder( CATCH_INTERNAL_LINEINFO, macroName, #expr ).setResultType( Catch::ResultWas::DidntThrowException ), stopOnFailure, false ); \
1373  } \
1374  } \
1375  catch( Catch::TestFailureException& ) { \
1376  throw; \
1377  } \
1378  catch( exceptionType ) { \
1379  INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionBuilder( CATCH_INTERNAL_LINEINFO, macroName, #expr ).setResultType( Catch::ResultWas::Ok ), stopOnFailure, false ); \
1380  }
1381 
1383 #define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, stopOnFailure, macroName ) \
1384  INTERNAL_CATCH_THROWS( expr, exceptionType, stopOnFailure, macroName ) \
1385  catch( ... ) { \
1386  INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionBuilder( CATCH_INTERNAL_LINEINFO, macroName, #expr ) << Catch::getRegistryHub().getExceptionTranslatorRegistry() ).setResultType( Catch::ResultWas::ThrewException ), stopOnFailure, false ); \
1387  }
1388 
1390 #define INTERNAL_CATCH_MSG( reason, resultType, stopOnFailure, macroName ) \
1391  Catch::getCurrentContext().getResultCapture().acceptExpression( ( Catch::ExpressionBuilder( CATCH_INTERNAL_LINEINFO, macroName ) << reason ).setResultType( resultType ) );
1392 
1394 #define INTERNAL_CATCH_SCOPED_INFO( log ) \
1395  Catch::ScopedInfo INTERNAL_CATCH_UNIQUE_NAME( info ); \
1396  INTERNAL_CATCH_UNIQUE_NAME( info ) << log
1397 
1399 #define INTERNAL_CHECK_THAT( arg, matcher, stopOnFailure, macroName ) \
1400  do { try { \
1401  INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionBuilder( CATCH_INTERNAL_LINEINFO, macroName, #arg " " #matcher, false ).acceptMatcher( ::Catch::Matchers::matcher, arg, #matcher ) ), stopOnFailure, false ); \
1402  } catch( Catch::TestFailureException& ) { \
1403  throw; \
1404  } catch( ... ) { \
1405  INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionBuilder( CATCH_INTERNAL_LINEINFO, macroName, #arg " " #matcher ) << Catch::getRegistryHub().getExceptionTranslatorRegistry().translateActiveException() ).setResultType( Catch::ResultWas::ThrewException ), false, false ); \
1406  throw; \
1407  }}while( Catch::isTrue( false ) )
1408 
1409 // #included from: internal/catch_section.hpp
1410 #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
1411 
1412 #include <string>
1413 
1414 namespace Catch {
1415 
1416  class Section {
1417  public:
1418  Section( const std::string& name,
1419  const std::string& description,
1420  const SourceLineInfo& lineInfo )
1421  : m_name( name ),
1422  m_sectionIncluded( getCurrentContext().getResultCapture().sectionStarted( name, description, lineInfo, m_assertions ) )
1423  {}
1424 
1425  ~Section() {
1426  if( m_sectionIncluded )
1427  getCurrentContext().getResultCapture().sectionEnded( m_name, m_assertions );
1428  }
1429 
1430  // This indicates whether the section should be executed or not
1431  operator bool() {
1432  return m_sectionIncluded;
1433  }
1434 
1435  private:
1436 
1437  std::string m_name;
1438  Counts m_assertions;
1439  bool m_sectionIncluded;
1440  };
1441 
1442 } // end namespace Catch
1443 
1444 #define INTERNAL_CATCH_SECTION( name, desc ) \
1445  if( Catch::Section INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::Section( name, desc, CATCH_INTERNAL_LINEINFO ) )
1446 
1447 // #included from: internal/catch_generators.hpp
1448 #define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
1449 
1450 #include <iterator>
1451 #include <vector>
1452 #include <string>
1453 #include <stdlib.h>
1454 
1455 namespace Catch {
1456 
1457 template<typename T>
1458 struct IGenerator {
1459  virtual ~IGenerator() {}
1460  virtual T getValue( std::size_t index ) const = 0;
1461  virtual std::size_t size () const = 0;
1462 };
1463 
1464 template<typename T>
1465 class BetweenGenerator : public IGenerator<T> {
1466 public:
1467  BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
1468 
1469  virtual T getValue( std::size_t index ) const {
1470  return m_from+static_cast<T>( index );
1471  }
1472 
1473  virtual std::size_t size() const {
1474  return static_cast<std::size_t>( 1+m_to-m_from );
1475  }
1476 
1477 private:
1478 
1479  T m_from;
1480  T m_to;
1481 };
1482 
1483 template<typename T>
1484 class ValuesGenerator : public IGenerator<T> {
1485 public:
1486  ValuesGenerator(){}
1487 
1488  void add( T value ) {
1489  m_values.push_back( value );
1490  }
1491 
1492  virtual T getValue( std::size_t index ) const {
1493  return m_values[index];
1494  }
1495 
1496  virtual std::size_t size() const {
1497  return m_values.size();
1498  }
1499 
1500 private:
1501  std::vector<T> m_values;
1502 };
1503 
1504 template<typename T>
1505 class CompositeGenerator {
1506 public:
1507  CompositeGenerator() : m_totalSize( 0 ) {}
1508 
1509  // *** Move semantics, similar to auto_ptr ***
1510  CompositeGenerator( CompositeGenerator& other )
1511  : m_fileInfo( other.m_fileInfo ),
1512  m_totalSize( 0 )
1513  {
1514  move( other );
1515  }
1516 
1517  CompositeGenerator& setFileInfo( const char* fileInfo ) {
1518  m_fileInfo = fileInfo;
1519  return *this;
1520  }
1521 
1522  ~CompositeGenerator() {
1523  deleteAll( m_composed );
1524  }
1525 
1526  operator T () const {
1527  size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
1528 
1529  typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
1530  typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
1531  for( size_t index = 0; it != itEnd; ++it )
1532  {
1533  const IGenerator<T>* generator = *it;
1534  if( overallIndex >= index && overallIndex < index + generator->size() )
1535  {
1536  return generator->getValue( overallIndex-index );
1537  }
1538  index += generator->size();
1539  }
1540  CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
1541  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
1542  }
1543 
1544  void add( const IGenerator<T>* generator ) {
1545  m_totalSize += generator->size();
1546  m_composed.push_back( generator );
1547  }
1548 
1549  CompositeGenerator& then( CompositeGenerator& other ) {
1550  move( other );
1551  return *this;
1552  }
1553 
1554  CompositeGenerator& then( T value ) {
1555  ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
1556  valuesGen->add( value );
1557  add( valuesGen );
1558  return *this;
1559  }
1560 
1561 private:
1562 
1563  void move( CompositeGenerator& other ) {
1564  std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
1565  m_totalSize += other.m_totalSize;
1566  other.m_composed.clear();
1567  }
1568 
1569  std::vector<const IGenerator<T>*> m_composed;
1570  std::string m_fileInfo;
1571  size_t m_totalSize;
1572 };
1573 
1574 namespace Generators
1575 {
1576  template<typename T>
1577  CompositeGenerator<T> between( T from, T to ) {
1578  CompositeGenerator<T> generators;
1579  generators.add( new BetweenGenerator<T>( from, to ) );
1580  return generators;
1581  }
1582 
1583  template<typename T>
1584  CompositeGenerator<T> values( T val1, T val2 ) {
1585  CompositeGenerator<T> generators;
1586  ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
1587  valuesGen->add( val1 );
1588  valuesGen->add( val2 );
1589  generators.add( valuesGen );
1590  return generators;
1591  }
1592 
1593  template<typename T>
1594  CompositeGenerator<T> values( T val1, T val2, T val3 ){
1595  CompositeGenerator<T> generators;
1596  ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
1597  valuesGen->add( val1 );
1598  valuesGen->add( val2 );
1599  valuesGen->add( val3 );
1600  generators.add( valuesGen );
1601  return generators;
1602  }
1603 
1604  template<typename T>
1605  CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
1606  CompositeGenerator<T> generators;
1607  ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
1608  valuesGen->add( val1 );
1609  valuesGen->add( val2 );
1610  valuesGen->add( val3 );
1611  valuesGen->add( val4 );
1612  generators.add( valuesGen );
1613  return generators;
1614  }
1615 
1616 } // end namespace Generators
1617 
1618 using namespace Generators;
1619 
1620 } // end namespace Catch
1621 
1622 #define INTERNAL_CATCH_LINESTR2( line ) #line
1623 #define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
1624 
1625 #define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
1626 
1627 // #included from: internal/catch_interfaces_exception.h
1628 #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTIONS_H_INCLUDED
1629 
1630 #include <string>
1631 // #included from: catch_interfaces_registry_hub.h
1632 #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
1633 
1634 // #included from: catch_interfaces_reporter.h
1635 #define TWOBLUECUBES_CATCH_IREPORTERREGISTRY_INCLUDED
1636 
1637 // #included from: catch_config.hpp
1638 #define TWOBLUECUBES_CATCH_RUNNERCONFIG_HPP_INCLUDED
1639 
1640 // #included from: catch_test_spec.h
1641 #define TWOBLUECUBES_CATCH_TESTSPEC_H_INCLUDED
1642 
1643 // #included from: catch_test_case_info.h
1644 #define TWOBLUECUBES_CATCH_TESTCASEINFO_H_INCLUDED
1645 
1646 #include <string>
1647 
1648 namespace Catch {
1649 
1650  struct ITestCase;
1651 
1652  class TestCaseInfo {
1653  public:
1654  TestCaseInfo();
1655 
1656  TestCaseInfo( ITestCase* testCase,
1657  const char* name,
1658  const char* description,
1659  const SourceLineInfo& lineInfo );
1660 
1661  TestCaseInfo( const TestCaseInfo& other, const std::string& name );
1662  TestCaseInfo( const TestCaseInfo& other );
1663 
1664  void invoke() const;
1665  const std::string& getName() const;
1666  const std::string& getDescription() const;
1667  const SourceLineInfo& getLineInfo() const;
1668  bool isHidden() const;
1669 
1670  void swap( TestCaseInfo& other );
1671  bool operator == ( const TestCaseInfo& other ) const;
1672  bool operator < ( const TestCaseInfo& other ) const;
1673  TestCaseInfo& operator = ( const TestCaseInfo& other );
1674 
1675  private:
1676  Ptr<ITestCase> m_test;
1677  std::string m_name;
1678  std::string m_description;
1679  SourceLineInfo m_lineInfo;
1680  };
1681 }
1682 
1683 #include <string>
1684 #include <vector>
1685 
1686 namespace Catch {
1687 
1688  struct IfFilterMatches{ enum DoWhat {
1689  IncludeTests,
1690  ExcludeTests
1691  }; };
1692 
1693  class TestCaseFilter {
1694  enum WildcardPosition {
1695  NoWildcard = 0,
1696  WildcardAtStart = 1,
1697  WildcardAtEnd = 2,
1698  WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
1699  };
1700 
1701  public:
1702  TestCaseFilter( const std::string& testSpec, IfFilterMatches::DoWhat matchBehaviour = IfFilterMatches::IncludeTests )
1703  : m_stringToMatch( testSpec ),
1704  m_filterType( matchBehaviour ),
1705  m_wildcardPosition( NoWildcard )
1706  {
1707  if( m_stringToMatch[0] == '*' ) {
1708  m_stringToMatch = m_stringToMatch.substr( 1 );
1709  m_wildcardPosition = (WildcardPosition)( m_wildcardPosition | WildcardAtStart );
1710  }
1711  if( m_stringToMatch[m_stringToMatch.size()-1] == '*' ) {
1712  m_stringToMatch = m_stringToMatch.substr( 0, m_stringToMatch.size()-1 );
1713  m_wildcardPosition = (WildcardPosition)( m_wildcardPosition | WildcardAtEnd );
1714  }
1715  }
1716 
1717  IfFilterMatches::DoWhat getFilterType() const {
1718  return m_filterType;
1719  }
1720 
1721  bool shouldInclude( const TestCaseInfo& testCase ) const {
1722  return isMatch( testCase ) == (m_filterType == IfFilterMatches::IncludeTests);
1723  }
1724  private:
1725 
1726 #ifdef __clang__
1727 #pragma clang diagnostic push
1728 #pragma clang diagnostic ignored "-Wunreachable-code"
1729 #endif
1730 
1731  bool isMatch( const TestCaseInfo& testCase ) const {
1732  const std::string& name = testCase.getName();
1733 
1734  switch( m_wildcardPosition ) {
1735  case NoWildcard:
1736  return m_stringToMatch == name;
1737  case WildcardAtStart:
1738  return endsWith( name, m_stringToMatch );
1739  case WildcardAtEnd:
1740  return startsWith( name, m_stringToMatch );
1741  case WildcardAtBothEnds:
1742  return contains( name, m_stringToMatch );
1743  }
1744  throw std::logic_error( "Unhandled wildcard type" );
1745  }
1746 
1747 #ifdef __clang__
1748 #pragma clang diagnostic pop
1749 #endif
1750 
1751  std::string m_stringToMatch;
1752  IfFilterMatches::DoWhat m_filterType;
1753  WildcardPosition m_wildcardPosition;
1754  };
1755 
1756  class TestCaseFilters {
1757  public:
1758  TestCaseFilters( const std::string& name ) : m_name( name ) {}
1759 
1760  std::string getName() const {
1761  return m_name;
1762  }
1763 
1764  void addFilter( const TestCaseFilter& filter ) {
1765  if( filter.getFilterType() == IfFilterMatches::ExcludeTests )
1766  m_exclusionFilters.push_back( filter );
1767  else
1768  m_inclusionFilters.push_back( filter );
1769  }
1770 
1771  bool shouldInclude( const TestCaseInfo& testCase ) const {
1772  if( !m_inclusionFilters.empty() ) {
1773  std::vector<TestCaseFilter>::const_iterator it = m_inclusionFilters.begin();
1774  std::vector<TestCaseFilter>::const_iterator itEnd = m_inclusionFilters.end();
1775  for(; it != itEnd; ++it )
1776  if( it->shouldInclude( testCase ) )
1777  break;
1778  if( it == itEnd )
1779  return false;
1780  }
1781  std::vector<TestCaseFilter>::const_iterator it = m_exclusionFilters.begin();
1782  std::vector<TestCaseFilter>::const_iterator itEnd = m_exclusionFilters.end();
1783  for(; it != itEnd; ++it )
1784  if( !it->shouldInclude( testCase ) )
1785  return false;
1786  return true;
1787  }
1788  private:
1789  std::vector<TestCaseFilter> m_inclusionFilters;
1790  std::vector<TestCaseFilter> m_exclusionFilters;
1791  std::string m_name;
1792  };
1793 
1794 }
1795 
1796 // #included from: catch_interfaces_config.h
1797 #define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
1798 
1799 namespace Catch {
1800 
1801  struct IConfig {
1802 
1803  virtual ~IConfig();
1804 
1805  virtual bool allowThrows() const = 0;
1806  };
1807 }
1808 
1809 #include <memory>
1810 #include <vector>
1811 #include <string>
1812 #include <iostream>
1813 
1814 namespace Catch {
1815 
1816  struct Include { enum WhichResults {
1817  FailedOnly,
1818  SuccessfulResults
1819  }; };
1820 
1821  struct List{ enum What {
1822  None = 0,
1823 
1824  Reports = 1,
1825  Tests = 2,
1826  All = 3,
1827 
1828  TestNames = 6,
1829 
1830  WhatMask = 0xf,
1831 
1832  AsText = 0x10,
1833  AsXml = 0x20,
1834 
1835  AsMask = 0xf0
1836  }; };
1837 
1838  struct ConfigData {
1839 
1840  struct WarnAbout { enum What {
1841  Nothing = 0x00,
1842  NoAssertions = 0x01
1843  }; };
1844 
1845  ConfigData()
1846  : listSpec( List::None ),
1847  shouldDebugBreak( false ),
1848  includeWhichResults( Include::FailedOnly ),
1849  cutoff( -1 ),
1850  allowThrows( true ),
1851  warnings( WarnAbout::Nothing )
1852  {}
1853 
1854  std::string reporter;
1855  std::string outputFilename;
1856  List::What listSpec;
1857  std::vector<TestCaseFilters> filters;
1858  bool shouldDebugBreak;
1859  std::string stream;
1860  Include::WhichResults includeWhichResults;
1861  std::string name;
1862  int cutoff;
1863  bool allowThrows;
1864  WarnAbout::What warnings;
1865  };
1866 
1867  class Config : public IConfig {
1868  private:
1869  Config( const Config& other );
1870  Config& operator = ( const Config& other );
1871  virtual void dummy();
1872  public:
1873 
1874  Config()
1875  : m_streambuf( NULL ),
1876  m_os( std::cout.rdbuf() )
1877  {}
1878 
1879  Config( const ConfigData& data )
1880  : m_data( data ),
1881  m_streambuf( NULL ),
1882  m_os( std::cout.rdbuf() )
1883  {}
1884 
1885  virtual ~Config() {
1886  m_os.rdbuf( std::cout.rdbuf() );
1887  delete m_streambuf;
1888  }
1889 
1890  void setFilename( const std::string& filename ) {
1891  m_data.outputFilename = filename;
1892  }
1893 
1894  List::What getListSpec( void ) const {
1895  return m_data.listSpec;
1896  }
1897 
1898  const std::string& getFilename() const {
1899  return m_data.outputFilename ;
1900  }
1901 
1902  List::What listWhat() const {
1903  return static_cast<List::What>( m_data.listSpec & List::WhatMask );
1904  }
1905 
1906  List::What listAs() const {
1907  return static_cast<List::What>( m_data.listSpec & List::AsMask );
1908  }
1909 
1910  std::string getName() const {
1911  return m_data.name;
1912  }
1913 
1914  bool shouldDebugBreak() const {
1915  return m_data.shouldDebugBreak;
1916  }
1917 
1918  virtual std::ostream& stream() const {
1919  return m_os;
1920  }
1921 
1922  void setStreamBuf( std::streambuf* buf ) {
1923  m_os.rdbuf( buf ? buf : std::cout.rdbuf() );
1924  }
1925 
1926  void useStream( const std::string& streamName ) {
1927  std::streambuf* newBuf = createStreamBuf( streamName );
1928  setStreamBuf( newBuf );
1929  delete m_streambuf;
1930  m_streambuf = newBuf;
1931  }
1932 
1933  virtual bool includeSuccessfulResults() const {
1934  return m_data.includeWhichResults == Include::SuccessfulResults;
1935  }
1936 
1937  int getCutoff() const {
1938  return m_data.cutoff;
1939  }
1940 
1941  virtual bool allowThrows() const {
1942  return m_data.allowThrows;
1943  }
1944 
1945  const ConfigData& data() const {
1946  return m_data;
1947  }
1948  ConfigData& data() {
1949  return m_data;
1950  }
1951 
1952  private:
1953  ConfigData m_data;
1954 
1955  // !TBD Move these out of here
1956  std::streambuf* m_streambuf;
1957  mutable std::ostream m_os;
1958  };
1959 
1960 } // end namespace Catch
1961 
1962 #include <string>
1963 #include <ostream>
1964 #include <map>
1965 
1966 namespace Catch
1967 {
1968  struct ReporterConfig
1969  {
1970  ReporterConfig( const std::string& _name,
1971  std::ostream& _stream,
1972  bool _includeSuccessfulResults,
1973  const ConfigData& _fullConfig )
1974  : name( _name ),
1975  stream( _stream ),
1976  includeSuccessfulResults( _includeSuccessfulResults ),
1977  fullConfig( _fullConfig )
1978  {}
1979 
1980  std::string name;
1981  std::ostream& stream;
1982  bool includeSuccessfulResults;
1983  ConfigData fullConfig;
1984  };
1985 
1986  class TestCaseInfo;
1987  class ResultInfo;
1988 
1989  struct IReporter : IShared {
1990  virtual ~IReporter();
1991  virtual bool shouldRedirectStdout() const = 0;
1992  virtual void StartTesting() = 0;
1993  virtual void EndTesting( const Totals& totals ) = 0;
1994  virtual void StartGroup( const std::string& groupName ) = 0;
1995  virtual void EndGroup( const std::string& groupName, const Totals& totals ) = 0;
1996  virtual void StartSection( const std::string& sectionName, const std::string& description ) = 0;
1997  virtual void NoAssertionsInSection( const std::string& sectionName ) = 0;
1998  virtual void NoAssertionsInTestCase( const std::string& testName ) = 0;
1999  virtual void EndSection( const std::string& sectionName, const Counts& assertions ) = 0;
2000  virtual void StartTestCase( const TestCaseInfo& testInfo ) = 0;
2001  virtual void Aborted() = 0;
2002  virtual void EndTestCase( const TestCaseInfo& testInfo, const Totals& totals, const std::string& stdOut, const std::string& stdErr ) = 0;
2003  virtual void Result( const ResultInfo& result ) = 0;
2004  };
2005 
2006  struct IReporterFactory {
2007  virtual ~IReporterFactory();
2008  virtual IReporter* create( const ReporterConfig& config ) const = 0;
2009  virtual std::string getDescription() const = 0;
2010  };
2011 
2012  struct IReporterRegistry {
2013  typedef std::map<std::string, IReporterFactory*> FactoryMap;
2014 
2015  virtual ~IReporterRegistry();
2016  virtual IReporter* create( const std::string& name, const ReporterConfig& config ) const = 0;
2017  virtual const FactoryMap& getFactories() const = 0;
2018  };
2019 
2020  inline std::string trim( const std::string& str ) {
2021  std::string::size_type start = str.find_first_not_of( "\n\r\t " );
2022  std::string::size_type end = str.find_last_not_of( "\n\r\t " );
2023 
2024  return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
2025  }
2026 }
2027 
2028 #include <vector>
2029 
2030 namespace Catch {
2031 
2032  class TestCaseInfo;
2033  struct ITestCaseRegistry;
2034  struct IExceptionTranslatorRegistry;
2035  struct IExceptionTranslator;
2036 
2037  struct IRegistryHub {
2038  virtual ~IRegistryHub();
2039 
2040  virtual const IReporterRegistry& getReporterRegistry() const = 0;
2041  virtual const ITestCaseRegistry& getTestCaseRegistry() const = 0;
2042  virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
2043  };
2044 
2045  struct IMutableRegistryHub {
2046  virtual ~IMutableRegistryHub();
2047  virtual void registerReporter( const std::string& name, IReporterFactory* factory ) = 0;
2048  virtual void registerTest( const TestCaseInfo& testInfo ) = 0;
2049  virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
2050  };
2051 
2052  IRegistryHub& getRegistryHub();
2053  IMutableRegistryHub& getMutableRegistryHub();
2054  void cleanUp();
2055 }
2056 
2057 
2058 namespace Catch {
2059 
2060  typedef std::string(*exceptionTranslateFunction)();
2061 
2062  struct IExceptionTranslator {
2063  virtual ~IExceptionTranslator();
2064  virtual std::string translate() const = 0;
2065  };
2066 
2067  struct IExceptionTranslatorRegistry {
2068  virtual ~IExceptionTranslatorRegistry();
2069 
2070  virtual std::string translateActiveException() const = 0;
2071  };
2072 
2073  class ExceptionTranslatorRegistrar {
2074  template<typename T>
2075  class ExceptionTranslator : public IExceptionTranslator {
2076  public:
2077 
2078  ExceptionTranslator( std::string(*translateFunction)( T& ) )
2079  : m_translateFunction( translateFunction )
2080  {}
2081 
2082  virtual std::string translate() const {
2083  try {
2084  throw;
2085  }
2086  catch( T& ex ) {
2087  return m_translateFunction( ex );
2088  }
2089  }
2090 
2091  protected:
2092  std::string(*m_translateFunction)( T& );
2093  };
2094 
2095  public:
2096  template<typename T>
2097  ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
2098  getMutableRegistryHub().registerTranslator
2099  ( new ExceptionTranslator<T>( translateFunction ) );
2100  }
2101  };
2102 }
2103 
2105 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \
2106  static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \
2107  namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\
2108  static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature )
2109 
2110 // #included from: internal/catch_approx.hpp
2111 #define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
2112 
2113 #include <cmath>
2114 #include <limits>
2115 
2116 namespace Catch {
2117 namespace Detail {
2118 
2119  class Approx {
2120  public:
2121  explicit Approx ( double value )
2122  : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
2123  m_scale( 1.0 ),
2124  m_value( value )
2125  {}
2126 
2127  Approx( const Approx& other )
2128  : m_epsilon( other.m_epsilon ),
2129  m_scale( other.m_scale ),
2130  m_value( other.m_value )
2131  {}
2132 
2133  static Approx custom() {
2134  return Approx( 0 );
2135  }
2136 
2137  Approx operator()( double value ) {
2138  Approx approx( value );
2139  approx.epsilon( m_epsilon );
2140  approx.scale( m_scale );
2141  return approx;
2142  }
2143 
2144  friend bool operator == ( double lhs, const Approx& rhs ) {
2145  // Thanks to Richard Harris for his help refining this formula
2146  return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
2147  }
2148 
2149  friend bool operator == ( const Approx& lhs, double rhs ) {
2150  return operator==( rhs, lhs );
2151  }
2152 
2153  friend bool operator != ( double lhs, const Approx& rhs ) {
2154  return !operator==( lhs, rhs );
2155  }
2156 
2157  friend bool operator != ( const Approx& lhs, double rhs ) {
2158  return !operator==( rhs, lhs );
2159  }
2160 
2161  Approx& epsilon( double newEpsilon ) {
2162  m_epsilon = newEpsilon;
2163  return *this;
2164  }
2165 
2166  Approx& scale( double newScale ) {
2167  m_scale = newScale;
2168  return *this;
2169  }
2170 
2171  std::string toString() const {
2172  std::ostringstream oss;
2173  oss << "Approx( " << m_value << ")";
2174  return oss.str();
2175  }
2176 
2177  private:
2178  double m_epsilon;
2179  double m_scale;
2180  double m_value;
2181  };
2182 }
2183 
2184 template<>
2185 inline std::string toString<Detail::Approx>( const Detail::Approx& value ) {
2186  return value.toString();
2187 }
2188 
2189 } // end namespace Catch
2190 
2191 // #included from: internal/catch_matchers.hpp
2192 #define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
2193 
2194 namespace Catch {
2195 namespace Matchers {
2196  namespace Impl {
2197  namespace StdString {
2198 
2199  struct Equals {
2200  Equals( const std::string& str ) : m_str( str ){}
2201 
2202  bool operator()( const std::string& str ) const
2203  {
2204  return str == m_str;
2205  }
2206 
2207  friend std::ostream& operator<<( std::ostream& os, const Equals& matcher )
2208  {
2209  os << "equals: \"" << matcher.m_str << "\"";
2210  return os;
2211  }
2212  std::string m_str;
2213  };
2214 
2215  struct Contains {
2216  Contains( const std::string& substr ) : m_substr( substr ){}
2217 
2218  bool operator()( const std::string& str ) const
2219  {
2220  return str.find( m_substr ) != std::string::npos;
2221  }
2222 
2223  friend std::ostream& operator<<( std::ostream& os, const Contains& matcher )
2224  {
2225  os << "contains: \"" << matcher.m_substr << "\"";
2226  return os;
2227  }
2228  std::string m_substr;
2229  };
2230 
2231  struct StartsWith {
2232  StartsWith( const std::string& substr ) : m_substr( substr ){}
2233 
2234  bool operator()( const std::string& str ) const
2235  {
2236  return str.find( m_substr ) == 0;
2237  }
2238 
2239  friend std::ostream& operator<<( std::ostream& os, const StartsWith& matcher )
2240  {
2241  os << "starts with: \"" << matcher.m_substr << "\"";
2242  return os;
2243  }
2244  std::string m_substr;
2245  };
2246 
2247  struct EndsWith {
2248  EndsWith( const std::string& substr ) : m_substr( substr ){}
2249 
2250  bool operator()( const std::string& str ) const
2251  {
2252  return str.find( m_substr ) == str.size() - m_substr.size();
2253  }
2254 
2255  friend std::ostream& operator<<( std::ostream& os, const EndsWith& matcher )
2256  {
2257  os << "ends with: \"" << matcher.m_substr << "\"";
2258  return os;
2259  }
2260  std::string m_substr;
2261  };
2262  } // namespace StdString
2263  } // namespace Impl
2264 
2265  inline Impl::StdString::Equals Equals( const std::string& str ){ return Impl::StdString::Equals( str ); }
2266  inline Impl::StdString::Contains Contains( const std::string& substr ){ return Impl::StdString::Contains( substr ); }
2267  inline Impl::StdString::StartsWith StartsWith( const std::string& substr ){ return Impl::StdString::StartsWith( substr ); }
2268  inline Impl::StdString::EndsWith EndsWith( const std::string& substr ){ return Impl::StdString::EndsWith( substr ); }
2269 
2270 } // namespace Matchers
2271 
2272 using namespace Matchers;
2273 
2274 } // namespace Catch
2275 
2276 // These files are included here so the single_include script doesn't put them
2277 // in the conditionally compiled sections
2278 // #included from: internal/catch_interfaces_runner.h
2279 #define TWOBLUECUBES_INTERNAL_CATCH_INTERFACES_RUNNER_H_INCLUDED
2280 
2281 #include <string>
2282 
2283 namespace Catch {
2284  class TestCaseInfo;
2285 
2286  struct IRunner {
2287  virtual ~IRunner();
2288  };
2289 }
2290 
2291 
2292 #ifdef __OBJC__
2293 // #included from: internal/catch_objc.hpp
2294 #define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
2295 
2296 #import <objc/runtime.h>
2297 
2298 #include <string>
2299 
2300 // NB. Any general catch headers included here must be included
2301 // in catch.hpp first to make sure they are included by the single
2302 // header for non obj-usage
2303 
2305 // This protocol is really only here for (self) documenting purposes, since
2306 // all its methods are optional.
2307 @protocol OcFixture
2308 
2309 @optional
2310 
2311 -(void) setUp;
2312 -(void) tearDown;
2313 
2314 @end
2315 
2316 namespace Catch {
2317 
2318  class OcMethod : public SharedImpl<ITestCase> {
2319 
2320  public:
2321  OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
2322 
2323  virtual void invoke() const {
2324  id obj = [[m_cls alloc] init];
2325 
2326  performOptionalSelector( obj, @selector(setUp) );
2327  performOptionalSelector( obj, m_sel );
2328  performOptionalSelector( obj, @selector(tearDown) );
2329 
2330  arcSafeRelease( obj );
2331  }
2332  private:
2333  virtual ~OcMethod() {}
2334 
2335  Class m_cls;
2336  SEL m_sel;
2337  };
2338 
2339  namespace Detail{
2340 
2341  inline bool startsWith( const std::string& str, const std::string& sub ) {
2342  return str.length() > sub.length() && str.substr( 0, sub.length() ) == sub;
2343  }
2344 
2345  inline std::string getAnnotation( Class cls,
2346  const std::string& annotationName,
2347  const std::string& testCaseName ) {
2348  NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
2349  SEL sel = NSSelectorFromString( selStr );
2350  arcSafeRelease( selStr );
2351  id value = performOptionalSelector( cls, sel );
2352  if( value )
2353  return [(NSString*)value UTF8String];
2354  return "";
2355  }
2356  }
2357 
2358  inline size_t registerTestMethods() {
2359  size_t noTestMethods = 0;
2360  int noClasses = objc_getClassList( NULL, 0 );
2361 
2362  Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
2363  objc_getClassList( classes, noClasses );
2364 
2365  for( int c = 0; c < noClasses; c++ ) {
2366  Class cls = classes[c];
2367  {
2368  u_int count;
2369  Method* methods = class_copyMethodList( cls, &count );
2370  for( u_int m = 0; m < count ; m++ ) {
2371  SEL selector = method_getName(methods[m]);
2372  std::string methodName = sel_getName(selector);
2373  if( Detail::startsWith( methodName, "Catch_TestCase_" ) ) {
2374  std::string testCaseName = methodName.substr( 15 );
2375  std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
2376  std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
2377 
2378  getMutableRegistryHub().registerTest( TestCaseInfo( new OcMethod( cls, selector ), name.c_str(), desc.c_str(), SourceLineInfo() ) );
2379  noTestMethods++;
2380  }
2381  }
2382  free(methods);
2383  }
2384  }
2385  return noTestMethods;
2386  }
2387 
2388  namespace Matchers {
2389  namespace Impl {
2390  namespace NSStringMatchers {
2391 
2392  struct StringHolder {
2393  StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
2394  StringHolder() {
2395  arcSafeRelease( m_substr );
2396  }
2397 
2398  NSString* m_substr;
2399  };
2400 
2401  struct Equals : StringHolder {
2402  Equals( NSString* substr ) : StringHolder( substr ){}
2403 
2404  bool operator()( NSString* str ) const {
2405  return [str isEqualToString:m_substr];
2406  }
2407 
2408  friend std::ostream& operator<<( std::ostream& os, const Equals& matcher ) {
2409  os << "equals string: " << Catch::toString( matcher.m_substr );
2410  return os;
2411  }
2412  };
2413 
2414  struct Contains : StringHolder {
2415  Contains( NSString* substr ) : StringHolder( substr ){}
2416 
2417  bool operator()( NSString* str ) const {
2418  return [str rangeOfString:m_substr].location != NSNotFound;
2419  }
2420 
2421  friend std::ostream& operator<<( std::ostream& os, const Contains& matcher ) {
2422  os << "contains: " << Catch::toString( matcher.m_substr );
2423  return os;
2424  }
2425  };
2426 
2427  struct StartsWith : StringHolder {
2428  StartsWith( NSString* substr ) : StringHolder( substr ){}
2429 
2430  bool operator()( NSString* str ) const {
2431  return [str rangeOfString:m_substr].location == 0;
2432  }
2433 
2434  friend std::ostream& operator<<( std::ostream& os, const StartsWith& matcher ) {
2435  os << "starts with: " << Catch::toString( matcher.m_substr );
2436  return os;
2437  }
2438  };
2439  struct EndsWith : StringHolder {
2440  EndsWith( NSString* substr ) : StringHolder( substr ){}
2441 
2442  bool operator()( NSString* str ) const {
2443  return [str rangeOfString:m_substr].location == [str length] - [m_substr length];
2444  }
2445 
2446  friend std::ostream& operator<<( std::ostream& os, const EndsWith& matcher ) {
2447  os << "ends with: " << Catch::toString( matcher.m_substr );
2448  return os;
2449  }
2450  };
2451 
2452  } // namespace NSStringMatchers
2453  } // namespace Impl
2454 
2455  inline Impl::NSStringMatchers::Equals
2456  Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
2457 
2458  inline Impl::NSStringMatchers::Contains
2459  Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
2460 
2461  inline Impl::NSStringMatchers::StartsWith
2462  StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
2463 
2464  inline Impl::NSStringMatchers::EndsWith
2465  EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
2466 
2467  } // namespace Matchers
2468 
2469  using namespace Matchers;
2470 
2471 } // namespace Catch
2472 
2474 #define OC_TEST_CASE( name, desc )\
2475 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
2476 {\
2477 return @ name; \
2478 }\
2479 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
2480 { \
2481 return @ desc; \
2482 } \
2483 -(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
2484 
2485 #endif
2486 
2487 #if defined( CATCH_CONFIG_MAIN ) || defined( CATCH_CONFIG_RUNNER )
2488 // #included from: internal/catch_impl.hpp
2489 
2490 // Collect all the implementation files together here
2491 // These are the equivalent of what would usually be cpp files
2492 
2493 #ifdef __clang__
2494 #pragma clang diagnostic push
2495 #pragma clang diagnostic ignored "-Wweak-vtables"
2496 #endif
2497 
2498 // #included from: catch_runner.hpp
2499 #define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
2500 
2501 // #included from: internal/catch_commandline.hpp
2502 #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
2503 
2504 namespace Catch {
2505 
2506  class Command {
2507  public:
2508  Command(){}
2509 
2510  explicit Command( const std::string& name ) : m_name( name ) {
2511  }
2512 
2513  Command& operator += ( const std::string& arg ) {
2514  m_args.push_back( arg );
2515  return *this;
2516  }
2517  Command& operator += ( const Command& other ) {
2518  std::copy( other.m_args.begin(), other.m_args.end(), std::back_inserter( m_args ) );
2519  if( m_name.empty() )
2520  m_name = other.m_name;
2521  return *this;
2522  }
2523  Command operator + ( const Command& other ) {
2524  Command newCommand( *this );
2525  newCommand += other;
2526  return newCommand;
2527  }
2528 
2529  operator SafeBool::type() const {
2530  return SafeBool::makeSafe( !m_name.empty() || !m_args.empty() );
2531  }
2532 
2533  std::string name() const { return m_name; }
2534  std::string operator[]( std::size_t i ) const { return m_args[i]; }
2535  std::size_t argsCount() const { return m_args.size(); }
2536 
2538  void raiseError( const std::string& message ) const {
2539  std::ostringstream oss;
2540  if( m_name.empty() )
2541  oss << "Error while parsing " << m_name << ". " << message << ".";
2542  else
2543  oss << "Error while parsing arguments. " << message << ".";
2544 
2545  if( m_args.size() > 0 )
2546  oss << " Arguments were:";
2547  for( std::size_t i = 0; i < m_args.size(); ++i )
2548  oss << " " << m_args[i];
2549  throw std::domain_error( oss.str() );
2550  }
2551 
2552  private:
2553 
2554  std::string m_name;
2555  std::vector<std::string> m_args;
2556  };
2557 
2558  class CommandParser {
2559  public:
2560  CommandParser( int argc, char const * const * argv ) : m_argc( static_cast<std::size_t>( argc ) ), m_argv( argv ) {}
2561 
2562  Command find( const std::string& arg1, const std::string& arg2, const std::string& arg3 ) const {
2563  return find( arg1 ) + find( arg2 ) + find( arg3 );
2564  }
2565 
2566  Command find( const std::string& shortArg, const std::string& longArg ) const {
2567  return find( shortArg ) + find( longArg );
2568  }
2569  Command find( const std::string& arg ) const {
2570  if( arg.empty() )
2571  return getArgs( "", 1 );
2572  else
2573  for( std::size_t i = 1; i < m_argc; ++i )
2574  if( m_argv[i] == arg )
2575  return getArgs( m_argv[i], i+1 );
2576  return Command();
2577  }
2578  Command getDefaultArgs() const {
2579  return getArgs( "", 1 );
2580  }
2581 
2582  private:
2583  Command getArgs( const std::string& cmdName, std::size_t from ) const {
2584  Command command( cmdName );
2585  for( std::size_t i = from; i < m_argc && m_argv[i][0] != '-'; ++i )
2586  command += m_argv[i];
2587  return command;
2588  }
2589 
2590  std::size_t m_argc;
2591  char const * const * m_argv;
2592  };
2593 
2594  class OptionParser : public SharedImpl<IShared> {
2595  public:
2596  OptionParser( int minArgs = 0, int maxArgs = 0 )
2597  : m_minArgs( minArgs ), m_maxArgs( maxArgs )
2598  {}
2599 
2600  virtual ~OptionParser() {}
2601 
2602  Command find( const CommandParser& parser ) const {
2603  Command cmd;
2604  for( std::vector<std::string>::const_iterator it = m_optionNames.begin();
2605  it != m_optionNames.end();
2606  ++it )
2607  cmd += parser.find( *it );
2608  return cmd;
2609  }
2610 
2611  void validateArgs( const Command& args ) const {
2612  if( tooFewArgs( args ) || tooManyArgs( args ) ) {
2613  std::ostringstream oss;
2614  if( m_maxArgs == -1 )
2615  oss <<"Expected at least " << pluralise( static_cast<std::size_t>( m_minArgs ), "argument" );
2616  else if( m_minArgs == m_maxArgs )
2617  oss <<"Expected " << pluralise( static_cast<std::size_t>( m_minArgs ), "argument" );
2618  else
2619  oss <<"Expected between " << m_minArgs << " and " << m_maxArgs << " argument";
2620  args.raiseError( oss.str() );
2621  }
2622  }
2623 
2624  void parseIntoConfig( const CommandParser& parser, ConfigData& config ) {
2625  if( Command cmd = find( parser ) ) {
2626  validateArgs( cmd );
2627  parseIntoConfig( cmd, config );
2628  }
2629  }
2630 
2631  virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) = 0;
2632  virtual std::string argsSynopsis() const = 0;
2633  virtual std::string optionSummary() const = 0;
2634 
2635  std::string optionNames() const {
2636  std::string names;
2637  for( std::vector<std::string>::const_iterator it = m_optionNames.begin();
2638  it != m_optionNames.end();
2639  ++it ) {
2640  if( !it->empty() ) {
2641  if( !names.empty() )
2642  names += ", ";
2643  names += *it;
2644  }
2645  else {
2646  names = "[" + names;
2647  }
2648  }
2649  if( names[0] == '[' )
2650  names += "]";
2651  return names;
2652  }
2653 
2654  protected:
2655 
2656  bool tooFewArgs( const Command& args ) const {
2657  return args.argsCount() < static_cast<std::size_t>( m_minArgs );
2658  }
2659  bool tooManyArgs( const Command& args ) const {
2660  return m_maxArgs >= 0 && args.argsCount() > static_cast<std::size_t>( m_maxArgs );
2661  }
2662  std::vector<std::string> m_optionNames;
2663  int m_minArgs;
2664  int m_maxArgs;
2665  };
2666 
2667  namespace Options {
2668 
2669  class HelpOptionParser : public OptionParser {
2670  public:
2671  HelpOptionParser() {
2672  m_optionNames.push_back( "-?" );
2673  m_optionNames.push_back( "-h" );
2674  m_optionNames.push_back( "--help" );
2675  }
2676  virtual std::string argsSynopsis() const {
2677  return "";
2678  }
2679  virtual std::string optionSummary() const {
2680  return "Shows this usage summary";
2681  }
2682 
2683  virtual void parseIntoConfig( const Command&, ConfigData& ) {
2684  // Does not affect config
2685  }
2686  };
2687 
2688  class TestCaseOptionParser : public OptionParser {
2689  public:
2690  TestCaseOptionParser() : OptionParser( 1, -1 ) {
2691  m_optionNames.push_back( "-t" );
2692  m_optionNames.push_back( "--test" );
2693  m_optionNames.push_back( "" ); // default option
2694  }
2695  virtual std::string argsSynopsis() const {
2696  return "<testspec> [<testspec>...]";
2697  }
2698  virtual std::string optionSummary() const {
2699  return "Specify which test case or cases to run";
2700  }
2701 
2702  virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
2703  std::string groupName;
2704  for( std::size_t i = 0; i < cmd.argsCount(); ++i ) {
2705  if( i != 0 )
2706  groupName += " ";
2707  groupName += cmd[i];
2708  }
2709  TestCaseFilters filters( groupName );
2710  for( std::size_t i = 0; i < cmd.argsCount(); ++i ) {
2711  if( Catch::startsWith( cmd[i], "exclude:" ) )
2712  filters.addFilter( TestCaseFilter( cmd[i].substr( 8 ), IfFilterMatches::ExcludeTests ) );
2713  else if( Catch::startsWith( cmd[i], "~" ) )
2714  filters.addFilter( TestCaseFilter( cmd[i].substr( 1 ), IfFilterMatches::ExcludeTests ) );
2715  else
2716  filters.addFilter( TestCaseFilter( cmd[i] ) );
2717  }
2718  config.filters.push_back( filters );
2719  }
2720  };
2721 
2722  class ListOptionParser : public OptionParser {
2723  public:
2724  ListOptionParser() : OptionParser( 0, 2 ) {
2725  m_optionNames.push_back( "-l" );
2726  m_optionNames.push_back( "--list" );
2727  }
2728  virtual std::string argsSynopsis() const {
2729  return "[all | tests | reporters [xml]]";
2730  }
2731  virtual std::string optionSummary() const {
2732  return "!TBD";
2733  }
2734 
2735  virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
2736  config.listSpec = List::TestNames;
2737  if( cmd.argsCount() >= 1 ) {
2738  if( cmd[0] == "all" )
2739  config.listSpec = List::All;
2740  else if( cmd[0] == "tests" )
2741  config.listSpec = List::Tests;
2742  else if( cmd[0] == "reporters" )
2743  config.listSpec = List::Reports;
2744  else
2745  cmd.raiseError( "Expected [tests] or [reporters]" );
2746  }
2747  if( cmd.argsCount() >= 2 ) {
2748  if( cmd[1] == "xml" )
2749  config.listSpec = static_cast<List::What>( config.listSpec | List::AsXml );
2750  else if( cmd[1] == "text" )
2751  config.listSpec = static_cast<List::What>( config.listSpec | List::AsText );
2752  else
2753  cmd.raiseError( "Expected [xml] or [text]" );
2754  }
2755  }
2756  };
2757 
2758  class ReporterOptionParser : public OptionParser {
2759  public:
2760  ReporterOptionParser() : OptionParser( 1, 1 ) {
2761  m_optionNames.push_back( "-r" );
2762  m_optionNames.push_back( "--reporter" );
2763  }
2764  virtual std::string argsSynopsis() const {
2765  return "<reporter name>";
2766  }
2767  virtual std::string optionSummary() const {
2768  return "!TBD";
2769  }
2770 
2771  virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
2772  config.reporter = cmd[0];
2773  }
2774  };
2775 
2776  class OutputOptionParser : public OptionParser {
2777  public:
2778  OutputOptionParser() : OptionParser( 1, 1 ) {
2779  m_optionNames.push_back( "-o" );
2780  m_optionNames.push_back( "--out" );
2781  }
2782  virtual std::string argsSynopsis() const {
2783  return "<file name>|<%stream name>";
2784  }
2785  virtual std::string optionSummary() const {
2786  return "!TBD";
2787  }
2788 
2789  virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
2790  if( cmd[0][0] == '%' )
2791  config.stream = cmd[0].substr( 1 );
2792  else
2793  config.outputFilename = cmd[0];
2794  }
2795  };
2796 
2797  class SuccesssOptionParser : public OptionParser {
2798  public:
2799  SuccesssOptionParser() {
2800  m_optionNames.push_back( "-s" );
2801  m_optionNames.push_back( "--success" );
2802  }
2803  virtual std::string argsSynopsis() const {
2804  return "";
2805  }
2806  virtual std::string optionSummary() const {
2807  return "!TBD";
2808  }
2809 
2810  virtual void parseIntoConfig( const Command&, ConfigData& config ) {
2811  config.includeWhichResults = Include::SuccessfulResults;
2812  }
2813  };
2814 
2815  class DebugBreakOptionParser : public OptionParser {
2816  public:
2817  DebugBreakOptionParser() {
2818  m_optionNames.push_back( "-b" );
2819  m_optionNames.push_back( "--break" );
2820  }
2821  virtual std::string argsSynopsis() const {
2822  return "";
2823  }
2824  virtual std::string optionSummary() const {
2825  return "!TBD";
2826  }
2827 
2828  virtual void parseIntoConfig( const Command&, ConfigData& config ) {
2829  config.shouldDebugBreak = true;
2830  }
2831  };
2832 
2833  class NameOptionParser : public OptionParser {
2834  public:
2835  NameOptionParser() : OptionParser( 1, 1 ) {
2836  m_optionNames.push_back( "-n" );
2837  m_optionNames.push_back( "--name" );
2838  }
2839  virtual std::string argsSynopsis() const {
2840  return "<name>";
2841  }
2842  virtual std::string optionSummary() const {
2843  return "!TBD";
2844  }
2845 
2846  virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
2847  config.name = cmd[0];
2848  }
2849  };
2850 
2851  class AbortOptionParser : public OptionParser {
2852  public:
2853  AbortOptionParser() : OptionParser( 0, 1 ) {
2854  m_optionNames.push_back( "-a" );
2855  m_optionNames.push_back( "--abort" );
2856  }
2857  virtual std::string argsSynopsis() const {
2858  return "[#]";
2859  }
2860  virtual std::string optionSummary() const {
2861  return "!TBD";
2862  }
2863 
2864  virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
2865  int threshold = 1;
2866  if( cmd.argsCount() == 1 ) {
2867  std::stringstream ss;
2868  ss << cmd[0];
2869  ss >> threshold;
2870  if( ss.fail() || threshold <= 0 )
2871  cmd.raiseError( "threshold must be a number greater than zero" );
2872  }
2873  config.cutoff = threshold;
2874  }
2875  };
2876 
2877  class NoThrowOptionParser : public OptionParser {
2878  public:
2879  NoThrowOptionParser() {
2880  m_optionNames.push_back( "-nt" );
2881  m_optionNames.push_back( "--nothrow" );
2882  }
2883  virtual std::string argsSynopsis() const {
2884  return "";
2885  }
2886  virtual std::string optionSummary() const {
2887  return "!TBD";
2888  }
2889 
2890  virtual void parseIntoConfig( const Command&, ConfigData& config ) {
2891  config.allowThrows = false;
2892  }
2893  };
2894 
2895  class WarningsOptionParser : public OptionParser {
2896  public:
2897  WarningsOptionParser() : OptionParser( 1, -1 ) {
2898  m_optionNames.push_back( "-w" );
2899  m_optionNames.push_back( "--warnings" );
2900  }
2901  virtual std::string argsSynopsis() const {
2902  return "<warning>";
2903  }
2904  virtual std::string optionSummary() const {
2905  return "!TBD";
2906  }
2907 
2908  virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) {
2909  for( std::size_t i = 0; i < cmd.argsCount(); ++i ) {
2910  if( cmd[i] == "NoAssertions" )
2911  config.warnings = (ConfigData::WarnAbout::What)( config.warnings | ConfigData::WarnAbout::NoAssertions );
2912  else
2913  cmd.raiseError( "Unrecognised warning: " + cmd[i] );
2914  }
2915  }
2916  };
2917  }
2918 
2919  class AllOptions
2920  {
2921  public:
2922  typedef std::vector<Ptr<OptionParser> > Parsers;
2923  typedef Parsers::const_iterator const_iterator;
2924  typedef Parsers::const_iterator iterator;
2925 
2926  AllOptions() {
2927  add<Options::TestCaseOptionParser>(); // Keep this one first
2928 
2929  add<Options::ListOptionParser>();
2930  add<Options::ReporterOptionParser>();
2931  add<Options::OutputOptionParser>();
2932  add<Options::SuccesssOptionParser>();
2933  add<Options::DebugBreakOptionParser>();
2934  add<Options::NameOptionParser>();
2935  add<Options::AbortOptionParser>();
2936  add<Options::NoThrowOptionParser>();
2937  add<Options::WarningsOptionParser>();
2938 
2939  add<Options::HelpOptionParser>(); // Keep this one last
2940  }
2941 
2942  void parseIntoConfig( const CommandParser& parser, ConfigData& config ) {
2943  for( const_iterator it = m_parsers.begin(); it != m_parsers.end(); ++it )
2944  (*it)->parseIntoConfig( parser, config );
2945  }
2946 
2947  const_iterator begin() const {
2948  return m_parsers.begin();
2949  }
2950  const_iterator end() const {
2951  return m_parsers.end();
2952  }
2953  private:
2954 
2955  template<typename T>
2956  void add() {
2957  m_parsers.push_back( new T() );
2958  }
2959  Parsers m_parsers;
2960 
2961  };
2962 
2963 } // end namespace Catch
2964 
2965 // #included from: internal/catch_list.hpp
2966 #define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
2967 
2968 #include <limits>
2969 
2970 namespace Catch {
2971  inline bool matchesFilters( const std::vector<TestCaseFilters>& filters, const TestCaseInfo& testCase ) {
2972  std::vector<TestCaseFilters>::const_iterator it = filters.begin();
2973  std::vector<TestCaseFilters>::const_iterator itEnd = filters.end();
2974  for(; it != itEnd; ++it )
2975  if( !it->shouldInclude( testCase ) )
2976  return false;
2977  return true;
2978  }
2979  inline void List( const ConfigData& config ) {
2980 
2981  if( config.listSpec & List::Reports ) {
2982  std::cout << "Available reports:\n";
2983  IReporterRegistry::FactoryMap::const_iterator it = getRegistryHub().getReporterRegistry().getFactories().begin();
2984  IReporterRegistry::FactoryMap::const_iterator itEnd = getRegistryHub().getReporterRegistry().getFactories().end();
2985  for(; it != itEnd; ++it ) {
2986  // !TBD: consider listAs()
2987  std::cout << "\t" << it->first << "\n\t\t'" << it->second->getDescription() << "'\n";
2988  }
2989  std::cout << std::endl;
2990  }
2991 
2992  if( config.listSpec & List::Tests ) {
2993  if( config.filters.empty() )
2994  std::cout << "All available test cases:\n";
2995  else
2996  std::cout << "Matching test cases:\n";
2997  std::vector<TestCaseInfo>::const_iterator it = getRegistryHub().getTestCaseRegistry().getAllTests().begin();
2998  std::vector<TestCaseInfo>::const_iterator itEnd = getRegistryHub().getTestCaseRegistry().getAllTests().end();
2999  std::size_t matchedTests = 0;
3000  for(; it != itEnd; ++it ) {
3001  if( matchesFilters( config.filters, *it ) ) {
3002  matchedTests++;
3003  // !TBD: consider listAs()
3004  std::cout << "\t" << it->getName() << "\n";
3005  if( ( config.listSpec & List::TestNames ) != List::TestNames )
3006  std::cout << "\t\t '" << it->getDescription() << "'\n";
3007  }
3008  }
3009  if( config.filters.empty() )
3010  std::cout << pluralise( matchedTests, "test case" ) << std::endl;
3011  else
3012  std::cout << pluralise( matchedTests, "matching test case" ) << std::endl;
3013  }
3014 
3015  if( ( config.listSpec & List::All ) == 0 ) {
3016  std::ostringstream oss;
3017  oss << "Unknown list type";
3018  throw std::domain_error( oss.str() );
3019  }
3020  }
3021 
3022 } // end namespace Catch
3023 
3024 // #included from: internal/catch_runner_impl.hpp
3025 #define TWOBLUECUBES_INTERNAL_CATCH_RUNNER_HPP_INCLUDED
3026 
3027 // #included from: catch_running_test.hpp
3028 #define TWOBLUECUBES_INTERNAL_CATCH_RUNNING_TEST_HPP_INCLUDED
3029 
3030 // #included from: catch_section_info.hpp
3031 #define TWOBLUECUBES_INTERNAL_CATCH_SECTION_INFO_HPP_INCLUDED
3032 
3033 #include <map>
3034 #include <string>
3035 
3036 namespace Catch {
3037 
3038  class SectionInfo {
3039  public:
3040 
3041  enum Status {
3042  Root,
3043  Unknown,
3044  Branch,
3045  TestedBranch,
3046  TestedLeaf
3047  };
3048 
3049  SectionInfo( SectionInfo* parent )
3050  : m_status( Unknown ),
3051  m_parent( parent )
3052  {}
3053 
3054  SectionInfo()
3055  : m_status( Root ),
3056  m_parent( NULL )
3057  {}
3058 
3059  ~SectionInfo() {
3060  deleteAllValues( m_subSections );
3061  }
3062 
3063  bool shouldRun() const {
3064  return m_status < TestedBranch;
3065  }
3066 
3067  bool ran() {
3068  if( m_status < Branch ) {
3069  m_status = TestedLeaf;
3070  return true;
3071  }
3072  return false;
3073  }
3074 
3075  bool isBranch() const {
3076  return m_status == Branch;
3077  }
3078 
3079  void ranToCompletion() {
3080  if( m_status == Branch && !hasUntestedSections() )
3081  m_status = TestedBranch;
3082  }
3083 
3084  SectionInfo* findSubSection( const std::string& name ) {
3085  std::map<std::string, SectionInfo*>::const_iterator it = m_subSections.find( name );
3086  return it != m_subSections.end()
3087  ? it->second
3088  : NULL;
3089  }
3090 
3091  SectionInfo* addSubSection( const std::string& name ) {
3092  SectionInfo* subSection = new SectionInfo( this );
3093  m_subSections.insert( std::make_pair( name, subSection ) );
3094  m_status = Branch;
3095  return subSection;
3096  }
3097 
3098  SectionInfo* getParent() {
3099  return m_parent;
3100  }
3101 
3102  bool hasUntestedSections() const {
3103  if( m_status == Unknown )
3104  return true;
3105 
3106  std::map<std::string, SectionInfo*>::const_iterator it = m_subSections.begin();
3107  std::map<std::string, SectionInfo*>::const_iterator itEnd = m_subSections.end();
3108  for(; it != itEnd; ++it ) {
3109  if( it->second->hasUntestedSections() )
3110  return true;
3111  }
3112  return false;
3113  }
3114 
3115  private:
3116  Status m_status;
3117  std::map<std::string, SectionInfo*> m_subSections;
3118  SectionInfo* m_parent;
3119  };
3120 }
3121 
3122 namespace Catch {
3123 
3124  class RunningTest {
3125 
3126  enum RunStatus {
3127  NothingRun,
3128  EncounteredASection,
3129  RanAtLeastOneSection,
3130  RanToCompletionWithSections,
3131  RanToCompletionWithNoSections
3132  };
3133 
3134  public:
3135  explicit RunningTest( const TestCaseInfo* info = NULL )
3136  : m_info( info ),
3137  m_runStatus( RanAtLeastOneSection ),
3138  m_currentSection( &m_rootSection ),
3139  m_changed( false )
3140  {}
3141 
3142  bool wasSectionSeen() const {
3143  return m_runStatus == RanAtLeastOneSection ||
3144  m_runStatus == RanToCompletionWithSections;
3145  }
3146 
3147  bool isBranchSection() const {
3148  return m_currentSection &&
3149  m_currentSection->isBranch();
3150  }
3151 
3152  bool hasSections() const {
3153  return m_runStatus == RanAtLeastOneSection ||
3154  m_runStatus == RanToCompletionWithSections ||
3155  m_runStatus == EncounteredASection;
3156  }
3157 
3158  void reset() {
3159  m_runStatus = NothingRun;
3160  m_changed = false;
3161  m_lastSectionToRun = NULL;
3162  }
3163 
3164  void ranToCompletion() {
3165  if( m_runStatus == RanAtLeastOneSection ||
3166  m_runStatus == EncounteredASection ) {
3167  m_runStatus = RanToCompletionWithSections;
3168  if( m_lastSectionToRun ) {
3169  m_lastSectionToRun->ranToCompletion();
3170  m_changed = true;
3171  }
3172  }
3173  else {
3174  m_runStatus = RanToCompletionWithNoSections;
3175  }
3176  }
3177 
3178  bool addSection( const std::string& name ) {
3179  if( m_runStatus == NothingRun )
3180  m_runStatus = EncounteredASection;
3181 
3182  SectionInfo* thisSection = m_currentSection->findSubSection( name );
3183  if( !thisSection ) {
3184  thisSection = m_currentSection->addSubSection( name );
3185  m_changed = true;
3186  }
3187 
3188  if( !wasSectionSeen() && thisSection->shouldRun() ) {
3189  m_currentSection = thisSection;
3190  m_lastSectionToRun = NULL;
3191  return true;
3192  }
3193  return false;
3194  }
3195 
3196  void endSection( const std::string& ) {
3197  if( m_currentSection->ran() ) {
3198  m_runStatus = RanAtLeastOneSection;
3199  m_changed = true;
3200  }
3201  else if( m_runStatus == EncounteredASection ) {
3202  m_runStatus = RanAtLeastOneSection;
3203  m_lastSectionToRun = m_currentSection;
3204  }
3205  m_currentSection = m_currentSection->getParent();
3206  }
3207 
3208  const TestCaseInfo& getTestCaseInfo() const {
3209  return *m_info;
3210  }
3211 
3212  bool hasUntestedSections() const {
3213  return m_runStatus == RanAtLeastOneSection ||
3214  ( m_rootSection.hasUntestedSections() && m_changed );
3215  }
3216 
3217  private:
3218  const TestCaseInfo* m_info;
3219  RunStatus m_runStatus;
3220  SectionInfo m_rootSection;
3221  SectionInfo* m_currentSection;
3222  SectionInfo* m_lastSectionToRun;
3223  bool m_changed;
3224  };
3225 }
3226 
3227 #include <set>
3228 #include <string>
3229 
3230 namespace Catch {
3231 
3232  class StreamRedirect {
3233 
3234  public:
3235  StreamRedirect( std::ostream& stream, std::string& targetString )
3236  : m_stream( stream ),
3237  m_prevBuf( stream.rdbuf() ),
3238  m_targetString( targetString )
3239  {
3240  stream.rdbuf( m_oss.rdbuf() );
3241  }
3242 
3243  ~StreamRedirect() {
3244  m_targetString += m_oss.str();
3245  m_stream.rdbuf( m_prevBuf );
3246  }
3247 
3248  private:
3249  std::ostream& m_stream;
3250  std::streambuf* m_prevBuf;
3251  std::ostringstream m_oss;
3252  std::string& m_targetString;
3253  };
3254 
3256 
3257  class Runner : public IResultCapture, public IRunner {
3258 
3259  Runner( const Runner& );
3260  void operator =( const Runner& );
3261 
3262  public:
3263 
3264  explicit Runner( const Config& config, const Ptr<IReporter>& reporter )
3265  : m_context( getCurrentMutableContext() ),
3266  m_runningTest( NULL ),
3267  m_config( config ),
3268  m_reporter( reporter ),
3269  m_prevRunner( &m_context.getRunner() ),
3270  m_prevResultCapture( &m_context.getResultCapture() ),
3271  m_prevConfig( m_context.getConfig() )
3272  {
3273  m_context.setRunner( this );
3274  m_context.setConfig( &m_config );
3275  m_context.setResultCapture( this );
3276  m_reporter->StartTesting();
3277  }
3278 
3279  virtual ~Runner() {
3280  m_reporter->EndTesting( m_totals );
3281  m_context.setRunner( m_prevRunner );
3282  m_context.setConfig( NULL );
3283  m_context.setResultCapture( m_prevResultCapture );
3284  m_context.setConfig( m_prevConfig );
3285  }
3286 
3287  Totals runMatching( const std::string& testSpec ) {
3288 
3289  std::vector<TestCaseInfo> matchingTests = getRegistryHub().getTestCaseRegistry().getMatchingTestCases( testSpec );
3290 
3291  Totals totals;
3292 
3293  m_reporter->StartGroup( testSpec );
3294 
3295  std::vector<TestCaseInfo>::const_iterator it = matchingTests.begin();
3296  std::vector<TestCaseInfo>::const_iterator itEnd = matchingTests.end();
3297  for(; it != itEnd; ++it )
3298  totals += runTest( *it );
3299  // !TBD use std::accumulate?
3300 
3301  m_reporter->EndGroup( testSpec, totals );
3302  return totals;
3303  }
3304 
3305  Totals runTest( const TestCaseInfo& testInfo ) {
3306  Totals prevTotals = m_totals;
3307 
3308  std::string redirectedCout;
3309  std::string redirectedCerr;
3310 
3311  m_reporter->StartTestCase( testInfo );
3312 
3313  m_runningTest = new RunningTest( &testInfo );
3314 
3315  do {
3316  do {
3317  m_currentResult.setLineInfo( m_runningTest->getTestCaseInfo().getLineInfo() );
3318  runCurrentTest( redirectedCout, redirectedCerr );
3319  }
3320  while( m_runningTest->hasUntestedSections() && !aborting() );
3321  }
3322  while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
3323 
3324  delete m_runningTest;
3325  m_runningTest = NULL;
3326 
3327  Totals deltaTotals = m_totals.delta( prevTotals );
3328  m_totals.testCases += deltaTotals.testCases;
3329  m_reporter->EndTestCase( testInfo, deltaTotals, redirectedCout, redirectedCerr );
3330  return deltaTotals;
3331  }
3332 
3333  const Config& config() const {
3334  return m_config;
3335  }
3336 
3337  private: // IResultCapture
3338 
3339  virtual ResultAction::Value acceptResult( bool result ) {
3340  return acceptResult( result ? ResultWas::Ok : ResultWas::ExpressionFailed );
3341  }
3342 
3343  virtual ResultAction::Value acceptResult( ResultWas::OfType result ) {
3344  m_currentResult.setResultType( result );
3345  return actOnCurrentResult();
3346  }
3347 
3348  virtual ResultAction::Value acceptExpression( const ResultInfoBuilder& resultInfo ) {
3349  m_currentResult = resultInfo;
3350  return actOnCurrentResult();
3351  }
3352 
3353  virtual void acceptMessage( const std::string& msg ) {
3354  m_currentResult.setMessage( msg );
3355  }
3356 
3357  virtual void testEnded( const ResultInfo& result ) {
3358  if( result.getResultType() == ResultWas::Ok ) {
3359  m_totals.assertions.passed++;
3360  }
3361  else if( !result.ok() ) {
3362  m_totals.assertions.failed++;
3363 
3364  std::vector<ResultInfo>::const_iterator it = m_info.begin();
3365  std::vector<ResultInfo>::const_iterator itEnd = m_info.end();
3366  for(; it != itEnd; ++it )
3367  m_reporter->Result( *it );
3368  m_info.clear();
3369  }
3370 
3371  if( result.getResultType() == ResultWas::Info )
3372  m_info.push_back( result );
3373  else
3374  m_reporter->Result( result );
3375  }
3376 
3377  virtual bool sectionStarted (
3378  const std::string& name,
3379  const std::string& description,
3380  const SourceLineInfo& lineInfo,
3381  Counts& assertions
3382  )
3383  {
3384  std::ostringstream oss;
3385  oss << name << "@" << lineInfo;
3386 
3387  if( !m_runningTest->addSection( oss.str() ) )
3388  return false;
3389 
3390  m_currentResult.setLineInfo( lineInfo );
3391  m_reporter->StartSection( name, description );
3392  assertions = m_totals.assertions;
3393 
3394  return true;
3395  }
3396 
3397  virtual void sectionEnded( const std::string& name, const Counts& prevAssertions ) {
3398  Counts assertions = m_totals.assertions - prevAssertions;
3399  if( assertions.total() == 0 &&
3400  ( m_config.data().warnings & ConfigData::WarnAbout::NoAssertions ) &&
3401  !m_runningTest->isBranchSection() ) {
3402  m_reporter->NoAssertionsInSection( name );
3403  m_totals.assertions.failed++;
3404  assertions.failed++;
3405  }
3406  m_runningTest->endSection( name );
3407  m_reporter->EndSection( name, assertions );
3408  }
3409 
3410  virtual void pushScopedInfo( ScopedInfo* scopedInfo ) {
3411  m_scopedInfos.push_back( scopedInfo );
3412  }
3413 
3414  virtual void popScopedInfo( ScopedInfo* scopedInfo ) {
3415  if( m_scopedInfos.back() == scopedInfo )
3416  m_scopedInfos.pop_back();
3417  }
3418 
3419  virtual bool shouldDebugBreak() const {
3420  return m_config.shouldDebugBreak();
3421  }
3422 
3423  virtual std::string getCurrentTestName() const {
3424  return m_runningTest
3425  ? m_runningTest->getTestCaseInfo().getName()
3426  : std::string("");
3427  }
3428 
3429  virtual const ResultInfo* getLastResult() const {
3430  return &m_lastResult;
3431  }
3432 
3433  public:
3434  // !TBD We need to do this another way!
3435  bool aborting() const {
3436  return m_totals.assertions.failed == static_cast<std::size_t>( m_config.getCutoff() );
3437  }
3438 
3439  private:
3440 
3441  ResultAction::Value actOnCurrentResult() {
3442  testEnded( m_currentResult );
3443  m_lastResult = m_currentResult;
3444 
3445  m_currentResult = ResultInfoBuilder();
3446 
3447  ResultAction::Value action = ResultAction::None;
3448 
3449  if( !m_lastResult.ok() ) {
3450  action = ResultAction::Failed;
3451  if( shouldDebugBreak() )
3452  action = (ResultAction::Value)( action | ResultAction::Debug );
3453  if( aborting() )
3454  action = (ResultAction::Value)( action | ResultAction::Abort );
3455  }
3456  return action;
3457  }
3458 
3459  void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
3460  try {
3461  m_runningTest->reset();
3462  Counts prevAssertions = m_totals.assertions;
3463  if( m_reporter->shouldRedirectStdout() ) {
3464  StreamRedirect coutRedir( std::cout, redirectedCout );
3465  StreamRedirect cerrRedir( std::cerr, redirectedCerr );
3466  m_runningTest->getTestCaseInfo().invoke();
3467  }
3468  else {
3469  m_runningTest->getTestCaseInfo().invoke();
3470  }
3471  Counts assertions = m_totals.assertions - prevAssertions;
3472  if( assertions.total() == 0 &&
3473  ( m_config.data().warnings & ConfigData::WarnAbout::NoAssertions ) &&
3474  !m_runningTest->hasSections() ) {
3475  m_totals.assertions.failed++;
3476  m_reporter->NoAssertionsInTestCase( m_runningTest->getTestCaseInfo().getName() );
3477  }
3478  m_runningTest->ranToCompletion();
3479  }
3480  catch( TestFailureException& ) {
3481  // This just means the test was aborted due to failure
3482  }
3483  catch(...) {
3484  acceptMessage( getRegistryHub().getExceptionTranslatorRegistry().translateActiveException() );
3485  acceptResult( ResultWas::ThrewException );
3486  }
3487  m_info.clear();
3488  }
3489 
3490  private:
3491  IMutableContext& m_context;
3492  RunningTest* m_runningTest;
3493  ResultInfoBuilder m_currentResult;
3494  ResultInfo m_lastResult;
3495 
3496  const Config& m_config;
3497  Totals m_totals;
3498  Ptr<IReporter> m_reporter;
3499  std::vector<ScopedInfo*> m_scopedInfos;
3500  std::vector<ResultInfo> m_info;
3501  IRunner* m_prevRunner;
3502  IResultCapture* m_prevResultCapture;
3503  const IConfig* m_prevConfig;
3504  };
3505 
3506 } // end namespace Catch
3507 
3508 #include <fstream>
3509 #include <stdlib.h>
3510 #include <limits>
3511 
3512 namespace Catch {
3513 
3514  class Runner2 { // This will become Runner when Runner becomes Context
3515 
3516  public:
3517  Runner2( Config& configWrapper )
3518  : m_configWrapper( configWrapper ),
3519  m_config( configWrapper.data() )
3520  {
3521  resolveStream();
3522  makeReporter();
3523  }
3524 
3525  Totals runTests() {
3526 
3527  std::vector<TestCaseFilters> filterGroups = m_config.filters;
3528  if( filterGroups.empty() ) {
3529  TestCaseFilters filterGroup( "" );
3530  filterGroup.addFilter( TestCaseFilter( "./*", IfFilterMatches::ExcludeTests ) );
3531  filterGroups.push_back( filterGroup );
3532  }
3533 
3534  Runner context( m_configWrapper, m_reporter ); // This Runner will be renamed Context
3535  Totals totals;
3536 
3537  std::vector<TestCaseFilters>::const_iterator it = filterGroups.begin();
3538  std::vector<TestCaseFilters>::const_iterator itEnd = filterGroups.end();
3539  for(; it != itEnd; ++it ) {
3540  m_reporter->StartGroup( it->getName() );
3541  totals += runTestsForGroup( context, *it );
3542  if( context.aborting() )
3543  m_reporter->Aborted();
3544  m_reporter->EndGroup( it->getName(), totals );
3545  }
3546  return totals;
3547  }
3548 
3549  Totals runTestsForGroup( Runner& context, const TestCaseFilters& filterGroup ) {
3550  Totals totals;
3551  std::vector<TestCaseInfo>::const_iterator it = getRegistryHub().getTestCaseRegistry().getAllTests().begin();
3552  std::vector<TestCaseInfo>::const_iterator itEnd = getRegistryHub().getTestCaseRegistry().getAllTests().end();
3553  int testsRunForGroup = 0;
3554  for(; it != itEnd; ++it ) {
3555  if( filterGroup.shouldInclude( *it ) ) {
3556  testsRunForGroup++;
3557  if( m_testsAlreadyRun.find( *it ) == m_testsAlreadyRun.end() ) {
3558 
3559  if( context.aborting() )
3560  break;
3561 
3562  totals += context.runTest( *it );
3563  m_testsAlreadyRun.insert( *it );
3564  }
3565  }
3566  }
3567  if( testsRunForGroup == 0 )
3568  std::cerr << "\n[No test cases matched with: " << filterGroup.getName() << "]" << std::endl;
3569  return totals;
3570 
3571  }
3572 
3573  private:
3574  void resolveStream() {
3575  if( !m_config.stream.empty() ) {
3576  if( m_config.stream[0] == '%' )
3577  m_configWrapper.useStream( m_config.stream.substr( 1 ) );
3578  else
3579  m_configWrapper.setFilename( m_config.stream );
3580  }
3581  // Open output file, if specified
3582  if( !m_config.outputFilename.empty() ) {
3583  m_ofs.open( m_config.outputFilename.c_str() );
3584  if( m_ofs.fail() ) {
3585  std::ostringstream oss;
3586  oss << "Unable to open file: '" << m_config.outputFilename << "'";
3587  throw std::domain_error( oss.str() );
3588  }
3589  m_configWrapper.setStreamBuf( m_ofs.rdbuf() );
3590  }
3591  }
3592  void makeReporter() {
3593  std::string reporterName = m_config.reporter.empty()
3594  ? std::string("basic")
3595  : m_config.reporter;
3596 
3597  ReporterConfig reporterConfig( m_config.name, m_configWrapper.stream(), m_config.includeWhichResults == Include::SuccessfulResults, m_config );
3598 
3599  m_reporter = getRegistryHub().getReporterRegistry().create( reporterName, reporterConfig );
3600  if( !m_reporter ) {
3601  std::ostringstream oss;
3602  oss << "No reporter registered with name: '" << reporterName << "'";
3603  throw std::domain_error( oss.str() );
3604  }
3605  }
3606 
3607  private:
3608  Config& m_configWrapper;
3609  const ConfigData& m_config;
3610  std::ofstream m_ofs;
3611  Ptr<IReporter> m_reporter;
3612  std::set<TestCaseInfo> m_testsAlreadyRun;
3613  };
3614 
3615  inline int Main( Config& configWrapper ) {
3616  int result = 0;
3617  try
3618  {
3619  Runner2 runner( configWrapper );
3620 
3621  const ConfigData& config = configWrapper.data();
3622 
3623  // Handle list request
3624  if( config.listSpec != List::None ) {
3625  List( config );
3626  return 0;
3627  }
3628 
3629  result = static_cast<int>( runner.runTests().assertions.failed );
3630 
3631  }
3632  catch( std::exception& ex ) {
3633  std::cerr << ex.what() << std::endl;
3634  result = (std::numeric_limits<int>::max)();
3635  }
3636 
3637  Catch::cleanUp();
3638  return result;
3639  }
3640 
3641  inline void showUsage( std::ostream& os ) {
3642  AllOptions options;
3643  for( AllOptions::const_iterator it = options.begin(); it != options.end(); ++it ) {
3644  OptionParser& opt = **it;
3645  os << " " << opt.optionNames() << " " << opt.argsSynopsis() << "\n";
3646  }
3647  os << "\nFor more detail usage please see: https://github.com/philsquared/Catch/wiki/Command-line\n" << std::endl;
3648  }
3649  inline void showHelp( std::string exeName ) {
3650  std::string::size_type pos = exeName.find_last_of( "/\\" );
3651  if( pos != std::string::npos ) {
3652  exeName = exeName.substr( pos+1 );
3653  }
3654 
3655  std::cout << exeName << " is a CATCH host application. Options are as follows:\n\n";
3656  showUsage( std::cout );
3657  }
3658 
3659  inline int Main( int argc, char* const argv[], Config& config ) {
3660 
3661  try {
3662  CommandParser parser( argc, (char const * const * ) argv );
3663 
3664  if( Command cmd = Options::HelpOptionParser().find( parser ) ) {
3665  if( cmd.argsCount() != 0 )
3666  cmd.raiseError( "Does not accept arguments" );
3667 
3668  showHelp( argv[0] );
3669  Catch::cleanUp();
3670  return 0;
3671  }
3672 
3673  AllOptions options;
3674 
3675  options.parseIntoConfig( parser, config.data() );
3676  }
3677  catch( std::exception& ex ) {
3678  std::cerr << ex.what() << "\n\nUsage: ...\n\n";
3679  showUsage( std::cerr );
3680  Catch::cleanUp();
3681  return (std::numeric_limits<int>::max)();
3682  }
3683 
3684  return Main( config );
3685  }
3686 
3687  inline int Main( int argc, char* const argv[] ) {
3688  Config config;
3689 // !TBD: This doesn't always work, for some reason
3690 // if( isDebuggerActive() )
3691 // config.useStream( "debug" );
3692  return Main( argc, argv, config );
3693  }
3694 
3695 } // end namespace Catch
3696 
3697 // #included from: catch_registry_hub.hpp
3698 
3699 // #included from: catch_test_case_registry_impl.hpp
3700 
3701 #include <vector>
3702 #include <set>
3703 #include <sstream>
3704 #include <iostream>
3705 
3706 namespace Catch {
3707 
3708  class TestRegistry : public ITestCaseRegistry {
3709  public:
3710  TestRegistry() : m_unnamedCount( 0 ) {}
3711  virtual ~TestRegistry();
3712 
3713  virtual void registerTest( const TestCaseInfo& testInfo ) {
3714  if( testInfo.getName() == "" ) {
3715  std::ostringstream oss;
3716  oss << testInfo.getName() << "unnamed/" << ++m_unnamedCount;
3717  return registerTest( TestCaseInfo( testInfo, oss.str() ) );
3718  }
3719 
3720  if( m_functions.find( testInfo ) == m_functions.end() ) {
3721  m_functions.insert( testInfo );
3722  m_functionsInOrder.push_back( testInfo );
3723  if( !testInfo.isHidden() )
3724  m_nonHiddenFunctions.push_back( testInfo );
3725  }
3726  else {
3727  const TestCaseInfo& prev = *m_functions.find( testInfo );
3728  std::cerr << "error: TEST_CASE( \"" << testInfo.getName() << "\" ) already defined.\n"
3729  << "\tFirst seen at " << SourceLineInfo( prev.getLineInfo() ) << "\n"
3730  << "\tRedefined at " << SourceLineInfo( testInfo.getLineInfo() ) << std::endl;
3731  exit(1);
3732  }
3733  }
3734 
3735  virtual const std::vector<TestCaseInfo>& getAllTests() const {
3736  return m_functionsInOrder;
3737  }
3738 
3739  virtual const std::vector<TestCaseInfo>& getAllNonHiddenTests() const {
3740  return m_nonHiddenFunctions;
3741  }
3742 
3743  // !TBD deprecated
3744  virtual std::vector<TestCaseInfo> getMatchingTestCases( const std::string& rawTestSpec ) const {
3745  std::vector<TestCaseInfo> matchingTests;
3746  getMatchingTestCases( rawTestSpec, matchingTests );
3747  return matchingTests;
3748  }
3749 
3750  // !TBD deprecated
3751  virtual void getMatchingTestCases( const std::string& rawTestSpec, std::vector<TestCaseInfo>& matchingTestsOut ) const {
3752  TestCaseFilter filter( rawTestSpec );
3753 
3754  std::vector<TestCaseInfo>::const_iterator it = m_functionsInOrder.begin();
3755  std::vector<TestCaseInfo>::const_iterator itEnd = m_functionsInOrder.end();
3756  for(; it != itEnd; ++it ) {
3757  if( filter.shouldInclude( *it ) ) {
3758  matchingTestsOut.push_back( *it );
3759  }
3760  }
3761  }
3762  virtual void getMatchingTestCases( const TestCaseFilters& filters, std::vector<TestCaseInfo>& matchingTestsOut ) const {
3763  std::vector<TestCaseInfo>::const_iterator it = m_functionsInOrder.begin();
3764  std::vector<TestCaseInfo>::const_iterator itEnd = m_functionsInOrder.end();
3765  // !TBD: replace with algorithm
3766  for(; it != itEnd; ++it )
3767  if( filters.shouldInclude( *it ) )
3768  matchingTestsOut.push_back( *it );
3769  }
3770 
3771  private:
3772 
3773  std::set<TestCaseInfo> m_functions;
3774  std::vector<TestCaseInfo> m_functionsInOrder;
3775  std::vector<TestCaseInfo> m_nonHiddenFunctions;
3776  size_t m_unnamedCount;
3777  };
3778 
3780 
3781  class FreeFunctionTestCase : public SharedImpl<ITestCase> {
3782  public:
3783 
3784  FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
3785 
3786  virtual void invoke() const {
3787  m_fun();
3788  }
3789 
3790  private:
3791  virtual ~FreeFunctionTestCase();
3792 
3793  TestFunction m_fun;
3794  };
3795 
3797 
3798  AutoReg::AutoReg( TestFunction function,
3799  const char* name,
3800  const char* description,
3801  const SourceLineInfo& lineInfo ) {
3802  registerTestCase( new FreeFunctionTestCase( function ), name, description, lineInfo );
3803  }
3804 
3805  AutoReg::~AutoReg() {}
3806 
3807  void AutoReg::registerTestCase( ITestCase* testCase,
3808  const char* name,
3809  const char* description,
3810  const SourceLineInfo& lineInfo ) {
3811  getMutableRegistryHub().registerTest( TestCaseInfo( testCase, name, description, lineInfo ) );
3812  }
3813 
3814 } // end namespace Catch
3815 
3816 // #included from: catch_reporter_registry.hpp
3817 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
3818 
3819 #include <map>
3820 
3821 namespace Catch {
3822 
3823  class ReporterRegistry : public IReporterRegistry {
3824 
3825  public:
3826 
3827  virtual ~ReporterRegistry() {
3828  deleteAllValues( m_factories );
3829  }
3830 
3831  virtual IReporter* create( const std::string& name, const ReporterConfig& config ) const {
3832  FactoryMap::const_iterator it = m_factories.find( name );
3833  if( it == m_factories.end() )
3834  return NULL;
3835  return it->second->create( config );
3836  }
3837 
3838  void registerReporter( const std::string& name, IReporterFactory* factory ) {
3839  m_factories.insert( std::make_pair( name, factory ) );
3840  }
3841 
3842  const FactoryMap& getFactories() const {
3843  return m_factories;
3844  }
3845 
3846  private:
3847  FactoryMap m_factories;
3848  };
3849 }
3850 
3851 // #included from: catch_exception_translator_registry.hpp
3852 #define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_HPP_INCLUDED
3853 
3854 #ifdef __OBJC__
3855 #import "Foundation/Foundation.h"
3856 #endif
3857 
3858 namespace Catch {
3859 
3860  class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
3861  public:
3862  ~ExceptionTranslatorRegistry() {
3863  deleteAll( m_translators );
3864  }
3865 
3866  virtual void registerTranslator( const IExceptionTranslator* translator ) {
3867  m_translators.push_back( translator );
3868  }
3869 
3870  virtual std::string translateActiveException() const {
3871  try {
3872 #ifdef __OBJC__
3873  // In Objective-C try objective-c exceptions first
3874  @try {
3875  throw;
3876  }
3877  @catch (NSException *exception) {
3878  return toString( [exception description] );
3879  }
3880 #else
3881  throw;
3882 #endif
3883  }
3884  catch( std::exception& ex ) {
3885  return ex.what();
3886  }
3887  catch( std::string& msg ) {
3888  return msg;
3889  }
3890  catch( const char* msg ) {
3891  return msg;
3892  }
3893  catch(...) {
3894  return tryTranslators( m_translators.begin() );
3895  }
3896  }
3897 
3898  std::string tryTranslators( std::vector<const IExceptionTranslator*>::const_iterator it ) const {
3899  if( it == m_translators.end() )
3900  return "Unknown exception";
3901 
3902  try {
3903  return (*it)->translate();
3904  }
3905  catch(...) {
3906  return tryTranslators( it+1 );
3907  }
3908  }
3909 
3910  private:
3911  std::vector<const IExceptionTranslator*> m_translators;
3912  };
3913 }
3914 
3915 namespace Catch {
3916 
3917  namespace {
3918 
3919  class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
3920 
3921  RegistryHub( const RegistryHub& );
3922  void operator=( const RegistryHub& );
3923 
3924  public: // IRegistryHub
3925  RegistryHub() {
3926  }
3927  virtual const IReporterRegistry& getReporterRegistry() const {
3928  return m_reporterRegistry;
3929  }
3930  virtual const ITestCaseRegistry& getTestCaseRegistry() const {
3931  return m_testCaseRegistry;
3932  }
3933  virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() {
3934  return m_exceptionTranslatorRegistry;
3935  }
3936 
3937  public: // IMutableRegistryHub
3938  virtual void registerReporter( const std::string& name, IReporterFactory* factory ) {
3939  m_reporterRegistry.registerReporter( name, factory );
3940  }
3941  virtual void registerTest( const TestCaseInfo& testInfo ) {
3942  m_testCaseRegistry.registerTest( testInfo );
3943  }
3944  virtual void registerTranslator( const IExceptionTranslator* translator ) {
3945  m_exceptionTranslatorRegistry.registerTranslator( translator );
3946  }
3947 
3948  private:
3949  TestRegistry m_testCaseRegistry;
3950  ReporterRegistry m_reporterRegistry;
3951  ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
3952  };
3953 
3954  // Single, global, instance
3955  inline RegistryHub*& getTheRegistryHub() {
3956  static RegistryHub* theRegistryHub = NULL;
3957  if( !theRegistryHub )
3958  theRegistryHub = new RegistryHub();
3959  return theRegistryHub;
3960  }
3961  }
3962 
3963  IRegistryHub& getRegistryHub() {
3964  return *getTheRegistryHub();
3965  }
3966  IMutableRegistryHub& getMutableRegistryHub() {
3967  return *getTheRegistryHub();
3968  }
3969  void cleanUp() {
3970  delete getTheRegistryHub();
3971  getTheRegistryHub() = NULL;
3972  cleanUpContext();
3973  }
3974 
3975 } // end namespace Catch
3976 // #included from: catch_notimplemented_exception.hpp
3977 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
3978 
3979 #include <ostream>
3980 
3981 namespace Catch {
3982 
3983  NotImplementedException::NotImplementedException( const SourceLineInfo& lineInfo )
3984  : m_lineInfo( lineInfo ) {
3985  std::ostringstream oss;
3986  oss << lineInfo << "function ";
3987  if( !lineInfo.function.empty() )
3988  oss << lineInfo.function << " ";
3989  oss << "not implemented";
3990  m_what = oss.str();
3991  }
3992 
3993  const char* NotImplementedException::what() const throw() {
3994  return m_what.c_str();
3995  }
3996 
3997 } // end namespace Catch
3998 
3999 // #included from: catch_context_impl.hpp
4000 
4001 // #included from: catch_stream.hpp
4002 #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
4003 
4004 #include <stdexcept>
4005 #include <cstdio>
4006 
4007 namespace Catch {
4008 
4009  template<typename WriterF, size_t bufferSize=256>
4010  class StreamBufImpl : public StreamBufBase {
4011  char data[bufferSize];
4012  WriterF m_writer;
4013 
4014  public:
4015  StreamBufImpl() {
4016  setp( data, data + sizeof(data) );
4017  }
4018 
4019  ~StreamBufImpl() {
4020  sync();
4021  }
4022 
4023  private:
4024  int overflow( int c ) {
4025  sync();
4026 
4027  if( c != EOF ) {
4028  if( pbase() == epptr() )
4029  m_writer( std::string( 1, static_cast<char>( c ) ) );
4030  else
4031  sputc( static_cast<char>( c ) );
4032  }
4033  return 0;
4034  }
4035 
4036  int sync() {
4037  if( pbase() != pptr() ) {
4038  m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
4039  setp( pbase(), epptr() );
4040  }
4041  return 0;
4042  }
4043  };
4044 
4046 
4047  struct OutputDebugWriter {
4048 
4049  void operator()( const std::string &str ) {
4050  writeToDebugConsole( str );
4051  }
4052  };
4053 }
4054 
4055 namespace Catch {
4056 
4057  class Context : public IMutableContext {
4058 
4059  Context() : m_config( NULL ) {}
4060  Context( const Context& );
4061  void operator=( const Context& );
4062 
4063  public: // IContext
4064  virtual IResultCapture& getResultCapture() {
4065  return *m_resultCapture;
4066  }
4067  virtual IRunner& getRunner() {
4068  return *m_runner;
4069  }
4070  virtual size_t getGeneratorIndex( const std::string& fileInfo, size_t totalSize ) {
4071  return getGeneratorsForCurrentTest()
4072  .getGeneratorInfo( fileInfo, totalSize )
4073  .getCurrentIndex();
4074  }
4075  virtual bool advanceGeneratorsForCurrentTest() {
4076  IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
4077  return generators && generators->moveNext();
4078  }
4079 
4080  virtual const IConfig* getConfig() const {
4081  return m_config;
4082  }
4083 
4084  public: // IMutableContext
4085  virtual void setResultCapture( IResultCapture* resultCapture ) {
4086  m_resultCapture = resultCapture;
4087  }
4088  virtual void setRunner( IRunner* runner ) {
4089  m_runner = runner;
4090  }
4091  virtual void setConfig( const IConfig* config ) {
4092  m_config = config;
4093  }
4094 
4095  friend IMutableContext& getCurrentMutableContext();
4096 
4097  private:
4098  IGeneratorsForTest* findGeneratorsForCurrentTest() {
4099  std::string testName = getResultCapture().getCurrentTestName();
4100 
4101  std::map<std::string, IGeneratorsForTest*>::const_iterator it =
4102  m_generatorsByTestName.find( testName );
4103  return it != m_generatorsByTestName.end()
4104  ? it->second
4105  : NULL;
4106  }
4107 
4108  IGeneratorsForTest& getGeneratorsForCurrentTest() {
4109  IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
4110  if( !generators ) {
4111  std::string testName = getResultCapture().getCurrentTestName();
4112  generators = createGeneratorsForTest();
4113  m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
4114  }
4115  return *generators;
4116  }
4117 
4118  private:
4119  IRunner* m_runner;
4120  IResultCapture* m_resultCapture;
4121  const IConfig* m_config;
4122  std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
4123  };
4124 
4125  namespace {
4126  Context* currentContext = NULL;
4127  }
4128  IMutableContext& getCurrentMutableContext() {
4129  if( !currentContext )
4130  currentContext = new Context();
4131  return *currentContext;
4132  }
4133  IContext& getCurrentContext() {
4134  return getCurrentMutableContext();
4135  }
4136 
4137  std::streambuf* createStreamBuf( const std::string& streamName ) {
4138  if( streamName == "stdout" ) return std::cout.rdbuf();
4139  if( streamName == "stderr" ) return std::cerr.rdbuf();
4140  if( streamName == "debug" ) return new StreamBufImpl<OutputDebugWriter>;
4141 
4142  throw std::domain_error( "Unknown stream: " + streamName );
4143  }
4144 
4145  void cleanUpContext() {
4146  delete currentContext;
4147  currentContext = NULL;
4148  }
4149 }
4150 // #included from: catch_console_colour_impl.hpp
4151 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
4152 
4153 // #included from: catch_console_colour.hpp
4154 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
4155 
4156 namespace Catch {
4157 
4158  struct ConsoleColourImpl;
4159 
4160  class TextColour : NonCopyable {
4161  public:
4162 
4163  enum Colours {
4164  None,
4165 
4166  FileName,
4167  ResultError,
4168  ResultSuccess,
4169 
4170  Error,
4171  Success,
4172 
4173  OriginalExpression,
4174  ReconstructedExpression
4175  };
4176 
4177  TextColour( Colours colour = None );
4178  void set( Colours colour );
4179  ~TextColour();
4180 
4181  private:
4182  ConsoleColourImpl* m_impl;
4183  };
4184 
4185 } // end namespace Catch
4186 
4187 #ifdef CATCH_PLATFORM_WINDOWS
4188 
4189 #include <windows.h>
4190 
4191 namespace Catch {
4192 
4193  namespace {
4194 
4195  WORD mapConsoleColour( TextColour::Colours colour ) {
4196  switch( colour ) {
4197  case TextColour::FileName:
4198  return FOREGROUND_INTENSITY; // greyed out
4199  case TextColour::ResultError:
4200  return FOREGROUND_RED | FOREGROUND_INTENSITY; // bright red
4201  case TextColour::ResultSuccess:
4202  return FOREGROUND_GREEN | FOREGROUND_INTENSITY; // bright green
4203  case TextColour::Error:
4204  return FOREGROUND_RED; // dark red
4205  case TextColour::Success:
4206  return FOREGROUND_GREEN; // dark green
4207  case TextColour::OriginalExpression:
4208  return FOREGROUND_BLUE | FOREGROUND_GREEN; // turquoise
4209  case TextColour::ReconstructedExpression:
4210  return FOREGROUND_RED | FOREGROUND_GREEN; // greeny-yellow
4211  default: return 0;
4212  }
4213  }
4214  }
4215 
4216  struct ConsoleColourImpl {
4217 
4218  ConsoleColourImpl()
4219  : hStdout( GetStdHandle(STD_OUTPUT_HANDLE) ),
4220  wOldColorAttrs( 0 )
4221  {
4222  GetConsoleScreenBufferInfo( hStdout, &csbiInfo );
4223  wOldColorAttrs = csbiInfo.wAttributes;
4224  }
4225 
4226  ~ConsoleColourImpl() {
4227  SetConsoleTextAttribute( hStdout, wOldColorAttrs );
4228  }
4229 
4230  void set( TextColour::Colours colour ) {
4231  WORD consoleColour = Catch::mapConsoleColour( colour );
4232  if( consoleColour > 0 )
4233  SetConsoleTextAttribute( hStdout, consoleColour );
4234  }
4235 
4236  HANDLE hStdout;
4237  CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
4238  WORD wOldColorAttrs;
4239  };
4240 
4241  TextColour::TextColour( Colours colour )
4242  : m_impl( new ConsoleColourImpl() )
4243  {
4244  if( colour )
4245  m_impl->set( colour );
4246  }
4247 
4248  TextColour::~TextColour() {
4249  delete m_impl;
4250  }
4251 
4252  void TextColour::set( Colours colour ) {
4253  m_impl->set( colour );
4254  }
4255 
4256 } // end namespace Catch
4257 
4258 #else
4259 
4260 namespace Catch {
4261  TextColour::TextColour( Colours ){}
4262  TextColour::~TextColour(){}
4263  void TextColour::set( Colours ){}
4264 
4265 } // end namespace Catch
4266 
4267 #endif
4268 
4269 // #included from: catch_generators_impl.hpp
4270 #define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
4271 
4272 #include <vector>
4273 #include <string>
4274 #include <map>
4275 
4276 namespace Catch {
4277 
4278  struct GeneratorInfo : IGeneratorInfo {
4279 
4280  GeneratorInfo( std::size_t size )
4281  : m_size( size ),
4282  m_currentIndex( 0 )
4283  {}
4284 
4285  bool moveNext() {
4286  if( ++m_currentIndex == m_size ) {
4287  m_currentIndex = 0;
4288  return false;
4289  }
4290  return true;
4291  }
4292 
4293  std::size_t getCurrentIndex() const {
4294  return m_currentIndex;
4295  }
4296 
4297  std::size_t m_size;
4298  std::size_t m_currentIndex;
4299  };
4300 
4302 
4303  class GeneratorsForTest : public IGeneratorsForTest {
4304 
4305  public:
4306  ~GeneratorsForTest() {
4307  deleteAll( m_generatorsInOrder );
4308  }
4309 
4310  IGeneratorInfo& getGeneratorInfo( const std::string& fileInfo, std::size_t size ) {
4311  std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
4312  if( it == m_generatorsByName.end() ) {
4313  IGeneratorInfo* info = new GeneratorInfo( size );
4314  m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
4315  m_generatorsInOrder.push_back( info );
4316  return *info;
4317  }
4318  return *it->second;
4319  }
4320 
4321  bool moveNext() {
4322  std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
4323  std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
4324  for(; it != itEnd; ++it ) {
4325  if( (*it)->moveNext() )
4326  return true;
4327  }
4328  return false;
4329  }
4330 
4331  private:
4332  std::map<std::string, IGeneratorInfo*> m_generatorsByName;
4333  std::vector<IGeneratorInfo*> m_generatorsInOrder;
4334  };
4335 
4336  IGeneratorsForTest* createGeneratorsForTest()
4337  {
4338  return new GeneratorsForTest();
4339  }
4340 
4341 } // end namespace Catch
4342 
4343 // #included from: catch_resultinfo.hpp
4344 #define TWOBLUECUBES_CATCH_RESULT_INFO_HPP_INCLUDED
4345 
4346 namespace Catch {
4347 
4348  ResultInfo::ResultInfo()
4349  : m_macroName(),
4350  m_expr(),
4351  m_lhs(),
4352  m_rhs(),
4353  m_op(),
4354  m_message(),
4355  m_result( ResultWas::Unknown ),
4356  m_isNot( false )
4357  {}
4358 
4359  ResultInfo::ResultInfo(const char* expr,
4360  ResultWas::OfType result,
4361  bool isNot,
4362  const SourceLineInfo& lineInfo,
4363  const char* macroName,
4364  const char* message )
4365  : m_macroName( macroName ),
4366  m_lineInfo( lineInfo ),
4367  m_expr( expr ),
4368  m_lhs(),
4369  m_rhs(),
4370  m_op( isNotExpression( expr ) ? "!" : "" ),
4371  m_message( message ),
4372  m_result( result ),
4373  m_isNot( isNot )
4374  {
4375  if( isNot )
4376  m_expr = "!" + m_expr;
4377  }
4378 
4379  ResultInfo::~ResultInfo() {}
4380 
4381  bool ResultInfo::ok() const {
4382  return ( m_result & ResultWas::FailureBit ) != ResultWas::FailureBit;
4383  }
4384 
4385  ResultWas::OfType ResultInfo::getResultType() const {
4386  return m_result;
4387  }
4388 
4389  bool ResultInfo::hasExpression() const {
4390  return !m_expr.empty();
4391  }
4392 
4393  bool ResultInfo::hasMessage() const {
4394  return !m_message.empty();
4395  }
4396 
4397  std::string ResultInfo::getExpression() const {
4398  return m_expr;
4399  }
4400 
4401  bool ResultInfo::hasExpandedExpression() const {
4402  return hasExpression() && getExpandedExpressionInternal() != m_expr;
4403  }
4404 
4405  std::string ResultInfo::getExpandedExpression() const {
4406  return hasExpression() ? getExpandedExpressionInternal() : std::string("");
4407  }
4408 
4409  std::string ResultInfo::getMessage() const {
4410  return m_message;
4411  }
4412 
4413  std::string ResultInfo::getFilename() const {
4414  return m_lineInfo.file;
4415  }
4416 
4417  std::size_t ResultInfo::getLine() const {
4418  return m_lineInfo.line;
4419  }
4420 
4421  std::string ResultInfo::getTestMacroName() const {
4422  return m_macroName;
4423  }
4424 
4425  std::string ResultInfo::getExpandedExpressionInternal() const {
4426  if( m_op == "" || m_isNot )
4427  return m_lhs.empty() ? m_expr : m_op + m_lhs;
4428  else if( m_op == "matches" )
4429  return m_lhs + " " + m_rhs;
4430  else if( m_op != "!" )
4431  {
4432  if( m_lhs.size() + m_rhs.size() < 30 )
4433  return m_lhs + " " + m_op + " " + m_rhs;
4434  else if( m_lhs.size() < 70 && m_rhs.size() < 70 )
4435  return "\n\t" + m_lhs + "\n\t" + m_op + "\n\t" + m_rhs;
4436  else
4437  return "\n" + m_lhs + "\n" + m_op + "\n" + m_rhs + "\n\n";
4438  }
4439  else
4440  return "{can't expand - use " + m_macroName + "_FALSE( " + m_expr.substr(1) + " ) instead of " + m_macroName + "( " + m_expr + " ) for better diagnostics}";
4441  }
4442 
4443  bool ResultInfo::isNotExpression( const char* expr ) {
4444  return expr && expr[0] == '!';
4445  }
4446 
4447 } // end namespace Catch
4448 
4449 // #included from: catch_resultinfo_builder.hpp
4450 #define TWOBLUECUBES_CATCH_RESULTINFO_BUILDER_HPP_INCLUDED
4451 
4452 namespace Catch {
4453 
4454  ResultInfoBuilder::ResultInfoBuilder() {}
4455 
4456  ResultInfoBuilder::ResultInfoBuilder( const char* expr,
4457  bool isNot,
4458  const SourceLineInfo& lineInfo,
4459  const char* macroName,
4460  const char* message )
4461  : ResultInfo( expr, ResultWas::Unknown, isNot, lineInfo, macroName, message )
4462  {}
4463 
4464  void ResultInfoBuilder::setResultType( ResultWas::OfType result ) {
4465  // Flip bool results if isNot is set
4466  if( m_isNot && result == ResultWas::Ok )
4467  m_result = ResultWas::ExpressionFailed;
4468  else if( m_isNot && result == ResultWas::ExpressionFailed )
4469  m_result = ResultWas::Ok;
4470  else
4471  m_result = result;
4472  }
4473 
4474  void ResultInfoBuilder::setMessage( const std::string& message ) {
4475  m_message = message;
4476  }
4477 
4478  void ResultInfoBuilder::setLineInfo( const SourceLineInfo& lineInfo ) {
4479  m_lineInfo = lineInfo;
4480  }
4481 
4482  void ResultInfoBuilder::setLhs( const std::string& lhs ) {
4483  m_lhs = lhs;
4484  }
4485 
4486  void ResultInfoBuilder::setRhs( const std::string& rhs ) {
4487  m_rhs = rhs;
4488  }
4489 
4490  void ResultInfoBuilder::setOp( const std::string& op ) {
4491  m_op = op;
4492  }
4493 
4494  ResultInfoBuilder& ResultInfoBuilder::captureBoolExpression( bool result ) {
4495  m_lhs = Catch::toString( result );
4496  m_op = m_isNot ? "!" : "";
4497  setResultType( result ? ResultWas::Ok : ResultWas::ExpressionFailed );
4498  return *this;
4499  }
4500 
4501 } // end namespace Catch
4502 
4503 // #included from: catch_test_case_info.hpp
4504 #define TWOBLUECUBES_CATCH_TESTCASEINFO_HPP_INCLUDED
4505 
4506 namespace Catch {
4507 
4508  TestCaseInfo::TestCaseInfo( ITestCase* testCase,
4509  const char* name,
4510  const char* description,
4511  const SourceLineInfo& lineInfo )
4512  : m_test( testCase ),
4513  m_name( name ),
4514  m_description( description ),
4515  m_lineInfo( lineInfo )
4516  {}
4517 
4518  TestCaseInfo::TestCaseInfo()
4519  : m_test( NULL ),
4520  m_name(),
4521  m_description()
4522  {}
4523 
4524  TestCaseInfo::TestCaseInfo( const TestCaseInfo& other, const std::string& name )
4525  : m_test( other.m_test ),
4526  m_name( name ),
4527  m_description( other.m_description ),
4528  m_lineInfo( other.m_lineInfo )
4529  {}
4530 
4531  TestCaseInfo::TestCaseInfo( const TestCaseInfo& other )
4532  : m_test( other.m_test ),
4533  m_name( other.m_name ),
4534  m_description( other.m_description ),
4535  m_lineInfo( other.m_lineInfo )
4536  {}
4537 
4538  void TestCaseInfo::invoke() const {
4539  m_test->invoke();
4540  }
4541 
4542  const std::string& TestCaseInfo::getName() const {
4543  return m_name;
4544  }
4545 
4546  const std::string& TestCaseInfo::getDescription() const {
4547  return m_description;
4548  }
4549 
4550  const SourceLineInfo& TestCaseInfo::getLineInfo() const {
4551  return m_lineInfo;
4552  }
4553 
4554  bool TestCaseInfo::isHidden() const {
4555  return m_name.size() >= 2 && m_name[0] == '.' && m_name[1] == '/';
4556  }
4557 
4558  void TestCaseInfo::swap( TestCaseInfo& other ) {
4559  m_test.swap( other.m_test );
4560  m_name.swap( other.m_name );
4561  m_description.swap( other.m_description );
4562  m_lineInfo.swap( other.m_lineInfo );
4563  }
4564 
4565  bool TestCaseInfo::operator == ( const TestCaseInfo& other ) const {
4566  return m_test.get() == other.m_test.get() && m_name == other.m_name;
4567  }
4568 
4569  bool TestCaseInfo::operator < ( const TestCaseInfo& other ) const {
4570  return m_name < other.m_name;
4571  }
4572  TestCaseInfo& TestCaseInfo::operator = ( const TestCaseInfo& other ) {
4573  TestCaseInfo temp( other );
4574  swap( temp );
4575  return *this;
4576  }
4577 }
4578 
4579 // #included from: ../reporters/catch_reporter_basic.hpp
4580 #define TWOBLUECUBES_CATCH_REPORTER_BASIC_HPP_INCLUDED
4581 
4582 // #included from: ../internal/catch_reporter_registrars.hpp
4583 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
4584 
4585 namespace Catch {
4586 
4587  template<typename T>
4588  class ReporterRegistrar {
4589 
4590  class ReporterFactory : public IReporterFactory {
4591 
4592  virtual IReporter* create( const ReporterConfig& config ) const {
4593  return new T( config );
4594  }
4595 
4596  virtual std::string getDescription() const {
4597  return T::getDescription();
4598  }
4599  };
4600 
4601  public:
4602 
4603  ReporterRegistrar( const std::string& name ) {
4604  getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
4605  }
4606  };
4607 }
4608 
4609 #define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
4610  Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name );
4611 
4612 namespace Catch {
4613 
4614  class BasicReporter : public SharedImpl<IReporter> {
4615 
4616  struct SpanInfo {
4617 
4618  SpanInfo()
4619  : emitted( false )
4620  {}
4621 
4622  SpanInfo( const std::string& spanName )
4623  : name( spanName ),
4624  emitted( false )
4625  {}
4626 
4627  SpanInfo( const SpanInfo& other )
4628  : name( other.name ),
4629  emitted( other.emitted )
4630  {}
4631 
4632  std::string name;
4633  bool emitted;
4634  };
4635 
4636  public:
4637  BasicReporter( const ReporterConfig& config )
4638  : m_config( config ),
4639  m_firstSectionInTestCase( true ),
4640  m_aborted( false )
4641  {}
4642 
4643  virtual ~BasicReporter();
4644 
4645  static std::string getDescription() {
4646  return "Reports test results as lines of text";
4647  }
4648 
4649  private:
4650 
4651  void ReportCounts( const std::string& label, const Counts& counts, const std::string& allPrefix = "All " ) {
4652  if( counts.passed )
4653  m_config.stream << counts.failed << " of " << counts.total() << " " << label << "s failed";
4654  else
4655  m_config.stream << ( counts.failed > 1 ? allPrefix : std::string("") ) << pluralise( counts.failed, label ) << " failed";
4656  }
4657 
4658  void ReportCounts( const Totals& totals, const std::string& allPrefix = "All " ) {
4659  if( totals.assertions.total() == 0 ) {
4660  m_config.stream << "No tests ran";
4661  }
4662  else if( totals.assertions.failed ) {
4663  TextColour colour( TextColour::ResultError );
4664  ReportCounts( "test case", totals.testCases, allPrefix );
4665  if( totals.testCases.failed > 0 ) {
4666  m_config.stream << " (";
4667  ReportCounts( "assertion", totals.assertions, allPrefix );
4668  m_config.stream << ")";
4669  }
4670  }
4671  else {
4672  TextColour colour( TextColour::ResultSuccess );
4673  m_config.stream << allPrefix << "tests passed ("
4674  << pluralise( totals.assertions.passed, "assertion" ) << " in "
4675  << pluralise( totals.testCases.passed, "test case" ) << ")";
4676  }
4677  }
4678 
4679  private: // IReporter
4680 
4681  virtual bool shouldRedirectStdout() const {
4682  return false;
4683  }
4684 
4685  virtual void StartTesting() {
4686  m_testingSpan = SpanInfo();
4687  }
4688 
4689  virtual void Aborted() {
4690  m_aborted = true;
4691  }
4692 
4693  virtual void EndTesting( const Totals& totals ) {
4694  // Output the overall test results even if "Started Testing" was not emitted
4695  if( m_aborted ) {
4696  m_config.stream << "\n[Testing aborted. ";
4697  ReportCounts( totals, "The first " );
4698  }
4699  else {
4700  m_config.stream << "\n[Testing completed. ";
4701  ReportCounts( totals );
4702  }
4703  m_config.stream << "]\n" << std::endl;
4704  }
4705 
4706  virtual void StartGroup( const std::string& groupName ) {
4707  m_groupSpan = groupName;
4708  }
4709 
4710  virtual void EndGroup( const std::string& groupName, const Totals& totals ) {
4711  if( m_groupSpan.emitted && !groupName.empty() ) {
4712  m_config.stream << "[End of group: '" << groupName << "'. ";
4713  ReportCounts( totals );
4714  m_config.stream << "]\n" << std::endl;
4715  m_groupSpan = SpanInfo();
4716  }
4717  }
4718 
4719  virtual void StartTestCase( const TestCaseInfo& testInfo ) {
4720  m_testSpan = testInfo.getName();
4721  }
4722 
4723  virtual void StartSection( const std::string& sectionName, const std::string& ) {
4724  m_sectionSpans.push_back( SpanInfo( sectionName ) );
4725  }
4726 
4727  virtual void NoAssertionsInSection( const std::string& sectionName ) {
4728  StartSpansLazily();
4729  TextColour colour( TextColour::ResultError );
4730  m_config.stream << "\nNo assertions in section, '" << sectionName << "'\n" << std::endl;
4731  }
4732  virtual void NoAssertionsInTestCase( const std::string& testName ) {
4733  StartSpansLazily();
4734  TextColour colour( TextColour::ResultError );
4735  m_config.stream << "\nNo assertions in test case, '" << testName << "'\n" << std::endl;
4736  }
4737 
4738  virtual void EndSection( const std::string& sectionName, const Counts& assertions ) {
4739 
4740  SpanInfo& sectionSpan = m_sectionSpans.back();
4741  if( sectionSpan.emitted && !sectionSpan.name.empty() ) {
4742  m_config.stream << "[End of section: '" << sectionName << "' ";
4743 
4744  if( assertions.failed ) {
4745  TextColour colour( TextColour::ResultError );
4746  ReportCounts( "assertion", assertions);
4747  }
4748  else {
4749  TextColour colour( TextColour::ResultSuccess );
4750  m_config.stream << ( assertions.passed > 1 ? "All " : "" )
4751  << pluralise( assertions.passed, "assertion" ) << " passed" ;
4752  }
4753  m_config.stream << "]\n" << std::endl;
4754  }
4755  m_sectionSpans.pop_back();
4756  }
4757 
4758  virtual void Result( const ResultInfo& resultInfo ) {
4759  if( !m_config.includeSuccessfulResults && resultInfo.getResultType() == ResultWas::Ok )
4760  return;
4761 
4762  StartSpansLazily();
4763 
4764  if( !resultInfo.getFilename().empty() ) {
4765  TextColour colour( TextColour::FileName );
4766  m_config.stream << SourceLineInfo( resultInfo.getFilename(), resultInfo.getLine() );
4767  }
4768 
4769  if( resultInfo.hasExpression() ) {
4770  TextColour colour( TextColour::OriginalExpression );
4771  m_config.stream << resultInfo.getExpression();
4772  if( resultInfo.ok() ) {
4773  TextColour successColour( TextColour::Success );
4774  m_config.stream << " succeeded";
4775  }
4776  else {
4777  TextColour errorColour( TextColour::Error );
4778  m_config.stream << " failed";
4779  }
4780  }
4781  switch( resultInfo.getResultType() ) {
4782  case ResultWas::ThrewException:
4783  {
4784  TextColour colour( TextColour::Error );
4785  if( resultInfo.hasExpression() )
4786  m_config.stream << " with unexpected";
4787  else
4788  m_config.stream << "Unexpected";
4789  m_config.stream << " exception with message: '" << resultInfo.getMessage() << "'";
4790  }
4791  break;
4792  case ResultWas::DidntThrowException:
4793  {
4794  TextColour colour( TextColour::Error );
4795  if( resultInfo.hasExpression() )
4796  m_config.stream << " because no exception was thrown where one was expected";
4797  else
4798  m_config.stream << "No exception thrown where one was expected";
4799  }
4800  break;
4801  case ResultWas::Info:
4802  streamVariableLengthText( "info", resultInfo.getMessage() );
4803  break;
4804  case ResultWas::Warning:
4805  m_config.stream << "warning:\n'" << resultInfo.getMessage() << "'";
4806  break;
4807  case ResultWas::ExplicitFailure:
4808  {
4809  TextColour colour( TextColour::Error );
4810  m_config.stream << "failed with message: '" << resultInfo.getMessage() << "'";
4811  }
4812  break;
4813  case ResultWas::Unknown: // These cases are here to prevent compiler warnings
4814  case ResultWas::Ok:
4815  case ResultWas::FailureBit:
4816  case ResultWas::ExpressionFailed:
4817  case ResultWas::Exception:
4818  if( !resultInfo.hasExpression() ) {
4819  if( resultInfo.ok() ) {
4820  TextColour colour( TextColour::Success );
4821  m_config.stream << " succeeded";
4822  }
4823  else {
4824  TextColour colour( TextColour::Error );
4825  m_config.stream << " failed";
4826  }
4827  }
4828  break;
4829  }
4830 
4831  if( resultInfo.hasExpandedExpression() ) {
4832  m_config.stream << " for: ";
4833  TextColour colour( TextColour::ReconstructedExpression );
4834  m_config.stream << resultInfo.getExpandedExpression();
4835  }
4836  m_config.stream << std::endl;
4837  }
4838 
4839  virtual void EndTestCase( const TestCaseInfo& testInfo,
4840  const Totals& totals,
4841  const std::string& stdOut,
4842  const std::string& stdErr ) {
4843  if( !stdOut.empty() ) {
4844  StartSpansLazily();
4845  streamVariableLengthText( "stdout", stdOut );
4846  }
4847 
4848  if( !stdErr.empty() ) {
4849  StartSpansLazily();
4850  streamVariableLengthText( "stderr", stdErr );
4851  }
4852 
4853  if( m_testSpan.emitted ) {
4854  m_config.stream << "[Finished: '" << testInfo.getName() << "' ";
4855  ReportCounts( totals );
4856  m_config.stream << "]" << std::endl;
4857  }
4858  }
4859 
4860  private: // helpers
4861 
4862  void StartSpansLazily() {
4863  if( !m_testingSpan.emitted ) {
4864  if( m_config.name.empty() )
4865  m_config.stream << "[Started testing]" << std::endl;
4866  else
4867  m_config.stream << "[Started testing: " << m_config.name << "]" << std::endl;
4868  m_testingSpan.emitted = true;
4869  }
4870 
4871  if( !m_groupSpan.emitted && !m_groupSpan.name.empty() ) {
4872  m_config.stream << "[Started group: '" << m_groupSpan.name << "']" << std::endl;
4873  m_groupSpan.emitted = true;
4874  }
4875 
4876  if( !m_testSpan.emitted ) {
4877  m_config.stream << std::endl << "[Running: " << m_testSpan.name << "]" << std::endl;
4878  m_testSpan.emitted = true;
4879  }
4880 
4881  if( !m_sectionSpans.empty() ) {
4882  SpanInfo& sectionSpan = m_sectionSpans.back();
4883  if( !sectionSpan.emitted && !sectionSpan.name.empty() ) {
4884  if( m_firstSectionInTestCase ) {
4885  m_config.stream << "\n";
4886  m_firstSectionInTestCase = false;
4887  }
4888  std::vector<SpanInfo>::iterator it = m_sectionSpans.begin();
4889  std::vector<SpanInfo>::iterator itEnd = m_sectionSpans.end();
4890  for(; it != itEnd; ++it ) {
4891  SpanInfo& prevSpan = *it;
4892  if( !prevSpan.emitted && !prevSpan.name.empty() ) {
4893  m_config.stream << "[Started section: '" << prevSpan.name << "']" << std::endl;
4894  prevSpan.emitted = true;
4895  }
4896  }
4897  }
4898  }
4899  }
4900 
4901  void streamVariableLengthText( const std::string& prefix, const std::string& text ) {
4902  std::string trimmed = trim( text );
4903  if( trimmed.find_first_of( "\r\n" ) == std::string::npos ) {
4904  m_config.stream << "[" << prefix << ": " << trimmed << "]\n";
4905  }
4906  else {
4907  m_config.stream << "\n[" << prefix << "] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n" << trimmed
4908  << "\n[end of " << prefix << "] <<<<<<<<<<<<<<<<<<<<<<<<\n";
4909  }
4910  }
4911 
4912  private:
4913  ReporterConfig m_config;
4914  bool m_firstSectionInTestCase;
4915 
4916  SpanInfo m_testingSpan;
4917  SpanInfo m_groupSpan;
4918  SpanInfo m_testSpan;
4919  std::vector<SpanInfo> m_sectionSpans;
4920  bool m_aborted;
4921  };
4922 
4923 } // end namespace Catch
4924 
4925 // #included from: ../reporters/catch_reporter_xml.hpp
4926 #define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
4927 
4928 // #included from: ../internal/catch_xmlwriter.hpp
4929 #define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
4930 
4931 #include <sstream>
4932 #include <string>
4933 #include <vector>
4934 
4935 namespace Catch {
4936 
4937  class XmlWriter {
4938  public:
4939 
4940  class ScopedElement {
4941  public:
4942  ScopedElement( XmlWriter* writer )
4943  : m_writer( writer )
4944  {}
4945 
4946  ScopedElement( const ScopedElement& other )
4947  : m_writer( other.m_writer ){
4948  other.m_writer = NULL;
4949  }
4950 
4951  ~ScopedElement() {
4952  if( m_writer )
4953  m_writer->endElement();
4954  }
4955 
4956  ScopedElement& writeText( const std::string& text ) {
4957  m_writer->writeText( text );
4958  return *this;
4959  }
4960 
4961  template<typename T>
4962  ScopedElement& writeAttribute( const std::string& name, const T& attribute ) {
4963  m_writer->writeAttribute( name, attribute );
4964  return *this;
4965  }
4966 
4967  private:
4968  mutable XmlWriter* m_writer;
4969  };
4970 
4971  XmlWriter()
4972  : m_tagIsOpen( false ),
4973  m_needsNewline( false ),
4974  m_os( &std::cout )
4975  {}
4976 
4977  XmlWriter( std::ostream& os )
4978  : m_tagIsOpen( false ),
4979  m_needsNewline( false ),
4980  m_os( &os )
4981  {}
4982 
4983  ~XmlWriter() {
4984  while( !m_tags.empty() )
4985  endElement();
4986  }
4987 
4988  XmlWriter& operator = ( const XmlWriter& other ) {
4989  XmlWriter temp( other );
4990  swap( temp );
4991  return *this;
4992  }
4993 
4994  void swap( XmlWriter& other ) {
4995  std::swap( m_tagIsOpen, other.m_tagIsOpen );
4996  std::swap( m_needsNewline, other.m_needsNewline );
4997  std::swap( m_tags, other.m_tags );
4998  std::swap( m_indent, other.m_indent );
4999  std::swap( m_os, other.m_os );
5000  }
5001 
5002  XmlWriter& startElement( const std::string& name ) {
5003  ensureTagClosed();
5004  newlineIfNecessary();
5005  stream() << m_indent << "<" << name;
5006  m_tags.push_back( name );
5007  m_indent += " ";
5008  m_tagIsOpen = true;
5009  return *this;
5010  }
5011 
5012  ScopedElement scopedElement( const std::string& name ) {
5013  ScopedElement scoped( this );
5014  startElement( name );
5015  return scoped;
5016  }
5017 
5018  XmlWriter& endElement() {
5019  newlineIfNecessary();
5020  m_indent = m_indent.substr( 0, m_indent.size()-2 );
5021  if( m_tagIsOpen ) {
5022  stream() << "/>\n";
5023  m_tagIsOpen = false;
5024  }
5025  else {
5026  stream() << m_indent << "</" << m_tags.back() << ">\n";
5027  }
5028  m_tags.pop_back();
5029  return *this;
5030  }
5031 
5032  XmlWriter& writeAttribute( const std::string& name, const std::string& attribute ) {
5033  if( !name.empty() && !attribute.empty() ) {
5034  stream() << " " << name << "=\"";
5035  writeEncodedText( attribute );
5036  stream() << "\"";
5037  }
5038  return *this;
5039  }
5040 
5041  XmlWriter& writeAttribute( const std::string& name, bool attribute ) {
5042  stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\"";
5043  return *this;
5044  }
5045 
5046  template<typename T>
5047  XmlWriter& writeAttribute( const std::string& name, const T& attribute ) {
5048  if( !name.empty() )
5049  stream() << " " << name << "=\"" << attribute << "\"";
5050  return *this;
5051  }
5052 
5053  XmlWriter& writeText( const std::string& text ) {
5054  if( !text.empty() ){
5055  bool tagWasOpen = m_tagIsOpen;
5056  ensureTagClosed();
5057  if( tagWasOpen )
5058  stream() << m_indent;
5059  writeEncodedText( text );
5060  m_needsNewline = true;
5061  }
5062  return *this;
5063  }
5064 
5065  XmlWriter& writeComment( const std::string& text ) {
5066  ensureTagClosed();
5067  stream() << m_indent << "<!--" << text << "-->";
5068  m_needsNewline = true;
5069  return *this;
5070  }
5071 
5072  XmlWriter& writeBlankLine() {
5073  ensureTagClosed();
5074  stream() << "\n";
5075  return *this;
5076  }
5077 
5078  private:
5079 
5080  std::ostream& stream() {
5081  return *m_os;
5082  }
5083 
5084  void ensureTagClosed() {
5085  if( m_tagIsOpen ) {
5086  stream() << ">\n";
5087  m_tagIsOpen = false;
5088  }
5089  }
5090 
5091  void newlineIfNecessary() {
5092  if( m_needsNewline ) {
5093  stream() << "\n";
5094  m_needsNewline = false;
5095  }
5096  }
5097 
5098  void writeEncodedText( const std::string& text ) {
5099  static const char* charsToEncode = "<&\"";
5100  std::string mtext = text;
5101  std::string::size_type pos = mtext.find_first_of( charsToEncode );
5102  while( pos != std::string::npos ) {
5103  stream() << mtext.substr( 0, pos );
5104 
5105  switch( mtext[pos] ) {
5106  case '<':
5107  stream() << "&lt;";
5108  break;
5109  case '&':
5110  stream() << "&amp;";
5111  break;
5112  case '\"':
5113  stream() << "&quot;";
5114  break;
5115  }
5116  mtext = mtext.substr( pos+1 );
5117  pos = mtext.find_first_of( charsToEncode );
5118  }
5119  stream() << mtext;
5120  }
5121 
5122  bool m_tagIsOpen;
5123  bool m_needsNewline;
5124  std::vector<std::string> m_tags;
5125  std::string m_indent;
5126  std::ostream* m_os;
5127  };
5128 
5129 }
5130 namespace Catch {
5131  class XmlReporter : public SharedImpl<IReporter> {
5132  public:
5133  XmlReporter( const ReporterConfig& config ) : m_config( config ) {}
5134 
5135  static std::string getDescription() {
5136  return "Reports test results as an XML document";
5137  }
5138  virtual ~XmlReporter();
5139 
5140  private: // IReporter
5141 
5142  virtual bool shouldRedirectStdout() const {
5143  return true;
5144  }
5145 
5146  virtual void StartTesting() {
5147  m_xml = XmlWriter( m_config.stream );
5148  m_xml.startElement( "Catch" );
5149  if( !m_config.name.empty() )
5150  m_xml.writeAttribute( "name", m_config.name );
5151  }
5152 
5153  virtual void EndTesting( const Totals& totals ) {
5154  m_xml.scopedElement( "OverallResults" )
5155  .writeAttribute( "successes", totals.assertions.passed )
5156  .writeAttribute( "failures", totals.assertions.failed );
5157  m_xml.endElement();
5158  }
5159 
5160  virtual void StartGroup( const std::string& groupName ) {
5161  m_xml.startElement( "Group" )
5162  .writeAttribute( "name", groupName );
5163  }
5164 
5165  virtual void EndGroup( const std::string&, const Totals& totals ) {
5166  m_xml.scopedElement( "OverallResults" )
5167  .writeAttribute( "successes", totals.assertions.passed )
5168  .writeAttribute( "failures", totals.assertions.failed );
5169  m_xml.endElement();
5170  }
5171 
5172  virtual void StartSection( const std::string& sectionName, const std::string& description ) {
5173  m_xml.startElement( "Section" )
5174  .writeAttribute( "name", sectionName )
5175  .writeAttribute( "description", description );
5176  }
5177  virtual void NoAssertionsInSection( const std::string& ) {}
5178  virtual void NoAssertionsInTestCase( const std::string& ) {}
5179 
5180  virtual void EndSection( const std::string& /*sectionName*/, const Counts& assertions ) {
5181  m_xml.scopedElement( "OverallResults" )
5182  .writeAttribute( "successes", assertions.passed )
5183  .writeAttribute( "failures", assertions.failed );
5184  m_xml.endElement();
5185  }
5186 
5187  virtual void StartTestCase( const Catch::TestCaseInfo& testInfo ) {
5188  m_xml.startElement( "TestCase" ).writeAttribute( "name", testInfo.getName() );
5189  m_currentTestSuccess = true;
5190  }
5191 
5192  virtual void Result( const Catch::ResultInfo& resultInfo ) {
5193  if( !m_config.includeSuccessfulResults && resultInfo.getResultType() == ResultWas::Ok )
5194  return;
5195 
5196  if( resultInfo.hasExpression() ) {
5197  m_xml.startElement( "Expression" )
5198  .writeAttribute( "success", resultInfo.ok() )
5199  .writeAttribute( "filename", resultInfo.getFilename() )
5200  .writeAttribute( "line", resultInfo.getLine() );
5201 
5202  m_xml.scopedElement( "Original" )
5203  .writeText( resultInfo.getExpression() );
5204  m_xml.scopedElement( "Expanded" )
5205  .writeText( resultInfo.getExpandedExpression() );
5206  m_currentTestSuccess &= resultInfo.ok();
5207  }
5208 
5209  switch( resultInfo.getResultType() ) {
5210  case ResultWas::ThrewException:
5211  m_xml.scopedElement( "Exception" )
5212  .writeAttribute( "filename", resultInfo.getFilename() )
5213  .writeAttribute( "line", resultInfo.getLine() )
5214  .writeText( resultInfo.getMessage() );
5215  m_currentTestSuccess = false;
5216  break;
5217  case ResultWas::Info:
5218  m_xml.scopedElement( "Info" )
5219  .writeText( resultInfo.getMessage() );
5220  break;
5221  case ResultWas::Warning:
5222  m_xml.scopedElement( "Warning" )
5223  .writeText( resultInfo.getMessage() );
5224  break;
5225  case ResultWas::ExplicitFailure:
5226  m_xml.scopedElement( "Failure" )
5227  .writeText( resultInfo.getMessage() );
5228  m_currentTestSuccess = false;
5229  break;
5230  case ResultWas::Unknown:
5231  case ResultWas::Ok:
5232  case ResultWas::FailureBit:
5233  case ResultWas::ExpressionFailed:
5234  case ResultWas::Exception:
5235  case ResultWas::DidntThrowException:
5236  break;
5237  }
5238  if( resultInfo.hasExpression() )
5239  m_xml.endElement();
5240  }
5241 
5242  virtual void Aborted() {
5243  // !TBD
5244  }
5245 
5246  virtual void EndTestCase( const Catch::TestCaseInfo&, const Totals&, const std::string&, const std::string& ) {
5247  m_xml.scopedElement( "OverallResult" ).writeAttribute( "success", m_currentTestSuccess );
5248  m_xml.endElement();
5249  }
5250 
5251  private:
5252  ReporterConfig m_config;
5253  bool m_currentTestSuccess;
5254  XmlWriter m_xml;
5255  };
5256 
5257 } // end namespace Catch
5258 
5259 // #included from: ../reporters/catch_reporter_junit.hpp
5260 #define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
5261 
5262 namespace Catch {
5263 
5264  class JunitReporter : public SharedImpl<IReporter> {
5265 
5266  struct TestStats {
5267  std::string m_element;
5268  std::string m_resultType;
5269  std::string m_message;
5270  std::string m_content;
5271  };
5272 
5273  struct TestCaseStats {
5274 
5275  TestCaseStats( const std::string& name = std::string() ) :m_name( name ){}
5276 
5277  double m_timeInSeconds;
5278  std::string m_status;
5279  std::string m_className;
5280  std::string m_name;
5281  std::vector<TestStats> m_testStats;
5282  };
5283 
5284  struct Stats {
5285 
5286  Stats( const std::string& name = std::string() )
5287  : m_testsCount( 0 ),
5288  m_failuresCount( 0 ),
5289  m_disabledCount( 0 ),
5290  m_errorsCount( 0 ),
5291  m_timeInSeconds( 0 ),
5292  m_name( name )
5293  {}
5294 
5295  std::size_t m_testsCount;
5296  std::size_t m_failuresCount;
5297  std::size_t m_disabledCount;
5298  std::size_t m_errorsCount;
5299  double m_timeInSeconds;
5300  std::string m_name;
5301 
5302  std::vector<TestCaseStats> m_testCaseStats;
5303  };
5304 
5305  public:
5306  JunitReporter( const ReporterConfig& config )
5307  : m_config( config ),
5308  m_testSuiteStats( "AllTests" ),
5309  m_currentStats( &m_testSuiteStats )
5310  {}
5311  virtual ~JunitReporter();
5312 
5313  static std::string getDescription() {
5314  return "Reports test results in an XML format that looks like Ant's junitreport target";
5315  }
5316 
5317  private: // IReporter
5318 
5319  virtual bool shouldRedirectStdout() const {
5320  return true;
5321  }
5322 
5323  virtual void StartTesting(){}
5324 
5325  virtual void StartGroup( const std::string& groupName ) {
5326  m_statsForSuites.push_back( Stats( groupName ) );
5327  m_currentStats = &m_statsForSuites.back();
5328  }
5329 
5330  virtual void EndGroup( const std::string&, const Totals& totals ) {
5331  m_currentStats->m_testsCount = totals.assertions.total();
5332  m_currentStats = &m_testSuiteStats;
5333  }
5334 
5335  virtual void StartSection( const std::string&, const std::string& ){}
5336 
5337  virtual void NoAssertionsInSection( const std::string& ) {}
5338  virtual void NoAssertionsInTestCase( const std::string& ) {}
5339 
5340  virtual void EndSection( const std::string&, const Counts& ) {}
5341 
5342  virtual void StartTestCase( const Catch::TestCaseInfo& testInfo ) {
5343  m_currentStats->m_testCaseStats.push_back( TestCaseStats( testInfo.getName() ) );
5344  }
5345 
5346  virtual void Result( const Catch::ResultInfo& resultInfo ) {
5347  if( resultInfo.getResultType() != ResultWas::Ok || m_config.includeSuccessfulResults ) {
5348  TestCaseStats& testCaseStats = m_currentStats->m_testCaseStats.back();
5349  TestStats stats;
5350  std::ostringstream oss;
5351  if( !resultInfo.getMessage().empty() )
5352  oss << resultInfo.getMessage() << " at ";
5353  oss << SourceLineInfo( resultInfo.getFilename(), resultInfo.getLine() );
5354  stats.m_content = oss.str();
5355  stats.m_message = resultInfo.getExpandedExpression();
5356  stats.m_resultType = resultInfo.getTestMacroName();
5357 
5358  switch( resultInfo.getResultType() ) {
5359  case ResultWas::ThrewException:
5360  stats.m_element = "error";
5361  m_currentStats->m_errorsCount++;
5362  break;
5363  case ResultWas::Info:
5364  stats.m_element = "info"; // !TBD ?
5365  break;
5366  case ResultWas::Warning:
5367  stats.m_element = "warning"; // !TBD ?
5368  break;
5369  case ResultWas::ExplicitFailure:
5370  stats.m_element = "failure";
5371  m_currentStats->m_failuresCount++;
5372  break;
5373  case ResultWas::ExpressionFailed:
5374  stats.m_element = "failure";
5375  m_currentStats->m_failuresCount++;
5376  break;
5377  case ResultWas::Ok:
5378  stats.m_element = "success";
5379  break;
5380  case ResultWas::Unknown:
5381  case ResultWas::FailureBit:
5382  case ResultWas::Exception:
5383  case ResultWas::DidntThrowException:
5384  break;
5385  }
5386  testCaseStats.m_testStats.push_back( stats );
5387  }
5388  }
5389 
5390  virtual void EndTestCase( const Catch::TestCaseInfo&, const Totals&, const std::string& stdOut, const std::string& stdErr ) {
5391  if( !stdOut.empty() )
5392  m_stdOut << stdOut << "\n";
5393  if( !stdErr.empty() )
5394  m_stdErr << stdErr << "\n";
5395  }
5396 
5397  virtual void Aborted() {
5398  // !TBD
5399  }
5400 
5401  virtual void EndTesting( const Totals& ) {
5402  std::ostream& str = m_config.stream;
5403  {
5404  XmlWriter xml( str );
5405 
5406  if( m_statsForSuites.size() > 0 )
5407  xml.startElement( "testsuites" );
5408 
5409  std::vector<Stats>::const_iterator it = m_statsForSuites.begin();
5410  std::vector<Stats>::const_iterator itEnd = m_statsForSuites.end();
5411 
5412  for(; it != itEnd; ++it ) {
5413  XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
5414  xml.writeAttribute( "name", it->m_name );
5415  xml.writeAttribute( "errors", it->m_errorsCount );
5416  xml.writeAttribute( "failures", it->m_failuresCount );
5417  xml.writeAttribute( "tests", it->m_testsCount );
5418  xml.writeAttribute( "hostname", "tbd" );
5419  xml.writeAttribute( "time", "tbd" );
5420  xml.writeAttribute( "timestamp", "tbd" );
5421 
5422  OutputTestCases( xml, *it );
5423  }
5424 
5425  xml.scopedElement( "system-out" ).writeText( trim( m_stdOut.str() ) );
5426  xml.scopedElement( "system-err" ).writeText( trim( m_stdErr.str() ) );
5427  }
5428  }
5429 
5430  void OutputTestCases( XmlWriter& xml, const Stats& stats ) {
5431  std::vector<TestCaseStats>::const_iterator it = stats.m_testCaseStats.begin();
5432  std::vector<TestCaseStats>::const_iterator itEnd = stats.m_testCaseStats.end();
5433  for(; it != itEnd; ++it ) {
5434  xml.writeBlankLine();
5435  xml.writeComment( "Test case" );
5436 
5437  XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
5438  xml.writeAttribute( "classname", it->m_className );
5439  xml.writeAttribute( "name", it->m_name );
5440  xml.writeAttribute( "time", "tbd" );
5441 
5442  OutputTestResult( xml, *it );
5443  }
5444  }
5445 
5446  void OutputTestResult( XmlWriter& xml, const TestCaseStats& stats ) {
5447  std::vector<TestStats>::const_iterator it = stats.m_testStats.begin();
5448  std::vector<TestStats>::const_iterator itEnd = stats.m_testStats.end();
5449  for(; it != itEnd; ++it ) {
5450  if( it->m_element != "success" ) {
5451  XmlWriter::ScopedElement e = xml.scopedElement( it->m_element );
5452 
5453  xml.writeAttribute( "message", it->m_message );
5454  xml.writeAttribute( "type", it->m_resultType );
5455  if( !it->m_content.empty() )
5456  xml.writeText( it->m_content );
5457  }
5458  }
5459  }
5460 
5461  private:
5462  ReporterConfig m_config;
5463  bool m_currentTestSuccess;
5464 
5465  Stats m_testSuiteStats;
5466  Stats* m_currentStats;
5467  std::vector<Stats> m_statsForSuites;
5468  std::ostringstream m_stdOut;
5469  std::ostringstream m_stdErr;
5470  };
5471 
5472 } // end namespace Catch
5473 
5474 namespace Catch {
5475  NonCopyable::~NonCopyable() {}
5476  IShared::~IShared() {}
5477  StreamBufBase::~StreamBufBase() {}
5478  IContext::~IContext() {}
5479  IResultCapture::~IResultCapture() {}
5480  ITestCase::~ITestCase() {}
5481  ITestCaseRegistry::~ITestCaseRegistry() {}
5482  IRegistryHub::~IRegistryHub() {}
5483  IMutableRegistryHub::~IMutableRegistryHub() {}
5484  IExceptionTranslator::~IExceptionTranslator() {}
5485  IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
5486  IReporter::~IReporter() {}
5487  IReporterFactory::~IReporterFactory() {}
5488  IReporterRegistry::~IReporterRegistry() {}
5489  BasicReporter::~BasicReporter() {}
5490  IRunner::~IRunner() {}
5491  IMutableContext::~IMutableContext() {}
5492  IConfig::~IConfig() {}
5493  XmlReporter::~XmlReporter() {}
5494  JunitReporter::~JunitReporter() {}
5495  TestRegistry::~TestRegistry() {}
5496  FreeFunctionTestCase::~FreeFunctionTestCase() {}
5497  IGeneratorInfo::~IGeneratorInfo() {}
5498  IGeneratorsForTest::~IGeneratorsForTest() {}
5499 
5500  void Config::dummy() {}
5501 
5502  INTERNAL_CATCH_REGISTER_REPORTER( "basic", BasicReporter )
5503  INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
5504  INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
5505 
5506 }
5507 
5508 #ifdef __clang__
5509 #pragma clang diagnostic pop
5510 #endif
5511 #endif
5512 
5513 #ifdef CATCH_CONFIG_MAIN
5514 // #included from: internal/catch_default_main.hpp
5515 #define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
5516 
5517 #ifndef __OBJC__
5518 
5519 // Standard C/C++ main entry point
5520 int main (int argc, char * const argv[]) {
5521  return Catch::Main( argc, argv );
5522 }
5523 
5524 #else // __OBJC__
5525 
5526 // Objective-C entry point
5527 int main (int argc, char * const argv[]) {
5528 #if !CATCH_ARC_ENABLED
5529  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
5530 #endif
5531 
5532  Catch::registerTestMethods();
5533  int result = Catch::Main( argc, (char* const*)argv );
5534 
5535 #if !CATCH_ARC_ENABLED
5536  [pool drain];
5537 #endif
5538 
5539  return result;
5540 }
5541 
5542 #endif // __OBJC__
5543 
5544 #endif
5545 
5547 
5548 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
5549 #ifdef CATCH_CONFIG_PREFIX_ALL
5550 
5551 #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, false, true, "CATCH_REQUIRE" )
5552 #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, true, true, "CATCH_REQUIRE_FALSE" )
5553 
5554 #define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, ..., true, "CATCH_REQUIRE_THROWS" )
5555 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, true, "CATCH_REQUIRE_THROWS_AS" )
5556 #define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, true, "CATCH_REQUIRE_NOTHROW" )
5557 
5558 #define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, false, false, "CATCH_CHECK" )
5559 #define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, true, false, "CATCH_CHECK_FALSE" )
5560 #define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, false, false, "CATCH_CHECKED_IF" )
5561 #define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, false, false, "CATCH_CHECKED_ELSE" )
5562 
5563 #define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, ..., false, "CATCH_CHECK_THROWS" )
5564 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, false, "CATCH_CHECK_THROWS_AS" )
5565 #define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, false, "CATCH_CHECK_NOTHROW" )
5566 
5567 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, false, "CATCH_CHECK_THAT" )
5568 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, true, "CATCH_REQUIRE_THAT" )
5569 
5570 #define CATCH_INFO( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Info, false, "CATCH_INFO" )
5571 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Warning, false, "CATCH_WARN" )
5572 #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::ExplicitFailure, true, "CATCH_FAIL" )
5573 #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Ok, false, "CATCH_SUCCEED" )
5574 #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_SCOPED_INFO( msg )
5575 #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_MSG( #msg " := " << msg, Catch::ResultWas::Info, false, "CATCH_CAPTURE" )
5576 
5577 #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
5578 
5579 #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
5580 #define CATCH_TEST_CASE_NORETURN( name, description ) INTERNAL_CATCH_TESTCASE_NORETURN( name, description )
5581 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "Anonymous test case" )
5582 #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
5583 
5584 #define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
5585 
5586 #define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
5587 
5589 // Still to be implemented
5590 //#define CHECK_NOFAIL( expr ) // !TBD - reports violation, but doesn't fail Test
5591 
5592 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
5593 #else
5594 
5595 #define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, false, true, "REQUIRE" )
5596 #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, true, true, "REQUIRE_FALSE" )
5597 
5598 #define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, ..., true, "REQUIRE_THROWS" )
5599 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, true, "REQUIRE_THROWS_AS" )
5600 #define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, true, "REQUIRE_NOTHROW" )
5601 
5602 #define CHECK( expr ) INTERNAL_CATCH_TEST( expr, false, false, "CHECK" )
5603 #define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, true, false, "CHECK_FALSE" )
5604 #define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, false, false, "CHECKED_IF" )
5605 #define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, false, false, "CHECKED_ELSE" )
5606 
5607 #define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, ..., false, "CHECK_THROWS" )
5608 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, false, "CHECK_THROWS_AS" )
5609 #define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, false, "CHECK_NOTHROW" )
5610 
5611 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, false, "CHECK_THAT" )
5612 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, true, "REQUIRE_THAT" )
5613 
5614 #define INFO( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Info, false, "INFO" )
5615 #define WARN( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Warning, false, "WARN" )
5616 #define FAIL( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::ExplicitFailure, true, "FAIL" )
5617 #define SUCCEED( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Ok, false, "SUCCEED" )
5618 #define SCOPED_INFO( msg ) INTERNAL_CATCH_SCOPED_INFO( msg )
5619 #define CAPTURE( msg ) INTERNAL_CATCH_MSG( #msg " := " << msg, Catch::ResultWas::Info, false, "CAPTURE" )
5620 
5621 #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
5622 
5623 #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
5624 #define TEST_CASE_NORETURN( name, description ) INTERNAL_CATCH_TESTCASE_NORETURN( name, description )
5625 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "Anonymous test case" )
5626 #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
5627 
5628 #define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
5629 
5630 #define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
5631 
5632 #endif
5633 
5634 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
5635 
5636 using Catch::Detail::Approx;
5637 
5638 #ifdef __clang__
5639 #pragma clang diagnostic pop
5640 #endif
5641 
5642 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
5643