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