1 /*
2  *  Catch v1.3.0
3  *  Generated: 2015-12-04 10:18:17.055188
4  *  ----------------------------------------------------------
5  *  This file has been merged from multiple headers. Please don't edit it directly
6  *  Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
7  *
8  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
9  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10  */
11 #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
12 #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
13 
14 #define TWOBLUECUBES_CATCH_HPP_INCLUDED
15 
16 #ifdef __clang__
17 #    pragma clang system_header
18 #elif defined __GNUC__
19 #    pragma GCC system_header
20 #endif
21 
22 // #included from: internal/catch_suppress_warnings.h
23 
24 #ifdef __clang__
25 #   ifdef __ICC // icpc defines the __clang__ macro
26 #       pragma warning(push)
27 #       pragma warning(disable: 161 1682)
28 #   else // __ICC
29 #       pragma clang diagnostic ignored "-Wglobal-constructors"
30 #       pragma clang diagnostic ignored "-Wvariadic-macros"
31 #       pragma clang diagnostic ignored "-Wc99-extensions"
32 #       pragma clang diagnostic ignored "-Wunused-variable"
33 #       pragma clang diagnostic push
34 #       pragma clang diagnostic ignored "-Wpadded"
35 #       pragma clang diagnostic ignored "-Wc++98-compat"
36 #       pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
37 #       pragma clang diagnostic ignored "-Wswitch-enum"
38 #       pragma clang diagnostic ignored "-Wcovered-switch-default"
39 #    endif
40 #elif defined __GNUC__
41 #    pragma GCC diagnostic ignored "-Wvariadic-macros"
42 #    pragma GCC diagnostic ignored "-Wunused-variable"
43 #    pragma GCC diagnostic push
44 #    pragma GCC diagnostic ignored "-Wpadded"
45 #endif
46 #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
47 #  define CATCH_IMPL
48 #endif
49 
50 #ifdef CATCH_IMPL
51 #  ifndef CLARA_CONFIG_MAIN
52 #    define CLARA_CONFIG_MAIN_NOT_DEFINED
53 #    define CLARA_CONFIG_MAIN
54 #  endif
55 #endif
56 
57 // #included from: internal/catch_notimplemented_exception.h
58 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
59 
60 // #included from: catch_common.h
61 #define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
62 
63 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
64 #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
65 #define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
66 
67 #define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
68 #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
69 
70 #include <sstream>
71 #include <stdexcept>
72 #include <algorithm>
73 
74 // #included from: catch_compiler_capabilities.h
75 #define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
76 
77 // Detect a number of compiler features - mostly C++11/14 conformance - by compiler
78 // The following features are defined:
79 //
80 // CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?
81 // CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
82 // CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
83 // CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
84 // CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
85 // CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?
86 // CATCH_CONFIG_CPP11_OVERRIDE : is override supported?
87 // CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
88 
89 // CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
90 
91 // CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
92 
93 // ****************
94 // Note to maintainers: if new toggles are added please document them
95 // in configuration.md, too
96 // ****************
97 
98 // In general each macro has a _NO_<feature name> form
99 // (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
100 // Many features, at point of detection, define an _INTERNAL_ macro, so they
101 // can be combined, en-mass, with the _NO_ forms later.
102 
103 // All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11
104 
105 #ifdef __clang__
106 
107 #  if __has_feature(cxx_nullptr)
108 #    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
109 #  endif
110 
111 #  if __has_feature(cxx_noexcept)
112 #    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
113 #  endif
114 
115 #endif // __clang__
116 
117 ////////////////////////////////////////////////////////////////////////////////
118 // Borland
119 #ifdef __BORLANDC__
120 
121 #endif // __BORLANDC__
122 
123 ////////////////////////////////////////////////////////////////////////////////
124 // EDG
125 #ifdef __EDG_VERSION__
126 
127 #endif // __EDG_VERSION__
128 
129 ////////////////////////////////////////////////////////////////////////////////
130 // Digital Mars
131 #ifdef __DMC__
132 
133 #endif // __DMC__
134 
135 ////////////////////////////////////////////////////////////////////////////////
136 // GCC
137 #ifdef __GNUC__
138 
139 #if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
140 #   define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
141 #endif
142 
143 // - otherwise more recent versions define __cplusplus >= 201103L
144 // and will get picked up below
145 
146 #endif // __GNUC__
147 
148 ////////////////////////////////////////////////////////////////////////////////
149 // Visual C++
150 #ifdef _MSC_VER
151 
152 #if (_MSC_VER >= 1600)
153 #   define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
154 #   define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
155 #endif
156 
157 #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
158 #define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
159 #define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
160 #endif
161 
162 #endif // _MSC_VER
163 
164 ////////////////////////////////////////////////////////////////////////////////
165 
166 // Use variadic macros if the compiler supports them
167 #if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
168     ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
169     ( defined __GNUC__ && __GNUC__ >= 3 ) || \
170     ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
171 
172 #define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
173 
174 #endif
175 
176 ////////////////////////////////////////////////////////////////////////////////
177 // C++ language feature support
178 
179 // catch all support for C++11
180 #if defined(__cplusplus) && __cplusplus >= 201103L
181 
182 #  define CATCH_CPP11_OR_GREATER
183 
184 #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
185 #    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
186 #  endif
187 
188 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
189 #    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
190 #  endif
191 
192 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
193 #    define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
194 #  endif
195 
196 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
197 #    define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
198 #  endif
199 
200 #  ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
201 #    define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
202 #  endif
203 
204 #  ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
205 #    define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
206 #  endif
207 
208 #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG)
209 #    define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG
210 #  endif
211 
212 #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE)
213 #    define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE
214 #  endif
215 #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
216 #    define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
217 #  endif
218 
219 #endif // __cplusplus >= 201103L
220 
221 // Now set the actual defines based on the above + anything the user has configured
222 #if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
223 #   define CATCH_CONFIG_CPP11_NULLPTR
224 #endif
225 #if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
226 #   define CATCH_CONFIG_CPP11_NOEXCEPT
227 #endif
228 #if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)
229 #   define CATCH_CONFIG_CPP11_GENERATED_METHODS
230 #endif
231 #if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)
232 #   define CATCH_CONFIG_CPP11_IS_ENUM
233 #endif
234 #if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
235 #   define CATCH_CONFIG_CPP11_TUPLE
236 #endif
237 #if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
238 #   define CATCH_CONFIG_VARIADIC_MACROS
239 #endif
240 #if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11)
241 #   define CATCH_CONFIG_CPP11_LONG_LONG
242 #endif
243 #if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)
244 #   define CATCH_CONFIG_CPP11_OVERRIDE
245 #endif
246 #if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
247 #   define CATCH_CONFIG_CPP11_UNIQUE_PTR
248 #endif
249 
250 // noexcept support:
251 #if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
252 #  define CATCH_NOEXCEPT noexcept
253 #  define CATCH_NOEXCEPT_IS(x) noexcept(x)
254 #else
255 #  define CATCH_NOEXCEPT throw()
256 #  define CATCH_NOEXCEPT_IS(x)
257 #endif
258 
259 // nullptr support
260 #ifdef CATCH_CONFIG_CPP11_NULLPTR
261 #   define CATCH_NULL nullptr
262 #else
263 #   define CATCH_NULL NULL
264 #endif
265 
266 // override support
267 #ifdef CATCH_CONFIG_CPP11_OVERRIDE
268 #   define CATCH_OVERRIDE override
269 #else
270 #   define CATCH_OVERRIDE
271 #endif
272 
273 // unique_ptr support
274 #ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR
275 #   define CATCH_AUTO_PTR( T ) std::unique_ptr<T>
276 #else
277 #   define CATCH_AUTO_PTR( T ) std::auto_ptr<T>
278 #endif
279 
280 namespace Catch {
281 
282     struct IConfig;
283 
284     struct CaseSensitive { enum Choice {
285         Yes,
286         No
287     }; };
288 
289     class NonCopyable {
290 #ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
291         NonCopyable( NonCopyable const& )              = delete;
292         NonCopyable( NonCopyable && )                  = delete;
293         NonCopyable& operator = ( NonCopyable const& ) = delete;
294         NonCopyable& operator = ( NonCopyable && )     = delete;
295 #else
296         NonCopyable( NonCopyable const& info );
297         NonCopyable& operator = ( NonCopyable const& );
298 #endif
299 
300     protected:
NonCopyable()301         NonCopyable() {}
302         virtual ~NonCopyable();
303     };
304 
305     class SafeBool {
306     public:
307         typedef void (SafeBool::*type)() const;
308 
makeSafe(bool value)309         static type makeSafe( bool value ) {
310             return value ? &SafeBool::trueValue : 0;
311         }
312     private:
trueValue() const313         void trueValue() const {}
314     };
315 
316     template<typename ContainerT>
deleteAll(ContainerT & container)317     inline void deleteAll( ContainerT& container ) {
318         typename ContainerT::const_iterator it = container.begin();
319         typename ContainerT::const_iterator itEnd = container.end();
320         for(; it != itEnd; ++it )
321             delete *it;
322     }
323     template<typename AssociativeContainerT>
deleteAllValues(AssociativeContainerT & container)324     inline void deleteAllValues( AssociativeContainerT& container ) {
325         typename AssociativeContainerT::const_iterator it = container.begin();
326         typename AssociativeContainerT::const_iterator itEnd = container.end();
327         for(; it != itEnd; ++it )
328             delete it->second;
329     }
330 
331     bool startsWith( std::string const& s, std::string const& prefix );
332     bool endsWith( std::string const& s, std::string const& suffix );
333     bool contains( std::string const& s, std::string const& infix );
334     void toLowerInPlace( std::string& s );
335     std::string toLower( std::string const& s );
336     std::string trim( std::string const& str );
337     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
338 
339     struct pluralise {
340         pluralise( std::size_t count, std::string const& label );
341 
342         friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
343 
344         std::size_t m_count;
345         std::string m_label;
346     };
347 
348     struct SourceLineInfo {
349 
350         SourceLineInfo();
351         SourceLineInfo( char const* _file, std::size_t _line );
352         SourceLineInfo( SourceLineInfo const& other );
353 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
354         SourceLineInfo( SourceLineInfo && )                  = default;
355         SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
356         SourceLineInfo& operator = ( SourceLineInfo && )     = default;
357 #  endif
358         bool empty() const;
359         bool operator == ( SourceLineInfo const& other ) const;
360         bool operator < ( SourceLineInfo const& other ) const;
361 
362         std::string file;
363         std::size_t line;
364     };
365 
366     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
367 
368     // This is just here to avoid compiler warnings with macro constants and boolean literals
isTrue(bool value)369     inline bool isTrue( bool value ){ return value; }
alwaysTrue()370     inline bool alwaysTrue() { return true; }
alwaysFalse()371     inline bool alwaysFalse() { return false; }
372 
373     void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
374 
375     void seedRng( IConfig const& config );
376     unsigned int rngSeed();
377 
378     // Use this in variadic streaming macros to allow
379     //    >> +StreamEndStop
380     // as well as
381     //    >> stuff +StreamEndStop
382     struct StreamEndStop {
operator +Catch::StreamEndStop383         std::string operator+() {
384             return std::string();
385         }
386     };
387     template<typename T>
operator +(T const & value,StreamEndStop)388     T const& operator + ( T const& value, StreamEndStop ) {
389         return value;
390     }
391 }
392 
393 #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
394 #define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
395 
396 #include <ostream>
397 
398 namespace Catch {
399 
400     class NotImplementedException : public std::exception
401     {
402     public:
403         NotImplementedException( SourceLineInfo const& lineInfo );
NotImplementedException(NotImplementedException const &)404         NotImplementedException( NotImplementedException const& ) {}
405 
~NotImplementedException()406         virtual ~NotImplementedException() CATCH_NOEXCEPT {}
407 
408         virtual const char* what() const CATCH_NOEXCEPT;
409 
410     private:
411         std::string m_what;
412         SourceLineInfo m_lineInfo;
413     };
414 
415 } // end namespace Catch
416 
417 ///////////////////////////////////////////////////////////////////////////////
418 #define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
419 
420 // #included from: internal/catch_context.h
421 #define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
422 
423 // #included from: catch_interfaces_generators.h
424 #define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
425 
426 #include <string>
427 
428 namespace Catch {
429 
430     struct IGeneratorInfo {
431         virtual ~IGeneratorInfo();
432         virtual bool moveNext() = 0;
433         virtual std::size_t getCurrentIndex() const = 0;
434     };
435 
436     struct IGeneratorsForTest {
437         virtual ~IGeneratorsForTest();
438 
439         virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
440         virtual bool moveNext() = 0;
441     };
442 
443     IGeneratorsForTest* createGeneratorsForTest();
444 
445 } // end namespace Catch
446 
447 // #included from: catch_ptr.hpp
448 #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
449 
450 #ifdef __clang__
451 #pragma clang diagnostic push
452 #pragma clang diagnostic ignored "-Wpadded"
453 #endif
454 
455 namespace Catch {
456 
457     // An intrusive reference counting smart pointer.
458     // T must implement addRef() and release() methods
459     // typically implementing the IShared interface
460     template<typename T>
461     class Ptr {
462     public:
Ptr()463         Ptr() : m_p( CATCH_NULL ){}
Ptr(T * p)464         Ptr( T* p ) : m_p( p ){
465             if( m_p )
466                 m_p->addRef();
467         }
Ptr(Ptr const & other)468         Ptr( Ptr const& other ) : m_p( other.m_p ){
469             if( m_p )
470                 m_p->addRef();
471         }
~Ptr()472         ~Ptr(){
473             if( m_p )
474                 m_p->release();
475         }
reset()476         void reset() {
477             if( m_p )
478                 m_p->release();
479             m_p = CATCH_NULL;
480         }
operator =(T * p)481         Ptr& operator = ( T* p ){
482             Ptr temp( p );
483             swap( temp );
484             return *this;
485         }
operator =(Ptr const & other)486         Ptr& operator = ( Ptr const& other ){
487             Ptr temp( other );
488             swap( temp );
489             return *this;
490         }
swap(Ptr & other)491         void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
get() const492         T* get() const{ return m_p; }
operator *() const493         T& operator*() const { return *m_p; }
operator ->() const494         T* operator->() const { return m_p; }
operator !() const495         bool operator !() const { return m_p == CATCH_NULL; }
operator SafeBool::type() const496         operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); }
497 
498     private:
499         T* m_p;
500     };
501 
502     struct IShared : NonCopyable {
503         virtual ~IShared();
504         virtual void addRef() const = 0;
505         virtual void release() const = 0;
506     };
507 
508     template<typename T = IShared>
509     struct SharedImpl : T {
510 
SharedImplCatch::SharedImpl511         SharedImpl() : m_rc( 0 ){}
512 
addRefCatch::SharedImpl513         virtual void addRef() const {
514             ++m_rc;
515         }
releaseCatch::SharedImpl516         virtual void release() const {
517             if( --m_rc == 0 )
518                 delete this;
519         }
520 
521         mutable unsigned int m_rc;
522     };
523 
524 } // end namespace Catch
525 
526 #ifdef __clang__
527 #pragma clang diagnostic pop
528 #endif
529 
530 #include <memory>
531 #include <vector>
532 #include <stdlib.h>
533 
534 namespace Catch {
535 
536     class TestCase;
537     class Stream;
538     struct IResultCapture;
539     struct IRunner;
540     struct IGeneratorsForTest;
541     struct IConfig;
542 
543     struct IContext
544     {
545         virtual ~IContext();
546 
547         virtual IResultCapture* getResultCapture() = 0;
548         virtual IRunner* getRunner() = 0;
549         virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
550         virtual bool advanceGeneratorsForCurrentTest() = 0;
551         virtual Ptr<IConfig const> getConfig() const = 0;
552     };
553 
554     struct IMutableContext : IContext
555     {
556         virtual ~IMutableContext();
557         virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
558         virtual void setRunner( IRunner* runner ) = 0;
559         virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
560     };
561 
562     IContext& getCurrentContext();
563     IMutableContext& getCurrentMutableContext();
564     void cleanUpContext();
565     Stream createStream( std::string const& streamName );
566 
567 }
568 
569 // #included from: internal/catch_test_registry.hpp
570 #define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
571 
572 // #included from: catch_interfaces_testcase.h
573 #define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
574 
575 #include <vector>
576 
577 namespace Catch {
578 
579     class TestSpec;
580 
581     struct ITestCase : IShared {
582         virtual void invoke () const = 0;
583     protected:
584         virtual ~ITestCase();
585     };
586 
587     class TestCase;
588     struct IConfig;
589 
590     struct ITestCaseRegistry {
591         virtual ~ITestCaseRegistry();
592         virtual std::vector<TestCase> const& getAllTests() const = 0;
593         virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
594     };
595 
596     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
597     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
598     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
599 
600 }
601 
602 namespace Catch {
603 
604 template<typename C>
605 class MethodTestCase : public SharedImpl<ITestCase> {
606 
607 public:
MethodTestCase(void (C::* method)())608     MethodTestCase( void (C::*method)() ) : m_method( method ) {}
609 
invoke() const610     virtual void invoke() const {
611         C obj;
612         (obj.*m_method)();
613     }
614 
615 private:
~MethodTestCase()616     virtual ~MethodTestCase() {}
617 
618     void (C::*m_method)();
619 };
620 
621 typedef void(*TestFunction)();
622 
623 struct NameAndDesc {
NameAndDescCatch::NameAndDesc624     NameAndDesc( const char* _name = "", const char* _description= "" )
625     : name( _name ), description( _description )
626     {}
627 
628     const char* name;
629     const char* description;
630 };
631 
632 void registerTestCase
633     (   ITestCase* testCase,
634         char const* className,
635         NameAndDesc const& nameAndDesc,
636         SourceLineInfo const& lineInfo );
637 
638 struct AutoReg {
639 
640     AutoReg
641         (   TestFunction function,
642             SourceLineInfo const& lineInfo,
643             NameAndDesc const& nameAndDesc );
644 
645     template<typename C>
AutoRegCatch::AutoReg646     AutoReg
647         (   void (C::*method)(),
648             char const* className,
649             NameAndDesc const& nameAndDesc,
650             SourceLineInfo const& lineInfo ) {
651 
652         registerTestCase
653             (   new MethodTestCase<C>( method ),
654                 className,
655                 nameAndDesc,
656                 lineInfo );
657     }
658 
659     ~AutoReg();
660 
661 private:
662     AutoReg( AutoReg const& );
663     void operator= ( AutoReg const& );
664 };
665 
666 void registerTestCaseFunction
667     (   TestFunction function,
668         SourceLineInfo const& lineInfo,
669         NameAndDesc const& nameAndDesc );
670 
671 } // end namespace Catch
672 
673 #ifdef CATCH_CONFIG_VARIADIC_MACROS
674     ///////////////////////////////////////////////////////////////////////////////
675     #define INTERNAL_CATCH_TESTCASE( ... ) \
676         static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
677         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__ ) ); }\
678         static void INTERNAL_CATCH_UNIQUE_NAME(  ____C_A_T_C_H____T_E_S_T____ )()
679 
680     ///////////////////////////////////////////////////////////////////////////////
681     #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
682         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
683 
684     ///////////////////////////////////////////////////////////////////////////////
685     #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\
686         namespace{ \
687             struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
688                 void test(); \
689             }; \
690             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 ); \
691         } \
692         void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
693 
694     ///////////////////////////////////////////////////////////////////////////////
695     #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
696         Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) );
697 
698 #else
699     ///////////////////////////////////////////////////////////////////////////////
700     #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
701         static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
702         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 ) ); }\
703         static void INTERNAL_CATCH_UNIQUE_NAME(  ____C_A_T_C_H____T_E_S_T____ )()
704 
705     ///////////////////////////////////////////////////////////////////////////////
706     #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
707         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
708 
709     ///////////////////////////////////////////////////////////////////////////////
710     #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
711         namespace{ \
712             struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
713                 void test(); \
714             }; \
715             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 ); \
716         } \
717         void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
718 
719     ///////////////////////////////////////////////////////////////////////////////
720     #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
721         Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) );
722 #endif
723 
724 // #included from: internal/catch_capture.hpp
725 #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
726 
727 // #included from: catch_result_builder.h
728 #define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
729 
730 // #included from: catch_result_type.h
731 #define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
732 
733 namespace Catch {
734 
735     // ResultWas::OfType enum
736     struct ResultWas { enum OfType {
737         Unknown = -1,
738         Ok = 0,
739         Info = 1,
740         Warning = 2,
741 
742         FailureBit = 0x10,
743 
744         ExpressionFailed = FailureBit | 1,
745         ExplicitFailure = FailureBit | 2,
746 
747         Exception = 0x100 | FailureBit,
748 
749         ThrewException = Exception | 1,
750         DidntThrowException = Exception | 2,
751 
752         FatalErrorCondition = 0x200 | FailureBit
753 
754     }; };
755 
isOk(ResultWas::OfType resultType)756     inline bool isOk( ResultWas::OfType resultType ) {
757         return ( resultType & ResultWas::FailureBit ) == 0;
758     }
isJustInfo(int flags)759     inline bool isJustInfo( int flags ) {
760         return flags == ResultWas::Info;
761     }
762 
763     // ResultDisposition::Flags enum
764     struct ResultDisposition { enum Flags {
765         Normal = 0x01,
766 
767         ContinueOnFailure = 0x02,   // Failures fail test, but execution continues
768         FalseTest = 0x04,           // Prefix expression with !
769         SuppressFail = 0x08         // Failures are reported but do not fail the test
770     }; };
771 
operator |(ResultDisposition::Flags lhs,ResultDisposition::Flags rhs)772     inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
773         return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
774     }
775 
shouldContinueOnFailure(int flags)776     inline bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
isFalseTest(int flags)777     inline bool isFalseTest( int flags )                { return ( flags & ResultDisposition::FalseTest ) != 0; }
shouldSuppressFailure(int flags)778     inline bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; }
779 
780 } // end namespace Catch
781 
782 // #included from: catch_assertionresult.h
783 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
784 
785 #include <string>
786 
787 namespace Catch {
788 
789     struct AssertionInfo
790     {
AssertionInfoCatch::AssertionInfo791         AssertionInfo() {}
792         AssertionInfo(  std::string const& _macroName,
793                         SourceLineInfo const& _lineInfo,
794                         std::string const& _capturedExpression,
795                         ResultDisposition::Flags _resultDisposition );
796 
797         std::string macroName;
798         SourceLineInfo lineInfo;
799         std::string capturedExpression;
800         ResultDisposition::Flags resultDisposition;
801     };
802 
803     struct AssertionResultData
804     {
AssertionResultDataCatch::AssertionResultData805         AssertionResultData() : resultType( ResultWas::Unknown ) {}
806 
807         std::string reconstructedExpression;
808         std::string message;
809         ResultWas::OfType resultType;
810     };
811 
812     class AssertionResult {
813     public:
814         AssertionResult();
815         AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
816         ~AssertionResult();
817 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
818          AssertionResult( AssertionResult const& )              = default;
819          AssertionResult( AssertionResult && )                  = default;
820          AssertionResult& operator = ( AssertionResult const& ) = default;
821          AssertionResult& operator = ( AssertionResult && )     = default;
822 #  endif
823 
824         bool isOk() const;
825         bool succeeded() const;
826         ResultWas::OfType getResultType() const;
827         bool hasExpression() const;
828         bool hasMessage() const;
829         std::string getExpression() const;
830         std::string getExpressionInMacro() const;
831         bool hasExpandedExpression() const;
832         std::string getExpandedExpression() const;
833         std::string getMessage() const;
834         SourceLineInfo getSourceInfo() const;
835         std::string getTestMacroName() const;
836 
837     protected:
838         AssertionInfo m_info;
839         AssertionResultData m_resultData;
840     };
841 
842 } // end namespace Catch
843 
844 // #included from: catch_matchers.hpp
845 #define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
846 
847 namespace Catch {
848 namespace Matchers {
849     namespace Impl {
850 
851     namespace Generic {
852         template<typename ExpressionT> class AllOf;
853         template<typename ExpressionT> class AnyOf;
854         template<typename ExpressionT> class Not;
855     }
856 
857     template<typename ExpressionT>
858     struct Matcher : SharedImpl<IShared>
859     {
860         typedef ExpressionT ExpressionType;
861 
~MatcherCatch::Matchers::Impl::Matcher862         virtual ~Matcher() {}
863         virtual Ptr<Matcher> clone() const = 0;
864         virtual bool match( ExpressionT const& expr ) const = 0;
865         virtual std::string toString() const = 0;
866 
867         Generic::AllOf<ExpressionT> operator && ( Matcher<ExpressionT> const& other ) const;
868         Generic::AnyOf<ExpressionT> operator || ( Matcher<ExpressionT> const& other ) const;
869         Generic::Not<ExpressionT> operator ! () const;
870     };
871 
872     template<typename DerivedT, typename ExpressionT>
873     struct MatcherImpl : Matcher<ExpressionT> {
874 
cloneCatch::Matchers::Impl::MatcherImpl875         virtual Ptr<Matcher<ExpressionT> > clone() const {
876             return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
877         }
878     };
879 
880     namespace Generic {
881         template<typename ExpressionT>
882         class Not : public MatcherImpl<Not<ExpressionT>, ExpressionT> {
883         public:
Not(Matcher<ExpressionT> const & matcher)884             explicit Not( Matcher<ExpressionT> const& matcher ) : m_matcher(matcher.clone()) {}
Not(Not const & other)885             Not( Not const& other ) : m_matcher( other.m_matcher ) {}
886 
match(ExpressionT const & expr) const887             virtual bool match( ExpressionT const& expr ) const CATCH_OVERRIDE {
888                 return !m_matcher->match( expr );
889             }
890 
toString() const891             virtual std::string toString() const CATCH_OVERRIDE {
892                 return "not " + m_matcher->toString();
893             }
894         private:
895             Ptr< Matcher<ExpressionT> > m_matcher;
896         };
897 
898         template<typename ExpressionT>
899         class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
900         public:
901 
AllOf()902             AllOf() {}
AllOf(AllOf const & other)903             AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
904 
add(Matcher<ExpressionT> const & matcher)905             AllOf& add( Matcher<ExpressionT> const& matcher ) {
906                 m_matchers.push_back( matcher.clone() );
907                 return *this;
908             }
match(ExpressionT const & expr) const909             virtual bool match( ExpressionT const& expr ) const
910             {
911                 for( std::size_t i = 0; i < m_matchers.size(); ++i )
912                     if( !m_matchers[i]->match( expr ) )
913                         return false;
914                 return true;
915             }
toString() const916             virtual std::string toString() const {
917                 std::ostringstream oss;
918                 oss << "( ";
919                 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
920                     if( i != 0 )
921                         oss << " and ";
922                     oss << m_matchers[i]->toString();
923                 }
924                 oss << " )";
925                 return oss.str();
926             }
927 
operator &&(Matcher<ExpressionT> const & other) const928             AllOf operator && ( Matcher<ExpressionT> const& other ) const {
929                 AllOf allOfExpr( *this );
930                 allOfExpr.add( other );
931                 return allOfExpr;
932             }
933 
934         private:
935             std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
936         };
937 
938         template<typename ExpressionT>
939         class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
940         public:
941 
AnyOf()942             AnyOf() {}
AnyOf(AnyOf const & other)943             AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
944 
add(Matcher<ExpressionT> const & matcher)945             AnyOf& add( Matcher<ExpressionT> const& matcher ) {
946                 m_matchers.push_back( matcher.clone() );
947                 return *this;
948             }
match(ExpressionT const & expr) const949             virtual bool match( ExpressionT const& expr ) const
950             {
951                 for( std::size_t i = 0; i < m_matchers.size(); ++i )
952                     if( m_matchers[i]->match( expr ) )
953                         return true;
954                 return false;
955             }
toString() const956             virtual std::string toString() const {
957                 std::ostringstream oss;
958                 oss << "( ";
959                 for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
960                     if( i != 0 )
961                         oss << " or ";
962                     oss << m_matchers[i]->toString();
963                 }
964                 oss << " )";
965                 return oss.str();
966             }
967 
operator ||(Matcher<ExpressionT> const & other) const968             AnyOf operator || ( Matcher<ExpressionT> const& other ) const {
969                 AnyOf anyOfExpr( *this );
970                 anyOfExpr.add( other );
971                 return anyOfExpr;
972             }
973 
974         private:
975             std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
976         };
977 
978     } // namespace Generic
979 
980     template<typename ExpressionT>
operator &&(Matcher<ExpressionT> const & other) const981     Generic::AllOf<ExpressionT> Matcher<ExpressionT>::operator && ( Matcher<ExpressionT> const& other ) const {
982         Generic::AllOf<ExpressionT> allOfExpr;
983         allOfExpr.add( *this );
984         allOfExpr.add( other );
985         return allOfExpr;
986     }
987 
988     template<typename ExpressionT>
operator ||(Matcher<ExpressionT> const & other) const989     Generic::AnyOf<ExpressionT> Matcher<ExpressionT>::operator || ( Matcher<ExpressionT> const& other ) const {
990         Generic::AnyOf<ExpressionT> anyOfExpr;
991         anyOfExpr.add( *this );
992         anyOfExpr.add( other );
993         return anyOfExpr;
994     }
995 
996     template<typename ExpressionT>
operator !() const997     Generic::Not<ExpressionT> Matcher<ExpressionT>::operator ! () const {
998         return Generic::Not<ExpressionT>( *this );
999     }
1000 
1001     namespace StdString {
1002 
makeString(std::string const & str)1003         inline std::string makeString( std::string const& str ) { return str; }
makeString(const char * str)1004         inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
1005 
1006         struct CasedString
1007         {
CasedStringCatch::Matchers::Impl::StdString::CasedString1008             CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
1009             :   m_caseSensitivity( caseSensitivity ),
1010                 m_str( adjustString( str ) )
1011             {}
adjustStringCatch::Matchers::Impl::StdString::CasedString1012             std::string adjustString( std::string const& str ) const {
1013                 return m_caseSensitivity == CaseSensitive::No
1014                     ? toLower( str )
1015                     : str;
1016 
1017             }
toStringSuffixCatch::Matchers::Impl::StdString::CasedString1018             std::string toStringSuffix() const
1019             {
1020                 return m_caseSensitivity == CaseSensitive::No
1021                     ? " (case insensitive)"
1022                     : "";
1023             }
1024             CaseSensitive::Choice m_caseSensitivity;
1025             std::string m_str;
1026         };
1027 
1028         struct Equals : MatcherImpl<Equals, std::string> {
EqualsCatch::Matchers::Impl::StdString::Equals1029             Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
1030             :   m_data( str, caseSensitivity )
1031             {}
EqualsCatch::Matchers::Impl::StdString::Equals1032             Equals( Equals const& other ) : m_data( other.m_data ){}
1033 
1034             virtual ~Equals();
1035 
matchCatch::Matchers::Impl::StdString::Equals1036             virtual bool match( std::string const& expr ) const {
1037                 return m_data.m_str == m_data.adjustString( expr );;
1038             }
toStringCatch::Matchers::Impl::StdString::Equals1039             virtual std::string toString() const {
1040                 return "equals: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
1041             }
1042 
1043             CasedString m_data;
1044         };
1045 
1046         struct Contains : MatcherImpl<Contains, std::string> {
ContainsCatch::Matchers::Impl::StdString::Contains1047             Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
1048             : m_data( substr, caseSensitivity ){}
ContainsCatch::Matchers::Impl::StdString::Contains1049             Contains( Contains const& other ) : m_data( other.m_data ){}
1050 
1051             virtual ~Contains();
1052 
matchCatch::Matchers::Impl::StdString::Contains1053             virtual bool match( std::string const& expr ) const {
1054                 return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos;
1055             }
toStringCatch::Matchers::Impl::StdString::Contains1056             virtual std::string toString() const {
1057                 return "contains: \"" + m_data.m_str  + "\"" + m_data.toStringSuffix();
1058             }
1059 
1060             CasedString m_data;
1061         };
1062 
1063         struct StartsWith : MatcherImpl<StartsWith, std::string> {
StartsWithCatch::Matchers::Impl::StdString::StartsWith1064             StartsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
1065             : m_data( substr, caseSensitivity ){}
1066 
StartsWithCatch::Matchers::Impl::StdString::StartsWith1067             StartsWith( StartsWith const& other ) : m_data( other.m_data ){}
1068 
1069             virtual ~StartsWith();
1070 
matchCatch::Matchers::Impl::StdString::StartsWith1071             virtual bool match( std::string const& expr ) const {
1072                 return m_data.adjustString( expr ).find( m_data.m_str ) == 0;
1073             }
toStringCatch::Matchers::Impl::StdString::StartsWith1074             virtual std::string toString() const {
1075                 return "starts with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
1076             }
1077 
1078             CasedString m_data;
1079         };
1080 
1081         struct EndsWith : MatcherImpl<EndsWith, std::string> {
EndsWithCatch::Matchers::Impl::StdString::EndsWith1082             EndsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
1083             : m_data( substr, caseSensitivity ){}
EndsWithCatch::Matchers::Impl::StdString::EndsWith1084             EndsWith( EndsWith const& other ) : m_data( other.m_data ){}
1085 
1086             virtual ~EndsWith();
1087 
matchCatch::Matchers::Impl::StdString::EndsWith1088             virtual bool match( std::string const& expr ) const {
1089                 return m_data.adjustString( expr ).find( m_data.m_str ) == expr.size() - m_data.m_str.size();
1090             }
toStringCatch::Matchers::Impl::StdString::EndsWith1091             virtual std::string toString() const {
1092                 return "ends with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
1093             }
1094 
1095             CasedString m_data;
1096         };
1097     } // namespace StdString
1098     } // namespace Impl
1099 
1100     // The following functions create the actual matcher objects.
1101     // This allows the types to be inferred
1102     template<typename ExpressionT>
Not(Impl::Matcher<ExpressionT> const & m)1103     inline Impl::Generic::Not<ExpressionT> Not( Impl::Matcher<ExpressionT> const& m ) {
1104         return Impl::Generic::Not<ExpressionT>( m );
1105     }
1106 
1107     template<typename ExpressionT>
AllOf(Impl::Matcher<ExpressionT> const & m1,Impl::Matcher<ExpressionT> const & m2)1108     inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
1109                                                     Impl::Matcher<ExpressionT> const& m2 ) {
1110         return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
1111     }
1112     template<typename ExpressionT>
AllOf(Impl::Matcher<ExpressionT> const & m1,Impl::Matcher<ExpressionT> const & m2,Impl::Matcher<ExpressionT> const & m3)1113     inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
1114                                                     Impl::Matcher<ExpressionT> const& m2,
1115                                                     Impl::Matcher<ExpressionT> const& m3 ) {
1116         return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
1117     }
1118     template<typename ExpressionT>
AnyOf(Impl::Matcher<ExpressionT> const & m1,Impl::Matcher<ExpressionT> const & m2)1119     inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
1120                                                     Impl::Matcher<ExpressionT> const& m2 ) {
1121         return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
1122     }
1123     template<typename ExpressionT>
AnyOf(Impl::Matcher<ExpressionT> const & m1,Impl::Matcher<ExpressionT> const & m2,Impl::Matcher<ExpressionT> const & m3)1124     inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
1125                                                     Impl::Matcher<ExpressionT> const& m2,
1126                                                     Impl::Matcher<ExpressionT> const& m3 ) {
1127         return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
1128     }
1129 
Equals(std::string const & str,CaseSensitive::Choice caseSensitivity=CaseSensitive::Yes)1130     inline Impl::StdString::Equals      Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
1131         return Impl::StdString::Equals( str, caseSensitivity );
1132     }
Equals(const char * str,CaseSensitive::Choice caseSensitivity=CaseSensitive::Yes)1133     inline Impl::StdString::Equals      Equals( const char* str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
1134         return Impl::StdString::Equals( Impl::StdString::makeString( str ), caseSensitivity );
1135     }
Contains(std::string const & substr,CaseSensitive::Choice caseSensitivity=CaseSensitive::Yes)1136     inline Impl::StdString::Contains    Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
1137         return Impl::StdString::Contains( substr, caseSensitivity );
1138     }
Contains(const char * substr,CaseSensitive::Choice caseSensitivity=CaseSensitive::Yes)1139     inline Impl::StdString::Contains    Contains( const char* substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
1140         return Impl::StdString::Contains( Impl::StdString::makeString( substr ), caseSensitivity );
1141     }
StartsWith(std::string const & substr)1142     inline Impl::StdString::StartsWith  StartsWith( std::string const& substr ) {
1143         return Impl::StdString::StartsWith( substr );
1144     }
StartsWith(const char * substr)1145     inline Impl::StdString::StartsWith  StartsWith( const char* substr ) {
1146         return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );
1147     }
EndsWith(std::string const & substr)1148     inline Impl::StdString::EndsWith    EndsWith( std::string const& substr ) {
1149         return Impl::StdString::EndsWith( substr );
1150     }
EndsWith(const char * substr)1151     inline Impl::StdString::EndsWith    EndsWith( const char* substr ) {
1152         return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );
1153     }
1154 
1155 } // namespace Matchers
1156 
1157 using namespace Matchers;
1158 
1159 } // namespace Catch
1160 
1161 namespace Catch {
1162 
1163     struct TestFailureException{};
1164 
1165     template<typename T> class ExpressionLhs;
1166 
1167     struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
1168 
1169     struct CopyableStream {
CopyableStreamCatch::CopyableStream1170         CopyableStream() {}
CopyableStreamCatch::CopyableStream1171         CopyableStream( CopyableStream const& other ) {
1172             oss << other.oss.str();
1173         }
operator =Catch::CopyableStream1174         CopyableStream& operator=( CopyableStream const& other ) {
1175             oss.str("");
1176             oss << other.oss.str();
1177             return *this;
1178         }
1179         std::ostringstream oss;
1180     };
1181 
1182     class ResultBuilder {
1183     public:
1184         ResultBuilder(  char const* macroName,
1185                         SourceLineInfo const& lineInfo,
1186                         char const* capturedExpression,
1187                         ResultDisposition::Flags resultDisposition,
1188                         char const* secondArg = "" );
1189 
1190         template<typename T>
1191         ExpressionLhs<T const&> operator <= ( T const& operand );
1192         ExpressionLhs<bool> operator <= ( bool value );
1193 
1194         template<typename T>
operator <<(T const & value)1195         ResultBuilder& operator << ( T const& value ) {
1196             m_stream.oss << value;
1197             return *this;
1198         }
1199 
1200         template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
1201         template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
1202 
1203         ResultBuilder& setResultType( ResultWas::OfType result );
1204         ResultBuilder& setResultType( bool result );
1205         ResultBuilder& setLhs( std::string const& lhs );
1206         ResultBuilder& setRhs( std::string const& rhs );
1207         ResultBuilder& setOp( std::string const& op );
1208 
1209         void endExpression();
1210 
1211         std::string reconstructExpression() const;
1212         AssertionResult build() const;
1213 
1214         void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
1215         void captureResult( ResultWas::OfType resultType );
1216         void captureExpression();
1217         void captureExpectedException( std::string const& expectedMessage );
1218         void captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher );
1219         void handleResult( AssertionResult const& result );
1220         void react();
1221         bool shouldDebugBreak() const;
1222         bool allowThrows() const;
1223 
1224     private:
1225         AssertionInfo m_assertionInfo;
1226         AssertionResultData m_data;
1227         struct ExprComponents {
ExprComponentsCatch::ResultBuilder::ExprComponents1228             ExprComponents() : testFalse( false ) {}
1229             bool testFalse;
1230             std::string lhs, rhs, op;
1231         } m_exprComponents;
1232         CopyableStream m_stream;
1233 
1234         bool m_shouldDebugBreak;
1235         bool m_shouldThrow;
1236     };
1237 
1238 } // namespace Catch
1239 
1240 // Include after due to circular dependency:
1241 // #included from: catch_expression_lhs.hpp
1242 #define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
1243 
1244 // #included from: catch_evaluate.hpp
1245 #define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
1246 
1247 #ifdef _MSC_VER
1248 #pragma warning(push)
1249 #pragma warning(disable:4389) // '==' : signed/unsigned mismatch
1250 #endif
1251 
1252 #include <cstddef>
1253 
1254 namespace Catch {
1255 namespace Internal {
1256 
1257     enum Operator {
1258         IsEqualTo,
1259         IsNotEqualTo,
1260         IsLessThan,
1261         IsGreaterThan,
1262         IsLessThanOrEqualTo,
1263         IsGreaterThanOrEqualTo
1264     };
1265 
getNameCatch::Internal::OperatorTraits1266     template<Operator Op> struct OperatorTraits             { static const char* getName(){ return "*error*"; } };
getNameCatch::Internal::OperatorTraits1267     template<> struct OperatorTraits<IsEqualTo>             { static const char* getName(){ return "=="; } };
getNameCatch::Internal::OperatorTraits1268     template<> struct OperatorTraits<IsNotEqualTo>          { static const char* getName(){ return "!="; } };
getNameCatch::Internal::OperatorTraits1269     template<> struct OperatorTraits<IsLessThan>            { static const char* getName(){ return "<"; } };
getNameCatch::Internal::OperatorTraits1270     template<> struct OperatorTraits<IsGreaterThan>         { static const char* getName(){ return ">"; } };
getNameCatch::Internal::OperatorTraits1271     template<> struct OperatorTraits<IsLessThanOrEqualTo>   { static const char* getName(){ return "<="; } };
getNameCatch::Internal::OperatorTraits1272     template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
1273 
1274     template<typename T>
opCast(T const & t)1275     inline T& opCast(T const& t) { return const_cast<T&>(t); }
1276 
1277 // nullptr_t support based on pull request #154 from Konstantin Baumann
1278 #ifdef CATCH_CONFIG_CPP11_NULLPTR
opCast(std::nullptr_t)1279     inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
1280 #endif // CATCH_CONFIG_CPP11_NULLPTR
1281 
1282     // So the compare overloads can be operator agnostic we convey the operator as a template
1283     // enum, which is used to specialise an Evaluator for doing the comparison.
1284     template<typename T1, typename T2, Operator Op>
1285     class Evaluator{};
1286 
1287     template<typename T1, typename T2>
1288     struct Evaluator<T1, T2, IsEqualTo> {
evaluateCatch::Internal::Evaluator1289         static bool evaluate( T1 const& lhs, T2 const& rhs) {
1290             return opCast( lhs ) ==  opCast( rhs );
1291         }
1292     };
1293     template<typename T1, typename T2>
1294     struct Evaluator<T1, T2, IsNotEqualTo> {
evaluateCatch::Internal::Evaluator1295         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1296             return opCast( lhs ) != opCast( rhs );
1297         }
1298     };
1299     template<typename T1, typename T2>
1300     struct Evaluator<T1, T2, IsLessThan> {
evaluateCatch::Internal::Evaluator1301         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1302             return opCast( lhs ) < opCast( rhs );
1303         }
1304     };
1305     template<typename T1, typename T2>
1306     struct Evaluator<T1, T2, IsGreaterThan> {
evaluateCatch::Internal::Evaluator1307         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1308             return opCast( lhs ) > opCast( rhs );
1309         }
1310     };
1311     template<typename T1, typename T2>
1312     struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
evaluateCatch::Internal::Evaluator1313         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1314             return opCast( lhs ) >= opCast( rhs );
1315         }
1316     };
1317     template<typename T1, typename T2>
1318     struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
evaluateCatch::Internal::Evaluator1319         static bool evaluate( T1 const& lhs, T2 const& rhs ) {
1320             return opCast( lhs ) <= opCast( rhs );
1321         }
1322     };
1323 
1324     template<Operator Op, typename T1, typename T2>
applyEvaluator(T1 const & lhs,T2 const & rhs)1325     bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
1326         return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
1327     }
1328 
1329     // This level of indirection allows us to specialise for integer types
1330     // to avoid signed/ unsigned warnings
1331 
1332     // "base" overload
1333     template<Operator Op, typename T1, typename T2>
compare(T1 const & lhs,T2 const & rhs)1334     bool compare( T1 const& lhs, T2 const& rhs ) {
1335         return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
1336     }
1337 
1338     // unsigned X to int
compare(unsigned int lhs,int rhs)1339     template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
1340         return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1341     }
compare(unsigned long lhs,int rhs)1342     template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
1343         return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1344     }
compare(unsigned char lhs,int rhs)1345     template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
1346         return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
1347     }
1348 
1349     // unsigned X to long
compare(unsigned int lhs,long rhs)1350     template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
1351         return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1352     }
compare(unsigned long lhs,long rhs)1353     template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
1354         return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1355     }
compare(unsigned char lhs,long rhs)1356     template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
1357         return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
1358     }
1359 
1360     // int to unsigned X
compare(int lhs,unsigned int rhs)1361     template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
1362         return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1363     }
compare(int lhs,unsigned long rhs)1364     template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
1365         return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1366     }
compare(int lhs,unsigned char rhs)1367     template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
1368         return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
1369     }
1370 
1371     // long to unsigned X
compare(long lhs,unsigned int rhs)1372     template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
1373         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1374     }
compare(long lhs,unsigned long rhs)1375     template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
1376         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1377     }
compare(long lhs,unsigned char rhs)1378     template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
1379         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1380     }
1381 
1382     // pointer to long (when comparing against NULL)
compare(long lhs,T * rhs)1383     template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
1384         return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
1385     }
compare(T * lhs,long rhs)1386     template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
1387         return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
1388     }
1389 
1390     // pointer to int (when comparing against NULL)
compare(int lhs,T * rhs)1391     template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
1392         return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
1393     }
compare(T * lhs,int rhs)1394     template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
1395         return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
1396     }
1397 
1398 #ifdef CATCH_CONFIG_CPP11_LONG_LONG
1399     // long long to unsigned X
compare(long long lhs,unsigned int rhs)1400     template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {
1401         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1402     }
compare(long long lhs,unsigned long rhs)1403     template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {
1404         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1405     }
compare(long long lhs,unsigned long long rhs)1406     template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {
1407         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1408     }
compare(long long lhs,unsigned char rhs)1409     template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
1410         return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
1411     }
1412 
1413     // unsigned long long to X
compare(unsigned long long lhs,int rhs)1414     template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
1415         return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1416     }
compare(unsigned long long lhs,long rhs)1417     template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {
1418         return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1419     }
compare(unsigned long long lhs,long long rhs)1420     template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {
1421         return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1422     }
compare(unsigned long long lhs,char rhs)1423     template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
1424         return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
1425     }
1426 
1427     // pointer to long long (when comparing against NULL)
compare(long long lhs,T * rhs)1428     template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
1429         return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
1430     }
compare(T * lhs,long long rhs)1431     template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {
1432         return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
1433     }
1434 #endif // CATCH_CONFIG_CPP11_LONG_LONG
1435 
1436 #ifdef CATCH_CONFIG_CPP11_NULLPTR
1437     // pointer to nullptr_t (when comparing against nullptr)
compare(std::nullptr_t,T * rhs)1438     template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
1439         return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );
1440     }
compare(T * lhs,std::nullptr_t)1441     template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
1442         return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );
1443     }
1444 #endif // CATCH_CONFIG_CPP11_NULLPTR
1445 
1446 } // end of namespace Internal
1447 } // end of namespace Catch
1448 
1449 #ifdef _MSC_VER
1450 #pragma warning(pop)
1451 #endif
1452 
1453 // #included from: catch_tostring.h
1454 #define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
1455 
1456 #include <sstream>
1457 #include <iomanip>
1458 #include <limits>
1459 #include <vector>
1460 #include <cstddef>
1461 
1462 #ifdef __OBJC__
1463 // #included from: catch_objc_arc.hpp
1464 #define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
1465 
1466 #import <Foundation/Foundation.h>
1467 
1468 #ifdef __has_feature
1469 #define CATCH_ARC_ENABLED __has_feature(objc_arc)
1470 #else
1471 #define CATCH_ARC_ENABLED 0
1472 #endif
1473 
1474 void arcSafeRelease( NSObject* obj );
1475 id performOptionalSelector( id obj, SEL sel );
1476 
1477 #if !CATCH_ARC_ENABLED
arcSafeRelease(NSObject * obj)1478 inline void arcSafeRelease( NSObject* obj ) {
1479     [obj release];
1480 }
performOptionalSelector(id obj,SEL sel)1481 inline id performOptionalSelector( id obj, SEL sel ) {
1482     if( [obj respondsToSelector: sel] )
1483         return [obj performSelector: sel];
1484     return nil;
1485 }
1486 #define CATCH_UNSAFE_UNRETAINED
1487 #define CATCH_ARC_STRONG
1488 #else
arcSafeRelease(NSObject *)1489 inline void arcSafeRelease( NSObject* ){}
performOptionalSelector(id obj,SEL sel)1490 inline id performOptionalSelector( id obj, SEL sel ) {
1491 #ifdef __clang__
1492 #pragma clang diagnostic push
1493 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
1494 #endif
1495     if( [obj respondsToSelector: sel] )
1496         return [obj performSelector: sel];
1497 #ifdef __clang__
1498 #pragma clang diagnostic pop
1499 #endif
1500     return nil;
1501 }
1502 #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
1503 #define CATCH_ARC_STRONG __strong
1504 #endif
1505 
1506 #endif
1507 
1508 #ifdef CATCH_CONFIG_CPP11_TUPLE
1509 #include <tuple>
1510 #endif
1511 
1512 #ifdef CATCH_CONFIG_CPP11_IS_ENUM
1513 #include <type_traits>
1514 #endif
1515 
1516 namespace Catch {
1517 
1518 // Why we're here.
1519 template<typename T>
1520 std::string toString( T const& value );
1521 
1522 // Built in overloads
1523 
1524 std::string toString( std::string const& value );
1525 std::string toString( std::wstring const& value );
1526 std::string toString( const char* const value );
1527 std::string toString( char* const value );
1528 std::string toString( const wchar_t* const value );
1529 std::string toString( wchar_t* const value );
1530 std::string toString( int value );
1531 std::string toString( unsigned long value );
1532 std::string toString( unsigned int value );
1533 std::string toString( const double value );
1534 std::string toString( const float value );
1535 std::string toString( bool value );
1536 std::string toString( char value );
1537 std::string toString( signed char value );
1538 std::string toString( unsigned char value );
1539 
1540 #ifdef CATCH_CONFIG_CPP11_LONG_LONG
1541 std::string toString( long long value );
1542 std::string toString( unsigned long long value );
1543 #endif
1544 
1545 #ifdef CATCH_CONFIG_CPP11_NULLPTR
1546 std::string toString( std::nullptr_t );
1547 #endif
1548 
1549 #ifdef __OBJC__
1550     std::string toString( NSString const * const& nsstring );
1551     std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );
1552     std::string toString( NSObject* const& nsObject );
1553 #endif
1554 
1555 namespace Detail {
1556 
1557     extern const std::string unprintableString;
1558 
1559     struct BorgType {
1560         template<typename T> BorgType( T const& );
1561     };
1562 
1563     struct TrueType { char sizer[1]; };
1564     struct FalseType { char sizer[2]; };
1565 
1566     TrueType& testStreamable( std::ostream& );
1567     FalseType testStreamable( FalseType );
1568 
1569     FalseType operator<<( std::ostream const&, BorgType const& );
1570 
1571     template<typename T>
1572     struct IsStreamInsertable {
1573         static std::ostream &s;
1574         static T  const&t;
1575         enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
1576     };
1577 
1578 #if defined(CATCH_CONFIG_CPP11_IS_ENUM)
1579     template<typename T,
1580              bool IsEnum = std::is_enum<T>::value
1581              >
1582     struct EnumStringMaker
1583     {
convertCatch::Detail::EnumStringMaker1584         static std::string convert( T const& ) { return unprintableString; }
1585     };
1586 
1587     template<typename T>
1588     struct EnumStringMaker<T,true>
1589     {
convertCatch::Detail::EnumStringMaker1590         static std::string convert( T const& v )
1591         {
1592             return ::Catch::toString(
1593                 static_cast<typename std::underlying_type<T>::type>(v)
1594                 );
1595         }
1596     };
1597 #endif
1598     template<bool C>
1599     struct StringMakerBase {
1600 #if defined(CATCH_CONFIG_CPP11_IS_ENUM)
1601         template<typename T>
convertCatch::Detail::StringMakerBase1602         static std::string convert( T const& v )
1603         {
1604             return EnumStringMaker<T>::convert( v );
1605         }
1606 #else
1607         template<typename T>
1608         static std::string convert( T const& ) { return unprintableString; }
1609 #endif
1610     };
1611 
1612     template<>
1613     struct StringMakerBase<true> {
1614         template<typename T>
convertCatch::Detail::StringMakerBase1615         static std::string convert( T const& _value ) {
1616             std::ostringstream oss;
1617             oss << _value;
1618             return oss.str();
1619         }
1620     };
1621 
1622     std::string rawMemoryToString( const void *object, std::size_t size );
1623 
1624     template<typename T>
rawMemoryToString(const T & object)1625     inline std::string rawMemoryToString( const T& object ) {
1626       return rawMemoryToString( &object, sizeof(object) );
1627     }
1628 
1629 } // end namespace Detail
1630 
1631 template<typename T>
1632 struct StringMaker :
1633     Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
1634 
1635 template<typename T>
1636 struct StringMaker<T*> {
1637     template<typename U>
convertCatch::StringMaker1638     static std::string convert( U* p ) {
1639         if( !p )
1640             return "NULL";
1641         else
1642             return Detail::rawMemoryToString( p );
1643     }
1644 };
1645 
1646 template<typename R, typename C>
1647 struct StringMaker<R C::*> {
convertCatch::StringMaker1648     static std::string convert( R C::* p ) {
1649         if( !p )
1650             return "NULL";
1651         else
1652             return Detail::rawMemoryToString( p );
1653     }
1654 };
1655 
1656 namespace Detail {
1657     template<typename InputIterator>
1658     std::string rangeToString( InputIterator first, InputIterator last );
1659 }
1660 
1661 //template<typename T, typename Allocator>
1662 //struct StringMaker<std::vector<T, Allocator> > {
1663 //    static std::string convert( std::vector<T,Allocator> const& v ) {
1664 //        return Detail::rangeToString( v.begin(), v.end() );
1665 //    }
1666 //};
1667 
1668 template<typename T, typename Allocator>
toString(std::vector<T,Allocator> const & v)1669 std::string toString( std::vector<T,Allocator> const& v ) {
1670     return Detail::rangeToString( v.begin(), v.end() );
1671 }
1672 
1673 #ifdef CATCH_CONFIG_CPP11_TUPLE
1674 
1675 // toString for tuples
1676 namespace TupleDetail {
1677   template<
1678       typename Tuple,
1679       std::size_t N = 0,
1680       bool = (N < std::tuple_size<Tuple>::value)
1681       >
1682   struct ElementPrinter {
printCatch::TupleDetail::ElementPrinter1683       static void print( const Tuple& tuple, std::ostream& os )
1684       {
1685           os << ( N ? ", " : " " )
1686              << Catch::toString(std::get<N>(tuple));
1687           ElementPrinter<Tuple,N+1>::print(tuple,os);
1688       }
1689   };
1690 
1691   template<
1692       typename Tuple,
1693       std::size_t N
1694       >
1695   struct ElementPrinter<Tuple,N,false> {
printCatch::TupleDetail::ElementPrinter1696       static void print( const Tuple&, std::ostream& ) {}
1697   };
1698 
1699 }
1700 
1701 template<typename ...Types>
1702 struct StringMaker<std::tuple<Types...>> {
1703 
convertCatch::StringMaker1704     static std::string convert( const std::tuple<Types...>& tuple )
1705     {
1706         std::ostringstream os;
1707         os << '{';
1708         TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
1709         os << " }";
1710         return os.str();
1711     }
1712 };
1713 #endif // CATCH_CONFIG_CPP11_TUPLE
1714 
1715 namespace Detail {
1716     template<typename T>
makeString(T const & value)1717     std::string makeString( T const& value ) {
1718         return StringMaker<T>::convert( value );
1719     }
1720 } // end namespace Detail
1721 
1722 /// \brief converts any type to a string
1723 ///
1724 /// The default template forwards on to ostringstream - except when an
1725 /// ostringstream overload does not exist - in which case it attempts to detect
1726 /// that and writes {?}.
1727 /// Overload (not specialise) this template for custom typs that you don't want
1728 /// to provide an ostream overload for.
1729 template<typename T>
toString(T const & value)1730 std::string toString( T const& value ) {
1731     return StringMaker<T>::convert( value );
1732 }
1733 
1734     namespace Detail {
1735     template<typename InputIterator>
rangeToString(InputIterator first,InputIterator last)1736     std::string rangeToString( InputIterator first, InputIterator last ) {
1737         std::ostringstream oss;
1738         oss << "{ ";
1739         if( first != last ) {
1740             oss << Catch::toString( *first );
1741             for( ++first ; first != last ; ++first )
1742                 oss << ", " << Catch::toString( *first );
1743         }
1744         oss << " }";
1745         return oss.str();
1746     }
1747 }
1748 
1749 } // end namespace Catch
1750 
1751 namespace Catch {
1752 
1753 // Wraps the LHS of an expression and captures the operator and RHS (if any) -
1754 // wrapping them all in a ResultBuilder object
1755 template<typename T>
1756 class ExpressionLhs {
1757     ExpressionLhs& operator = ( ExpressionLhs const& );
1758 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
1759     ExpressionLhs& operator = ( ExpressionLhs && ) = delete;
1760 #  endif
1761 
1762 public:
ExpressionLhs(ResultBuilder & rb,T lhs)1763     ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}
1764 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
1765     ExpressionLhs( ExpressionLhs const& ) = default;
1766     ExpressionLhs( ExpressionLhs && )     = default;
1767 #  endif
1768 
1769     template<typename RhsT>
operator ==(RhsT const & rhs)1770     ResultBuilder& operator == ( RhsT const& rhs ) {
1771         return captureExpression<Internal::IsEqualTo>( rhs );
1772     }
1773 
1774     template<typename RhsT>
operator !=(RhsT const & rhs)1775     ResultBuilder& operator != ( RhsT const& rhs ) {
1776         return captureExpression<Internal::IsNotEqualTo>( rhs );
1777     }
1778 
1779     template<typename RhsT>
operator <(RhsT const & rhs)1780     ResultBuilder& operator < ( RhsT const& rhs ) {
1781         return captureExpression<Internal::IsLessThan>( rhs );
1782     }
1783 
1784     template<typename RhsT>
operator >(RhsT const & rhs)1785     ResultBuilder& operator > ( RhsT const& rhs ) {
1786         return captureExpression<Internal::IsGreaterThan>( rhs );
1787     }
1788 
1789     template<typename RhsT>
operator <=(RhsT const & rhs)1790     ResultBuilder& operator <= ( RhsT const& rhs ) {
1791         return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
1792     }
1793 
1794     template<typename RhsT>
operator >=(RhsT const & rhs)1795     ResultBuilder& operator >= ( RhsT const& rhs ) {
1796         return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
1797     }
1798 
operator ==(bool rhs)1799     ResultBuilder& operator == ( bool rhs ) {
1800         return captureExpression<Internal::IsEqualTo>( rhs );
1801     }
1802 
operator !=(bool rhs)1803     ResultBuilder& operator != ( bool rhs ) {
1804         return captureExpression<Internal::IsNotEqualTo>( rhs );
1805     }
1806 
endExpression()1807     void endExpression() {
1808         bool value = m_lhs ? true : false;
1809         m_rb
1810             .setLhs( Catch::toString( value ) )
1811             .setResultType( value )
1812             .endExpression();
1813     }
1814 
1815     // Only simple binary expressions are allowed on the LHS.
1816     // If more complex compositions are required then place the sub expression in parentheses
1817     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
1818     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
1819     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
1820     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
1821     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
1822     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
1823 
1824 private:
1825     template<Internal::Operator Op, typename RhsT>
captureExpression(RhsT const & rhs)1826     ResultBuilder& captureExpression( RhsT const& rhs ) {
1827         return m_rb
1828             .setResultType( Internal::compare<Op>( m_lhs, rhs ) )
1829             .setLhs( Catch::toString( m_lhs ) )
1830             .setRhs( Catch::toString( rhs ) )
1831             .setOp( Internal::OperatorTraits<Op>::getName() );
1832     }
1833 
1834 private:
1835     ResultBuilder& m_rb;
1836     T m_lhs;
1837 };
1838 
1839 } // end namespace Catch
1840 
1841 
1842 namespace Catch {
1843 
1844     template<typename T>
operator <=(T const & operand)1845     inline ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
1846         return ExpressionLhs<T const&>( *this, operand );
1847     }
1848 
operator <=(bool value)1849     inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {
1850         return ExpressionLhs<bool>( *this, value );
1851     }
1852 
1853 } // namespace Catch
1854 
1855 // #included from: catch_message.h
1856 #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
1857 
1858 #include <string>
1859 
1860 namespace Catch {
1861 
1862     struct MessageInfo {
1863         MessageInfo(    std::string const& _macroName,
1864                         SourceLineInfo const& _lineInfo,
1865                         ResultWas::OfType _type );
1866 
1867         std::string macroName;
1868         SourceLineInfo lineInfo;
1869         ResultWas::OfType type;
1870         std::string message;
1871         unsigned int sequence;
1872 
operator ==Catch::MessageInfo1873         bool operator == ( MessageInfo const& other ) const {
1874             return sequence == other.sequence;
1875         }
operator <Catch::MessageInfo1876         bool operator < ( MessageInfo const& other ) const {
1877             return sequence < other.sequence;
1878         }
1879     private:
1880         static unsigned int globalCount;
1881     };
1882 
1883     struct MessageBuilder {
MessageBuilderCatch::MessageBuilder1884         MessageBuilder( std::string const& macroName,
1885                         SourceLineInfo const& lineInfo,
1886                         ResultWas::OfType type )
1887         : m_info( macroName, lineInfo, type )
1888         {}
1889 
1890         template<typename T>
operator <<Catch::MessageBuilder1891         MessageBuilder& operator << ( T const& value ) {
1892             m_stream << value;
1893             return *this;
1894         }
1895 
1896         MessageInfo m_info;
1897         std::ostringstream m_stream;
1898     };
1899 
1900     class ScopedMessage {
1901     public:
1902         ScopedMessage( MessageBuilder const& builder );
1903         ScopedMessage( ScopedMessage const& other );
1904         ~ScopedMessage();
1905 
1906         MessageInfo m_info;
1907     };
1908 
1909 } // end namespace Catch
1910 
1911 // #included from: catch_interfaces_capture.h
1912 #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
1913 
1914 #include <string>
1915 
1916 namespace Catch {
1917 
1918     class TestCase;
1919     class AssertionResult;
1920     struct AssertionInfo;
1921     struct SectionInfo;
1922     struct SectionEndInfo;
1923     struct MessageInfo;
1924     class ScopedMessageBuilder;
1925     struct Counts;
1926 
1927     struct IResultCapture {
1928 
1929         virtual ~IResultCapture();
1930 
1931         virtual void assertionEnded( AssertionResult const& result ) = 0;
1932         virtual bool sectionStarted(    SectionInfo const& sectionInfo,
1933                                         Counts& assertions ) = 0;
1934         virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
1935         virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
1936         virtual void pushScopedMessage( MessageInfo const& message ) = 0;
1937         virtual void popScopedMessage( MessageInfo const& message ) = 0;
1938 
1939         virtual std::string getCurrentTestName() const = 0;
1940         virtual const AssertionResult* getLastResult() const = 0;
1941 
1942         virtual void handleFatalErrorCondition( std::string const& message ) = 0;
1943     };
1944 
1945     IResultCapture& getResultCapture();
1946 }
1947 
1948 // #included from: catch_debugger.h
1949 #define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
1950 
1951 // #included from: catch_platform.h
1952 #define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
1953 
1954 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
1955 #define CATCH_PLATFORM_MAC
1956 #elif  defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
1957 #define CATCH_PLATFORM_IPHONE
1958 #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
1959 #define CATCH_PLATFORM_WINDOWS
1960 #endif
1961 
1962 #include <string>
1963 
1964 namespace Catch{
1965 
1966     bool isDebuggerActive();
1967     void writeToDebugConsole( std::string const& text );
1968 }
1969 
1970 #ifdef CATCH_PLATFORM_MAC
1971 
1972     // The following code snippet based on:
1973     // http://cocoawithlove.com/2008/03/break-into-debugger.html
1974     #ifdef DEBUG
1975         #if defined(__ppc64__) || defined(__ppc__)
1976             #define CATCH_BREAK_INTO_DEBUGGER() \
1977                 if( Catch::isDebuggerActive() ) { \
1978                     __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
1979                     : : : "memory","r0","r3","r4" ); \
1980                 }
1981         #else
1982             #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
1983         #endif
1984     #endif
1985 
1986 #elif defined(_MSC_VER)
1987     #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
1988 #elif defined(__MINGW32__)
1989     extern "C" __declspec(dllimport) void __stdcall DebugBreak();
1990     #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
1991 #endif
1992 
1993 #ifndef CATCH_BREAK_INTO_DEBUGGER
1994 #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
1995 #endif
1996 
1997 // #included from: catch_interfaces_runner.h
1998 #define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
1999 
2000 namespace Catch {
2001     class TestCase;
2002 
2003     struct IRunner {
2004         virtual ~IRunner();
2005         virtual bool aborting() const = 0;
2006     };
2007 }
2008 
2009 ///////////////////////////////////////////////////////////////////////////////
2010 // In the event of a failure works out if the debugger needs to be invoked
2011 // and/or an exception thrown and takes appropriate action.
2012 // This needs to be done as a macro so the debugger will stop in the user
2013 // source code rather than in Catch library code
2014 #define INTERNAL_CATCH_REACT( resultBuilder ) \
2015     if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
2016     resultBuilder.react();
2017 
2018 ///////////////////////////////////////////////////////////////////////////////
2019 #define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
2020     do { \
2021         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
2022         try { \
2023             ( __catchResult <= expr ).endExpression(); \
2024         } \
2025         catch( ... ) { \
2026             __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
2027         } \
2028         INTERNAL_CATCH_REACT( __catchResult ) \
2029     } while( Catch::isTrue( false && (expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
2030 
2031 ///////////////////////////////////////////////////////////////////////////////
2032 #define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
2033     INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
2034     if( Catch::getResultCapture().getLastResult()->succeeded() )
2035 
2036 ///////////////////////////////////////////////////////////////////////////////
2037 #define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
2038     INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
2039     if( !Catch::getResultCapture().getLastResult()->succeeded() )
2040 
2041 ///////////////////////////////////////////////////////////////////////////////
2042 #define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
2043     do { \
2044         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
2045         try { \
2046             expr; \
2047             __catchResult.captureResult( Catch::ResultWas::Ok ); \
2048         } \
2049         catch( ... ) { \
2050             __catchResult.useActiveException( resultDisposition ); \
2051         } \
2052         INTERNAL_CATCH_REACT( __catchResult ) \
2053     } while( Catch::alwaysFalse() )
2054 
2055 ///////////////////////////////////////////////////////////////////////////////
2056 #define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \
2057     do { \
2058         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \
2059         if( __catchResult.allowThrows() ) \
2060             try { \
2061                 expr; \
2062                 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
2063             } \
2064             catch( ... ) { \
2065                 __catchResult.captureExpectedException( matcher ); \
2066             } \
2067         else \
2068             __catchResult.captureResult( Catch::ResultWas::Ok ); \
2069         INTERNAL_CATCH_REACT( __catchResult ) \
2070     } while( Catch::alwaysFalse() )
2071 
2072 ///////////////////////////////////////////////////////////////////////////////
2073 #define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
2074     do { \
2075         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
2076         if( __catchResult.allowThrows() ) \
2077             try { \
2078                 expr; \
2079                 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
2080             } \
2081             catch( exceptionType ) { \
2082                 __catchResult.captureResult( Catch::ResultWas::Ok ); \
2083             } \
2084             catch( ... ) { \
2085                 __catchResult.useActiveException( resultDisposition ); \
2086             } \
2087         else \
2088             __catchResult.captureResult( Catch::ResultWas::Ok ); \
2089         INTERNAL_CATCH_REACT( __catchResult ) \
2090     } while( Catch::alwaysFalse() )
2091 
2092 ///////////////////////////////////////////////////////////////////////////////
2093 #ifdef CATCH_CONFIG_VARIADIC_MACROS
2094     #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
2095         do { \
2096             Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
2097             __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
2098             __catchResult.captureResult( messageType ); \
2099             INTERNAL_CATCH_REACT( __catchResult ) \
2100         } while( Catch::alwaysFalse() )
2101 #else
2102     #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
2103         do { \
2104             Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
2105             __catchResult << log + ::Catch::StreamEndStop(); \
2106             __catchResult.captureResult( messageType ); \
2107             INTERNAL_CATCH_REACT( __catchResult ) \
2108         } while( Catch::alwaysFalse() )
2109 #endif
2110 
2111 ///////////////////////////////////////////////////////////////////////////////
2112 #define INTERNAL_CATCH_INFO( log, macroName ) \
2113     Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
2114 
2115 ///////////////////////////////////////////////////////////////////////////////
2116 #define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
2117     do { \
2118         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg " " #matcher, resultDisposition ); \
2119         try { \
2120             std::string matcherAsString = (matcher).toString(); \
2121             __catchResult \
2122                 .setLhs( Catch::toString( arg ) ) \
2123                 .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
2124                 .setOp( "matches" ) \
2125                 .setResultType( (matcher).match( arg ) ); \
2126             __catchResult.captureExpression(); \
2127         } catch( ... ) { \
2128             __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
2129         } \
2130         INTERNAL_CATCH_REACT( __catchResult ) \
2131     } while( Catch::alwaysFalse() )
2132 
2133 // #included from: internal/catch_section.h
2134 #define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
2135 
2136 // #included from: catch_section_info.h
2137 #define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
2138 
2139 // #included from: catch_totals.hpp
2140 #define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
2141 
2142 #include <cstddef>
2143 
2144 namespace Catch {
2145 
2146     struct Counts {
CountsCatch::Counts2147         Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
2148 
operator -Catch::Counts2149         Counts operator - ( Counts const& other ) const {
2150             Counts diff;
2151             diff.passed = passed - other.passed;
2152             diff.failed = failed - other.failed;
2153             diff.failedButOk = failedButOk - other.failedButOk;
2154             return diff;
2155         }
operator +=Catch::Counts2156         Counts& operator += ( Counts const& other ) {
2157             passed += other.passed;
2158             failed += other.failed;
2159             failedButOk += other.failedButOk;
2160             return *this;
2161         }
2162 
totalCatch::Counts2163         std::size_t total() const {
2164             return passed + failed + failedButOk;
2165         }
allPassedCatch::Counts2166         bool allPassed() const {
2167             return failed == 0 && failedButOk == 0;
2168         }
allOkCatch::Counts2169         bool allOk() const {
2170             return failed == 0;
2171         }
2172 
2173         std::size_t passed;
2174         std::size_t failed;
2175         std::size_t failedButOk;
2176     };
2177 
2178     struct Totals {
2179 
operator -Catch::Totals2180         Totals operator - ( Totals const& other ) const {
2181             Totals diff;
2182             diff.assertions = assertions - other.assertions;
2183             diff.testCases = testCases - other.testCases;
2184             return diff;
2185         }
2186 
deltaCatch::Totals2187         Totals delta( Totals const& prevTotals ) const {
2188             Totals diff = *this - prevTotals;
2189             if( diff.assertions.failed > 0 )
2190                 ++diff.testCases.failed;
2191             else if( diff.assertions.failedButOk > 0 )
2192                 ++diff.testCases.failedButOk;
2193             else
2194                 ++diff.testCases.passed;
2195             return diff;
2196         }
2197 
operator +=Catch::Totals2198         Totals& operator += ( Totals const& other ) {
2199             assertions += other.assertions;
2200             testCases += other.testCases;
2201             return *this;
2202         }
2203 
2204         Counts assertions;
2205         Counts testCases;
2206     };
2207 }
2208 
2209 namespace Catch {
2210 
2211     struct SectionInfo {
2212         SectionInfo
2213             (   SourceLineInfo const& _lineInfo,
2214                 std::string const& _name,
2215                 std::string const& _description = std::string() );
2216 
2217         std::string name;
2218         std::string description;
2219         SourceLineInfo lineInfo;
2220     };
2221 
2222     struct SectionEndInfo {
SectionEndInfoCatch::SectionEndInfo2223         SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
2224         : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
2225         {}
2226 
2227         SectionInfo sectionInfo;
2228         Counts prevAssertions;
2229         double durationInSeconds;
2230     };
2231 
2232 } // end namespace Catch
2233 
2234 // #included from: catch_timer.h
2235 #define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
2236 
2237 #ifdef CATCH_PLATFORM_WINDOWS
2238 typedef unsigned long long uint64_t;
2239 #else
2240 #include <stdint.h>
2241 #endif
2242 
2243 namespace Catch {
2244 
2245     class Timer {
2246     public:
Timer()2247         Timer() : m_ticks( 0 ) {}
2248         void start();
2249         unsigned int getElapsedMicroseconds() const;
2250         unsigned int getElapsedMilliseconds() const;
2251         double getElapsedSeconds() const;
2252 
2253     private:
2254         uint64_t m_ticks;
2255     };
2256 
2257 } // namespace Catch
2258 
2259 #include <string>
2260 
2261 namespace Catch {
2262 
2263     class Section : NonCopyable {
2264     public:
2265         Section( SectionInfo const& info );
2266         ~Section();
2267 
2268         // This indicates whether the section should be executed or not
2269         operator bool() const;
2270 
2271     private:
2272         SectionInfo m_info;
2273 
2274         std::string m_name;
2275         Counts m_assertions;
2276         bool m_sectionIncluded;
2277         Timer m_timer;
2278     };
2279 
2280 } // end namespace Catch
2281 
2282 #ifdef CATCH_CONFIG_VARIADIC_MACROS
2283     #define INTERNAL_CATCH_SECTION( ... ) \
2284         if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
2285 #else
2286     #define INTERNAL_CATCH_SECTION( name, desc ) \
2287         if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
2288 #endif
2289 
2290 // #included from: internal/catch_generators.hpp
2291 #define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
2292 
2293 #include <iterator>
2294 #include <vector>
2295 #include <string>
2296 #include <stdlib.h>
2297 
2298 namespace Catch {
2299 
2300 template<typename T>
2301 struct IGenerator {
~IGeneratorCatch::IGenerator2302     virtual ~IGenerator() {}
2303     virtual T getValue( std::size_t index ) const = 0;
2304     virtual std::size_t size () const = 0;
2305 };
2306 
2307 template<typename T>
2308 class BetweenGenerator : public IGenerator<T> {
2309 public:
BetweenGenerator(T from,T to)2310     BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
2311 
getValue(std::size_t index) const2312     virtual T getValue( std::size_t index ) const {
2313         return m_from+static_cast<int>( index );
2314     }
2315 
size() const2316     virtual std::size_t size() const {
2317         return static_cast<std::size_t>( 1+m_to-m_from );
2318     }
2319 
2320 private:
2321 
2322     T m_from;
2323     T m_to;
2324 };
2325 
2326 template<typename T>
2327 class ValuesGenerator : public IGenerator<T> {
2328 public:
ValuesGenerator()2329     ValuesGenerator(){}
2330 
add(T value)2331     void add( T value ) {
2332         m_values.push_back( value );
2333     }
2334 
getValue(std::size_t index) const2335     virtual T getValue( std::size_t index ) const {
2336         return m_values[index];
2337     }
2338 
size() const2339     virtual std::size_t size() const {
2340         return m_values.size();
2341     }
2342 
2343 private:
2344     std::vector<T> m_values;
2345 };
2346 
2347 template<typename T>
2348 class CompositeGenerator {
2349 public:
CompositeGenerator()2350     CompositeGenerator() : m_totalSize( 0 ) {}
2351 
2352     // *** Move semantics, similar to auto_ptr ***
CompositeGenerator(CompositeGenerator & other)2353     CompositeGenerator( CompositeGenerator& other )
2354     :   m_fileInfo( other.m_fileInfo ),
2355         m_totalSize( 0 )
2356     {
2357         move( other );
2358     }
2359 
setFileInfo(const char * fileInfo)2360     CompositeGenerator& setFileInfo( const char* fileInfo ) {
2361         m_fileInfo = fileInfo;
2362         return *this;
2363     }
2364 
~CompositeGenerator()2365     ~CompositeGenerator() {
2366         deleteAll( m_composed );
2367     }
2368 
operator T() const2369     operator T () const {
2370         size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
2371 
2372         typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
2373         typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
2374         for( size_t index = 0; it != itEnd; ++it )
2375         {
2376             const IGenerator<T>* generator = *it;
2377             if( overallIndex >= index && overallIndex < index + generator->size() )
2378             {
2379                 return generator->getValue( overallIndex-index );
2380             }
2381             index += generator->size();
2382         }
2383         CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
2384         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
2385     }
2386 
add(const IGenerator<T> * generator)2387     void add( const IGenerator<T>* generator ) {
2388         m_totalSize += generator->size();
2389         m_composed.push_back( generator );
2390     }
2391 
then(CompositeGenerator & other)2392     CompositeGenerator& then( CompositeGenerator& other ) {
2393         move( other );
2394         return *this;
2395     }
2396 
then(T value)2397     CompositeGenerator& then( T value ) {
2398         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2399         valuesGen->add( value );
2400         add( valuesGen );
2401         return *this;
2402     }
2403 
2404 private:
2405 
move(CompositeGenerator & other)2406     void move( CompositeGenerator& other ) {
2407         std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
2408         m_totalSize += other.m_totalSize;
2409         other.m_composed.clear();
2410     }
2411 
2412     std::vector<const IGenerator<T>*> m_composed;
2413     std::string m_fileInfo;
2414     size_t m_totalSize;
2415 };
2416 
2417 namespace Generators
2418 {
2419     template<typename T>
between(T from,T to)2420     CompositeGenerator<T> between( T from, T to ) {
2421         CompositeGenerator<T> generators;
2422         generators.add( new BetweenGenerator<T>( from, to ) );
2423         return generators;
2424     }
2425 
2426     template<typename T>
values(T val1,T val2)2427     CompositeGenerator<T> values( T val1, T val2 ) {
2428         CompositeGenerator<T> generators;
2429         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2430         valuesGen->add( val1 );
2431         valuesGen->add( val2 );
2432         generators.add( valuesGen );
2433         return generators;
2434     }
2435 
2436     template<typename T>
values(T val1,T val2,T val3)2437     CompositeGenerator<T> values( T val1, T val2, T val3 ){
2438         CompositeGenerator<T> generators;
2439         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2440         valuesGen->add( val1 );
2441         valuesGen->add( val2 );
2442         valuesGen->add( val3 );
2443         generators.add( valuesGen );
2444         return generators;
2445     }
2446 
2447     template<typename T>
values(T val1,T val2,T val3,T val4)2448     CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
2449         CompositeGenerator<T> generators;
2450         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
2451         valuesGen->add( val1 );
2452         valuesGen->add( val2 );
2453         valuesGen->add( val3 );
2454         valuesGen->add( val4 );
2455         generators.add( valuesGen );
2456         return generators;
2457     }
2458 
2459 } // end namespace Generators
2460 
2461 using namespace Generators;
2462 
2463 } // end namespace Catch
2464 
2465 #define INTERNAL_CATCH_LINESTR2( line ) #line
2466 #define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
2467 
2468 #define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
2469 
2470 // #included from: internal/catch_interfaces_exception.h
2471 #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
2472 
2473 #include <string>
2474 #include <vector>
2475 
2476 // #included from: catch_interfaces_registry_hub.h
2477 #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
2478 
2479 #include <string>
2480 
2481 namespace Catch {
2482 
2483     class TestCase;
2484     struct ITestCaseRegistry;
2485     struct IExceptionTranslatorRegistry;
2486     struct IExceptionTranslator;
2487     struct IReporterRegistry;
2488     struct IReporterFactory;
2489 
2490     struct IRegistryHub {
2491         virtual ~IRegistryHub();
2492 
2493         virtual IReporterRegistry const& getReporterRegistry() const = 0;
2494         virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
2495         virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
2496     };
2497 
2498     struct IMutableRegistryHub {
2499         virtual ~IMutableRegistryHub();
2500         virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) = 0;
2501         virtual void registerListener( Ptr<IReporterFactory> const& factory ) = 0;
2502         virtual void registerTest( TestCase const& testInfo ) = 0;
2503         virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
2504     };
2505 
2506     IRegistryHub& getRegistryHub();
2507     IMutableRegistryHub& getMutableRegistryHub();
2508     void cleanUp();
2509     std::string translateActiveException();
2510 
2511 }
2512 
2513 namespace Catch {
2514 
2515     typedef std::string(*exceptionTranslateFunction)();
2516 
2517     struct IExceptionTranslator;
2518     typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;
2519 
2520     struct IExceptionTranslator {
2521         virtual ~IExceptionTranslator();
2522         virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
2523     };
2524 
2525     struct IExceptionTranslatorRegistry {
2526         virtual ~IExceptionTranslatorRegistry();
2527 
2528         virtual std::string translateActiveException() const = 0;
2529     };
2530 
2531     class ExceptionTranslatorRegistrar {
2532         template<typename T>
2533         class ExceptionTranslator : public IExceptionTranslator {
2534         public:
2535 
ExceptionTranslator(std::string (* translateFunction)(T &))2536             ExceptionTranslator( std::string(*translateFunction)( T& ) )
2537             : m_translateFunction( translateFunction )
2538             {}
2539 
translate(ExceptionTranslators::const_iterator it,ExceptionTranslators::const_iterator itEnd) const2540             virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE {
2541                 try {
2542                     if( it == itEnd )
2543                         throw;
2544                     else
2545                         return (*it)->translate( it+1, itEnd );
2546                 }
2547                 catch( T& ex ) {
2548                     return m_translateFunction( ex );
2549                 }
2550             }
2551 
2552         protected:
2553             std::string(*m_translateFunction)( T& );
2554         };
2555 
2556     public:
2557         template<typename T>
ExceptionTranslatorRegistrar(std::string (* translateFunction)(T &))2558         ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
2559             getMutableRegistryHub().registerTranslator
2560                 ( new ExceptionTranslator<T>( translateFunction ) );
2561         }
2562     };
2563 }
2564 
2565 ///////////////////////////////////////////////////////////////////////////////
2566 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \
2567     static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \
2568     namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\
2569     static std::string INTERNAL_CATCH_UNIQUE_NAME(  catch_internal_ExceptionTranslator )( signature )
2570 
2571 // #included from: internal/catch_approx.hpp
2572 #define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
2573 
2574 #include <cmath>
2575 #include <limits>
2576 
2577 namespace Catch {
2578 namespace Detail {
2579 
2580     class Approx {
2581     public:
Approx(double value)2582         explicit Approx ( double value )
2583         :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
2584             m_scale( 1.0 ),
2585             m_value( value )
2586         {}
2587 
Approx(Approx const & other)2588         Approx( Approx const& other )
2589         :   m_epsilon( other.m_epsilon ),
2590             m_scale( other.m_scale ),
2591             m_value( other.m_value )
2592         {}
2593 
custom()2594         static Approx custom() {
2595             return Approx( 0 );
2596         }
2597 
operator ()(double value)2598         Approx operator()( double value ) {
2599             Approx approx( value );
2600             approx.epsilon( m_epsilon );
2601             approx.scale( m_scale );
2602             return approx;
2603         }
2604 
operator ==(double lhs,Approx const & rhs)2605         friend bool operator == ( double lhs, Approx const& rhs ) {
2606             // Thanks to Richard Harris for his help refining this formula
2607             return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
2608         }
2609 
operator ==(Approx const & lhs,double rhs)2610         friend bool operator == ( Approx const& lhs, double rhs ) {
2611             return operator==( rhs, lhs );
2612         }
2613 
operator !=(double lhs,Approx const & rhs)2614         friend bool operator != ( double lhs, Approx const& rhs ) {
2615             return !operator==( lhs, rhs );
2616         }
2617 
operator !=(Approx const & lhs,double rhs)2618         friend bool operator != ( Approx const& lhs, double rhs ) {
2619             return !operator==( rhs, lhs );
2620         }
2621 
epsilon(double newEpsilon)2622         Approx& epsilon( double newEpsilon ) {
2623             m_epsilon = newEpsilon;
2624             return *this;
2625         }
2626 
scale(double newScale)2627         Approx& scale( double newScale ) {
2628             m_scale = newScale;
2629             return *this;
2630         }
2631 
toString() const2632         std::string toString() const {
2633             std::ostringstream oss;
2634             oss << "Approx( " << Catch::toString( m_value ) << " )";
2635             return oss.str();
2636         }
2637 
2638     private:
2639         double m_epsilon;
2640         double m_scale;
2641         double m_value;
2642     };
2643 }
2644 
2645 template<>
toString(Detail::Approx const & value)2646 inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
2647     return value.toString();
2648 }
2649 
2650 } // end namespace Catch
2651 
2652 // #included from: internal/catch_interfaces_tag_alias_registry.h
2653 #define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
2654 
2655 // #included from: catch_tag_alias.h
2656 #define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
2657 
2658 #include <string>
2659 
2660 namespace Catch {
2661 
2662     struct TagAlias {
TagAliasCatch::TagAlias2663         TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
2664 
2665         std::string tag;
2666         SourceLineInfo lineInfo;
2667     };
2668 
2669     struct RegistrarForTagAliases {
2670         RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
2671     };
2672 
2673 } // end namespace Catch
2674 
2675 #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
2676 // #included from: catch_option.hpp
2677 #define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
2678 
2679 namespace Catch {
2680 
2681     // An optional type
2682     template<typename T>
2683     class Option {
2684     public:
Option()2685         Option() : nullableValue( CATCH_NULL ) {}
Option(T const & _value)2686         Option( T const& _value )
2687         : nullableValue( new( storage ) T( _value ) )
2688         {}
Option(Option const & _other)2689         Option( Option const& _other )
2690         : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL )
2691         {}
2692 
~Option()2693         ~Option() {
2694             reset();
2695         }
2696 
operator =(Option const & _other)2697         Option& operator= ( Option const& _other ) {
2698             if( &_other != this ) {
2699                 reset();
2700                 if( _other )
2701                     nullableValue = new( storage ) T( *_other );
2702             }
2703             return *this;
2704         }
operator =(T const & _value)2705         Option& operator = ( T const& _value ) {
2706             reset();
2707             nullableValue = new( storage ) T( _value );
2708             return *this;
2709         }
2710 
reset()2711         void reset() {
2712             if( nullableValue )
2713                 nullableValue->~T();
2714             nullableValue = CATCH_NULL;
2715         }
2716 
operator *()2717         T& operator*() { return *nullableValue; }
operator *() const2718         T const& operator*() const { return *nullableValue; }
operator ->()2719         T* operator->() { return nullableValue; }
operator ->() const2720         const T* operator->() const { return nullableValue; }
2721 
valueOr(T const & defaultValue) const2722         T valueOr( T const& defaultValue ) const {
2723             return nullableValue ? *nullableValue : defaultValue;
2724         }
2725 
some() const2726         bool some() const { return nullableValue != CATCH_NULL; }
none() const2727         bool none() const { return nullableValue == CATCH_NULL; }
2728 
operator !() const2729         bool operator !() const { return nullableValue == CATCH_NULL; }
operator SafeBool::type() const2730         operator SafeBool::type() const {
2731             return SafeBool::makeSafe( some() );
2732         }
2733 
2734     private:
2735         T* nullableValue;
2736         char storage[sizeof(T)];
2737     };
2738 
2739 } // end namespace Catch
2740 
2741 namespace Catch {
2742 
2743     struct ITagAliasRegistry {
2744         virtual ~ITagAliasRegistry();
2745         virtual Option<TagAlias> find( std::string const& alias ) const = 0;
2746         virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
2747 
2748         static ITagAliasRegistry const& get();
2749     };
2750 
2751 } // end namespace Catch
2752 
2753 // These files are included here so the single_include script doesn't put them
2754 // in the conditionally compiled sections
2755 // #included from: internal/catch_test_case_info.h
2756 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
2757 
2758 #include <string>
2759 #include <set>
2760 
2761 #ifdef __clang__
2762 #pragma clang diagnostic push
2763 #pragma clang diagnostic ignored "-Wpadded"
2764 #endif
2765 
2766 namespace Catch {
2767 
2768     struct ITestCase;
2769 
2770     struct TestCaseInfo {
2771         enum SpecialProperties{
2772             None = 0,
2773             IsHidden = 1 << 1,
2774             ShouldFail = 1 << 2,
2775             MayFail = 1 << 3,
2776             Throws = 1 << 4
2777         };
2778 
2779         TestCaseInfo(   std::string const& _name,
2780                         std::string const& _className,
2781                         std::string const& _description,
2782                         std::set<std::string> const& _tags,
2783                         SourceLineInfo const& _lineInfo );
2784 
2785         TestCaseInfo( TestCaseInfo const& other );
2786 
2787         friend void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags );
2788 
2789         bool isHidden() const;
2790         bool throws() const;
2791         bool okToFail() const;
2792         bool expectedToFail() const;
2793 
2794         std::string name;
2795         std::string className;
2796         std::string description;
2797         std::set<std::string> tags;
2798         std::set<std::string> lcaseTags;
2799         std::string tagsAsString;
2800         SourceLineInfo lineInfo;
2801         SpecialProperties properties;
2802     };
2803 
2804     class TestCase : public TestCaseInfo {
2805     public:
2806 
2807         TestCase( ITestCase* testCase, TestCaseInfo const& info );
2808         TestCase( TestCase const& other );
2809 
2810         TestCase withName( std::string const& _newName ) const;
2811 
2812         void invoke() const;
2813 
2814         TestCaseInfo const& getTestCaseInfo() const;
2815 
2816         void swap( TestCase& other );
2817         bool operator == ( TestCase const& other ) const;
2818         bool operator < ( TestCase const& other ) const;
2819         TestCase& operator = ( TestCase const& other );
2820 
2821     private:
2822         Ptr<ITestCase> test;
2823     };
2824 
2825     TestCase makeTestCase(  ITestCase* testCase,
2826                             std::string const& className,
2827                             std::string const& name,
2828                             std::string const& description,
2829                             SourceLineInfo const& lineInfo );
2830 }
2831 
2832 #ifdef __clang__
2833 #pragma clang diagnostic pop
2834 #endif
2835 
2836 
2837 #ifdef __OBJC__
2838 // #included from: internal/catch_objc.hpp
2839 #define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
2840 
2841 #import <objc/runtime.h>
2842 
2843 #include <string>
2844 
2845 // NB. Any general catch headers included here must be included
2846 // in catch.hpp first to make sure they are included by the single
2847 // header for non obj-usage
2848 
2849 ///////////////////////////////////////////////////////////////////////////////
2850 // This protocol is really only here for (self) documenting purposes, since
2851 // all its methods are optional.
2852 @protocol OcFixture
2853 
2854 @optional
2855 
2856 -(void) setUp;
2857 -(void) tearDown;
2858 
2859 @end
2860 
2861 namespace Catch {
2862 
2863     class OcMethod : public SharedImpl<ITestCase> {
2864 
2865     public:
OcMethod(Class cls,SEL sel)2866         OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
2867 
invoke() const2868         virtual void invoke() const {
2869             id obj = [[m_cls alloc] init];
2870 
2871             performOptionalSelector( obj, @selector(setUp)  );
2872             performOptionalSelector( obj, m_sel );
2873             performOptionalSelector( obj, @selector(tearDown)  );
2874 
2875             arcSafeRelease( obj );
2876         }
2877     private:
~OcMethod()2878         virtual ~OcMethod() {}
2879 
2880         Class m_cls;
2881         SEL m_sel;
2882     };
2883 
2884     namespace Detail{
2885 
getAnnotation(Class cls,std::string const & annotationName,std::string const & testCaseName)2886         inline std::string getAnnotation(   Class cls,
2887                                             std::string const& annotationName,
2888                                             std::string const& testCaseName ) {
2889             NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
2890             SEL sel = NSSelectorFromString( selStr );
2891             arcSafeRelease( selStr );
2892             id value = performOptionalSelector( cls, sel );
2893             if( value )
2894                 return [(NSString*)value UTF8String];
2895             return "";
2896         }
2897     }
2898 
registerTestMethods()2899     inline size_t registerTestMethods() {
2900         size_t noTestMethods = 0;
2901         int noClasses = objc_getClassList( CATCH_NULL, 0 );
2902 
2903         Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
2904         objc_getClassList( classes, noClasses );
2905 
2906         for( int c = 0; c < noClasses; c++ ) {
2907             Class cls = classes[c];
2908             {
2909                 u_int count;
2910                 Method* methods = class_copyMethodList( cls, &count );
2911                 for( u_int m = 0; m < count ; m++ ) {
2912                     SEL selector = method_getName(methods[m]);
2913                     std::string methodName = sel_getName(selector);
2914                     if( startsWith( methodName, "Catch_TestCase_" ) ) {
2915                         std::string testCaseName = methodName.substr( 15 );
2916                         std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
2917                         std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
2918                         const char* className = class_getName( cls );
2919 
2920                         getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
2921                         noTestMethods++;
2922                     }
2923                 }
2924                 free(methods);
2925             }
2926         }
2927         return noTestMethods;
2928     }
2929 
2930     namespace Matchers {
2931         namespace Impl {
2932         namespace NSStringMatchers {
2933 
2934             template<typename MatcherT>
2935             struct StringHolder : MatcherImpl<MatcherT, NSString*>{
StringHolderCatch::Matchers::Impl::NSStringMatchers::StringHolder2936                 StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
StringHolderCatch::Matchers::Impl::NSStringMatchers::StringHolder2937                 StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
StringHolderCatch::Matchers::Impl::NSStringMatchers::StringHolder2938                 StringHolder() {
2939                     arcSafeRelease( m_substr );
2940                 }
2941 
2942                 NSString* m_substr;
2943             };
2944 
2945             struct Equals : StringHolder<Equals> {
EqualsCatch::Matchers::Impl::NSStringMatchers::Equals2946                 Equals( NSString* substr ) : StringHolder( substr ){}
2947 
matchCatch::Matchers::Impl::NSStringMatchers::Equals2948                 virtual bool match( ExpressionType const& str ) const {
2949                     return  (str != nil || m_substr == nil ) &&
2950                             [str isEqualToString:m_substr];
2951                 }
2952 
toStringCatch::Matchers::Impl::NSStringMatchers::Equals2953                 virtual std::string toString() const {
2954                     return "equals string: " + Catch::toString( m_substr );
2955                 }
2956             };
2957 
2958             struct Contains : StringHolder<Contains> {
ContainsCatch::Matchers::Impl::NSStringMatchers::Contains2959                 Contains( NSString* substr ) : StringHolder( substr ){}
2960 
matchCatch::Matchers::Impl::NSStringMatchers::Contains2961                 virtual bool match( ExpressionType const& str ) const {
2962                     return  (str != nil || m_substr == nil ) &&
2963                             [str rangeOfString:m_substr].location != NSNotFound;
2964                 }
2965 
toStringCatch::Matchers::Impl::NSStringMatchers::Contains2966                 virtual std::string toString() const {
2967                     return "contains string: " + Catch::toString( m_substr );
2968                 }
2969             };
2970 
2971             struct StartsWith : StringHolder<StartsWith> {
StartsWithCatch::Matchers::Impl::NSStringMatchers::StartsWith2972                 StartsWith( NSString* substr ) : StringHolder( substr ){}
2973 
matchCatch::Matchers::Impl::NSStringMatchers::StartsWith2974                 virtual bool match( ExpressionType const& str ) const {
2975                     return  (str != nil || m_substr == nil ) &&
2976                             [str rangeOfString:m_substr].location == 0;
2977                 }
2978 
toStringCatch::Matchers::Impl::NSStringMatchers::StartsWith2979                 virtual std::string toString() const {
2980                     return "starts with: " + Catch::toString( m_substr );
2981                 }
2982             };
2983             struct EndsWith : StringHolder<EndsWith> {
EndsWithCatch::Matchers::Impl::NSStringMatchers::EndsWith2984                 EndsWith( NSString* substr ) : StringHolder( substr ){}
2985 
matchCatch::Matchers::Impl::NSStringMatchers::EndsWith2986                 virtual bool match( ExpressionType const& str ) const {
2987                     return  (str != nil || m_substr == nil ) &&
2988                             [str rangeOfString:m_substr].location == [str length] - [m_substr length];
2989                 }
2990 
toStringCatch::Matchers::Impl::NSStringMatchers::EndsWith2991                 virtual std::string toString() const {
2992                     return "ends with: " + Catch::toString( m_substr );
2993                 }
2994             };
2995 
2996         } // namespace NSStringMatchers
2997         } // namespace Impl
2998 
2999         inline Impl::NSStringMatchers::Equals
Equals(NSString * substr)3000             Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
3001 
3002         inline Impl::NSStringMatchers::Contains
Contains(NSString * substr)3003             Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
3004 
3005         inline Impl::NSStringMatchers::StartsWith
StartsWith(NSString * substr)3006             StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
3007 
3008         inline Impl::NSStringMatchers::EndsWith
EndsWith(NSString * substr)3009             EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
3010 
3011     } // namespace Matchers
3012 
3013     using namespace Matchers;
3014 
3015 } // namespace Catch
3016 
3017 ///////////////////////////////////////////////////////////////////////////////
3018 #define OC_TEST_CASE( name, desc )\
3019 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
3020 {\
3021 return @ name; \
3022 }\
3023 +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
3024 { \
3025 return @ desc; \
3026 } \
3027 -(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
3028 
3029 #endif
3030 
3031 #ifdef CATCH_IMPL
3032 // #included from: internal/catch_impl.hpp
3033 #define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
3034 
3035 // Collect all the implementation files together here
3036 // These are the equivalent of what would usually be cpp files
3037 
3038 #ifdef __clang__
3039 #pragma clang diagnostic push
3040 #pragma clang diagnostic ignored "-Wweak-vtables"
3041 #endif
3042 
3043 // #included from: ../catch_session.hpp
3044 #define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
3045 
3046 // #included from: internal/catch_commandline.hpp
3047 #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
3048 
3049 // #included from: catch_config.hpp
3050 #define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
3051 
3052 // #included from: catch_test_spec_parser.hpp
3053 #define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
3054 
3055 #ifdef __clang__
3056 #pragma clang diagnostic push
3057 #pragma clang diagnostic ignored "-Wpadded"
3058 #endif
3059 
3060 // #included from: catch_test_spec.hpp
3061 #define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
3062 
3063 #ifdef __clang__
3064 #pragma clang diagnostic push
3065 #pragma clang diagnostic ignored "-Wpadded"
3066 #endif
3067 
3068 // #included from: catch_wildcard_pattern.hpp
3069 #define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED
3070 
3071 namespace Catch
3072 {
3073     class WildcardPattern {
3074         enum WildcardPosition {
3075             NoWildcard = 0,
3076             WildcardAtStart = 1,
3077             WildcardAtEnd = 2,
3078             WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
3079         };
3080 
3081     public:
3082 
WildcardPattern(std::string const & pattern,CaseSensitive::Choice caseSensitivity)3083         WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity )
3084         :   m_caseSensitivity( caseSensitivity ),
3085             m_wildcard( NoWildcard ),
3086             m_pattern( adjustCase( pattern ) )
3087         {
3088             if( startsWith( m_pattern, "*" ) ) {
3089                 m_pattern = m_pattern.substr( 1 );
3090                 m_wildcard = WildcardAtStart;
3091             }
3092             if( endsWith( m_pattern, "*" ) ) {
3093                 m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
3094                 m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
3095             }
3096         }
3097         virtual ~WildcardPattern();
matches(std::string const & str) const3098         virtual bool matches( std::string const& str ) const {
3099             switch( m_wildcard ) {
3100                 case NoWildcard:
3101                     return m_pattern == adjustCase( str );
3102                 case WildcardAtStart:
3103                     return endsWith( adjustCase( str ), m_pattern );
3104                 case WildcardAtEnd:
3105                     return startsWith( adjustCase( str ), m_pattern );
3106                 case WildcardAtBothEnds:
3107                     return contains( adjustCase( str ), m_pattern );
3108             }
3109 
3110 #ifdef __clang__
3111 #pragma clang diagnostic push
3112 #pragma clang diagnostic ignored "-Wunreachable-code"
3113 #endif
3114             throw std::logic_error( "Unknown enum" );
3115 #ifdef __clang__
3116 #pragma clang diagnostic pop
3117 #endif
3118         }
3119     private:
adjustCase(std::string const & str) const3120         std::string adjustCase( std::string const& str ) const {
3121             return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
3122         }
3123         CaseSensitive::Choice m_caseSensitivity;
3124         WildcardPosition m_wildcard;
3125         std::string m_pattern;
3126     };
3127 }
3128 
3129 #include <string>
3130 #include <vector>
3131 
3132 namespace Catch {
3133 
3134     class TestSpec {
3135         struct Pattern : SharedImpl<> {
3136             virtual ~Pattern();
3137             virtual bool matches( TestCaseInfo const& testCase ) const = 0;
3138         };
3139         class NamePattern : public Pattern {
3140         public:
NamePattern(std::string const & name)3141             NamePattern( std::string const& name )
3142             : m_wildcardPattern( toLower( name ), CaseSensitive::No )
3143             {}
3144             virtual ~NamePattern();
matches(TestCaseInfo const & testCase) const3145             virtual bool matches( TestCaseInfo const& testCase ) const {
3146                 return m_wildcardPattern.matches( toLower( testCase.name ) );
3147             }
3148         private:
3149             WildcardPattern m_wildcardPattern;
3150         };
3151 
3152         class TagPattern : public Pattern {
3153         public:
TagPattern(std::string const & tag)3154             TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
3155             virtual ~TagPattern();
matches(TestCaseInfo const & testCase) const3156             virtual bool matches( TestCaseInfo const& testCase ) const {
3157                 return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
3158             }
3159         private:
3160             std::string m_tag;
3161         };
3162 
3163         class ExcludedPattern : public Pattern {
3164         public:
ExcludedPattern(Ptr<Pattern> const & underlyingPattern)3165             ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
3166             virtual ~ExcludedPattern();
matches(TestCaseInfo const & testCase) const3167             virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
3168         private:
3169             Ptr<Pattern> m_underlyingPattern;
3170         };
3171 
3172         struct Filter {
3173             std::vector<Ptr<Pattern> > m_patterns;
3174 
matchesCatch::TestSpec::Filter3175             bool matches( TestCaseInfo const& testCase ) const {
3176                 // All patterns in a filter must match for the filter to be a match
3177                 for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it )
3178                     if( !(*it)->matches( testCase ) )
3179                         return false;
3180                     return true;
3181             }
3182         };
3183 
3184     public:
hasFilters() const3185         bool hasFilters() const {
3186             return !m_filters.empty();
3187         }
matches(TestCaseInfo const & testCase) const3188         bool matches( TestCaseInfo const& testCase ) const {
3189             // A TestSpec matches if any filter matches
3190             for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
3191                 if( it->matches( testCase ) )
3192                     return true;
3193             return false;
3194         }
3195 
3196     private:
3197         std::vector<Filter> m_filters;
3198 
3199         friend class TestSpecParser;
3200     };
3201 }
3202 
3203 #ifdef __clang__
3204 #pragma clang diagnostic pop
3205 #endif
3206 
3207 namespace Catch {
3208 
3209     class TestSpecParser {
3210         enum Mode{ None, Name, QuotedName, Tag };
3211         Mode m_mode;
3212         bool m_exclusion;
3213         std::size_t m_start, m_pos;
3214         std::string m_arg;
3215         TestSpec::Filter m_currentFilter;
3216         TestSpec m_testSpec;
3217         ITagAliasRegistry const* m_tagAliases;
3218 
3219     public:
TestSpecParser(ITagAliasRegistry const & tagAliases)3220         TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
3221 
parse(std::string const & arg)3222         TestSpecParser& parse( std::string const& arg ) {
3223             m_mode = None;
3224             m_exclusion = false;
3225             m_start = std::string::npos;
3226             m_arg = m_tagAliases->expandAliases( arg );
3227             for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
3228                 visitChar( m_arg[m_pos] );
3229             if( m_mode == Name )
3230                 addPattern<TestSpec::NamePattern>();
3231             return *this;
3232         }
testSpec()3233         TestSpec testSpec() {
3234             addFilter();
3235             return m_testSpec;
3236         }
3237     private:
visitChar(char c)3238         void visitChar( char c ) {
3239             if( m_mode == None ) {
3240                 switch( c ) {
3241                 case ' ': return;
3242                 case '~': m_exclusion = true; return;
3243                 case '[': return startNewMode( Tag, ++m_pos );
3244                 case '"': return startNewMode( QuotedName, ++m_pos );
3245                 default: startNewMode( Name, m_pos ); break;
3246                 }
3247             }
3248             if( m_mode == Name ) {
3249                 if( c == ',' ) {
3250                     addPattern<TestSpec::NamePattern>();
3251                     addFilter();
3252                 }
3253                 else if( c == '[' ) {
3254                     if( subString() == "exclude:" )
3255                         m_exclusion = true;
3256                     else
3257                         addPattern<TestSpec::NamePattern>();
3258                     startNewMode( Tag, ++m_pos );
3259                 }
3260             }
3261             else if( m_mode == QuotedName && c == '"' )
3262                 addPattern<TestSpec::NamePattern>();
3263             else if( m_mode == Tag && c == ']' )
3264                 addPattern<TestSpec::TagPattern>();
3265         }
startNewMode(Mode mode,std::size_t start)3266         void startNewMode( Mode mode, std::size_t start ) {
3267             m_mode = mode;
3268             m_start = start;
3269         }
subString() const3270         std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
3271         template<typename T>
addPattern()3272         void addPattern() {
3273             std::string token = subString();
3274             if( startsWith( token, "exclude:" ) ) {
3275                 m_exclusion = true;
3276                 token = token.substr( 8 );
3277             }
3278             if( !token.empty() ) {
3279                 Ptr<TestSpec::Pattern> pattern = new T( token );
3280                 if( m_exclusion )
3281                     pattern = new TestSpec::ExcludedPattern( pattern );
3282                 m_currentFilter.m_patterns.push_back( pattern );
3283             }
3284             m_exclusion = false;
3285             m_mode = None;
3286         }
addFilter()3287         void addFilter() {
3288             if( !m_currentFilter.m_patterns.empty() ) {
3289                 m_testSpec.m_filters.push_back( m_currentFilter );
3290                 m_currentFilter = TestSpec::Filter();
3291             }
3292         }
3293     };
parseTestSpec(std::string const & arg)3294     inline TestSpec parseTestSpec( std::string const& arg ) {
3295         return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
3296     }
3297 
3298 } // namespace Catch
3299 
3300 #ifdef __clang__
3301 #pragma clang diagnostic pop
3302 #endif
3303 
3304 // #included from: catch_interfaces_config.h
3305 #define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
3306 
3307 #include <iostream>
3308 #include <string>
3309 #include <vector>
3310 
3311 namespace Catch {
3312 
3313     struct Verbosity { enum Level {
3314         NoOutput = 0,
3315         Quiet,
3316         Normal
3317     }; };
3318 
3319     struct WarnAbout { enum What {
3320         Nothing = 0x00,
3321         NoAssertions = 0x01
3322     }; };
3323 
3324     struct ShowDurations { enum OrNot {
3325         DefaultForReporter,
3326         Always,
3327         Never
3328     }; };
3329     struct RunTests { enum InWhatOrder {
3330         InDeclarationOrder,
3331         InLexicographicalOrder,
3332         InRandomOrder
3333     }; };
3334 
3335     class TestSpec;
3336 
3337     struct IConfig : IShared {
3338 
3339         virtual ~IConfig();
3340 
3341         virtual bool allowThrows() const = 0;
3342         virtual std::ostream& stream() const = 0;
3343         virtual std::string name() const = 0;
3344         virtual bool includeSuccessfulResults() const = 0;
3345         virtual bool shouldDebugBreak() const = 0;
3346         virtual bool warnAboutMissingAssertions() const = 0;
3347         virtual int abortAfter() const = 0;
3348         virtual bool showInvisibles() const = 0;
3349         virtual ShowDurations::OrNot showDurations() const = 0;
3350         virtual TestSpec const& testSpec() const = 0;
3351         virtual RunTests::InWhatOrder runOrder() const = 0;
3352         virtual unsigned int rngSeed() const = 0;
3353         virtual bool forceColour() const = 0;
3354     };
3355 }
3356 
3357 // #included from: catch_stream.h
3358 #define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
3359 
3360 // #included from: catch_streambuf.h
3361 #define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
3362 
3363 #include <streambuf>
3364 
3365 namespace Catch {
3366 
3367     class StreamBufBase : public std::streambuf {
3368     public:
3369         virtual ~StreamBufBase() CATCH_NOEXCEPT;
3370     };
3371 }
3372 
3373 #include <streambuf>
3374 #include <ostream>
3375 #include <fstream>
3376 
3377 namespace Catch {
3378 
3379     std::ostream& cout();
3380     std::ostream& cerr();
3381 
3382     struct IStream {
3383         virtual ~IStream() CATCH_NOEXCEPT;
3384         virtual std::ostream& stream() const = 0;
3385     };
3386 
3387     class FileStream : public IStream {
3388         mutable std::ofstream m_ofs;
3389     public:
3390         FileStream( std::string const& filename );
3391         virtual ~FileStream() CATCH_NOEXCEPT;
3392     public: // IStream
3393         virtual std::ostream& stream() const CATCH_OVERRIDE;
3394     };
3395 
3396     class CoutStream : public IStream {
3397         mutable std::ostream m_os;
3398     public:
3399         CoutStream();
3400         virtual ~CoutStream() CATCH_NOEXCEPT;
3401 
3402     public: // IStream
3403         virtual std::ostream& stream() const CATCH_OVERRIDE;
3404     };
3405 
3406     class DebugOutStream : public IStream {
3407         std::auto_ptr<StreamBufBase> m_streamBuf;
3408         mutable std::ostream m_os;
3409     public:
3410         DebugOutStream();
3411         virtual ~DebugOutStream() CATCH_NOEXCEPT;
3412 
3413     public: // IStream
3414         virtual std::ostream& stream() const CATCH_OVERRIDE;
3415     };
3416 }
3417 
3418 #include <memory>
3419 #include <vector>
3420 #include <string>
3421 #include <iostream>
3422 #include <ctime>
3423 
3424 #ifndef CATCH_CONFIG_CONSOLE_WIDTH
3425 #define CATCH_CONFIG_CONSOLE_WIDTH 80
3426 #endif
3427 
3428 namespace Catch {
3429 
3430     struct ConfigData {
3431 
ConfigDataCatch::ConfigData3432         ConfigData()
3433         :   listTests( false ),
3434             listTags( false ),
3435             listReporters( false ),
3436             listTestNamesOnly( false ),
3437             showSuccessfulTests( false ),
3438             shouldDebugBreak( false ),
3439             noThrow( false ),
3440             showHelp( false ),
3441             showInvisibles( false ),
3442             forceColour( false ),
3443             filenamesAsTags( false ),
3444             abortAfter( -1 ),
3445             rngSeed( 0 ),
3446             verbosity( Verbosity::Normal ),
3447             warnings( WarnAbout::Nothing ),
3448             showDurations( ShowDurations::DefaultForReporter ),
3449             runOrder( RunTests::InDeclarationOrder )
3450         {}
3451 
3452         bool listTests;
3453         bool listTags;
3454         bool listReporters;
3455         bool listTestNamesOnly;
3456 
3457         bool showSuccessfulTests;
3458         bool shouldDebugBreak;
3459         bool noThrow;
3460         bool showHelp;
3461         bool showInvisibles;
3462         bool forceColour;
3463         bool filenamesAsTags;
3464 
3465         int abortAfter;
3466         unsigned int rngSeed;
3467 
3468         Verbosity::Level verbosity;
3469         WarnAbout::What warnings;
3470         ShowDurations::OrNot showDurations;
3471         RunTests::InWhatOrder runOrder;
3472 
3473         std::string outputFilename;
3474         std::string name;
3475         std::string processName;
3476 
3477         std::vector<std::string> reporterNames;
3478         std::vector<std::string> testsOrTags;
3479     };
3480 
3481     class Config : public SharedImpl<IConfig> {
3482     private:
3483         Config( Config const& other );
3484         Config& operator = ( Config const& other );
3485         virtual void dummy();
3486     public:
3487 
Config()3488         Config()
3489         {}
3490 
Config(ConfigData const & data)3491         Config( ConfigData const& data )
3492         :   m_data( data ),
3493             m_stream( openStream() )
3494         {
3495             if( !data.testsOrTags.empty() ) {
3496                 TestSpecParser parser( ITagAliasRegistry::get() );
3497                 for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
3498                     parser.parse( data.testsOrTags[i] );
3499                 m_testSpec = parser.testSpec();
3500             }
3501         }
3502 
~Config()3503         virtual ~Config() {
3504         }
3505 
getFilename() const3506         std::string const& getFilename() const {
3507             return m_data.outputFilename ;
3508         }
3509 
listTests() const3510         bool listTests() const { return m_data.listTests; }
listTestNamesOnly() const3511         bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
listTags() const3512         bool listTags() const { return m_data.listTags; }
listReporters() const3513         bool listReporters() const { return m_data.listReporters; }
3514 
getProcessName() const3515         std::string getProcessName() const { return m_data.processName; }
3516 
shouldDebugBreak() const3517         bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
3518 
getReporterNames() const3519         std::vector<std::string> getReporterNames() const { return m_data.reporterNames; }
3520 
abortAfter() const3521         int abortAfter() const { return m_data.abortAfter; }
3522 
testSpec() const3523         TestSpec const& testSpec() const { return m_testSpec; }
3524 
showHelp() const3525         bool showHelp() const { return m_data.showHelp; }
showInvisibles() const3526         bool showInvisibles() const { return m_data.showInvisibles; }
3527 
3528         // IConfig interface
allowThrows() const3529         virtual bool allowThrows() const        { return !m_data.noThrow; }
stream() const3530         virtual std::ostream& stream() const    { return m_stream->stream(); }
name() const3531         virtual std::string name() const        { return m_data.name.empty() ? m_data.processName : m_data.name; }
includeSuccessfulResults() const3532         virtual bool includeSuccessfulResults() const   { return m_data.showSuccessfulTests; }
warnAboutMissingAssertions() const3533         virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
showDurations() const3534         virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
runOrder() const3535         virtual RunTests::InWhatOrder runOrder() const  { return m_data.runOrder; }
rngSeed() const3536         virtual unsigned int rngSeed() const    { return m_data.rngSeed; }
forceColour() const3537         virtual bool forceColour() const { return m_data.forceColour; }
3538 
3539     private:
3540 
openStream()3541         IStream const* openStream() {
3542             if( m_data.outputFilename.empty() )
3543                 return new CoutStream();
3544             else if( m_data.outputFilename[0] == '%' ) {
3545                 if( m_data.outputFilename == "%debug" )
3546                     return new DebugOutStream();
3547                 else
3548                     throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename );
3549             }
3550             else
3551                 return new FileStream( m_data.outputFilename );
3552         }
3553         ConfigData m_data;
3554 
3555         std::auto_ptr<IStream const> m_stream;
3556         TestSpec m_testSpec;
3557     };
3558 
3559 } // end namespace Catch
3560 
3561 // #included from: catch_clara.h
3562 #define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
3563 
3564 // Use Catch's value for console width (store Clara's off to the side, if present)
3565 #ifdef CLARA_CONFIG_CONSOLE_WIDTH
3566 #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
3567 #undef CLARA_CONFIG_CONSOLE_WIDTH
3568 #endif
3569 #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
3570 
3571 // Declare Clara inside the Catch namespace
3572 #define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
3573 // #included from: ../external/clara.h
3574 
3575 // Only use header guard if we are not using an outer namespace
3576 #if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
3577 
3578 #ifndef STITCH_CLARA_OPEN_NAMESPACE
3579 #define TWOBLUECUBES_CLARA_H_INCLUDED
3580 #define STITCH_CLARA_OPEN_NAMESPACE
3581 #define STITCH_CLARA_CLOSE_NAMESPACE
3582 #else
3583 #define STITCH_CLARA_CLOSE_NAMESPACE }
3584 #endif
3585 
3586 #define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
3587 
3588 // ----------- #included from tbc_text_format.h -----------
3589 
3590 // Only use header guard if we are not using an outer namespace
3591 #if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
3592 #ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
3593 #define TBC_TEXT_FORMAT_H_INCLUDED
3594 #endif
3595 
3596 #include <string>
3597 #include <vector>
3598 #include <sstream>
3599 
3600 // Use optional outer namespace
3601 #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
3602 namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
3603 #endif
3604 
3605 namespace Tbc {
3606 
3607 #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
3608     const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
3609 #else
3610     const unsigned int consoleWidth = 80;
3611 #endif
3612 
3613     struct TextAttributes {
TextAttributesSTITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes3614         TextAttributes()
3615         :   initialIndent( std::string::npos ),
3616             indent( 0 ),
3617             width( consoleWidth-1 ),
3618             tabChar( '\t' )
3619         {}
3620 
setInitialIndentSTITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes3621         TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; }
setIndentSTITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes3622         TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; }
setWidthSTITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes3623         TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; }
setTabCharSTITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes3624         TextAttributes& setTabChar( char _value )               { tabChar = _value; return *this; }
3625 
3626         std::size_t initialIndent;  // indent of first line, or npos
3627         std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos
3628         std::size_t width;          // maximum width of text, including indent. Longer text will wrap
3629         char tabChar;               // If this char is seen the indent is changed to current pos
3630     };
3631 
3632     class Text {
3633     public:
Text(std::string const & _str,TextAttributes const & _attr=TextAttributes ())3634         Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
3635         : attr( _attr )
3636         {
3637             std::string wrappableChars = " [({.,/|\\-";
3638             std::size_t indent = _attr.initialIndent != std::string::npos
3639                 ? _attr.initialIndent
3640                 : _attr.indent;
3641             std::string remainder = _str;
3642 
3643             while( !remainder.empty() ) {
3644                 if( lines.size() >= 1000 ) {
3645                     lines.push_back( "... message truncated due to excessive size" );
3646                     return;
3647                 }
3648                 std::size_t tabPos = std::string::npos;
3649                 std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
3650                 std::size_t pos = remainder.find_first_of( '\n' );
3651                 if( pos <= width ) {
3652                     width = pos;
3653                 }
3654                 pos = remainder.find_last_of( _attr.tabChar, width );
3655                 if( pos != std::string::npos ) {
3656                     tabPos = pos;
3657                     if( remainder[width] == '\n' )
3658                         width--;
3659                     remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
3660                 }
3661 
3662                 if( width == remainder.size() ) {
3663                     spliceLine( indent, remainder, width );
3664                 }
3665                 else if( remainder[width] == '\n' ) {
3666                     spliceLine( indent, remainder, width );
3667                     if( width <= 1 || remainder.size() != 1 )
3668                         remainder = remainder.substr( 1 );
3669                     indent = _attr.indent;
3670                 }
3671                 else {
3672                     pos = remainder.find_last_of( wrappableChars, width );
3673                     if( pos != std::string::npos && pos > 0 ) {
3674                         spliceLine( indent, remainder, pos );
3675                         if( remainder[0] == ' ' )
3676                             remainder = remainder.substr( 1 );
3677                     }
3678                     else {
3679                         spliceLine( indent, remainder, width-1 );
3680                         lines.back() += "-";
3681                     }
3682                     if( lines.size() == 1 )
3683                         indent = _attr.indent;
3684                     if( tabPos != std::string::npos )
3685                         indent += tabPos;
3686                 }
3687             }
3688         }
3689 
spliceLine(std::size_t _indent,std::string & _remainder,std::size_t _pos)3690         void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
3691             lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
3692             _remainder = _remainder.substr( _pos );
3693         }
3694 
3695         typedef std::vector<std::string>::const_iterator const_iterator;
3696 
begin() const3697         const_iterator begin() const { return lines.begin(); }
end() const3698         const_iterator end() const { return lines.end(); }
last() const3699         std::string const& last() const { return lines.back(); }
size() const3700         std::size_t size() const { return lines.size(); }
operator [](std::size_t _index) const3701         std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
toString() const3702         std::string toString() const {
3703             std::ostringstream oss;
3704             oss << *this;
3705             return oss.str();
3706         }
3707 
operator <<(std::ostream & _stream,Text const & _text)3708         inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
3709             for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
3710                 it != itEnd; ++it ) {
3711                 if( it != _text.begin() )
3712                     _stream << "\n";
3713                 _stream << *it;
3714             }
3715             return _stream;
3716         }
3717 
3718     private:
3719         std::string str;
3720         TextAttributes attr;
3721         std::vector<std::string> lines;
3722     };
3723 
3724 } // end namespace Tbc
3725 
3726 #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
3727 } // end outer namespace
3728 #endif
3729 
3730 #endif // TBC_TEXT_FORMAT_H_INCLUDED
3731 
3732 // ----------- end of #include from tbc_text_format.h -----------
3733 // ........... back in /Users/philnash/Dev/OSS/Clara/srcs/clara.h
3734 
3735 #undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
3736 
3737 #include <map>
3738 #include <algorithm>
3739 #include <stdexcept>
3740 #include <memory>
3741 
3742 // Use optional outer namespace
3743 #ifdef STITCH_CLARA_OPEN_NAMESPACE
3744 STITCH_CLARA_OPEN_NAMESPACE
3745 #endif
3746 
3747 namespace Clara {
3748 
3749     struct UnpositionalTag {};
3750 
3751     extern UnpositionalTag _;
3752 
3753 #ifdef CLARA_CONFIG_MAIN
3754     UnpositionalTag _;
3755 #endif
3756 
3757     namespace Detail {
3758 
3759 #ifdef CLARA_CONSOLE_WIDTH
3760     const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
3761 #else
3762     const unsigned int consoleWidth = 80;
3763 #endif
3764 
3765         using namespace Tbc;
3766 
startsWith(std::string const & str,std::string const & prefix)3767         inline bool startsWith( std::string const& str, std::string const& prefix ) {
3768             return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
3769         }
3770 
3771         template<typename T> struct RemoveConstRef{ typedef T type; };
3772         template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
3773         template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
3774         template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
3775 
3776         template<typename T>    struct IsBool       { static const bool value = false; };
3777         template<>              struct IsBool<bool> { static const bool value = true; };
3778 
3779         template<typename T>
convertInto(std::string const & _source,T & _dest)3780         void convertInto( std::string const& _source, T& _dest ) {
3781             std::stringstream ss;
3782             ss << _source;
3783             ss >> _dest;
3784             if( ss.fail() )
3785                 throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
3786         }
convertInto(std::string const & _source,std::string & _dest)3787         inline void convertInto( std::string const& _source, std::string& _dest ) {
3788             _dest = _source;
3789         }
convertInto(std::string const & _source,bool & _dest)3790         inline void convertInto( std::string const& _source, bool& _dest ) {
3791             std::string sourceLC = _source;
3792             std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
3793             if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
3794                 _dest = true;
3795             else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
3796                 _dest = false;
3797             else
3798                 throw std::runtime_error( "Expected a boolean value but did not recognise:\n  '" + _source + "'" );
3799         }
convertInto(bool _source,bool & _dest)3800         inline void convertInto( bool _source, bool& _dest ) {
3801             _dest = _source;
3802         }
3803         template<typename T>
convertInto(bool,T &)3804         inline void convertInto( bool, T& ) {
3805             throw std::runtime_error( "Invalid conversion" );
3806         }
3807 
3808         template<typename ConfigT>
3809         struct IArgFunction {
~IArgFunctionClara::Detail::IArgFunction3810             virtual ~IArgFunction() {}
3811 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
3812             IArgFunction()                      = default;
3813             IArgFunction( IArgFunction const& ) = default;
3814 #  endif
3815             virtual void set( ConfigT& config, std::string const& value ) const = 0;
3816             virtual void setFlag( ConfigT& config ) const = 0;
3817             virtual bool takesArg() const = 0;
3818             virtual IArgFunction* clone() const = 0;
3819         };
3820 
3821         template<typename ConfigT>
3822         class BoundArgFunction {
3823         public:
BoundArgFunction()3824             BoundArgFunction() : functionObj( CATCH_NULL ) {}
BoundArgFunction(IArgFunction<ConfigT> * _functionObj)3825             BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
BoundArgFunction(BoundArgFunction const & other)3826             BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CATCH_NULL ) {}
operator =(BoundArgFunction const & other)3827             BoundArgFunction& operator = ( BoundArgFunction const& other ) {
3828                 IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : CATCH_NULL;
3829                 delete functionObj;
3830                 functionObj = newFunctionObj;
3831                 return *this;
3832             }
~BoundArgFunction()3833             ~BoundArgFunction() { delete functionObj; }
3834 
set(ConfigT & config,std::string const & value) const3835             void set( ConfigT& config, std::string const& value ) const {
3836                 functionObj->set( config, value );
3837             }
setFlag(ConfigT & config) const3838             void setFlag( ConfigT& config ) const {
3839                 functionObj->setFlag( config );
3840             }
takesArg() const3841             bool takesArg() const { return functionObj->takesArg(); }
3842 
isSet() const3843             bool isSet() const {
3844                 return functionObj != CATCH_NULL;
3845             }
3846         private:
3847             IArgFunction<ConfigT>* functionObj;
3848         };
3849 
3850         template<typename C>
3851         struct NullBinder : IArgFunction<C>{
setClara::Detail::NullBinder3852             virtual void set( C&, std::string const& ) const {}
setFlagClara::Detail::NullBinder3853             virtual void setFlag( C& ) const {}
takesArgClara::Detail::NullBinder3854             virtual bool takesArg() const { return true; }
cloneClara::Detail::NullBinder3855             virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
3856         };
3857 
3858         template<typename C, typename M>
3859         struct BoundDataMember : IArgFunction<C>{
BoundDataMemberClara::Detail::BoundDataMember3860             BoundDataMember( M C::* _member ) : member( _member ) {}
setClara::Detail::BoundDataMember3861             virtual void set( C& p, std::string const& stringValue ) const {
3862                 convertInto( stringValue, p.*member );
3863             }
setFlagClara::Detail::BoundDataMember3864             virtual void setFlag( C& p ) const {
3865                 convertInto( true, p.*member );
3866             }
takesArgClara::Detail::BoundDataMember3867             virtual bool takesArg() const { return !IsBool<M>::value; }
cloneClara::Detail::BoundDataMember3868             virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
3869             M C::* member;
3870         };
3871         template<typename C, typename M>
3872         struct BoundUnaryMethod : IArgFunction<C>{
BoundUnaryMethodClara::Detail::BoundUnaryMethod3873             BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
setClara::Detail::BoundUnaryMethod3874             virtual void set( C& p, std::string const& stringValue ) const {
3875                 typename RemoveConstRef<M>::type value;
3876                 convertInto( stringValue, value );
3877                 (p.*member)( value );
3878             }
setFlagClara::Detail::BoundUnaryMethod3879             virtual void setFlag( C& p ) const {
3880                 typename RemoveConstRef<M>::type value;
3881                 convertInto( true, value );
3882                 (p.*member)( value );
3883             }
takesArgClara::Detail::BoundUnaryMethod3884             virtual bool takesArg() const { return !IsBool<M>::value; }
cloneClara::Detail::BoundUnaryMethod3885             virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
3886             void (C::*member)( M );
3887         };
3888         template<typename C>
3889         struct BoundNullaryMethod : IArgFunction<C>{
BoundNullaryMethodClara::Detail::BoundNullaryMethod3890             BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
setClara::Detail::BoundNullaryMethod3891             virtual void set( C& p, std::string const& stringValue ) const {
3892                 bool value;
3893                 convertInto( stringValue, value );
3894                 if( value )
3895                     (p.*member)();
3896             }
setFlagClara::Detail::BoundNullaryMethod3897             virtual void setFlag( C& p ) const {
3898                 (p.*member)();
3899             }
takesArgClara::Detail::BoundNullaryMethod3900             virtual bool takesArg() const { return false; }
cloneClara::Detail::BoundNullaryMethod3901             virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
3902             void (C::*member)();
3903         };
3904 
3905         template<typename C>
3906         struct BoundUnaryFunction : IArgFunction<C>{
BoundUnaryFunctionClara::Detail::BoundUnaryFunction3907             BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
setClara::Detail::BoundUnaryFunction3908             virtual void set( C& obj, std::string const& stringValue ) const {
3909                 bool value;
3910                 convertInto( stringValue, value );
3911                 if( value )
3912                     function( obj );
3913             }
setFlagClara::Detail::BoundUnaryFunction3914             virtual void setFlag( C& p ) const {
3915                 function( p );
3916             }
takesArgClara::Detail::BoundUnaryFunction3917             virtual bool takesArg() const { return false; }
cloneClara::Detail::BoundUnaryFunction3918             virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
3919             void (*function)( C& );
3920         };
3921 
3922         template<typename C, typename T>
3923         struct BoundBinaryFunction : IArgFunction<C>{
BoundBinaryFunctionClara::Detail::BoundBinaryFunction3924             BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
setClara::Detail::BoundBinaryFunction3925             virtual void set( C& obj, std::string const& stringValue ) const {
3926                 typename RemoveConstRef<T>::type value;
3927                 convertInto( stringValue, value );
3928                 function( obj, value );
3929             }
setFlagClara::Detail::BoundBinaryFunction3930             virtual void setFlag( C& obj ) const {
3931                 typename RemoveConstRef<T>::type value;
3932                 convertInto( true, value );
3933                 function( obj, value );
3934             }
takesArgClara::Detail::BoundBinaryFunction3935             virtual bool takesArg() const { return !IsBool<T>::value; }
cloneClara::Detail::BoundBinaryFunction3936             virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
3937             void (*function)( C&, T );
3938         };
3939 
3940     } // namespace Detail
3941 
3942     struct Parser {
ParserClara::Parser3943         Parser() : separators( " \t=:" ) {}
3944 
3945         struct Token {
3946             enum Type { Positional, ShortOpt, LongOpt };
TokenClara::Parser::Token3947             Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
3948             Type type;
3949             std::string data;
3950         };
3951 
parseIntoTokensClara::Parser3952         void parseIntoTokens( int argc, char const * const * argv, std::vector<Parser::Token>& tokens ) const {
3953             const std::string doubleDash = "--";
3954             for( int i = 1; i < argc && argv[i] != doubleDash; ++i )
3955                 parseIntoTokens( argv[i] , tokens);
3956         }
parseIntoTokensClara::Parser3957         void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens ) const {
3958             while( !arg.empty() ) {
3959                 Parser::Token token( Parser::Token::Positional, arg );
3960                 arg = "";
3961                 if( token.data[0] == '-' ) {
3962                     if( token.data.size() > 1 && token.data[1] == '-' ) {
3963                         token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) );
3964                     }
3965                     else {
3966                         token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) );
3967                         if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) {
3968                             arg = "-" + token.data.substr( 1 );
3969                             token.data = token.data.substr( 0, 1 );
3970                         }
3971                     }
3972                 }
3973                 if( token.type != Parser::Token::Positional ) {
3974                     std::size_t pos = token.data.find_first_of( separators );
3975                     if( pos != std::string::npos ) {
3976                         arg = token.data.substr( pos+1 );
3977                         token.data = token.data.substr( 0, pos );
3978                     }
3979                 }
3980                 tokens.push_back( token );
3981             }
3982         }
3983         std::string separators;
3984     };
3985 
3986     template<typename ConfigT>
3987     struct CommonArgProperties {
CommonArgPropertiesClara::CommonArgProperties3988         CommonArgProperties() {}
CommonArgPropertiesClara::CommonArgProperties3989         CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}
3990 
3991         Detail::BoundArgFunction<ConfigT> boundField;
3992         std::string description;
3993         std::string detail;
3994         std::string placeholder; // Only value if boundField takes an arg
3995 
takesArgClara::CommonArgProperties3996         bool takesArg() const {
3997             return !placeholder.empty();
3998         }
validateClara::CommonArgProperties3999         void validate() const {
4000             if( !boundField.isSet() )
4001                 throw std::logic_error( "option not bound" );
4002         }
4003     };
4004     struct OptionArgProperties {
4005         std::vector<std::string> shortNames;
4006         std::string longName;
4007 
hasShortNameClara::OptionArgProperties4008         bool hasShortName( std::string const& shortName ) const {
4009             return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
4010         }
hasLongNameClara::OptionArgProperties4011         bool hasLongName( std::string const& _longName ) const {
4012             return _longName == longName;
4013         }
4014     };
4015     struct PositionalArgProperties {
PositionalArgPropertiesClara::PositionalArgProperties4016         PositionalArgProperties() : position( -1 ) {}
4017         int position; // -1 means non-positional (floating)
4018 
isFixedPositionalClara::PositionalArgProperties4019         bool isFixedPositional() const {
4020             return position != -1;
4021         }
4022     };
4023 
4024     template<typename ConfigT>
4025     class CommandLine {
4026 
4027         struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
ArgClara::CommandLine::Arg4028             Arg() {}
ArgClara::CommandLine::Arg4029             Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
4030 
4031             using CommonArgProperties<ConfigT>::placeholder; // !TBD
4032 
dbgNameClara::CommandLine::Arg4033             std::string dbgName() const {
4034                 if( !longName.empty() )
4035                     return "--" + longName;
4036                 if( !shortNames.empty() )
4037                     return "-" + shortNames[0];
4038                 return "positional args";
4039             }
commandsClara::CommandLine::Arg4040             std::string commands() const {
4041                 std::ostringstream oss;
4042                 bool first = true;
4043                 std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
4044                 for(; it != itEnd; ++it ) {
4045                     if( first )
4046                         first = false;
4047                     else
4048                         oss << ", ";
4049                     oss << "-" << *it;
4050                 }
4051                 if( !longName.empty() ) {
4052                     if( !first )
4053                         oss << ", ";
4054                     oss << "--" << longName;
4055                 }
4056                 if( !placeholder.empty() )
4057                     oss << " <" << placeholder << ">";
4058                 return oss.str();
4059             }
4060         };
4061 
4062         typedef CATCH_AUTO_PTR( Arg ) ArgAutoPtr;
4063 
addOptName(Arg & arg,std::string const & optName)4064         friend void addOptName( Arg& arg, std::string const& optName )
4065         {
4066             if( optName.empty() )
4067                 return;
4068             if( Detail::startsWith( optName, "--" ) ) {
4069                 if( !arg.longName.empty() )
4070                     throw std::logic_error( "Only one long opt may be specified. '"
4071                         + arg.longName
4072                         + "' already specified, now attempting to add '"
4073                         + optName + "'" );
4074                 arg.longName = optName.substr( 2 );
4075             }
4076             else if( Detail::startsWith( optName, "-" ) )
4077                 arg.shortNames.push_back( optName.substr( 1 ) );
4078             else
4079                 throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
4080         }
setPositionalArg(Arg & arg,int position)4081         friend void setPositionalArg( Arg& arg, int position )
4082         {
4083             arg.position = position;
4084         }
4085 
4086         class ArgBuilder {
4087         public:
ArgBuilder(Arg * arg)4088             ArgBuilder( Arg* arg ) : m_arg( arg ) {}
4089 
4090             // Bind a non-boolean data member (requires placeholder string)
4091             template<typename C, typename M>
bind(M C::* field,std::string const & placeholder)4092             void bind( M C::* field, std::string const& placeholder ) {
4093                 m_arg->boundField = new Detail::BoundDataMember<C,M>( field );
4094                 m_arg->placeholder = placeholder;
4095             }
4096             // Bind a boolean data member (no placeholder required)
4097             template<typename C>
bind(bool C::* field)4098             void bind( bool C::* field ) {
4099                 m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );
4100             }
4101 
4102             // Bind a method taking a single, non-boolean argument (requires a placeholder string)
4103             template<typename C, typename M>
bind(void (C::* unaryMethod)(M),std::string const & placeholder)4104             void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {
4105                 m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );
4106                 m_arg->placeholder = placeholder;
4107             }
4108 
4109             // Bind a method taking a single, boolean argument (no placeholder string required)
4110             template<typename C>
bind(void (C::* unaryMethod)(bool))4111             void bind( void (C::* unaryMethod)( bool ) ) {
4112                 m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
4113             }
4114 
4115             // Bind a method that takes no arguments (will be called if opt is present)
4116             template<typename C>
bind(void (C::* nullaryMethod)())4117             void bind( void (C::* nullaryMethod)() ) {
4118                 m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );
4119             }
4120 
4121             // Bind a free function taking a single argument - the object to operate on (no placeholder string required)
4122             template<typename C>
bind(void (* unaryFunction)(C &))4123             void bind( void (* unaryFunction)( C& ) ) {
4124                 m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );
4125             }
4126 
4127             // Bind a free function taking a single argument - the object to operate on (requires a placeholder string)
4128             template<typename C, typename T>
bind(void (* binaryFunction)(C &,T),std::string const & placeholder)4129             void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {
4130                 m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );
4131                 m_arg->placeholder = placeholder;
4132             }
4133 
describe(std::string const & description)4134             ArgBuilder& describe( std::string const& description ) {
4135                 m_arg->description = description;
4136                 return *this;
4137             }
detail(std::string const & _detail)4138             ArgBuilder& detail( std::string const& _detail ) {
4139                 m_arg->detail = _detail;
4140                 return *this;
4141             }
4142 
4143         protected:
4144             Arg* m_arg;
4145         };
4146 
4147         class OptBuilder : public ArgBuilder {
4148         public:
OptBuilder(Arg * arg)4149             OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
OptBuilder(OptBuilder & other)4150             OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
4151 
operator [](std::string const & optName)4152             OptBuilder& operator[]( std::string const& optName ) {
4153                 addOptName( *ArgBuilder::m_arg, optName );
4154                 return *this;
4155             }
4156         };
4157 
4158     public:
4159 
CommandLine()4160         CommandLine()
4161         :   m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
4162             m_highestSpecifiedArgPosition( 0 ),
4163             m_throwOnUnrecognisedTokens( false )
4164         {}
CommandLine(CommandLine const & other)4165         CommandLine( CommandLine const& other )
4166         :   m_boundProcessName( other.m_boundProcessName ),
4167             m_options ( other.m_options ),
4168             m_positionalArgs( other.m_positionalArgs ),
4169             m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
4170             m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
4171         {
4172             if( other.m_floatingArg.get() )
4173                 m_floatingArg.reset( new Arg( *other.m_floatingArg ) );
4174         }
4175 
setThrowOnUnrecognisedTokens(bool shouldThrow=true)4176         CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {
4177             m_throwOnUnrecognisedTokens = shouldThrow;
4178             return *this;
4179         }
4180 
operator [](std::string const & optName)4181         OptBuilder operator[]( std::string const& optName ) {
4182             m_options.push_back( Arg() );
4183             addOptName( m_options.back(), optName );
4184             OptBuilder builder( &m_options.back() );
4185             return builder;
4186         }
4187 
operator [](int position)4188         ArgBuilder operator[]( int position ) {
4189             m_positionalArgs.insert( std::make_pair( position, Arg() ) );
4190             if( position > m_highestSpecifiedArgPosition )
4191                 m_highestSpecifiedArgPosition = position;
4192             setPositionalArg( m_positionalArgs[position], position );
4193             ArgBuilder builder( &m_positionalArgs[position] );
4194             return builder;
4195         }
4196 
4197         // Invoke this with the _ instance
operator [](UnpositionalTag)4198         ArgBuilder operator[]( UnpositionalTag ) {
4199             if( m_floatingArg.get() )
4200                 throw std::logic_error( "Only one unpositional argument can be added" );
4201             m_floatingArg.reset( new Arg() );
4202             ArgBuilder builder( m_floatingArg.get() );
4203             return builder;
4204         }
4205 
4206         template<typename C, typename M>
bindProcessName(M C::* field)4207         void bindProcessName( M C::* field ) {
4208             m_boundProcessName = new Detail::BoundDataMember<C,M>( field );
4209         }
4210         template<typename C, typename M>
bindProcessName(void (C::* _unaryMethod)(M))4211         void bindProcessName( void (C::*_unaryMethod)( M ) ) {
4212             m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
4213         }
4214 
optUsage(std::ostream & os,std::size_t indent=0,std::size_t width=Detail::consoleWidth) const4215         void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {
4216             typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
4217             std::size_t maxWidth = 0;
4218             for( it = itBegin; it != itEnd; ++it )
4219                 maxWidth = (std::max)( maxWidth, it->commands().size() );
4220 
4221             for( it = itBegin; it != itEnd; ++it ) {
4222                 Detail::Text usageText( it->commands(), Detail::TextAttributes()
4223                                                         .setWidth( maxWidth+indent )
4224                                                         .setIndent( indent ) );
4225                 Detail::Text desc( it->description, Detail::TextAttributes()
4226                                                         .setWidth( width - maxWidth - 3 ) );
4227 
4228                 for( std::size_t i = 0; i < (std::max)( usageText.size(), desc.size() ); ++i ) {
4229                     std::string usageCol = i < usageText.size() ? usageText[i] : "";
4230                     os << usageCol;
4231 
4232                     if( i < desc.size() && !desc[i].empty() )
4233                         os  << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
4234                             << desc[i];
4235                     os << "\n";
4236                 }
4237             }
4238         }
optUsage() const4239         std::string optUsage() const {
4240             std::ostringstream oss;
4241             optUsage( oss );
4242             return oss.str();
4243         }
4244 
argSynopsis(std::ostream & os) const4245         void argSynopsis( std::ostream& os ) const {
4246             for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
4247                 if( i > 1 )
4248                     os << " ";
4249                 typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
4250                 if( it != m_positionalArgs.end() )
4251                     os << "<" << it->second.placeholder << ">";
4252                 else if( m_floatingArg.get() )
4253                     os << "<" << m_floatingArg->placeholder << ">";
4254                 else
4255                     throw std::logic_error( "non consecutive positional arguments with no floating args" );
4256             }
4257             // !TBD No indication of mandatory args
4258             if( m_floatingArg.get() ) {
4259                 if( m_highestSpecifiedArgPosition > 1 )
4260                     os << " ";
4261                 os << "[<" << m_floatingArg->placeholder << "> ...]";
4262             }
4263         }
argSynopsis() const4264         std::string argSynopsis() const {
4265             std::ostringstream oss;
4266             argSynopsis( oss );
4267             return oss.str();
4268         }
4269 
usage(std::ostream & os,std::string const & procName) const4270         void usage( std::ostream& os, std::string const& procName ) const {
4271             validate();
4272             os << "usage:\n  " << procName << " ";
4273             argSynopsis( os );
4274             if( !m_options.empty() ) {
4275                 os << " [options]\n\nwhere options are: \n";
4276                 optUsage( os, 2 );
4277             }
4278             os << "\n";
4279         }
usage(std::string const & procName) const4280         std::string usage( std::string const& procName ) const {
4281             std::ostringstream oss;
4282             usage( oss, procName );
4283             return oss.str();
4284         }
4285 
parse(int argc,char const * const * argv) const4286         ConfigT parse( int argc, char const * const * argv ) const {
4287             ConfigT config;
4288             parseInto( argc, argv, config );
4289             return config;
4290         }
4291 
parseInto(int argc,char const * const * argv,ConfigT & config) const4292         std::vector<Parser::Token> parseInto( int argc, char const * const * argv, ConfigT& config ) const {
4293             std::string processName = argv[0];
4294             std::size_t lastSlash = processName.find_last_of( "/\\" );
4295             if( lastSlash != std::string::npos )
4296                 processName = processName.substr( lastSlash+1 );
4297             m_boundProcessName.set( config, processName );
4298             std::vector<Parser::Token> tokens;
4299             Parser parser;
4300             parser.parseIntoTokens( argc, argv, tokens );
4301             return populate( tokens, config );
4302         }
4303 
populate(std::vector<Parser::Token> const & tokens,ConfigT & config) const4304         std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4305             validate();
4306             std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
4307             unusedTokens = populateFixedArgs( unusedTokens, config );
4308             unusedTokens = populateFloatingArgs( unusedTokens, config );
4309             return unusedTokens;
4310         }
4311 
populateOptions(std::vector<Parser::Token> const & tokens,ConfigT & config) const4312         std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4313             std::vector<Parser::Token> unusedTokens;
4314             std::vector<std::string> errors;
4315             for( std::size_t i = 0; i < tokens.size(); ++i ) {
4316                 Parser::Token const& token = tokens[i];
4317                 typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
4318                 for(; it != itEnd; ++it ) {
4319                     Arg const& arg = *it;
4320 
4321                     try {
4322                         if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
4323                             ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
4324                             if( arg.takesArg() ) {
4325                                 if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
4326                                     errors.push_back( "Expected argument to option: " + token.data );
4327                                 else
4328                                     arg.boundField.set( config, tokens[++i].data );
4329                             }
4330                             else {
4331                                 arg.boundField.setFlag( config );
4332                             }
4333                             break;
4334                         }
4335                     }
4336                     catch( std::exception& ex ) {
4337                         errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
4338                     }
4339                 }
4340                 if( it == itEnd ) {
4341                     if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
4342                         unusedTokens.push_back( token );
4343                     else if( errors.empty() && m_throwOnUnrecognisedTokens )
4344                         errors.push_back( "unrecognised option: " + token.data );
4345                 }
4346             }
4347             if( !errors.empty() ) {
4348                 std::ostringstream oss;
4349                 for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
4350                         it != itEnd;
4351                         ++it ) {
4352                     if( it != errors.begin() )
4353                         oss << "\n";
4354                     oss << *it;
4355                 }
4356                 throw std::runtime_error( oss.str() );
4357             }
4358             return unusedTokens;
4359         }
populateFixedArgs(std::vector<Parser::Token> const & tokens,ConfigT & config) const4360         std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4361             std::vector<Parser::Token> unusedTokens;
4362             int position = 1;
4363             for( std::size_t i = 0; i < tokens.size(); ++i ) {
4364                 Parser::Token const& token = tokens[i];
4365                 typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
4366                 if( it != m_positionalArgs.end() )
4367                     it->second.boundField.set( config, token.data );
4368                 else
4369                     unusedTokens.push_back( token );
4370                 if( token.type == Parser::Token::Positional )
4371                     position++;
4372             }
4373             return unusedTokens;
4374         }
populateFloatingArgs(std::vector<Parser::Token> const & tokens,ConfigT & config) const4375         std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
4376             if( !m_floatingArg.get() )
4377                 return tokens;
4378             std::vector<Parser::Token> unusedTokens;
4379             for( std::size_t i = 0; i < tokens.size(); ++i ) {
4380                 Parser::Token const& token = tokens[i];
4381                 if( token.type == Parser::Token::Positional )
4382                     m_floatingArg->boundField.set( config, token.data );
4383                 else
4384                     unusedTokens.push_back( token );
4385             }
4386             return unusedTokens;
4387         }
4388 
validate() const4389         void validate() const
4390         {
4391             if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
4392                 throw std::logic_error( "No options or arguments specified" );
4393 
4394             for( typename std::vector<Arg>::const_iterator  it = m_options.begin(),
4395                                                             itEnd = m_options.end();
4396                     it != itEnd; ++it )
4397                 it->validate();
4398         }
4399 
4400     private:
4401         Detail::BoundArgFunction<ConfigT> m_boundProcessName;
4402         std::vector<Arg> m_options;
4403         std::map<int, Arg> m_positionalArgs;
4404         ArgAutoPtr m_floatingArg;
4405         int m_highestSpecifiedArgPosition;
4406         bool m_throwOnUnrecognisedTokens;
4407     };
4408 
4409 } // end namespace Clara
4410 
4411 STITCH_CLARA_CLOSE_NAMESPACE
4412 #undef STITCH_CLARA_OPEN_NAMESPACE
4413 #undef STITCH_CLARA_CLOSE_NAMESPACE
4414 
4415 #endif // TWOBLUECUBES_CLARA_H_INCLUDED
4416 #undef STITCH_CLARA_OPEN_NAMESPACE
4417 
4418 // Restore Clara's value for console width, if present
4419 #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
4420 #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
4421 #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
4422 #endif
4423 
4424 #include <fstream>
4425 
4426 namespace Catch {
4427 
abortAfterFirst(ConfigData & config)4428     inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
abortAfterX(ConfigData & config,int x)4429     inline void abortAfterX( ConfigData& config, int x ) {
4430         if( x < 1 )
4431             throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
4432         config.abortAfter = x;
4433     }
addTestOrTags(ConfigData & config,std::string const & _testSpec)4434     inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
addReporterName(ConfigData & config,std::string const & _reporterName)4435     inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }
4436 
addWarning(ConfigData & config,std::string const & _warning)4437     inline void addWarning( ConfigData& config, std::string const& _warning ) {
4438         if( _warning == "NoAssertions" )
4439             config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
4440         else
4441             throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" );
4442     }
setOrder(ConfigData & config,std::string const & order)4443     inline void setOrder( ConfigData& config, std::string const& order ) {
4444         if( startsWith( "declared", order ) )
4445             config.runOrder = RunTests::InDeclarationOrder;
4446         else if( startsWith( "lexical", order ) )
4447             config.runOrder = RunTests::InLexicographicalOrder;
4448         else if( startsWith( "random", order ) )
4449             config.runOrder = RunTests::InRandomOrder;
4450         else
4451             throw std::runtime_error( "Unrecognised ordering: '" + order + "'" );
4452     }
setRngSeed(ConfigData & config,std::string const & seed)4453     inline void setRngSeed( ConfigData& config, std::string const& seed ) {
4454         if( seed == "time" ) {
4455             config.rngSeed = static_cast<unsigned int>( std::time(0) );
4456         }
4457         else {
4458             std::stringstream ss;
4459             ss << seed;
4460             ss >> config.rngSeed;
4461             if( ss.fail() )
4462                 throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" );
4463         }
4464     }
setVerbosity(ConfigData & config,int level)4465     inline void setVerbosity( ConfigData& config, int level ) {
4466         // !TBD: accept strings?
4467         config.verbosity = static_cast<Verbosity::Level>( level );
4468     }
setShowDurations(ConfigData & config,bool _showDurations)4469     inline void setShowDurations( ConfigData& config, bool _showDurations ) {
4470         config.showDurations = _showDurations
4471             ? ShowDurations::Always
4472             : ShowDurations::Never;
4473     }
loadTestNamesFromFile(ConfigData & config,std::string const & _filename)4474     inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
4475         std::ifstream f( _filename.c_str() );
4476         if( !f.is_open() )
4477             throw std::domain_error( "Unable to load input file: " + _filename );
4478 
4479         std::string line;
4480         while( std::getline( f, line ) ) {
4481             line = trim(line);
4482             if( !line.empty() && !startsWith( line, "#" ) )
4483                 addTestOrTags( config, "\"" + line + "\"," );
4484         }
4485     }
4486 
makeCommandLineParser()4487     inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
4488 
4489         using namespace Clara;
4490         CommandLine<ConfigData> cli;
4491 
4492         cli.bindProcessName( &ConfigData::processName );
4493 
4494         cli["-?"]["-h"]["--help"]
4495             .describe( "display usage information" )
4496             .bind( &ConfigData::showHelp );
4497 
4498         cli["-l"]["--list-tests"]
4499             .describe( "list all/matching test cases" )
4500             .bind( &ConfigData::listTests );
4501 
4502         cli["-t"]["--list-tags"]
4503             .describe( "list all/matching tags" )
4504             .bind( &ConfigData::listTags );
4505 
4506         cli["-s"]["--success"]
4507             .describe( "include successful tests in output" )
4508             .bind( &ConfigData::showSuccessfulTests );
4509 
4510         cli["-b"]["--break"]
4511             .describe( "break into debugger on failure" )
4512             .bind( &ConfigData::shouldDebugBreak );
4513 
4514         cli["-e"]["--nothrow"]
4515             .describe( "skip exception tests" )
4516             .bind( &ConfigData::noThrow );
4517 
4518         cli["-i"]["--invisibles"]
4519             .describe( "show invisibles (tabs, newlines)" )
4520             .bind( &ConfigData::showInvisibles );
4521 
4522         cli["-o"]["--out"]
4523             .describe( "output filename" )
4524             .bind( &ConfigData::outputFilename, "filename" );
4525 
4526         cli["-r"]["--reporter"]
4527 //            .placeholder( "name[:filename]" )
4528             .describe( "reporter to use (defaults to console)" )
4529             .bind( &addReporterName, "name" );
4530 
4531         cli["-n"]["--name"]
4532             .describe( "suite name" )
4533             .bind( &ConfigData::name, "name" );
4534 
4535         cli["-a"]["--abort"]
4536             .describe( "abort at first failure" )
4537             .bind( &abortAfterFirst );
4538 
4539         cli["-x"]["--abortx"]
4540             .describe( "abort after x failures" )
4541             .bind( &abortAfterX, "no. failures" );
4542 
4543         cli["-w"]["--warn"]
4544             .describe( "enable warnings" )
4545             .bind( &addWarning, "warning name" );
4546 
4547 // - needs updating if reinstated
4548 //        cli.into( &setVerbosity )
4549 //            .describe( "level of verbosity (0=no output)" )
4550 //            .shortOpt( "v")
4551 //            .longOpt( "verbosity" )
4552 //            .placeholder( "level" );
4553 
4554         cli[_]
4555             .describe( "which test or tests to use" )
4556             .bind( &addTestOrTags, "test name, pattern or tags" );
4557 
4558         cli["-d"]["--durations"]
4559             .describe( "show test durations" )
4560             .bind( &setShowDurations, "yes/no" );
4561 
4562         cli["-f"]["--input-file"]
4563             .describe( "load test names to run from a file" )
4564             .bind( &loadTestNamesFromFile, "filename" );
4565 
4566         cli["-#"]["--filenames-as-tags"]
4567             .describe( "adds a tag for the filename" )
4568             .bind( &ConfigData::filenamesAsTags );
4569 
4570         // Less common commands which don't have a short form
4571         cli["--list-test-names-only"]
4572             .describe( "list all/matching test cases names only" )
4573             .bind( &ConfigData::listTestNamesOnly );
4574 
4575         cli["--list-reporters"]
4576             .describe( "list all reporters" )
4577             .bind( &ConfigData::listReporters );
4578 
4579         cli["--order"]
4580             .describe( "test case order (defaults to decl)" )
4581             .bind( &setOrder, "decl|lex|rand" );
4582 
4583         cli["--rng-seed"]
4584             .describe( "set a specific seed for random numbers" )
4585             .bind( &setRngSeed, "'time'|number" );
4586 
4587         cli["--force-colour"]
4588             .describe( "force colourised output" )
4589             .bind( &ConfigData::forceColour );
4590 
4591         return cli;
4592     }
4593 
4594 } // end namespace Catch
4595 
4596 // #included from: internal/catch_list.hpp
4597 #define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
4598 
4599 // #included from: catch_text.h
4600 #define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
4601 
4602 #define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
4603 
4604 #define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch
4605 // #included from: ../external/tbc_text_format.h
4606 // Only use header guard if we are not using an outer namespace
4607 #ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4608 # ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
4609 #  ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
4610 #   define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
4611 #  endif
4612 # else
4613 #  define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
4614 # endif
4615 #endif
4616 #ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
4617 #include <string>
4618 #include <vector>
4619 #include <sstream>
4620 
4621 // Use optional outer namespace
4622 #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4623 namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
4624 #endif
4625 
4626 namespace Tbc {
4627 
4628 #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
4629     const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
4630 #else
4631     const unsigned int consoleWidth = 80;
4632 #endif
4633 
4634     struct TextAttributes {
TextAttributesCLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes4635         TextAttributes()
4636         :   initialIndent( std::string::npos ),
4637             indent( 0 ),
4638             width( consoleWidth-1 ),
4639             tabChar( '\t' )
4640         {}
4641 
setInitialIndentCLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes4642         TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; }
setIndentCLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes4643         TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; }
setWidthCLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes4644         TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; }
setTabCharCLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE::Tbc::TextAttributes4645         TextAttributes& setTabChar( char _value )               { tabChar = _value; return *this; }
4646 
4647         std::size_t initialIndent;  // indent of first line, or npos
4648         std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos
4649         std::size_t width;          // maximum width of text, including indent. Longer text will wrap
4650         char tabChar;               // If this char is seen the indent is changed to current pos
4651     };
4652 
4653     class Text {
4654     public:
Text(std::string const & _str,TextAttributes const & _attr=TextAttributes ())4655         Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
4656         : attr( _attr )
4657         {
4658             std::string wrappableChars = " [({.,/|\\-";
4659             std::size_t indent = _attr.initialIndent != std::string::npos
4660                 ? _attr.initialIndent
4661                 : _attr.indent;
4662             std::string remainder = _str;
4663 
4664             while( !remainder.empty() ) {
4665                 if( lines.size() >= 1000 ) {
4666                     lines.push_back( "... message truncated due to excessive size" );
4667                     return;
4668                 }
4669                 std::size_t tabPos = std::string::npos;
4670                 std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
4671                 std::size_t pos = remainder.find_first_of( '\n' );
4672                 if( pos <= width ) {
4673                     width = pos;
4674                 }
4675                 pos = remainder.find_last_of( _attr.tabChar, width );
4676                 if( pos != std::string::npos ) {
4677                     tabPos = pos;
4678                     if( remainder[width] == '\n' )
4679                         width--;
4680                     remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
4681                 }
4682 
4683                 if( width == remainder.size() ) {
4684                     spliceLine( indent, remainder, width );
4685                 }
4686                 else if( remainder[width] == '\n' ) {
4687                     spliceLine( indent, remainder, width );
4688                     if( width <= 1 || remainder.size() != 1 )
4689                         remainder = remainder.substr( 1 );
4690                     indent = _attr.indent;
4691                 }
4692                 else {
4693                     pos = remainder.find_last_of( wrappableChars, width );
4694                     if( pos != std::string::npos && pos > 0 ) {
4695                         spliceLine( indent, remainder, pos );
4696                         if( remainder[0] == ' ' )
4697                             remainder = remainder.substr( 1 );
4698                     }
4699                     else {
4700                         spliceLine( indent, remainder, width-1 );
4701                         lines.back() += "-";
4702                     }
4703                     if( lines.size() == 1 )
4704                         indent = _attr.indent;
4705                     if( tabPos != std::string::npos )
4706                         indent += tabPos;
4707                 }
4708             }
4709         }
4710 
spliceLine(std::size_t _indent,std::string & _remainder,std::size_t _pos)4711         void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
4712             lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
4713             _remainder = _remainder.substr( _pos );
4714         }
4715 
4716         typedef std::vector<std::string>::const_iterator const_iterator;
4717 
begin() const4718         const_iterator begin() const { return lines.begin(); }
end() const4719         const_iterator end() const { return lines.end(); }
last() const4720         std::string const& last() const { return lines.back(); }
size() const4721         std::size_t size() const { return lines.size(); }
operator [](std::size_t _index) const4722         std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
toString() const4723         std::string toString() const {
4724             std::ostringstream oss;
4725             oss << *this;
4726             return oss.str();
4727         }
4728 
operator <<(std::ostream & _stream,Text const & _text)4729         inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
4730             for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
4731                 it != itEnd; ++it ) {
4732                 if( it != _text.begin() )
4733                     _stream << "\n";
4734                 _stream << *it;
4735             }
4736             return _stream;
4737         }
4738 
4739     private:
4740         std::string str;
4741         TextAttributes attr;
4742         std::vector<std::string> lines;
4743     };
4744 
4745 } // end namespace Tbc
4746 
4747 #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4748 } // end outer namespace
4749 #endif
4750 
4751 #endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
4752 #undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
4753 
4754 namespace Catch {
4755     using Tbc::Text;
4756     using Tbc::TextAttributes;
4757 }
4758 
4759 // #included from: catch_console_colour.hpp
4760 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
4761 
4762 namespace Catch {
4763 
4764     struct Colour {
4765         enum Code {
4766             None = 0,
4767 
4768             White,
4769             Red,
4770             Green,
4771             Blue,
4772             Cyan,
4773             Yellow,
4774             Grey,
4775 
4776             Bright = 0x10,
4777 
4778             BrightRed = Bright | Red,
4779             BrightGreen = Bright | Green,
4780             LightGrey = Bright | Grey,
4781             BrightWhite = Bright | White,
4782 
4783             // By intention
4784             FileName = LightGrey,
4785             Warning = Yellow,
4786             ResultError = BrightRed,
4787             ResultSuccess = BrightGreen,
4788             ResultExpectedFailure = Warning,
4789 
4790             Error = BrightRed,
4791             Success = Green,
4792 
4793             OriginalExpression = Cyan,
4794             ReconstructedExpression = Yellow,
4795 
4796             SecondaryText = LightGrey,
4797             Headers = White
4798         };
4799 
4800         // Use constructed object for RAII guard
4801         Colour( Code _colourCode );
4802         Colour( Colour const& other );
4803         ~Colour();
4804 
4805         // Use static method for one-shot changes
4806         static void use( Code _colourCode );
4807 
4808     private:
4809         bool m_moved;
4810     };
4811 
operator <<(std::ostream & os,Colour const &)4812     inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }
4813 
4814 } // end namespace Catch
4815 
4816 // #included from: catch_interfaces_reporter.h
4817 #define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
4818 
4819 #include <string>
4820 #include <ostream>
4821 #include <map>
4822 #include <assert.h>
4823 
4824 namespace Catch
4825 {
4826     struct ReporterConfig {
ReporterConfigCatch::ReporterConfig4827         explicit ReporterConfig( Ptr<IConfig const> const& _fullConfig )
4828         :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
4829 
ReporterConfigCatch::ReporterConfig4830         ReporterConfig( Ptr<IConfig const> const& _fullConfig, std::ostream& _stream )
4831         :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
4832 
streamCatch::ReporterConfig4833         std::ostream& stream() const    { return *m_stream; }
fullConfigCatch::ReporterConfig4834         Ptr<IConfig const> fullConfig() const { return m_fullConfig; }
4835 
4836     private:
4837         std::ostream* m_stream;
4838         Ptr<IConfig const> m_fullConfig;
4839     };
4840 
4841     struct ReporterPreferences {
ReporterPreferencesCatch::ReporterPreferences4842         ReporterPreferences()
4843         : shouldRedirectStdOut( false )
4844         {}
4845 
4846         bool shouldRedirectStdOut;
4847     };
4848 
4849     template<typename T>
4850     struct LazyStat : Option<T> {
LazyStatCatch::LazyStat4851         LazyStat() : used( false ) {}
operator =Catch::LazyStat4852         LazyStat& operator=( T const& _value ) {
4853             Option<T>::operator=( _value );
4854             used = false;
4855             return *this;
4856         }
resetCatch::LazyStat4857         void reset() {
4858             Option<T>::reset();
4859             used = false;
4860         }
4861         bool used;
4862     };
4863 
4864     struct TestRunInfo {
TestRunInfoCatch::TestRunInfo4865         TestRunInfo( std::string const& _name ) : name( _name ) {}
4866         std::string name;
4867     };
4868     struct GroupInfo {
GroupInfoCatch::GroupInfo4869         GroupInfo(  std::string const& _name,
4870                     std::size_t _groupIndex,
4871                     std::size_t _groupsCount )
4872         :   name( _name ),
4873             groupIndex( _groupIndex ),
4874             groupsCounts( _groupsCount )
4875         {}
4876 
4877         std::string name;
4878         std::size_t groupIndex;
4879         std::size_t groupsCounts;
4880     };
4881 
4882     struct AssertionStats {
AssertionStatsCatch::AssertionStats4883         AssertionStats( AssertionResult const& _assertionResult,
4884                         std::vector<MessageInfo> const& _infoMessages,
4885                         Totals const& _totals )
4886         :   assertionResult( _assertionResult ),
4887             infoMessages( _infoMessages ),
4888             totals( _totals )
4889         {
4890             if( assertionResult.hasMessage() ) {
4891                 // Copy message into messages list.
4892                 // !TBD This should have been done earlier, somewhere
4893                 MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
4894                 builder << assertionResult.getMessage();
4895                 builder.m_info.message = builder.m_stream.str();
4896 
4897                 infoMessages.push_back( builder.m_info );
4898             }
4899         }
4900         virtual ~AssertionStats();
4901 
4902 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
4903         AssertionStats( AssertionStats const& )              = default;
4904         AssertionStats( AssertionStats && )                  = default;
4905         AssertionStats& operator = ( AssertionStats const& ) = default;
4906         AssertionStats& operator = ( AssertionStats && )     = default;
4907 #  endif
4908 
4909         AssertionResult assertionResult;
4910         std::vector<MessageInfo> infoMessages;
4911         Totals totals;
4912     };
4913 
4914     struct SectionStats {
SectionStatsCatch::SectionStats4915         SectionStats(   SectionInfo const& _sectionInfo,
4916                         Counts const& _assertions,
4917                         double _durationInSeconds,
4918                         bool _missingAssertions )
4919         :   sectionInfo( _sectionInfo ),
4920             assertions( _assertions ),
4921             durationInSeconds( _durationInSeconds ),
4922             missingAssertions( _missingAssertions )
4923         {}
4924         virtual ~SectionStats();
4925 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
4926         SectionStats( SectionStats const& )              = default;
4927         SectionStats( SectionStats && )                  = default;
4928         SectionStats& operator = ( SectionStats const& ) = default;
4929         SectionStats& operator = ( SectionStats && )     = default;
4930 #  endif
4931 
4932         SectionInfo sectionInfo;
4933         Counts assertions;
4934         double durationInSeconds;
4935         bool missingAssertions;
4936     };
4937 
4938     struct TestCaseStats {
TestCaseStatsCatch::TestCaseStats4939         TestCaseStats(  TestCaseInfo const& _testInfo,
4940                         Totals const& _totals,
4941                         std::string const& _stdOut,
4942                         std::string const& _stdErr,
4943                         bool _aborting )
4944         : testInfo( _testInfo ),
4945             totals( _totals ),
4946             stdOut( _stdOut ),
4947             stdErr( _stdErr ),
4948             aborting( _aborting )
4949         {}
4950         virtual ~TestCaseStats();
4951 
4952 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
4953         TestCaseStats( TestCaseStats const& )              = default;
4954         TestCaseStats( TestCaseStats && )                  = default;
4955         TestCaseStats& operator = ( TestCaseStats const& ) = default;
4956         TestCaseStats& operator = ( TestCaseStats && )     = default;
4957 #  endif
4958 
4959         TestCaseInfo testInfo;
4960         Totals totals;
4961         std::string stdOut;
4962         std::string stdErr;
4963         bool aborting;
4964     };
4965 
4966     struct TestGroupStats {
TestGroupStatsCatch::TestGroupStats4967         TestGroupStats( GroupInfo const& _groupInfo,
4968                         Totals const& _totals,
4969                         bool _aborting )
4970         :   groupInfo( _groupInfo ),
4971             totals( _totals ),
4972             aborting( _aborting )
4973         {}
TestGroupStatsCatch::TestGroupStats4974         TestGroupStats( GroupInfo const& _groupInfo )
4975         :   groupInfo( _groupInfo ),
4976             aborting( false )
4977         {}
4978         virtual ~TestGroupStats();
4979 
4980 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
4981         TestGroupStats( TestGroupStats const& )              = default;
4982         TestGroupStats( TestGroupStats && )                  = default;
4983         TestGroupStats& operator = ( TestGroupStats const& ) = default;
4984         TestGroupStats& operator = ( TestGroupStats && )     = default;
4985 #  endif
4986 
4987         GroupInfo groupInfo;
4988         Totals totals;
4989         bool aborting;
4990     };
4991 
4992     struct TestRunStats {
TestRunStatsCatch::TestRunStats4993         TestRunStats(   TestRunInfo const& _runInfo,
4994                         Totals const& _totals,
4995                         bool _aborting )
4996         :   runInfo( _runInfo ),
4997             totals( _totals ),
4998             aborting( _aborting )
4999         {}
5000         virtual ~TestRunStats();
5001 
5002 #  ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
TestRunStatsCatch::TestRunStats5003         TestRunStats( TestRunStats const& _other )
5004         :   runInfo( _other.runInfo ),
5005             totals( _other.totals ),
5006             aborting( _other.aborting )
5007         {}
5008 #  else
5009         TestRunStats( TestRunStats const& )              = default;
5010         TestRunStats( TestRunStats && )                  = default;
5011         TestRunStats& operator = ( TestRunStats const& ) = default;
5012         TestRunStats& operator = ( TestRunStats && )     = default;
5013 #  endif
5014 
5015         TestRunInfo runInfo;
5016         Totals totals;
5017         bool aborting;
5018     };
5019 
5020     struct IStreamingReporter : IShared {
5021         virtual ~IStreamingReporter();
5022 
5023         // Implementing class must also provide the following static method:
5024         // static std::string getDescription();
5025 
5026         virtual ReporterPreferences getPreferences() const = 0;
5027 
5028         virtual void noMatchingTestCases( std::string const& spec ) = 0;
5029 
5030         virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
5031         virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
5032 
5033         virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
5034         virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
5035 
5036         virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
5037 
5038         // The return value indicates if the messages buffer should be cleared:
5039         virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
5040 
5041         virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
5042         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
5043         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
5044         virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
5045 
5046         virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
5047     };
5048 
5049     struct IReporterFactory : IShared {
5050         virtual ~IReporterFactory();
5051         virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
5052         virtual std::string getDescription() const = 0;
5053     };
5054 
5055     struct IReporterRegistry {
5056         typedef std::map<std::string, Ptr<IReporterFactory> > FactoryMap;
5057         typedef std::vector<Ptr<IReporterFactory> > Listeners;
5058 
5059         virtual ~IReporterRegistry();
5060         virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const = 0;
5061         virtual FactoryMap const& getFactories() const = 0;
5062         virtual Listeners const& getListeners() const = 0;
5063     };
5064 
5065     Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter );
5066 
5067 }
5068 
5069 #include <limits>
5070 #include <algorithm>
5071 
5072 namespace Catch {
5073 
listTests(Config const & config)5074     inline std::size_t listTests( Config const& config ) {
5075 
5076         TestSpec testSpec = config.testSpec();
5077         if( config.testSpec().hasFilters() )
5078             Catch::cout() << "Matching test cases:\n";
5079         else {
5080             Catch::cout() << "All available test cases:\n";
5081             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
5082         }
5083 
5084         std::size_t matchedTests = 0;
5085         TextAttributes nameAttr, tagsAttr;
5086         nameAttr.setInitialIndent( 2 ).setIndent( 4 );
5087         tagsAttr.setIndent( 6 );
5088 
5089         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
5090         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5091                 it != itEnd;
5092                 ++it ) {
5093             matchedTests++;
5094             TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
5095             Colour::Code colour = testCaseInfo.isHidden()
5096                 ? Colour::SecondaryText
5097                 : Colour::None;
5098             Colour colourGuard( colour );
5099 
5100             Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
5101             if( !testCaseInfo.tags.empty() )
5102                 Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
5103         }
5104 
5105         if( !config.testSpec().hasFilters() )
5106             Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl;
5107         else
5108             Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl;
5109         return matchedTests;
5110     }
5111 
listTestsNamesOnly(Config const & config)5112     inline std::size_t listTestsNamesOnly( Config const& config ) {
5113         TestSpec testSpec = config.testSpec();
5114         if( !config.testSpec().hasFilters() )
5115             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
5116         std::size_t matchedTests = 0;
5117         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
5118         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5119                 it != itEnd;
5120                 ++it ) {
5121             matchedTests++;
5122             TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
5123             Catch::cout() << testCaseInfo.name << std::endl;
5124         }
5125         return matchedTests;
5126     }
5127 
5128     struct TagInfo {
TagInfoCatch::TagInfo5129         TagInfo() : count ( 0 ) {}
addCatch::TagInfo5130         void add( std::string const& spelling ) {
5131             ++count;
5132             spellings.insert( spelling );
5133         }
allCatch::TagInfo5134         std::string all() const {
5135             std::string out;
5136             for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
5137                         it != itEnd;
5138                         ++it )
5139                 out += "[" + *it + "]";
5140             return out;
5141         }
5142         std::set<std::string> spellings;
5143         std::size_t count;
5144     };
5145 
listTags(Config const & config)5146     inline std::size_t listTags( Config const& config ) {
5147         TestSpec testSpec = config.testSpec();
5148         if( config.testSpec().hasFilters() )
5149             Catch::cout() << "Tags for matching test cases:\n";
5150         else {
5151             Catch::cout() << "All available tags:\n";
5152             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
5153         }
5154 
5155         std::map<std::string, TagInfo> tagCounts;
5156 
5157         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
5158         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
5159                 it != itEnd;
5160                 ++it ) {
5161             for( std::set<std::string>::const_iterator  tagIt = it->getTestCaseInfo().tags.begin(),
5162                                                         tagItEnd = it->getTestCaseInfo().tags.end();
5163                     tagIt != tagItEnd;
5164                     ++tagIt ) {
5165                 std::string tagName = *tagIt;
5166                 std::string lcaseTagName = toLower( tagName );
5167                 std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
5168                 if( countIt == tagCounts.end() )
5169                     countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
5170                 countIt->second.add( tagName );
5171             }
5172         }
5173 
5174         for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
5175                                                             countItEnd = tagCounts.end();
5176                 countIt != countItEnd;
5177                 ++countIt ) {
5178             std::ostringstream oss;
5179             oss << "  " << std::setw(2) << countIt->second.count << "  ";
5180             Text wrapper( countIt->second.all(), TextAttributes()
5181                                                     .setInitialIndent( 0 )
5182                                                     .setIndent( oss.str().size() )
5183                                                     .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
5184             Catch::cout() << oss.str() << wrapper << "\n";
5185         }
5186         Catch::cout() << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl;
5187         return tagCounts.size();
5188     }
5189 
listReporters(Config const &)5190     inline std::size_t listReporters( Config const& /*config*/ ) {
5191         Catch::cout() << "Available reporters:\n";
5192         IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
5193         IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
5194         std::size_t maxNameLen = 0;
5195         for(it = itBegin; it != itEnd; ++it )
5196             maxNameLen = (std::max)( maxNameLen, it->first.size() );
5197 
5198         for(it = itBegin; it != itEnd; ++it ) {
5199             Text wrapper( it->second->getDescription(), TextAttributes()
5200                                                         .setInitialIndent( 0 )
5201                                                         .setIndent( 7+maxNameLen )
5202                                                         .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
5203             Catch::cout() << "  "
5204                     << it->first
5205                     << ":"
5206                     << std::string( maxNameLen - it->first.size() + 2, ' ' )
5207                     << wrapper << "\n";
5208         }
5209         Catch::cout() << std::endl;
5210         return factories.size();
5211     }
5212 
list(Config const & config)5213     inline Option<std::size_t> list( Config const& config ) {
5214         Option<std::size_t> listedCount;
5215         if( config.listTests() )
5216             listedCount = listedCount.valueOr(0) + listTests( config );
5217         if( config.listTestNamesOnly() )
5218             listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
5219         if( config.listTags() )
5220             listedCount = listedCount.valueOr(0) + listTags( config );
5221         if( config.listReporters() )
5222             listedCount = listedCount.valueOr(0) + listReporters( config );
5223         return listedCount;
5224     }
5225 
5226 } // end namespace Catch
5227 
5228 // #included from: internal/catch_run_context.hpp
5229 #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
5230 
5231 // #included from: catch_test_case_tracker.hpp
5232 #define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
5233 
5234 #include <map>
5235 #include <string>
5236 #include <assert.h>
5237 #include <vector>
5238 
5239 namespace Catch {
5240 namespace TestCaseTracking {
5241 
5242     struct ITracker : SharedImpl<> {
5243         virtual ~ITracker();
5244 
5245         // static queries
5246         virtual std::string name() const = 0;
5247 
5248         // dynamic queries
5249         virtual bool isComplete() const = 0; // Successfully completed or failed
5250         virtual bool isSuccessfullyCompleted() const = 0;
5251         virtual bool isOpen() const = 0; // Started but not complete
5252         virtual bool hasChildren() const = 0;
5253 
5254         virtual ITracker& parent() = 0;
5255 
5256         // actions
5257         virtual void close() = 0; // Successfully complete
5258         virtual void fail() = 0;
5259         virtual void markAsNeedingAnotherRun() = 0;
5260 
5261         virtual void addChild( Ptr<ITracker> const& child ) = 0;
5262         virtual ITracker* findChild( std::string const& name ) = 0;
5263         virtual void openChild() = 0;
5264     };
5265 
5266     class TrackerContext {
5267 
5268         enum RunState {
5269             NotStarted,
5270             Executing,
5271             CompletedCycle
5272         };
5273 
5274         Ptr<ITracker> m_rootTracker;
5275         ITracker* m_currentTracker;
5276         RunState m_runState;
5277 
5278     public:
5279 
instance()5280         static TrackerContext& instance() {
5281             static TrackerContext s_instance;
5282             return s_instance;
5283         }
5284 
TrackerContext()5285         TrackerContext()
5286         :   m_currentTracker( CATCH_NULL ),
5287             m_runState( NotStarted )
5288         {}
5289 
5290         ITracker& startRun();
5291 
endRun()5292         void endRun() {
5293             m_rootTracker.reset();
5294             m_currentTracker = CATCH_NULL;
5295             m_runState = NotStarted;
5296         }
5297 
startCycle()5298         void startCycle() {
5299             m_currentTracker = m_rootTracker.get();
5300             m_runState = Executing;
5301         }
completeCycle()5302         void completeCycle() {
5303             m_runState = CompletedCycle;
5304         }
5305 
completedCycle() const5306         bool completedCycle() const {
5307             return m_runState == CompletedCycle;
5308         }
currentTracker()5309         ITracker& currentTracker() {
5310             return *m_currentTracker;
5311         }
setCurrentTracker(ITracker * tracker)5312         void setCurrentTracker( ITracker* tracker ) {
5313             m_currentTracker = tracker;
5314         }
5315     };
5316 
5317     class TrackerBase : public ITracker {
5318     protected:
5319         enum CycleState {
5320             NotStarted,
5321             Executing,
5322             ExecutingChildren,
5323             NeedsAnotherRun,
5324             CompletedSuccessfully,
5325             Failed
5326         };
5327         class TrackerHasName {
5328             std::string m_name;
5329         public:
TrackerHasName(std::string const & name)5330             TrackerHasName( std::string const& name ) : m_name( name ) {}
operator ()(Ptr<ITracker> const & tracker)5331             bool operator ()( Ptr<ITracker> const& tracker ) {
5332                 return tracker->name() == m_name;
5333             }
5334         };
5335         typedef std::vector<Ptr<ITracker> > Children;
5336         std::string m_name;
5337         TrackerContext& m_ctx;
5338         ITracker* m_parent;
5339         Children m_children;
5340         CycleState m_runState;
5341     public:
TrackerBase(std::string const & name,TrackerContext & ctx,ITracker * parent)5342         TrackerBase( std::string const& name, TrackerContext& ctx, ITracker* parent )
5343         :   m_name( name ),
5344             m_ctx( ctx ),
5345             m_parent( parent ),
5346             m_runState( NotStarted )
5347         {}
5348         virtual ~TrackerBase();
5349 
name() const5350         virtual std::string name() const CATCH_OVERRIDE {
5351             return m_name;
5352         }
isComplete() const5353         virtual bool isComplete() const CATCH_OVERRIDE {
5354             return m_runState == CompletedSuccessfully || m_runState == Failed;
5355         }
isSuccessfullyCompleted() const5356         virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE {
5357             return m_runState == CompletedSuccessfully;
5358         }
isOpen() const5359         virtual bool isOpen() const CATCH_OVERRIDE {
5360             return m_runState != NotStarted && !isComplete();
5361         }
hasChildren() const5362         virtual bool hasChildren() const CATCH_OVERRIDE {
5363             return !m_children.empty();
5364         }
5365 
addChild(Ptr<ITracker> const & child)5366         virtual void addChild( Ptr<ITracker> const& child ) CATCH_OVERRIDE {
5367             m_children.push_back( child );
5368         }
5369 
findChild(std::string const & name)5370         virtual ITracker* findChild( std::string const& name ) CATCH_OVERRIDE {
5371             Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) );
5372             return( it != m_children.end() )
5373                 ? it->get()
5374                 : CATCH_NULL;
5375         }
parent()5376         virtual ITracker& parent() CATCH_OVERRIDE {
5377             assert( m_parent ); // Should always be non-null except for root
5378             return *m_parent;
5379         }
5380 
openChild()5381         virtual void openChild() CATCH_OVERRIDE {
5382             if( m_runState != ExecutingChildren ) {
5383                 m_runState = ExecutingChildren;
5384                 if( m_parent )
5385                     m_parent->openChild();
5386             }
5387         }
open()5388         void open() {
5389             m_runState = Executing;
5390             moveToThis();
5391             if( m_parent )
5392                 m_parent->openChild();
5393         }
5394 
close()5395         virtual void close() CATCH_OVERRIDE {
5396 
5397             // Close any still open children (e.g. generators)
5398             while( &m_ctx.currentTracker() != this )
5399                 m_ctx.currentTracker().close();
5400 
5401             switch( m_runState ) {
5402                 case NotStarted:
5403                 case CompletedSuccessfully:
5404                 case Failed:
5405                     throw std::logic_error( "Illogical state" );
5406 
5407                 case NeedsAnotherRun:
5408                     break;;
5409 
5410                 case Executing:
5411                     m_runState = CompletedSuccessfully;
5412                     break;
5413                 case ExecutingChildren:
5414                     if( m_children.empty() || m_children.back()->isComplete() )
5415                         m_runState = CompletedSuccessfully;
5416                     break;
5417 
5418                 default:
5419                     throw std::logic_error( "Unexpected state" );
5420             }
5421             moveToParent();
5422             m_ctx.completeCycle();
5423         }
fail()5424         virtual void fail() CATCH_OVERRIDE {
5425             m_runState = Failed;
5426             if( m_parent )
5427                 m_parent->markAsNeedingAnotherRun();
5428             moveToParent();
5429             m_ctx.completeCycle();
5430         }
markAsNeedingAnotherRun()5431         virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE {
5432             m_runState = NeedsAnotherRun;
5433         }
5434     private:
moveToParent()5435         void moveToParent() {
5436             assert( m_parent );
5437             m_ctx.setCurrentTracker( m_parent );
5438         }
moveToThis()5439         void moveToThis() {
5440             m_ctx.setCurrentTracker( this );
5441         }
5442     };
5443 
5444     class SectionTracker : public TrackerBase {
5445     public:
SectionTracker(std::string const & name,TrackerContext & ctx,ITracker * parent)5446         SectionTracker( std::string const& name, TrackerContext& ctx, ITracker* parent )
5447         :   TrackerBase( name, ctx, parent )
5448         {}
5449         virtual ~SectionTracker();
5450 
acquire(TrackerContext & ctx,std::string const & name)5451         static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) {
5452             SectionTracker* section = CATCH_NULL;
5453 
5454             ITracker& currentTracker = ctx.currentTracker();
5455             if( ITracker* childTracker = currentTracker.findChild( name ) ) {
5456                 section = dynamic_cast<SectionTracker*>( childTracker );
5457                 assert( section );
5458             }
5459             else {
5460                 section = new SectionTracker( name, ctx, &currentTracker );
5461                 currentTracker.addChild( section );
5462             }
5463             if( !ctx.completedCycle() && !section->isComplete() ) {
5464 
5465                 section->open();
5466             }
5467             return *section;
5468         }
5469     };
5470 
5471     class IndexTracker : public TrackerBase {
5472         int m_size;
5473         int m_index;
5474     public:
IndexTracker(std::string const & name,TrackerContext & ctx,ITracker * parent,int size)5475         IndexTracker( std::string const& name, TrackerContext& ctx, ITracker* parent, int size )
5476         :   TrackerBase( name, ctx, parent ),
5477             m_size( size ),
5478             m_index( -1 )
5479         {}
5480         virtual ~IndexTracker();
5481 
acquire(TrackerContext & ctx,std::string const & name,int size)5482         static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) {
5483             IndexTracker* tracker = CATCH_NULL;
5484 
5485             ITracker& currentTracker = ctx.currentTracker();
5486             if( ITracker* childTracker = currentTracker.findChild( name ) ) {
5487                 tracker = dynamic_cast<IndexTracker*>( childTracker );
5488                 assert( tracker );
5489             }
5490             else {
5491                 tracker = new IndexTracker( name, ctx, &currentTracker, size );
5492                 currentTracker.addChild( tracker );
5493             }
5494 
5495             if( !ctx.completedCycle() && !tracker->isComplete() ) {
5496                 if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
5497                     tracker->moveNext();
5498                 tracker->open();
5499             }
5500 
5501             return *tracker;
5502         }
5503 
index() const5504         int index() const { return m_index; }
5505 
moveNext()5506         void moveNext() {
5507             m_index++;
5508             m_children.clear();
5509         }
5510 
close()5511         virtual void close() CATCH_OVERRIDE {
5512             TrackerBase::close();
5513             if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
5514                 m_runState = Executing;
5515         }
5516     };
5517 
startRun()5518     inline ITracker& TrackerContext::startRun() {
5519         m_rootTracker = new SectionTracker( "{root}", *this, CATCH_NULL );
5520         m_currentTracker = CATCH_NULL;
5521         m_runState = Executing;
5522         return *m_rootTracker;
5523     }
5524 
5525 } // namespace TestCaseTracking
5526 
5527 using TestCaseTracking::ITracker;
5528 using TestCaseTracking::TrackerContext;
5529 using TestCaseTracking::SectionTracker;
5530 using TestCaseTracking::IndexTracker;
5531 
5532 } // namespace Catch
5533 
5534 // #included from: catch_fatal_condition.hpp
5535 #define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
5536 
5537 namespace Catch {
5538 
5539     // Report the error condition then exit the process
fatal(std::string const & message,int exitCode)5540     inline void fatal( std::string const& message, int exitCode ) {
5541         IContext& context = Catch::getCurrentContext();
5542         IResultCapture* resultCapture = context.getResultCapture();
5543         resultCapture->handleFatalErrorCondition( message );
5544 
5545 		if( Catch::alwaysTrue() ) // avoids "no return" warnings
5546             exit( exitCode );
5547     }
5548 
5549 } // namespace Catch
5550 
5551 #if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
5552 
5553 namespace Catch {
5554 
5555     struct FatalConditionHandler {
resetCatch::FatalConditionHandler5556 		void reset() {}
5557 	};
5558 
5559 } // namespace Catch
5560 
5561 #else // Not Windows - assumed to be POSIX compatible //////////////////////////
5562 
5563 #include <signal.h>
5564 
5565 namespace Catch {
5566 
5567     struct SignalDefs { int id; const char* name; };
5568     extern SignalDefs signalDefs[];
5569     SignalDefs signalDefs[] = {
5570             { SIGINT,  "SIGINT - Terminal interrupt signal" },
5571             { SIGILL,  "SIGILL - Illegal instruction signal" },
5572             { SIGFPE,  "SIGFPE - Floating point error signal" },
5573             { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
5574             { SIGTERM, "SIGTERM - Termination request signal" },
5575             { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
5576         };
5577 
5578     struct FatalConditionHandler {
5579 
handleSignalCatch::FatalConditionHandler5580         static void handleSignal( int sig ) {
5581             for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
5582                 if( sig == signalDefs[i].id )
5583                     fatal( signalDefs[i].name, -sig );
5584             fatal( "<unknown signal>", -sig );
5585         }
5586 
FatalConditionHandlerCatch::FatalConditionHandler5587         FatalConditionHandler() : m_isSet( true ) {
5588             for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
5589                 signal( signalDefs[i].id, handleSignal );
5590         }
~FatalConditionHandlerCatch::FatalConditionHandler5591         ~FatalConditionHandler() {
5592             reset();
5593         }
resetCatch::FatalConditionHandler5594         void reset() {
5595             if( m_isSet ) {
5596                 for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
5597                     signal( signalDefs[i].id, SIG_DFL );
5598                 m_isSet = false;
5599             }
5600         }
5601 
5602         bool m_isSet;
5603     };
5604 
5605 } // namespace Catch
5606 
5607 #endif // not Windows
5608 
5609 #include <set>
5610 #include <string>
5611 
5612 namespace Catch {
5613 
5614     class StreamRedirect {
5615 
5616     public:
StreamRedirect(std::ostream & stream,std::string & targetString)5617         StreamRedirect( std::ostream& stream, std::string& targetString )
5618         :   m_stream( stream ),
5619             m_prevBuf( stream.rdbuf() ),
5620             m_targetString( targetString )
5621         {
5622             stream.rdbuf( m_oss.rdbuf() );
5623         }
5624 
~StreamRedirect()5625         ~StreamRedirect() {
5626             m_targetString += m_oss.str();
5627             m_stream.rdbuf( m_prevBuf );
5628         }
5629 
5630     private:
5631         std::ostream& m_stream;
5632         std::streambuf* m_prevBuf;
5633         std::ostringstream m_oss;
5634         std::string& m_targetString;
5635     };
5636 
5637     ///////////////////////////////////////////////////////////////////////////
5638 
5639     class RunContext : public IResultCapture, public IRunner {
5640 
5641         RunContext( RunContext const& );
5642         void operator =( RunContext const& );
5643 
5644     public:
5645 
RunContext(Ptr<IConfig const> const & _config,Ptr<IStreamingReporter> const & reporter)5646         explicit RunContext( Ptr<IConfig const> const& _config, Ptr<IStreamingReporter> const& reporter )
5647         :   m_runInfo( _config->name() ),
5648             m_context( getCurrentMutableContext() ),
5649             m_activeTestCase( CATCH_NULL ),
5650             m_config( _config ),
5651             m_reporter( reporter )
5652         {
5653             m_context.setRunner( this );
5654             m_context.setConfig( m_config );
5655             m_context.setResultCapture( this );
5656             m_reporter->testRunStarting( m_runInfo );
5657         }
5658 
~RunContext()5659         virtual ~RunContext() {
5660             m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
5661         }
5662 
testGroupStarting(std::string const & testSpec,std::size_t groupIndex,std::size_t groupsCount)5663         void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
5664             m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
5665         }
testGroupEnded(std::string const & testSpec,Totals const & totals,std::size_t groupIndex,std::size_t groupsCount)5666         void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
5667             m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
5668         }
5669 
runTest(TestCase const & testCase)5670         Totals runTest( TestCase const& testCase ) {
5671             Totals prevTotals = m_totals;
5672 
5673             std::string redirectedCout;
5674             std::string redirectedCerr;
5675 
5676             TestCaseInfo testInfo = testCase.getTestCaseInfo();
5677 
5678             m_reporter->testCaseStarting( testInfo );
5679 
5680             m_activeTestCase = &testCase;
5681 
5682             do {
5683                 m_trackerContext.startRun();
5684                 do {
5685                     m_trackerContext.startCycle();
5686                     m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testInfo.name );
5687                     runCurrentTest( redirectedCout, redirectedCerr );
5688                 }
5689                 while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() );
5690             }
5691             // !TBD: deprecated - this will be replaced by indexed trackers
5692             while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
5693 
5694             Totals deltaTotals = m_totals.delta( prevTotals );
5695             m_totals.testCases += deltaTotals.testCases;
5696             m_reporter->testCaseEnded( TestCaseStats(   testInfo,
5697                                                         deltaTotals,
5698                                                         redirectedCout,
5699                                                         redirectedCerr,
5700                                                         aborting() ) );
5701 
5702             m_activeTestCase = CATCH_NULL;
5703             m_testCaseTracker = CATCH_NULL;
5704 
5705             return deltaTotals;
5706         }
5707 
config() const5708         Ptr<IConfig const> config() const {
5709             return m_config;
5710         }
5711 
5712     private: // IResultCapture
5713 
assertionEnded(AssertionResult const & result)5714         virtual void assertionEnded( AssertionResult const& result ) {
5715             if( result.getResultType() == ResultWas::Ok ) {
5716                 m_totals.assertions.passed++;
5717             }
5718             else if( !result.isOk() ) {
5719                 m_totals.assertions.failed++;
5720             }
5721 
5722             if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
5723                 m_messages.clear();
5724 
5725             // Reset working state
5726             m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
5727             m_lastResult = result;
5728         }
5729 
sectionStarted(SectionInfo const & sectionInfo,Counts & assertions)5730         virtual bool sectionStarted (
5731             SectionInfo const& sectionInfo,
5732             Counts& assertions
5733         )
5734         {
5735             std::ostringstream oss;
5736             oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
5737 
5738             ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, oss.str() );
5739             if( !sectionTracker.isOpen() )
5740                 return false;
5741             m_activeSections.push_back( &sectionTracker );
5742 
5743             m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
5744 
5745             m_reporter->sectionStarting( sectionInfo );
5746 
5747             assertions = m_totals.assertions;
5748 
5749             return true;
5750         }
testForMissingAssertions(Counts & assertions)5751         bool testForMissingAssertions( Counts& assertions ) {
5752             if( assertions.total() != 0 )
5753                 return false;
5754             if( !m_config->warnAboutMissingAssertions() )
5755                 return false;
5756             if( m_trackerContext.currentTracker().hasChildren() )
5757                 return false;
5758             m_totals.assertions.failed++;
5759             assertions.failed++;
5760             return true;
5761         }
5762 
sectionEnded(SectionEndInfo const & endInfo)5763         virtual void sectionEnded( SectionEndInfo const& endInfo ) {
5764             Counts assertions = m_totals.assertions - endInfo.prevAssertions;
5765             bool missingAssertions = testForMissingAssertions( assertions );
5766 
5767             if( !m_activeSections.empty() ) {
5768                 m_activeSections.back()->close();
5769                 m_activeSections.pop_back();
5770             }
5771 
5772             m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) );
5773             m_messages.clear();
5774         }
5775 
sectionEndedEarly(SectionEndInfo const & endInfo)5776         virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) {
5777             if( m_unfinishedSections.empty() )
5778                 m_activeSections.back()->fail();
5779             else
5780                 m_activeSections.back()->close();
5781             m_activeSections.pop_back();
5782 
5783             m_unfinishedSections.push_back( endInfo );
5784         }
5785 
pushScopedMessage(MessageInfo const & message)5786         virtual void pushScopedMessage( MessageInfo const& message ) {
5787             m_messages.push_back( message );
5788         }
5789 
popScopedMessage(MessageInfo const & message)5790         virtual void popScopedMessage( MessageInfo const& message ) {
5791             m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
5792         }
5793 
getCurrentTestName() const5794         virtual std::string getCurrentTestName() const {
5795             return m_activeTestCase
5796                 ? m_activeTestCase->getTestCaseInfo().name
5797                 : "";
5798         }
5799 
getLastResult() const5800         virtual const AssertionResult* getLastResult() const {
5801             return &m_lastResult;
5802         }
5803 
handleFatalErrorCondition(std::string const & message)5804         virtual void handleFatalErrorCondition( std::string const& message ) {
5805             ResultBuilder resultBuilder = makeUnexpectedResultBuilder();
5806             resultBuilder.setResultType( ResultWas::FatalErrorCondition );
5807             resultBuilder << message;
5808             resultBuilder.captureExpression();
5809 
5810             handleUnfinishedSections();
5811 
5812             // Recreate section for test case (as we will lose the one that was in scope)
5813             TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
5814             SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
5815 
5816             Counts assertions;
5817             assertions.failed = 1;
5818             SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );
5819             m_reporter->sectionEnded( testCaseSectionStats );
5820 
5821             TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
5822 
5823             Totals deltaTotals;
5824             deltaTotals.testCases.failed = 1;
5825             m_reporter->testCaseEnded( TestCaseStats(   testInfo,
5826                                                         deltaTotals,
5827                                                         "",
5828                                                         "",
5829                                                         false ) );
5830             m_totals.testCases.failed++;
5831             testGroupEnded( "", m_totals, 1, 1 );
5832             m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
5833         }
5834 
5835     public:
5836         // !TBD We need to do this another way!
aborting() const5837         bool aborting() const {
5838             return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
5839         }
5840 
5841     private:
5842 
runCurrentTest(std::string & redirectedCout,std::string & redirectedCerr)5843         void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
5844             TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
5845             SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
5846             m_reporter->sectionStarting( testCaseSection );
5847             Counts prevAssertions = m_totals.assertions;
5848             double duration = 0;
5849             try {
5850                 m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
5851 
5852                 seedRng( *m_config );
5853 
5854                 Timer timer;
5855                 timer.start();
5856                 if( m_reporter->getPreferences().shouldRedirectStdOut ) {
5857                     StreamRedirect coutRedir( Catch::cout(), redirectedCout );
5858                     StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );
5859                     invokeActiveTestCase();
5860                 }
5861                 else {
5862                     invokeActiveTestCase();
5863                 }
5864                 duration = timer.getElapsedSeconds();
5865             }
5866             catch( TestFailureException& ) {
5867                 // This just means the test was aborted due to failure
5868             }
5869             catch(...) {
5870                 makeUnexpectedResultBuilder().useActiveException();
5871             }
5872             m_testCaseTracker->close();
5873             handleUnfinishedSections();
5874             m_messages.clear();
5875 
5876             Counts assertions = m_totals.assertions - prevAssertions;
5877             bool missingAssertions = testForMissingAssertions( assertions );
5878 
5879             if( testCaseInfo.okToFail() ) {
5880                 std::swap( assertions.failedButOk, assertions.failed );
5881                 m_totals.assertions.failed -= assertions.failedButOk;
5882                 m_totals.assertions.failedButOk += assertions.failedButOk;
5883             }
5884 
5885             SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
5886             m_reporter->sectionEnded( testCaseSectionStats );
5887         }
5888 
invokeActiveTestCase()5889         void invokeActiveTestCase() {
5890             FatalConditionHandler fatalConditionHandler; // Handle signals
5891             m_activeTestCase->invoke();
5892             fatalConditionHandler.reset();
5893         }
5894 
5895     private:
5896 
makeUnexpectedResultBuilder() const5897         ResultBuilder makeUnexpectedResultBuilder() const {
5898             return ResultBuilder(   m_lastAssertionInfo.macroName.c_str(),
5899                                     m_lastAssertionInfo.lineInfo,
5900                                     m_lastAssertionInfo.capturedExpression.c_str(),
5901                                     m_lastAssertionInfo.resultDisposition );
5902         }
5903 
handleUnfinishedSections()5904         void handleUnfinishedSections() {
5905             // If sections ended prematurely due to an exception we stored their
5906             // infos here so we can tear them down outside the unwind process.
5907             for( std::vector<SectionEndInfo>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
5908                         itEnd = m_unfinishedSections.rend();
5909                     it != itEnd;
5910                     ++it )
5911                 sectionEnded( *it );
5912             m_unfinishedSections.clear();
5913         }
5914 
5915         TestRunInfo m_runInfo;
5916         IMutableContext& m_context;
5917         TestCase const* m_activeTestCase;
5918         ITracker* m_testCaseTracker;
5919         ITracker* m_currentSectionTracker;
5920         AssertionResult m_lastResult;
5921 
5922         Ptr<IConfig const> m_config;
5923         Totals m_totals;
5924         Ptr<IStreamingReporter> m_reporter;
5925         std::vector<MessageInfo> m_messages;
5926         AssertionInfo m_lastAssertionInfo;
5927         std::vector<SectionEndInfo> m_unfinishedSections;
5928         std::vector<ITracker*> m_activeSections;
5929         TrackerContext m_trackerContext;
5930     };
5931 
getResultCapture()5932     IResultCapture& getResultCapture() {
5933         if( IResultCapture* capture = getCurrentContext().getResultCapture() )
5934             return *capture;
5935         else
5936             throw std::logic_error( "No result capture instance" );
5937     }
5938 
5939 } // end namespace Catch
5940 
5941 // #included from: internal/catch_version.h
5942 #define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
5943 
5944 namespace Catch {
5945 
5946     // Versioning information
5947     struct Version {
5948         Version(    unsigned int _majorVersion,
5949                     unsigned int _minorVersion,
5950                     unsigned int _patchNumber,
5951                     std::string const& _branchName,
5952                     unsigned int _buildNumber );
5953 
5954         unsigned int const majorVersion;
5955         unsigned int const minorVersion;
5956         unsigned int const patchNumber;
5957 
5958         // buildNumber is only used if branchName is not null
5959         std::string const branchName;
5960         unsigned int const buildNumber;
5961 
5962         friend std::ostream& operator << ( std::ostream& os, Version const& version );
5963 
5964     private:
5965         void operator=( Version const& );
5966     };
5967 
5968     extern Version libraryVersion;
5969 }
5970 
5971 #include <fstream>
5972 #include <stdlib.h>
5973 #include <limits>
5974 
5975 namespace Catch {
5976 
createReporter(std::string const & reporterName,Ptr<Config> const & config)5977     Ptr<IStreamingReporter> createReporter( std::string const& reporterName, Ptr<Config> const& config ) {
5978         Ptr<IStreamingReporter> reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() );
5979         if( !reporter ) {
5980             std::ostringstream oss;
5981             oss << "No reporter registered with name: '" << reporterName << "'";
5982             throw std::domain_error( oss.str() );
5983         }
5984         return reporter;
5985     }
5986 
makeReporter(Ptr<Config> const & config)5987     Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) {
5988         std::vector<std::string> reporters = config->getReporterNames();
5989         if( reporters.empty() )
5990             reporters.push_back( "console" );
5991 
5992         Ptr<IStreamingReporter> reporter;
5993         for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();
5994                 it != itEnd;
5995                 ++it )
5996             reporter = addReporter( reporter, createReporter( *it, config ) );
5997         return reporter;
5998     }
addListeners(Ptr<IConfig const> const & config,Ptr<IStreamingReporter> reporters)5999     Ptr<IStreamingReporter> addListeners( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> reporters ) {
6000         IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();
6001         for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();
6002                 it != itEnd;
6003                 ++it )
6004             reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) );
6005         return reporters;
6006     }
6007 
runTests(Ptr<Config> const & config)6008     Totals runTests( Ptr<Config> const& config ) {
6009 
6010         Ptr<IConfig const> iconfig = config.get();
6011 
6012         Ptr<IStreamingReporter> reporter = makeReporter( config );
6013         reporter = addListeners( iconfig, reporter );
6014 
6015         RunContext context( iconfig, reporter );
6016 
6017         Totals totals;
6018 
6019         context.testGroupStarting( config->name(), 1, 1 );
6020 
6021         TestSpec testSpec = config->testSpec();
6022         if( !testSpec.hasFilters() )
6023             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
6024 
6025         std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *iconfig );
6026         for( std::vector<TestCase>::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end();
6027                 it != itEnd;
6028                 ++it ) {
6029             if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) )
6030                 totals += context.runTest( *it );
6031             else
6032                 reporter->skipTest( *it );
6033         }
6034 
6035         context.testGroupEnded( iconfig->name(), totals, 1, 1 );
6036         return totals;
6037     }
6038 
applyFilenamesAsTags(IConfig const & config)6039     void applyFilenamesAsTags( IConfig const& config ) {
6040         std::vector<TestCase> const& tests = getAllTestCasesSorted( config );
6041         for(std::size_t i = 0; i < tests.size(); ++i ) {
6042             TestCase& test = const_cast<TestCase&>( tests[i] );
6043             std::set<std::string> tags = test.tags;
6044 
6045             std::string filename = test.lineInfo.file;
6046             std::string::size_type lastSlash = filename.find_last_of( "\\/" );
6047             if( lastSlash != std::string::npos )
6048                 filename = filename.substr( lastSlash+1 );
6049 
6050             std::string::size_type lastDot = filename.find_last_of( "." );
6051             if( lastDot != std::string::npos )
6052                 filename = filename.substr( 0, lastDot );
6053 
6054             tags.insert( "#" + filename );
6055             setTags( test, tags );
6056         }
6057     }
6058 
6059     class Session : NonCopyable {
6060         static bool alreadyInstantiated;
6061 
6062     public:
6063 
6064         struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
6065 
Session()6066         Session()
6067         : m_cli( makeCommandLineParser() ) {
6068             if( alreadyInstantiated ) {
6069                 std::string msg = "Only one instance of Catch::Session can ever be used";
6070                 Catch::cerr() << msg << std::endl;
6071                 throw std::logic_error( msg );
6072             }
6073             alreadyInstantiated = true;
6074         }
~Session()6075         ~Session() {
6076             Catch::cleanUp();
6077         }
6078 
showHelp(std::string const & processName)6079         void showHelp( std::string const& processName ) {
6080             Catch::cout() << "\nCatch v" << libraryVersion << "\n";
6081 
6082             m_cli.usage( Catch::cout(), processName );
6083             Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
6084         }
6085 
applyCommandLine(int argc,char const * const argv[],OnUnusedOptions::DoWhat unusedOptionBehaviour=OnUnusedOptions::Fail)6086         int applyCommandLine( int argc, char const* const argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
6087             try {
6088                 m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
6089                 m_unusedTokens = m_cli.parseInto( argc, argv, m_configData );
6090                 if( m_configData.showHelp )
6091                     showHelp( m_configData.processName );
6092                 m_config.reset();
6093             }
6094             catch( std::exception& ex ) {
6095                 {
6096                     Colour colourGuard( Colour::Red );
6097                     Catch::cerr()
6098                         << "\nError(s) in input:\n"
6099                         << Text( ex.what(), TextAttributes().setIndent(2) )
6100                         << "\n\n";
6101                 }
6102                 m_cli.usage( Catch::cout(), m_configData.processName );
6103                 return (std::numeric_limits<int>::max)();
6104             }
6105             return 0;
6106         }
6107 
useConfigData(ConfigData const & _configData)6108         void useConfigData( ConfigData const& _configData ) {
6109             m_configData = _configData;
6110             m_config.reset();
6111         }
6112 
run(int argc,char const * const argv[])6113         int run( int argc, char const* const argv[] ) {
6114 
6115             int returnCode = applyCommandLine( argc, argv );
6116             if( returnCode == 0 )
6117                 returnCode = run();
6118             return returnCode;
6119         }
6120 
run()6121         int run() {
6122             if( m_configData.showHelp )
6123                 return 0;
6124 
6125             try
6126             {
6127                 config(); // Force config to be constructed
6128 
6129                 seedRng( *m_config );
6130 
6131                 if( m_configData.filenamesAsTags )
6132                     applyFilenamesAsTags( *m_config );
6133 
6134                 // Handle list request
6135                 if( Option<std::size_t> listed = list( config() ) )
6136                     return static_cast<int>( *listed );
6137 
6138                 return static_cast<int>( runTests( m_config ).assertions.failed );
6139             }
6140             catch( std::exception& ex ) {
6141                 Catch::cerr() << ex.what() << std::endl;
6142                 return (std::numeric_limits<int>::max)();
6143             }
6144         }
6145 
cli() const6146         Clara::CommandLine<ConfigData> const& cli() const {
6147             return m_cli;
6148         }
unusedTokens() const6149         std::vector<Clara::Parser::Token> const& unusedTokens() const {
6150             return m_unusedTokens;
6151         }
configData()6152         ConfigData& configData() {
6153             return m_configData;
6154         }
config()6155         Config& config() {
6156             if( !m_config )
6157                 m_config = new Config( m_configData );
6158             return *m_config;
6159         }
6160     private:
6161         Clara::CommandLine<ConfigData> m_cli;
6162         std::vector<Clara::Parser::Token> m_unusedTokens;
6163         ConfigData m_configData;
6164         Ptr<Config> m_config;
6165     };
6166 
6167     bool Session::alreadyInstantiated = false;
6168 
6169 } // end namespace Catch
6170 
6171 // #included from: catch_registry_hub.hpp
6172 #define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
6173 
6174 // #included from: catch_test_case_registry_impl.hpp
6175 #define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
6176 
6177 #include <vector>
6178 #include <set>
6179 #include <sstream>
6180 #include <iostream>
6181 #include <algorithm>
6182 
6183 namespace Catch {
6184 
6185     struct LexSort {
operator ()Catch::LexSort6186         bool operator() (TestCase i,TestCase j) const { return (i<j);}
6187     };
6188     struct RandomNumberGenerator {
operator ()Catch::RandomNumberGenerator6189         int operator()( int n ) const { return std::rand() % n; }
6190     };
6191 
sortTests(IConfig const & config,std::vector<TestCase> const & unsortedTestCases)6192     inline std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
6193 
6194         std::vector<TestCase> sorted = unsortedTestCases;
6195 
6196         switch( config.runOrder() ) {
6197             case RunTests::InLexicographicalOrder:
6198                 std::sort( sorted.begin(), sorted.end(), LexSort() );
6199                 break;
6200             case RunTests::InRandomOrder:
6201                 {
6202                     seedRng( config );
6203 
6204                     RandomNumberGenerator rng;
6205                     std::random_shuffle( sorted.begin(), sorted.end(), rng );
6206                 }
6207                 break;
6208             case RunTests::InDeclarationOrder:
6209                 // already in declaration order
6210                 break;
6211         }
6212         return sorted;
6213     }
matchTest(TestCase const & testCase,TestSpec const & testSpec,IConfig const & config)6214     bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
6215         return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
6216     }
6217 
enforceNoDuplicateTestCases(std::vector<TestCase> const & functions)6218     void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
6219         std::set<TestCase> seenFunctions;
6220         for( std::vector<TestCase>::const_iterator it = functions.begin(), itEnd = functions.end();
6221             it != itEnd;
6222             ++it ) {
6223             std::pair<std::set<TestCase>::const_iterator, bool> prev = seenFunctions.insert( *it );
6224             if( !prev.second ){
6225                 Catch::cerr()
6226                 << Colour( Colour::Red )
6227                 << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
6228                 << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
6229                 << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
6230                 exit(1);
6231             }
6232         }
6233     }
6234 
filterTests(std::vector<TestCase> const & testCases,TestSpec const & testSpec,IConfig const & config)6235     std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
6236         std::vector<TestCase> filtered;
6237         filtered.reserve( testCases.size() );
6238         for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
6239                 it != itEnd;
6240                 ++it )
6241             if( matchTest( *it, testSpec, config ) )
6242                 filtered.push_back( *it );
6243         return filtered;
6244     }
getAllTestCasesSorted(IConfig const & config)6245     std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
6246         return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
6247     }
6248 
6249     class TestRegistry : public ITestCaseRegistry {
6250     public:
TestRegistry()6251         TestRegistry() : m_unnamedCount( 0 ) {}
6252         virtual ~TestRegistry();
6253 
registerTest(TestCase const & testCase)6254         virtual void registerTest( TestCase const& testCase ) {
6255             std::string name = testCase.getTestCaseInfo().name;
6256             if( name == "" ) {
6257                 std::ostringstream oss;
6258                 oss << "Anonymous test case " << ++m_unnamedCount;
6259                 return registerTest( testCase.withName( oss.str() ) );
6260             }
6261             m_functions.push_back( testCase );
6262         }
6263 
getAllTests() const6264         virtual std::vector<TestCase> const& getAllTests() const {
6265             return m_functions;
6266         }
getAllTestsSorted(IConfig const & config) const6267         virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const {
6268             if( m_sortedFunctions.empty() )
6269                 enforceNoDuplicateTestCases( m_functions );
6270 
6271             if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
6272                 m_sortedFunctions = sortTests( config, m_functions );
6273                 m_currentSortOrder = config.runOrder();
6274             }
6275             return m_sortedFunctions;
6276         }
6277 
6278     private:
6279         std::vector<TestCase> m_functions;
6280         mutable RunTests::InWhatOrder m_currentSortOrder;
6281         mutable std::vector<TestCase> m_sortedFunctions;
6282         size_t m_unnamedCount;
6283         std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
6284     };
6285 
6286     ///////////////////////////////////////////////////////////////////////////
6287 
6288     class FreeFunctionTestCase : public SharedImpl<ITestCase> {
6289     public:
6290 
FreeFunctionTestCase(TestFunction fun)6291         FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
6292 
invoke() const6293         virtual void invoke() const {
6294             m_fun();
6295         }
6296 
6297     private:
6298         virtual ~FreeFunctionTestCase();
6299 
6300         TestFunction m_fun;
6301     };
6302 
extractClassName(std::string const & classOrQualifiedMethodName)6303     inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
6304         std::string className = classOrQualifiedMethodName;
6305         if( startsWith( className, "&" ) )
6306         {
6307             std::size_t lastColons = className.rfind( "::" );
6308             std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
6309             if( penultimateColons == std::string::npos )
6310                 penultimateColons = 1;
6311             className = className.substr( penultimateColons, lastColons-penultimateColons );
6312         }
6313         return className;
6314     }
6315 
registerTestCase(ITestCase * testCase,char const * classOrQualifiedMethodName,NameAndDesc const & nameAndDesc,SourceLineInfo const & lineInfo)6316     void registerTestCase
6317         (   ITestCase* testCase,
6318             char const* classOrQualifiedMethodName,
6319             NameAndDesc const& nameAndDesc,
6320             SourceLineInfo const& lineInfo ) {
6321 
6322         getMutableRegistryHub().registerTest
6323             ( makeTestCase
6324                 (   testCase,
6325                     extractClassName( classOrQualifiedMethodName ),
6326                     nameAndDesc.name,
6327                     nameAndDesc.description,
6328                     lineInfo ) );
6329     }
registerTestCaseFunction(TestFunction function,SourceLineInfo const & lineInfo,NameAndDesc const & nameAndDesc)6330     void registerTestCaseFunction
6331         (   TestFunction function,
6332             SourceLineInfo const& lineInfo,
6333             NameAndDesc const& nameAndDesc ) {
6334         registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
6335     }
6336 
6337     ///////////////////////////////////////////////////////////////////////////
6338 
AutoReg(TestFunction function,SourceLineInfo const & lineInfo,NameAndDesc const & nameAndDesc)6339     AutoReg::AutoReg
6340         (   TestFunction function,
6341             SourceLineInfo const& lineInfo,
6342             NameAndDesc const& nameAndDesc ) {
6343         registerTestCaseFunction( function, lineInfo, nameAndDesc );
6344     }
6345 
~AutoReg()6346     AutoReg::~AutoReg() {}
6347 
6348 } // end namespace Catch
6349 
6350 // #included from: catch_reporter_registry.hpp
6351 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
6352 
6353 #include <map>
6354 
6355 namespace Catch {
6356 
6357     class ReporterRegistry : public IReporterRegistry {
6358 
6359     public:
6360 
~ReporterRegistry()6361         virtual ~ReporterRegistry() CATCH_OVERRIDE {}
6362 
create(std::string const & name,Ptr<IConfig const> const & config) const6363         virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const CATCH_OVERRIDE {
6364             FactoryMap::const_iterator it =  m_factories.find( name );
6365             if( it == m_factories.end() )
6366                 return CATCH_NULL;
6367             return it->second->create( ReporterConfig( config ) );
6368         }
6369 
registerReporter(std::string const & name,Ptr<IReporterFactory> const & factory)6370         void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) {
6371             m_factories.insert( std::make_pair( name, factory ) );
6372         }
registerListener(Ptr<IReporterFactory> const & factory)6373         void registerListener( Ptr<IReporterFactory> const& factory ) {
6374             m_listeners.push_back( factory );
6375         }
6376 
getFactories() const6377         virtual FactoryMap const& getFactories() const CATCH_OVERRIDE {
6378             return m_factories;
6379         }
getListeners() const6380         virtual Listeners const& getListeners() const CATCH_OVERRIDE {
6381             return m_listeners;
6382         }
6383 
6384     private:
6385         FactoryMap m_factories;
6386         Listeners m_listeners;
6387     };
6388 }
6389 
6390 // #included from: catch_exception_translator_registry.hpp
6391 #define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
6392 
6393 #ifdef __OBJC__
6394 #import "Foundation/Foundation.h"
6395 #endif
6396 
6397 namespace Catch {
6398 
6399     class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
6400     public:
~ExceptionTranslatorRegistry()6401         ~ExceptionTranslatorRegistry() {
6402             deleteAll( m_translators );
6403         }
6404 
registerTranslator(const IExceptionTranslator * translator)6405         virtual void registerTranslator( const IExceptionTranslator* translator ) {
6406             m_translators.push_back( translator );
6407         }
6408 
translateActiveException() const6409         virtual std::string translateActiveException() const {
6410             try {
6411 #ifdef __OBJC__
6412                 // In Objective-C try objective-c exceptions first
6413                 @try {
6414                     return tryTranslators();
6415                 }
6416                 @catch (NSException *exception) {
6417                     return Catch::toString( [exception description] );
6418                 }
6419 #else
6420                 return tryTranslators();
6421 #endif
6422             }
6423             catch( TestFailureException& ) {
6424                 throw;
6425             }
6426             catch( std::exception& ex ) {
6427                 return ex.what();
6428             }
6429             catch( std::string& msg ) {
6430                 return msg;
6431             }
6432             catch( const char* msg ) {
6433                 return msg;
6434             }
6435             catch(...) {
6436                 return "Unknown exception";
6437             }
6438         }
6439 
tryTranslators() const6440         std::string tryTranslators() const {
6441             if( m_translators.empty() )
6442                 throw;
6443             else
6444                 return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
6445         }
6446 
6447     private:
6448         std::vector<const IExceptionTranslator*> m_translators;
6449     };
6450 }
6451 
6452 namespace Catch {
6453 
6454     namespace {
6455 
6456         class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
6457 
6458             RegistryHub( RegistryHub const& );
6459             void operator=( RegistryHub const& );
6460 
6461         public: // IRegistryHub
RegistryHub()6462             RegistryHub() {
6463             }
getReporterRegistry() const6464             virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE {
6465                 return m_reporterRegistry;
6466             }
getTestCaseRegistry() const6467             virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE {
6468                 return m_testCaseRegistry;
6469             }
getExceptionTranslatorRegistry()6470             virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE {
6471                 return m_exceptionTranslatorRegistry;
6472             }
6473 
6474         public: // IMutableRegistryHub
registerReporter(std::string const & name,Ptr<IReporterFactory> const & factory)6475             virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
6476                 m_reporterRegistry.registerReporter( name, factory );
6477             }
registerListener(Ptr<IReporterFactory> const & factory)6478             virtual void registerListener( Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
6479                 m_reporterRegistry.registerListener( factory );
6480             }
registerTest(TestCase const & testInfo)6481             virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE {
6482                 m_testCaseRegistry.registerTest( testInfo );
6483             }
registerTranslator(const IExceptionTranslator * translator)6484             virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE {
6485                 m_exceptionTranslatorRegistry.registerTranslator( translator );
6486             }
6487 
6488         private:
6489             TestRegistry m_testCaseRegistry;
6490             ReporterRegistry m_reporterRegistry;
6491             ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
6492         };
6493 
6494         // Single, global, instance
getTheRegistryHub()6495         inline RegistryHub*& getTheRegistryHub() {
6496             static RegistryHub* theRegistryHub = CATCH_NULL;
6497             if( !theRegistryHub )
6498                 theRegistryHub = new RegistryHub();
6499             return theRegistryHub;
6500         }
6501     }
6502 
getRegistryHub()6503     IRegistryHub& getRegistryHub() {
6504         return *getTheRegistryHub();
6505     }
getMutableRegistryHub()6506     IMutableRegistryHub& getMutableRegistryHub() {
6507         return *getTheRegistryHub();
6508     }
cleanUp()6509     void cleanUp() {
6510         delete getTheRegistryHub();
6511         getTheRegistryHub() = CATCH_NULL;
6512         cleanUpContext();
6513     }
translateActiveException()6514     std::string translateActiveException() {
6515         return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
6516     }
6517 
6518 } // end namespace Catch
6519 
6520 // #included from: catch_notimplemented_exception.hpp
6521 #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
6522 
6523 #include <ostream>
6524 
6525 namespace Catch {
6526 
NotImplementedException(SourceLineInfo const & lineInfo)6527     NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
6528     :   m_lineInfo( lineInfo ) {
6529         std::ostringstream oss;
6530         oss << lineInfo << ": function ";
6531         oss << "not implemented";
6532         m_what = oss.str();
6533     }
6534 
what() const6535     const char* NotImplementedException::what() const CATCH_NOEXCEPT {
6536         return m_what.c_str();
6537     }
6538 
6539 } // end namespace Catch
6540 
6541 // #included from: catch_context_impl.hpp
6542 #define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
6543 
6544 // #included from: catch_stream.hpp
6545 #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
6546 
6547 #include <stdexcept>
6548 #include <cstdio>
6549 #include <iostream>
6550 
6551 namespace Catch {
6552 
6553     template<typename WriterF, size_t bufferSize=256>
6554     class StreamBufImpl : public StreamBufBase {
6555         char data[bufferSize];
6556         WriterF m_writer;
6557 
6558     public:
StreamBufImpl()6559         StreamBufImpl() {
6560             setp( data, data + sizeof(data) );
6561         }
6562 
~StreamBufImpl()6563         ~StreamBufImpl() CATCH_NOEXCEPT {
6564             sync();
6565         }
6566 
6567     private:
overflow(int c)6568         int overflow( int c ) {
6569             sync();
6570 
6571             if( c != EOF ) {
6572                 if( pbase() == epptr() )
6573                     m_writer( std::string( 1, static_cast<char>( c ) ) );
6574                 else
6575                     sputc( static_cast<char>( c ) );
6576             }
6577             return 0;
6578         }
6579 
sync()6580         int sync() {
6581             if( pbase() != pptr() ) {
6582                 m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
6583                 setp( pbase(), epptr() );
6584             }
6585             return 0;
6586         }
6587     };
6588 
6589     ///////////////////////////////////////////////////////////////////////////
6590 
FileStream(std::string const & filename)6591     FileStream::FileStream( std::string const& filename ) {
6592         m_ofs.open( filename.c_str() );
6593         if( m_ofs.fail() ) {
6594             std::ostringstream oss;
6595             oss << "Unable to open file: '" << filename << "'";
6596             throw std::domain_error( oss.str() );
6597         }
6598     }
6599 
stream() const6600     std::ostream& FileStream::stream() const {
6601         return m_ofs;
6602     }
6603 
6604     struct OutputDebugWriter {
6605 
operator ()Catch::OutputDebugWriter6606         void operator()( std::string const&str ) {
6607             writeToDebugConsole( str );
6608         }
6609     };
6610 
DebugOutStream()6611     DebugOutStream::DebugOutStream()
6612     :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
6613         m_os( m_streamBuf.get() )
6614     {}
6615 
stream() const6616     std::ostream& DebugOutStream::stream() const {
6617         return m_os;
6618     }
6619 
6620     // Store the streambuf from cout up-front because
6621     // cout may get redirected when running tests
CoutStream()6622     CoutStream::CoutStream()
6623     :   m_os( Catch::cout().rdbuf() )
6624     {}
6625 
stream() const6626     std::ostream& CoutStream::stream() const {
6627         return m_os;
6628     }
6629 
6630 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
cout()6631     std::ostream& cout() {
6632         return std::cout;
6633     }
cerr()6634     std::ostream& cerr() {
6635         return std::cerr;
6636     }
6637 #endif
6638 }
6639 
6640 namespace Catch {
6641 
6642     class Context : public IMutableContext {
6643 
Context()6644         Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {}
6645         Context( Context const& );
6646         void operator=( Context const& );
6647 
6648     public: // IContext
getResultCapture()6649         virtual IResultCapture* getResultCapture() {
6650             return m_resultCapture;
6651         }
getRunner()6652         virtual IRunner* getRunner() {
6653             return m_runner;
6654         }
getGeneratorIndex(std::string const & fileInfo,size_t totalSize)6655         virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
6656             return getGeneratorsForCurrentTest()
6657             .getGeneratorInfo( fileInfo, totalSize )
6658             .getCurrentIndex();
6659         }
advanceGeneratorsForCurrentTest()6660         virtual bool advanceGeneratorsForCurrentTest() {
6661             IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
6662             return generators && generators->moveNext();
6663         }
6664 
getConfig() const6665         virtual Ptr<IConfig const> getConfig() const {
6666             return m_config;
6667         }
6668 
6669     public: // IMutableContext
setResultCapture(IResultCapture * resultCapture)6670         virtual void setResultCapture( IResultCapture* resultCapture ) {
6671             m_resultCapture = resultCapture;
6672         }
setRunner(IRunner * runner)6673         virtual void setRunner( IRunner* runner ) {
6674             m_runner = runner;
6675         }
setConfig(Ptr<IConfig const> const & config)6676         virtual void setConfig( Ptr<IConfig const> const& config ) {
6677             m_config = config;
6678         }
6679 
6680         friend IMutableContext& getCurrentMutableContext();
6681 
6682     private:
findGeneratorsForCurrentTest()6683         IGeneratorsForTest* findGeneratorsForCurrentTest() {
6684             std::string testName = getResultCapture()->getCurrentTestName();
6685 
6686             std::map<std::string, IGeneratorsForTest*>::const_iterator it =
6687                 m_generatorsByTestName.find( testName );
6688             return it != m_generatorsByTestName.end()
6689                 ? it->second
6690                 : CATCH_NULL;
6691         }
6692 
getGeneratorsForCurrentTest()6693         IGeneratorsForTest& getGeneratorsForCurrentTest() {
6694             IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
6695             if( !generators ) {
6696                 std::string testName = getResultCapture()->getCurrentTestName();
6697                 generators = createGeneratorsForTest();
6698                 m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
6699             }
6700             return *generators;
6701         }
6702 
6703     private:
6704         Ptr<IConfig const> m_config;
6705         IRunner* m_runner;
6706         IResultCapture* m_resultCapture;
6707         std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
6708     };
6709 
6710     namespace {
6711         Context* currentContext = CATCH_NULL;
6712     }
getCurrentMutableContext()6713     IMutableContext& getCurrentMutableContext() {
6714         if( !currentContext )
6715             currentContext = new Context();
6716         return *currentContext;
6717     }
getCurrentContext()6718     IContext& getCurrentContext() {
6719         return getCurrentMutableContext();
6720     }
6721 
cleanUpContext()6722     void cleanUpContext() {
6723         delete currentContext;
6724         currentContext = CATCH_NULL;
6725     }
6726 }
6727 
6728 // #included from: catch_console_colour_impl.hpp
6729 #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
6730 
6731 namespace Catch {
6732     namespace {
6733 
6734         struct IColourImpl {
~IColourImplCatch::__anon4d2db9d10411::IColourImpl6735             virtual ~IColourImpl() {}
6736             virtual void use( Colour::Code _colourCode ) = 0;
6737         };
6738 
6739         struct NoColourImpl : IColourImpl {
useCatch::__anon4d2db9d10411::NoColourImpl6740             void use( Colour::Code ) {}
6741 
instanceCatch::__anon4d2db9d10411::NoColourImpl6742             static IColourImpl* instance() {
6743                 static NoColourImpl s_instance;
6744                 return &s_instance;
6745             }
6746         };
6747 
6748     } // anon namespace
6749 } // namespace Catch
6750 
6751 #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
6752 #   ifdef CATCH_PLATFORM_WINDOWS
6753 #       define CATCH_CONFIG_COLOUR_WINDOWS
6754 #   else
6755 #       define CATCH_CONFIG_COLOUR_ANSI
6756 #   endif
6757 #endif
6758 
6759 #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
6760 
6761 #ifndef NOMINMAX
6762 #define NOMINMAX
6763 #endif
6764 
6765 #ifdef __AFXDLL
6766 #include <AfxWin.h>
6767 #else
6768 #include <windows.h>
6769 #endif
6770 
6771 namespace Catch {
6772 namespace {
6773 
6774     class Win32ColourImpl : public IColourImpl {
6775     public:
Win32ColourImpl()6776         Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
6777         {
6778             CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
6779             GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
6780             originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
6781             originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
6782         }
6783 
use(Colour::Code _colourCode)6784         virtual void use( Colour::Code _colourCode ) {
6785             switch( _colourCode ) {
6786                 case Colour::None:      return setTextAttribute( originalForegroundAttributes );
6787                 case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
6788                 case Colour::Red:       return setTextAttribute( FOREGROUND_RED );
6789                 case Colour::Green:     return setTextAttribute( FOREGROUND_GREEN );
6790                 case Colour::Blue:      return setTextAttribute( FOREGROUND_BLUE );
6791                 case Colour::Cyan:      return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
6792                 case Colour::Yellow:    return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
6793                 case Colour::Grey:      return setTextAttribute( 0 );
6794 
6795                 case Colour::LightGrey:     return setTextAttribute( FOREGROUND_INTENSITY );
6796                 case Colour::BrightRed:     return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
6797                 case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
6798                 case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
6799 
6800                 case Colour::Bright: throw std::logic_error( "not a colour" );
6801             }
6802         }
6803 
6804     private:
setTextAttribute(WORD _textAttribute)6805         void setTextAttribute( WORD _textAttribute ) {
6806             SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
6807         }
6808         HANDLE stdoutHandle;
6809         WORD originalForegroundAttributes;
6810         WORD originalBackgroundAttributes;
6811     };
6812 
platformColourInstance()6813     IColourImpl* platformColourInstance() {
6814         static Win32ColourImpl s_instance;
6815         return &s_instance;
6816     }
6817 
6818 } // end anon namespace
6819 } // end namespace Catch
6820 
6821 #elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
6822 
6823 #include <unistd.h>
6824 
6825 namespace Catch {
6826 namespace {
6827 
6828     // use POSIX/ ANSI console terminal codes
6829     // Thanks to Adam Strzelecki for original contribution
6830     // (http://github.com/nanoant)
6831     // https://github.com/philsquared/Catch/pull/131
6832     class PosixColourImpl : public IColourImpl {
6833     public:
use(Colour::Code _colourCode)6834         virtual void use( Colour::Code _colourCode ) {
6835             switch( _colourCode ) {
6836                 case Colour::None:
6837                 case Colour::White:     return setColour( "[0m" );
6838                 case Colour::Red:       return setColour( "[0;31m" );
6839                 case Colour::Green:     return setColour( "[0;32m" );
6840                 case Colour::Blue:      return setColour( "[0:34m" );
6841                 case Colour::Cyan:      return setColour( "[0;36m" );
6842                 case Colour::Yellow:    return setColour( "[0;33m" );
6843                 case Colour::Grey:      return setColour( "[1;30m" );
6844 
6845                 case Colour::LightGrey:     return setColour( "[0;37m" );
6846                 case Colour::BrightRed:     return setColour( "[1;31m" );
6847                 case Colour::BrightGreen:   return setColour( "[1;32m" );
6848                 case Colour::BrightWhite:   return setColour( "[1;37m" );
6849 
6850                 case Colour::Bright: throw std::logic_error( "not a colour" );
6851             }
6852         }
instance()6853         static IColourImpl* instance() {
6854             static PosixColourImpl s_instance;
6855             return &s_instance;
6856         }
6857 
6858     private:
setColour(const char * _escapeCode)6859         void setColour( const char* _escapeCode ) {
6860             Catch::cout() << '\033' << _escapeCode;
6861         }
6862     };
6863 
platformColourInstance()6864     IColourImpl* platformColourInstance() {
6865         Ptr<IConfig const> config = getCurrentContext().getConfig();
6866         return (config && config->forceColour()) || isatty(STDOUT_FILENO)
6867             ? PosixColourImpl::instance()
6868             : NoColourImpl::instance();
6869     }
6870 
6871 } // end anon namespace
6872 } // end namespace Catch
6873 
6874 #else  // not Windows or ANSI ///////////////////////////////////////////////
6875 
6876 namespace Catch {
6877 
platformColourInstance()6878     static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
6879 
6880 } // end namespace Catch
6881 
6882 #endif // Windows/ ANSI/ None
6883 
6884 namespace Catch {
6885 
Colour(Code _colourCode)6886     Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
Colour(Colour const & _other)6887     Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
~Colour()6888     Colour::~Colour(){ if( !m_moved ) use( None ); }
6889 
use(Code _colourCode)6890     void Colour::use( Code _colourCode ) {
6891         static IColourImpl* impl = isDebuggerActive()
6892             ? NoColourImpl::instance()
6893             : platformColourInstance();
6894         impl->use( _colourCode );
6895     }
6896 
6897 } // end namespace Catch
6898 
6899 // #included from: catch_generators_impl.hpp
6900 #define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
6901 
6902 #include <vector>
6903 #include <string>
6904 #include <map>
6905 
6906 namespace Catch {
6907 
6908     struct GeneratorInfo : IGeneratorInfo {
6909 
GeneratorInfoCatch::GeneratorInfo6910         GeneratorInfo( std::size_t size )
6911         :   m_size( size ),
6912             m_currentIndex( 0 )
6913         {}
6914 
moveNextCatch::GeneratorInfo6915         bool moveNext() {
6916             if( ++m_currentIndex == m_size ) {
6917                 m_currentIndex = 0;
6918                 return false;
6919             }
6920             return true;
6921         }
6922 
getCurrentIndexCatch::GeneratorInfo6923         std::size_t getCurrentIndex() const {
6924             return m_currentIndex;
6925         }
6926 
6927         std::size_t m_size;
6928         std::size_t m_currentIndex;
6929     };
6930 
6931     ///////////////////////////////////////////////////////////////////////////
6932 
6933     class GeneratorsForTest : public IGeneratorsForTest {
6934 
6935     public:
~GeneratorsForTest()6936         ~GeneratorsForTest() {
6937             deleteAll( m_generatorsInOrder );
6938         }
6939 
getGeneratorInfo(std::string const & fileInfo,std::size_t size)6940         IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
6941             std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
6942             if( it == m_generatorsByName.end() ) {
6943                 IGeneratorInfo* info = new GeneratorInfo( size );
6944                 m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
6945                 m_generatorsInOrder.push_back( info );
6946                 return *info;
6947             }
6948             return *it->second;
6949         }
6950 
moveNext()6951         bool moveNext() {
6952             std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
6953             std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
6954             for(; it != itEnd; ++it ) {
6955                 if( (*it)->moveNext() )
6956                     return true;
6957             }
6958             return false;
6959         }
6960 
6961     private:
6962         std::map<std::string, IGeneratorInfo*> m_generatorsByName;
6963         std::vector<IGeneratorInfo*> m_generatorsInOrder;
6964     };
6965 
createGeneratorsForTest()6966     IGeneratorsForTest* createGeneratorsForTest()
6967     {
6968         return new GeneratorsForTest();
6969     }
6970 
6971 } // end namespace Catch
6972 
6973 // #included from: catch_assertionresult.hpp
6974 #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
6975 
6976 namespace Catch {
6977 
AssertionInfo(std::string const & _macroName,SourceLineInfo const & _lineInfo,std::string const & _capturedExpression,ResultDisposition::Flags _resultDisposition)6978     AssertionInfo::AssertionInfo(   std::string const& _macroName,
6979                                     SourceLineInfo const& _lineInfo,
6980                                     std::string const& _capturedExpression,
6981                                     ResultDisposition::Flags _resultDisposition )
6982     :   macroName( _macroName ),
6983         lineInfo( _lineInfo ),
6984         capturedExpression( _capturedExpression ),
6985         resultDisposition( _resultDisposition )
6986     {}
6987 
AssertionResult()6988     AssertionResult::AssertionResult() {}
6989 
AssertionResult(AssertionInfo const & info,AssertionResultData const & data)6990     AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
6991     :   m_info( info ),
6992         m_resultData( data )
6993     {}
6994 
~AssertionResult()6995     AssertionResult::~AssertionResult() {}
6996 
6997     // Result was a success
succeeded() const6998     bool AssertionResult::succeeded() const {
6999         return Catch::isOk( m_resultData.resultType );
7000     }
7001 
7002     // Result was a success, or failure is suppressed
isOk() const7003     bool AssertionResult::isOk() const {
7004         return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
7005     }
7006 
getResultType() const7007     ResultWas::OfType AssertionResult::getResultType() const {
7008         return m_resultData.resultType;
7009     }
7010 
hasExpression() const7011     bool AssertionResult::hasExpression() const {
7012         return !m_info.capturedExpression.empty();
7013     }
7014 
hasMessage() const7015     bool AssertionResult::hasMessage() const {
7016         return !m_resultData.message.empty();
7017     }
7018 
getExpression() const7019     std::string AssertionResult::getExpression() const {
7020         if( isFalseTest( m_info.resultDisposition ) )
7021             return "!" + m_info.capturedExpression;
7022         else
7023             return m_info.capturedExpression;
7024     }
getExpressionInMacro() const7025     std::string AssertionResult::getExpressionInMacro() const {
7026         if( m_info.macroName.empty() )
7027             return m_info.capturedExpression;
7028         else
7029             return m_info.macroName + "( " + m_info.capturedExpression + " )";
7030     }
7031 
hasExpandedExpression() const7032     bool AssertionResult::hasExpandedExpression() const {
7033         return hasExpression() && getExpandedExpression() != getExpression();
7034     }
7035 
getExpandedExpression() const7036     std::string AssertionResult::getExpandedExpression() const {
7037         return m_resultData.reconstructedExpression;
7038     }
7039 
getMessage() const7040     std::string AssertionResult::getMessage() const {
7041         return m_resultData.message;
7042     }
getSourceInfo() const7043     SourceLineInfo AssertionResult::getSourceInfo() const {
7044         return m_info.lineInfo;
7045     }
7046 
getTestMacroName() const7047     std::string AssertionResult::getTestMacroName() const {
7048         return m_info.macroName;
7049     }
7050 
7051 } // end namespace Catch
7052 
7053 // #included from: catch_test_case_info.hpp
7054 #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
7055 
7056 namespace Catch {
7057 
parseSpecialTag(std::string const & tag)7058     inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
7059         if( startsWith( tag, "." ) ||
7060             tag == "hide" ||
7061             tag == "!hide" )
7062             return TestCaseInfo::IsHidden;
7063         else if( tag == "!throws" )
7064             return TestCaseInfo::Throws;
7065         else if( tag == "!shouldfail" )
7066             return TestCaseInfo::ShouldFail;
7067         else if( tag == "!mayfail" )
7068             return TestCaseInfo::MayFail;
7069         else
7070             return TestCaseInfo::None;
7071     }
isReservedTag(std::string const & tag)7072     inline bool isReservedTag( std::string const& tag ) {
7073         return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );
7074     }
enforceNotReservedTag(std::string const & tag,SourceLineInfo const & _lineInfo)7075     inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
7076         if( isReservedTag( tag ) ) {
7077             {
7078                 Colour colourGuard( Colour::Red );
7079                 Catch::cerr()
7080                     << "Tag name [" << tag << "] not allowed.\n"
7081                     << "Tag names starting with non alpha-numeric characters are reserved\n";
7082             }
7083             {
7084                 Colour colourGuard( Colour::FileName );
7085                 Catch::cerr() << _lineInfo << std::endl;
7086             }
7087             exit(1);
7088         }
7089     }
7090 
makeTestCase(ITestCase * _testCase,std::string const & _className,std::string const & _name,std::string const & _descOrTags,SourceLineInfo const & _lineInfo)7091     TestCase makeTestCase(  ITestCase* _testCase,
7092                             std::string const& _className,
7093                             std::string const& _name,
7094                             std::string const& _descOrTags,
7095                             SourceLineInfo const& _lineInfo )
7096     {
7097         bool isHidden( startsWith( _name, "./" ) ); // Legacy support
7098 
7099         // Parse out tags
7100         std::set<std::string> tags;
7101         std::string desc, tag;
7102         bool inTag = false;
7103         for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
7104             char c = _descOrTags[i];
7105             if( !inTag ) {
7106                 if( c == '[' )
7107                     inTag = true;
7108                 else
7109                     desc += c;
7110             }
7111             else {
7112                 if( c == ']' ) {
7113                     TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
7114                     if( prop == TestCaseInfo::IsHidden )
7115                         isHidden = true;
7116                     else if( prop == TestCaseInfo::None )
7117                         enforceNotReservedTag( tag, _lineInfo );
7118 
7119                     tags.insert( tag );
7120                     tag.clear();
7121                     inTag = false;
7122                 }
7123                 else
7124                     tag += c;
7125             }
7126         }
7127         if( isHidden ) {
7128             tags.insert( "hide" );
7129             tags.insert( "." );
7130         }
7131 
7132         TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
7133         return TestCase( _testCase, info );
7134     }
7135 
setTags(TestCaseInfo & testCaseInfo,std::set<std::string> const & tags)7136     void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags )
7137     {
7138         testCaseInfo.tags = tags;
7139         testCaseInfo.lcaseTags.clear();
7140 
7141         std::ostringstream oss;
7142         for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {
7143             oss << "[" << *it << "]";
7144             std::string lcaseTag = toLower( *it );
7145             testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
7146             testCaseInfo.lcaseTags.insert( lcaseTag );
7147         }
7148         testCaseInfo.tagsAsString = oss.str();
7149     }
7150 
TestCaseInfo(std::string const & _name,std::string const & _className,std::string const & _description,std::set<std::string> const & _tags,SourceLineInfo const & _lineInfo)7151     TestCaseInfo::TestCaseInfo( std::string const& _name,
7152                                 std::string const& _className,
7153                                 std::string const& _description,
7154                                 std::set<std::string> const& _tags,
7155                                 SourceLineInfo const& _lineInfo )
7156     :   name( _name ),
7157         className( _className ),
7158         description( _description ),
7159         lineInfo( _lineInfo ),
7160         properties( None )
7161     {
7162         setTags( *this, _tags );
7163     }
7164 
TestCaseInfo(TestCaseInfo const & other)7165     TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
7166     :   name( other.name ),
7167         className( other.className ),
7168         description( other.description ),
7169         tags( other.tags ),
7170         lcaseTags( other.lcaseTags ),
7171         tagsAsString( other.tagsAsString ),
7172         lineInfo( other.lineInfo ),
7173         properties( other.properties )
7174     {}
7175 
isHidden() const7176     bool TestCaseInfo::isHidden() const {
7177         return ( properties & IsHidden ) != 0;
7178     }
throws() const7179     bool TestCaseInfo::throws() const {
7180         return ( properties & Throws ) != 0;
7181     }
okToFail() const7182     bool TestCaseInfo::okToFail() const {
7183         return ( properties & (ShouldFail | MayFail ) ) != 0;
7184     }
expectedToFail() const7185     bool TestCaseInfo::expectedToFail() const {
7186         return ( properties & (ShouldFail ) ) != 0;
7187     }
7188 
TestCase(ITestCase * testCase,TestCaseInfo const & info)7189     TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
7190 
TestCase(TestCase const & other)7191     TestCase::TestCase( TestCase const& other )
7192     :   TestCaseInfo( other ),
7193         test( other.test )
7194     {}
7195 
withName(std::string const & _newName) const7196     TestCase TestCase::withName( std::string const& _newName ) const {
7197         TestCase other( *this );
7198         other.name = _newName;
7199         return other;
7200     }
7201 
swap(TestCase & other)7202     void TestCase::swap( TestCase& other ) {
7203         test.swap( other.test );
7204         name.swap( other.name );
7205         className.swap( other.className );
7206         description.swap( other.description );
7207         tags.swap( other.tags );
7208         lcaseTags.swap( other.lcaseTags );
7209         tagsAsString.swap( other.tagsAsString );
7210         std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
7211         std::swap( lineInfo, other.lineInfo );
7212     }
7213 
invoke() const7214     void TestCase::invoke() const {
7215         test->invoke();
7216     }
7217 
operator ==(TestCase const & other) const7218     bool TestCase::operator == ( TestCase const& other ) const {
7219         return  test.get() == other.test.get() &&
7220                 name == other.name &&
7221                 className == other.className;
7222     }
7223 
operator <(TestCase const & other) const7224     bool TestCase::operator < ( TestCase const& other ) const {
7225         return name < other.name;
7226     }
operator =(TestCase const & other)7227     TestCase& TestCase::operator = ( TestCase const& other ) {
7228         TestCase temp( other );
7229         swap( temp );
7230         return *this;
7231     }
7232 
getTestCaseInfo() const7233     TestCaseInfo const& TestCase::getTestCaseInfo() const
7234     {
7235         return *this;
7236     }
7237 
7238 } // end namespace Catch
7239 
7240 // #included from: catch_version.hpp
7241 #define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
7242 
7243 namespace Catch {
7244 
Version(unsigned int _majorVersion,unsigned int _minorVersion,unsigned int _patchNumber,std::string const & _branchName,unsigned int _buildNumber)7245     Version::Version
7246         (   unsigned int _majorVersion,
7247             unsigned int _minorVersion,
7248             unsigned int _patchNumber,
7249             std::string const& _branchName,
7250             unsigned int _buildNumber )
7251     :   majorVersion( _majorVersion ),
7252         minorVersion( _minorVersion ),
7253         patchNumber( _patchNumber ),
7254         branchName( _branchName ),
7255         buildNumber( _buildNumber )
7256     {}
7257 
operator <<(std::ostream & os,Version const & version)7258     std::ostream& operator << ( std::ostream& os, Version const& version ) {
7259         os  << version.majorVersion << "."
7260             << version.minorVersion << "."
7261             << version.patchNumber;
7262 
7263         if( !version.branchName.empty() ) {
7264             os  << "-" << version.branchName
7265                 << "." << version.buildNumber;
7266         }
7267         return os;
7268     }
7269 
7270     Version libraryVersion( 1, 3, 0, "", 0 );
7271 
7272 }
7273 
7274 // #included from: catch_message.hpp
7275 #define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
7276 
7277 namespace Catch {
7278 
MessageInfo(std::string const & _macroName,SourceLineInfo const & _lineInfo,ResultWas::OfType _type)7279     MessageInfo::MessageInfo(   std::string const& _macroName,
7280                                 SourceLineInfo const& _lineInfo,
7281                                 ResultWas::OfType _type )
7282     :   macroName( _macroName ),
7283         lineInfo( _lineInfo ),
7284         type( _type ),
7285         sequence( ++globalCount )
7286     {}
7287 
7288     // This may need protecting if threading support is added
7289     unsigned int MessageInfo::globalCount = 0;
7290 
7291     ////////////////////////////////////////////////////////////////////////////
7292 
ScopedMessage(MessageBuilder const & builder)7293     ScopedMessage::ScopedMessage( MessageBuilder const& builder )
7294     : m_info( builder.m_info )
7295     {
7296         m_info.message = builder.m_stream.str();
7297         getResultCapture().pushScopedMessage( m_info );
7298     }
ScopedMessage(ScopedMessage const & other)7299     ScopedMessage::ScopedMessage( ScopedMessage const& other )
7300     : m_info( other.m_info )
7301     {}
7302 
~ScopedMessage()7303     ScopedMessage::~ScopedMessage() {
7304         getResultCapture().popScopedMessage( m_info );
7305     }
7306 
7307 } // end namespace Catch
7308 
7309 // #included from: catch_legacy_reporter_adapter.hpp
7310 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
7311 
7312 // #included from: catch_legacy_reporter_adapter.h
7313 #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
7314 
7315 namespace Catch
7316 {
7317     // Deprecated
7318     struct IReporter : IShared {
7319         virtual ~IReporter();
7320 
7321         virtual bool shouldRedirectStdout() const = 0;
7322 
7323         virtual void StartTesting() = 0;
7324         virtual void EndTesting( Totals const& totals ) = 0;
7325         virtual void StartGroup( std::string const& groupName ) = 0;
7326         virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
7327         virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
7328         virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
7329         virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
7330         virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
7331         virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
7332         virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
7333         virtual void Aborted() = 0;
7334         virtual void Result( AssertionResult const& result ) = 0;
7335     };
7336 
7337     class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
7338     {
7339     public:
7340         LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
7341         virtual ~LegacyReporterAdapter();
7342 
7343         virtual ReporterPreferences getPreferences() const;
7344         virtual void noMatchingTestCases( std::string const& );
7345         virtual void testRunStarting( TestRunInfo const& );
7346         virtual void testGroupStarting( GroupInfo const& groupInfo );
7347         virtual void testCaseStarting( TestCaseInfo const& testInfo );
7348         virtual void sectionStarting( SectionInfo const& sectionInfo );
7349         virtual void assertionStarting( AssertionInfo const& );
7350         virtual bool assertionEnded( AssertionStats const& assertionStats );
7351         virtual void sectionEnded( SectionStats const& sectionStats );
7352         virtual void testCaseEnded( TestCaseStats const& testCaseStats );
7353         virtual void testGroupEnded( TestGroupStats const& testGroupStats );
7354         virtual void testRunEnded( TestRunStats const& testRunStats );
7355         virtual void skipTest( TestCaseInfo const& );
7356 
7357     private:
7358         Ptr<IReporter> m_legacyReporter;
7359     };
7360 }
7361 
7362 namespace Catch
7363 {
LegacyReporterAdapter(Ptr<IReporter> const & legacyReporter)7364     LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
7365     :   m_legacyReporter( legacyReporter )
7366     {}
~LegacyReporterAdapter()7367     LegacyReporterAdapter::~LegacyReporterAdapter() {}
7368 
getPreferences() const7369     ReporterPreferences LegacyReporterAdapter::getPreferences() const {
7370         ReporterPreferences prefs;
7371         prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
7372         return prefs;
7373     }
7374 
noMatchingTestCases(std::string const &)7375     void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
testRunStarting(TestRunInfo const &)7376     void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
7377         m_legacyReporter->StartTesting();
7378     }
testGroupStarting(GroupInfo const & groupInfo)7379     void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
7380         m_legacyReporter->StartGroup( groupInfo.name );
7381     }
testCaseStarting(TestCaseInfo const & testInfo)7382     void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
7383         m_legacyReporter->StartTestCase( testInfo );
7384     }
sectionStarting(SectionInfo const & sectionInfo)7385     void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
7386         m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
7387     }
assertionStarting(AssertionInfo const &)7388     void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
7389         // Not on legacy interface
7390     }
7391 
assertionEnded(AssertionStats const & assertionStats)7392     bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
7393         if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
7394             for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
7395                     it != itEnd;
7396                     ++it ) {
7397                 if( it->type == ResultWas::Info ) {
7398                     ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal );
7399                     rb << it->message;
7400                     rb.setResultType( ResultWas::Info );
7401                     AssertionResult result = rb.build();
7402                     m_legacyReporter->Result( result );
7403                 }
7404             }
7405         }
7406         m_legacyReporter->Result( assertionStats.assertionResult );
7407         return true;
7408     }
sectionEnded(SectionStats const & sectionStats)7409     void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
7410         if( sectionStats.missingAssertions )
7411             m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
7412         m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
7413     }
testCaseEnded(TestCaseStats const & testCaseStats)7414     void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
7415         m_legacyReporter->EndTestCase
7416             (   testCaseStats.testInfo,
7417                 testCaseStats.totals,
7418                 testCaseStats.stdOut,
7419                 testCaseStats.stdErr );
7420     }
testGroupEnded(TestGroupStats const & testGroupStats)7421     void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
7422         if( testGroupStats.aborting )
7423             m_legacyReporter->Aborted();
7424         m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
7425     }
testRunEnded(TestRunStats const & testRunStats)7426     void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
7427         m_legacyReporter->EndTesting( testRunStats.totals );
7428     }
skipTest(TestCaseInfo const &)7429     void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {
7430     }
7431 }
7432 
7433 // #included from: catch_timer.hpp
7434 
7435 #ifdef __clang__
7436 #pragma clang diagnostic push
7437 #pragma clang diagnostic ignored "-Wc++11-long-long"
7438 #endif
7439 
7440 #ifdef CATCH_PLATFORM_WINDOWS
7441 #include <windows.h>
7442 #else
7443 #include <sys/time.h>
7444 #endif
7445 
7446 namespace Catch {
7447 
7448     namespace {
7449 #ifdef CATCH_PLATFORM_WINDOWS
getCurrentTicks()7450         uint64_t getCurrentTicks() {
7451             static uint64_t hz=0, hzo=0;
7452             if (!hz) {
7453                 QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
7454                 QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
7455             }
7456             uint64_t t;
7457             QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
7458             return ((t-hzo)*1000000)/hz;
7459         }
7460 #else
7461         uint64_t getCurrentTicks() {
7462             timeval t;
7463             gettimeofday(&t,CATCH_NULL);
7464             return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );
7465         }
7466 #endif
7467     }
7468 
start()7469     void Timer::start() {
7470         m_ticks = getCurrentTicks();
7471     }
getElapsedMicroseconds() const7472     unsigned int Timer::getElapsedMicroseconds() const {
7473         return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
7474     }
getElapsedMilliseconds() const7475     unsigned int Timer::getElapsedMilliseconds() const {
7476         return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
7477     }
getElapsedSeconds() const7478     double Timer::getElapsedSeconds() const {
7479         return getElapsedMicroseconds()/1000000.0;
7480     }
7481 
7482 } // namespace Catch
7483 
7484 #ifdef __clang__
7485 #pragma clang diagnostic pop
7486 #endif
7487 // #included from: catch_common.hpp
7488 #define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
7489 
7490 namespace Catch {
7491 
startsWith(std::string const & s,std::string const & prefix)7492     bool startsWith( std::string const& s, std::string const& prefix ) {
7493         return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
7494     }
endsWith(std::string const & s,std::string const & suffix)7495     bool endsWith( std::string const& s, std::string const& suffix ) {
7496         return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
7497     }
contains(std::string const & s,std::string const & infix)7498     bool contains( std::string const& s, std::string const& infix ) {
7499         return s.find( infix ) != std::string::npos;
7500     }
toLowerInPlace(std::string & s)7501     void toLowerInPlace( std::string& s ) {
7502         std::transform( s.begin(), s.end(), s.begin(), ::tolower );
7503     }
toLower(std::string const & s)7504     std::string toLower( std::string const& s ) {
7505         std::string lc = s;
7506         toLowerInPlace( lc );
7507         return lc;
7508     }
trim(std::string const & str)7509     std::string trim( std::string const& str ) {
7510         static char const* whitespaceChars = "\n\r\t ";
7511         std::string::size_type start = str.find_first_not_of( whitespaceChars );
7512         std::string::size_type end = str.find_last_not_of( whitespaceChars );
7513 
7514         return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
7515     }
7516 
replaceInPlace(std::string & str,std::string const & replaceThis,std::string const & withThis)7517     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
7518         bool replaced = false;
7519         std::size_t i = str.find( replaceThis );
7520         while( i != std::string::npos ) {
7521             replaced = true;
7522             str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
7523             if( i < str.size()-withThis.size() )
7524                 i = str.find( replaceThis, i+withThis.size() );
7525             else
7526                 i = std::string::npos;
7527         }
7528         return replaced;
7529     }
7530 
pluralise(std::size_t count,std::string const & label)7531     pluralise::pluralise( std::size_t count, std::string const& label )
7532     :   m_count( count ),
7533         m_label( label )
7534     {}
7535 
operator <<(std::ostream & os,pluralise const & pluraliser)7536     std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
7537         os << pluraliser.m_count << " " << pluraliser.m_label;
7538         if( pluraliser.m_count != 1 )
7539             os << "s";
7540         return os;
7541     }
7542 
SourceLineInfo()7543     SourceLineInfo::SourceLineInfo() : line( 0 ){}
SourceLineInfo(char const * _file,std::size_t _line)7544     SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
7545     :   file( _file ),
7546         line( _line )
7547     {}
SourceLineInfo(SourceLineInfo const & other)7548     SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )
7549     :   file( other.file ),
7550         line( other.line )
7551     {}
empty() const7552     bool SourceLineInfo::empty() const {
7553         return file.empty();
7554     }
operator ==(SourceLineInfo const & other) const7555     bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
7556         return line == other.line && file == other.file;
7557     }
operator <(SourceLineInfo const & other) const7558     bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
7559         return line < other.line || ( line == other.line  && file < other.file );
7560     }
7561 
seedRng(IConfig const & config)7562     void seedRng( IConfig const& config ) {
7563         if( config.rngSeed() != 0 )
7564             std::srand( config.rngSeed() );
7565     }
rngSeed()7566     unsigned int rngSeed() {
7567         return getCurrentContext().getConfig()->rngSeed();
7568     }
7569 
operator <<(std::ostream & os,SourceLineInfo const & info)7570     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
7571 #ifndef __GNUG__
7572         os << info.file << "(" << info.line << ")";
7573 #else
7574         os << info.file << ":" << info.line;
7575 #endif
7576         return os;
7577     }
7578 
throwLogicError(std::string const & message,SourceLineInfo const & locationInfo)7579     void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
7580         std::ostringstream oss;
7581         oss << locationInfo << ": Internal Catch error: '" << message << "'";
7582         if( alwaysTrue() )
7583             throw std::logic_error( oss.str() );
7584     }
7585 }
7586 
7587 // #included from: catch_section.hpp
7588 #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
7589 
7590 namespace Catch {
7591 
SectionInfo(SourceLineInfo const & _lineInfo,std::string const & _name,std::string const & _description)7592     SectionInfo::SectionInfo
7593         (   SourceLineInfo const& _lineInfo,
7594             std::string const& _name,
7595             std::string const& _description )
7596     :   name( _name ),
7597         description( _description ),
7598         lineInfo( _lineInfo )
7599     {}
7600 
Section(SectionInfo const & info)7601     Section::Section( SectionInfo const& info )
7602     :   m_info( info ),
7603         m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
7604     {
7605         m_timer.start();
7606     }
7607 
~Section()7608     Section::~Section() {
7609         if( m_sectionIncluded ) {
7610             SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
7611             if( std::uncaught_exception() )
7612                 getResultCapture().sectionEndedEarly( endInfo );
7613             else
7614                 getResultCapture().sectionEnded( endInfo );
7615         }
7616     }
7617 
7618     // This indicates whether the section should be executed or not
operator bool() const7619     Section::operator bool() const {
7620         return m_sectionIncluded;
7621     }
7622 
7623 } // end namespace Catch
7624 
7625 // #included from: catch_debugger.hpp
7626 #define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
7627 
7628 #include <iostream>
7629 
7630 #ifdef CATCH_PLATFORM_MAC
7631 
7632     #include <assert.h>
7633     #include <stdbool.h>
7634     #include <sys/types.h>
7635     #include <unistd.h>
7636     #include <sys/sysctl.h>
7637 
7638     namespace Catch{
7639 
7640         // The following function is taken directly from the following technical note:
7641         // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
7642 
7643         // Returns true if the current process is being debugged (either
7644         // running under the debugger or has a debugger attached post facto).
isDebuggerActive()7645         bool isDebuggerActive(){
7646 
7647             int                 mib[4];
7648             struct kinfo_proc   info;
7649             size_t              size;
7650 
7651             // Initialize the flags so that, if sysctl fails for some bizarre
7652             // reason, we get a predictable result.
7653 
7654             info.kp_proc.p_flag = 0;
7655 
7656             // Initialize mib, which tells sysctl the info we want, in this case
7657             // we're looking for information about a specific process ID.
7658 
7659             mib[0] = CTL_KERN;
7660             mib[1] = KERN_PROC;
7661             mib[2] = KERN_PROC_PID;
7662             mib[3] = getpid();
7663 
7664             // Call sysctl.
7665 
7666             size = sizeof(info);
7667             if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) {
7668                 Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
7669                 return false;
7670             }
7671 
7672             // We're being debugged if the P_TRACED flag is set.
7673 
7674             return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
7675         }
7676     } // namespace Catch
7677 
7678 #elif defined(_MSC_VER)
7679     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
7680     namespace Catch {
isDebuggerActive()7681         bool isDebuggerActive() {
7682             return IsDebuggerPresent() != 0;
7683         }
7684     }
7685 #elif defined(__MINGW32__)
7686     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
7687     namespace Catch {
isDebuggerActive()7688         bool isDebuggerActive() {
7689             return IsDebuggerPresent() != 0;
7690         }
7691     }
7692 #else
7693     namespace Catch {
isDebuggerActive()7694        inline bool isDebuggerActive() { return false; }
7695     }
7696 #endif // Platform
7697 
7698 #ifdef CATCH_PLATFORM_WINDOWS
7699     extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
7700     namespace Catch {
writeToDebugConsole(std::string const & text)7701         void writeToDebugConsole( std::string const& text ) {
7702             ::OutputDebugStringA( text.c_str() );
7703         }
7704     }
7705 #else
7706     namespace Catch {
writeToDebugConsole(std::string const & text)7707         void writeToDebugConsole( std::string const& text ) {
7708             // !TBD: Need a version for Mac/ XCode and other IDEs
7709             Catch::cout() << text;
7710         }
7711     }
7712 #endif // Platform
7713 
7714 // #included from: catch_tostring.hpp
7715 #define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
7716 
7717 namespace Catch {
7718 
7719 namespace Detail {
7720 
7721     const std::string unprintableString = "{?}";
7722 
7723     namespace {
7724         const int hexThreshold = 255;
7725 
7726         struct Endianness {
7727             enum Arch { Big, Little };
7728 
whichCatch::Detail::__anon4d2db9d10811::Endianness7729             static Arch which() {
7730                 union _{
7731                     int asInt;
7732                     char asChar[sizeof (int)];
7733                 } u;
7734 
7735                 u.asInt = 1;
7736                 return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
7737             }
7738         };
7739     }
7740 
rawMemoryToString(const void * object,std::size_t size)7741     std::string rawMemoryToString( const void *object, std::size_t size )
7742     {
7743         // Reverse order for little endian architectures
7744         int i = 0, end = static_cast<int>( size ), inc = 1;
7745         if( Endianness::which() == Endianness::Little ) {
7746             i = end-1;
7747             end = inc = -1;
7748         }
7749 
7750         unsigned char const *bytes = static_cast<unsigned char const *>(object);
7751         std::ostringstream os;
7752         os << "0x" << std::setfill('0') << std::hex;
7753         for( ; i != end; i += inc )
7754              os << std::setw(2) << static_cast<unsigned>(bytes[i]);
7755        return os.str();
7756     }
7757 }
7758 
toString(std::string const & value)7759 std::string toString( std::string const& value ) {
7760     std::string s = value;
7761     if( getCurrentContext().getConfig()->showInvisibles() ) {
7762         for(size_t i = 0; i < s.size(); ++i ) {
7763             std::string subs;
7764             switch( s[i] ) {
7765             case '\n': subs = "\\n"; break;
7766             case '\t': subs = "\\t"; break;
7767             default: break;
7768             }
7769             if( !subs.empty() ) {
7770                 s = s.substr( 0, i ) + subs + s.substr( i+1 );
7771                 ++i;
7772             }
7773         }
7774     }
7775     return "\"" + s + "\"";
7776 }
toString(std::wstring const & value)7777 std::string toString( std::wstring const& value ) {
7778 
7779     std::string s;
7780     s.reserve( value.size() );
7781     for(size_t i = 0; i < value.size(); ++i )
7782         s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
7783     return Catch::toString( s );
7784 }
7785 
toString(const char * const value)7786 std::string toString( const char* const value ) {
7787     return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
7788 }
7789 
toString(char * const value)7790 std::string toString( char* const value ) {
7791     return Catch::toString( static_cast<const char*>( value ) );
7792 }
7793 
toString(const wchar_t * const value)7794 std::string toString( const wchar_t* const value )
7795 {
7796 	return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
7797 }
7798 
toString(wchar_t * const value)7799 std::string toString( wchar_t* const value )
7800 {
7801 	return Catch::toString( static_cast<const wchar_t*>( value ) );
7802 }
7803 
toString(int value)7804 std::string toString( int value ) {
7805     std::ostringstream oss;
7806     oss << value;
7807     if( value > Detail::hexThreshold )
7808         oss << " (0x" << std::hex << value << ")";
7809     return oss.str();
7810 }
7811 
toString(unsigned long value)7812 std::string toString( unsigned long value ) {
7813     std::ostringstream oss;
7814     oss << value;
7815     if( value > Detail::hexThreshold )
7816         oss << " (0x" << std::hex << value << ")";
7817     return oss.str();
7818 }
7819 
toString(unsigned int value)7820 std::string toString( unsigned int value ) {
7821     return Catch::toString( static_cast<unsigned long>( value ) );
7822 }
7823 
7824 template<typename T>
fpToString(T value,int precision)7825 std::string fpToString( T value, int precision ) {
7826     std::ostringstream oss;
7827     oss << std::setprecision( precision )
7828         << std::fixed
7829         << value;
7830     std::string d = oss.str();
7831     std::size_t i = d.find_last_not_of( '0' );
7832     if( i != std::string::npos && i != d.size()-1 ) {
7833         if( d[i] == '.' )
7834             i++;
7835         d = d.substr( 0, i+1 );
7836     }
7837     return d;
7838 }
7839 
toString(const double value)7840 std::string toString( const double value ) {
7841     return fpToString( value, 10 );
7842 }
toString(const float value)7843 std::string toString( const float value ) {
7844     return fpToString( value, 5 ) + "f";
7845 }
7846 
toString(bool value)7847 std::string toString( bool value ) {
7848     return value ? "true" : "false";
7849 }
7850 
toString(char value)7851 std::string toString( char value ) {
7852     return value < ' '
7853         ? toString( static_cast<unsigned int>( value ) )
7854         : Detail::makeString( value );
7855 }
7856 
toString(signed char value)7857 std::string toString( signed char value ) {
7858     return toString( static_cast<char>( value ) );
7859 }
7860 
toString(unsigned char value)7861 std::string toString( unsigned char value ) {
7862     return toString( static_cast<char>( value ) );
7863 }
7864 
7865 #ifdef CATCH_CONFIG_CPP11_LONG_LONG
toString(long long value)7866 std::string toString( long long value ) {
7867     std::ostringstream oss;
7868     oss << value;
7869     if( value > Detail::hexThreshold )
7870         oss << " (0x" << std::hex << value << ")";
7871     return oss.str();
7872 }
toString(unsigned long long value)7873 std::string toString( unsigned long long value ) {
7874     std::ostringstream oss;
7875     oss << value;
7876     if( value > Detail::hexThreshold )
7877         oss << " (0x" << std::hex << value << ")";
7878     return oss.str();
7879 }
7880 #endif
7881 
7882 #ifdef CATCH_CONFIG_CPP11_NULLPTR
toString(std::nullptr_t)7883 std::string toString( std::nullptr_t ) {
7884     return "nullptr";
7885 }
7886 #endif
7887 
7888 #ifdef __OBJC__
toString(NSString const * const & nsstring)7889     std::string toString( NSString const * const& nsstring ) {
7890         if( !nsstring )
7891             return "nil";
7892         return "@" + toString([nsstring UTF8String]);
7893     }
toString(NSString * CATCH_ARC_STRONG const & nsstring)7894     std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
7895         if( !nsstring )
7896             return "nil";
7897         return "@" + toString([nsstring UTF8String]);
7898     }
toString(NSObject * const & nsObject)7899     std::string toString( NSObject* const& nsObject ) {
7900         return toString( [nsObject description] );
7901     }
7902 #endif
7903 
7904 } // end namespace Catch
7905 
7906 // #included from: catch_result_builder.hpp
7907 #define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
7908 
7909 namespace Catch {
7910 
capturedExpressionWithSecondArgument(std::string const & capturedExpression,std::string const & secondArg)7911     std::string capturedExpressionWithSecondArgument( std::string const& capturedExpression, std::string const& secondArg ) {
7912         return secondArg.empty() || secondArg == "\"\""
7913             ? capturedExpression
7914             : capturedExpression + ", " + secondArg;
7915     }
ResultBuilder(char const * macroName,SourceLineInfo const & lineInfo,char const * capturedExpression,ResultDisposition::Flags resultDisposition,char const * secondArg)7916     ResultBuilder::ResultBuilder(   char const* macroName,
7917                                     SourceLineInfo const& lineInfo,
7918                                     char const* capturedExpression,
7919                                     ResultDisposition::Flags resultDisposition,
7920                                     char const* secondArg )
7921     :   m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ),
7922         m_shouldDebugBreak( false ),
7923         m_shouldThrow( false )
7924     {}
7925 
setResultType(ResultWas::OfType result)7926     ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
7927         m_data.resultType = result;
7928         return *this;
7929     }
setResultType(bool result)7930     ResultBuilder& ResultBuilder::setResultType( bool result ) {
7931         m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
7932         return *this;
7933     }
setLhs(std::string const & lhs)7934     ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) {
7935         m_exprComponents.lhs = lhs;
7936         return *this;
7937     }
setRhs(std::string const & rhs)7938     ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) {
7939         m_exprComponents.rhs = rhs;
7940         return *this;
7941     }
setOp(std::string const & op)7942     ResultBuilder& ResultBuilder::setOp( std::string const& op ) {
7943         m_exprComponents.op = op;
7944         return *this;
7945     }
7946 
endExpression()7947     void ResultBuilder::endExpression() {
7948         m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition );
7949         captureExpression();
7950     }
7951 
useActiveException(ResultDisposition::Flags resultDisposition)7952     void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
7953         m_assertionInfo.resultDisposition = resultDisposition;
7954         m_stream.oss << Catch::translateActiveException();
7955         captureResult( ResultWas::ThrewException );
7956     }
7957 
captureResult(ResultWas::OfType resultType)7958     void ResultBuilder::captureResult( ResultWas::OfType resultType ) {
7959         setResultType( resultType );
7960         captureExpression();
7961     }
captureExpectedException(std::string const & expectedMessage)7962     void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) {
7963         if( expectedMessage.empty() )
7964             captureExpectedException( Matchers::Impl::Generic::AllOf<std::string>() );
7965         else
7966             captureExpectedException( Matchers::Equals( expectedMessage ) );
7967     }
7968 
captureExpectedException(Matchers::Impl::Matcher<std::string> const & matcher)7969     void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher ) {
7970 
7971         assert( m_exprComponents.testFalse == false );
7972         AssertionResultData data = m_data;
7973         data.resultType = ResultWas::Ok;
7974         data.reconstructedExpression = m_assertionInfo.capturedExpression;
7975 
7976         std::string actualMessage = Catch::translateActiveException();
7977         if( !matcher.match( actualMessage ) ) {
7978             data.resultType = ResultWas::ExpressionFailed;
7979             data.reconstructedExpression = actualMessage;
7980         }
7981         AssertionResult result( m_assertionInfo, data );
7982         handleResult( result );
7983     }
7984 
captureExpression()7985     void ResultBuilder::captureExpression() {
7986         AssertionResult result = build();
7987         handleResult( result );
7988     }
handleResult(AssertionResult const & result)7989     void ResultBuilder::handleResult( AssertionResult const& result )
7990     {
7991         getResultCapture().assertionEnded( result );
7992 
7993         if( !result.isOk() ) {
7994             if( getCurrentContext().getConfig()->shouldDebugBreak() )
7995                 m_shouldDebugBreak = true;
7996             if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )
7997                 m_shouldThrow = true;
7998         }
7999     }
react()8000     void ResultBuilder::react() {
8001         if( m_shouldThrow )
8002             throw Catch::TestFailureException();
8003     }
8004 
shouldDebugBreak() const8005     bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }
allowThrows() const8006     bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }
8007 
build() const8008     AssertionResult ResultBuilder::build() const
8009     {
8010         assert( m_data.resultType != ResultWas::Unknown );
8011 
8012         AssertionResultData data = m_data;
8013 
8014         // Flip bool results if testFalse is set
8015         if( m_exprComponents.testFalse ) {
8016             if( data.resultType == ResultWas::Ok )
8017                 data.resultType = ResultWas::ExpressionFailed;
8018             else if( data.resultType == ResultWas::ExpressionFailed )
8019                 data.resultType = ResultWas::Ok;
8020         }
8021 
8022         data.message = m_stream.oss.str();
8023         data.reconstructedExpression = reconstructExpression();
8024         if( m_exprComponents.testFalse ) {
8025             if( m_exprComponents.op == "" )
8026                 data.reconstructedExpression = "!" + data.reconstructedExpression;
8027             else
8028                 data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
8029         }
8030         return AssertionResult( m_assertionInfo, data );
8031     }
reconstructExpression() const8032     std::string ResultBuilder::reconstructExpression() const {
8033         if( m_exprComponents.op == "" )
8034             return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
8035         else if( m_exprComponents.op == "matches" )
8036             return m_exprComponents.lhs + " " + m_exprComponents.rhs;
8037         else if( m_exprComponents.op != "!" ) {
8038             if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
8039                 m_exprComponents.lhs.find("\n") == std::string::npos &&
8040                 m_exprComponents.rhs.find("\n") == std::string::npos )
8041                 return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs;
8042             else
8043                 return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs;
8044         }
8045         else
8046             return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}";
8047     }
8048 
8049 } // end namespace Catch
8050 
8051 // #included from: catch_tag_alias_registry.hpp
8052 #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
8053 
8054 // #included from: catch_tag_alias_registry.h
8055 #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
8056 
8057 #include <map>
8058 
8059 namespace Catch {
8060 
8061     class TagAliasRegistry : public ITagAliasRegistry {
8062     public:
8063         virtual ~TagAliasRegistry();
8064         virtual Option<TagAlias> find( std::string const& alias ) const;
8065         virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
8066         void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
8067         static TagAliasRegistry& get();
8068 
8069     private:
8070         std::map<std::string, TagAlias> m_registry;
8071     };
8072 
8073 } // end namespace Catch
8074 
8075 #include <map>
8076 #include <iostream>
8077 
8078 namespace Catch {
8079 
~TagAliasRegistry()8080     TagAliasRegistry::~TagAliasRegistry() {}
8081 
find(std::string const & alias) const8082     Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {
8083         std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
8084         if( it != m_registry.end() )
8085             return it->second;
8086         else
8087             return Option<TagAlias>();
8088     }
8089 
expandAliases(std::string const & unexpandedTestSpec) const8090     std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
8091         std::string expandedTestSpec = unexpandedTestSpec;
8092         for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
8093                 it != itEnd;
8094                 ++it ) {
8095             std::size_t pos = expandedTestSpec.find( it->first );
8096             if( pos != std::string::npos ) {
8097                 expandedTestSpec =  expandedTestSpec.substr( 0, pos ) +
8098                                     it->second.tag +
8099                                     expandedTestSpec.substr( pos + it->first.size() );
8100             }
8101         }
8102         return expandedTestSpec;
8103     }
8104 
add(char const * alias,char const * tag,SourceLineInfo const & lineInfo)8105     void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
8106 
8107         if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) {
8108             std::ostringstream oss;
8109             oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
8110             throw std::domain_error( oss.str().c_str() );
8111         }
8112         if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
8113             std::ostringstream oss;
8114             oss << "error: tag alias, \"" << alias << "\" already registered.\n"
8115                 << "\tFirst seen at " << find(alias)->lineInfo << "\n"
8116                 << "\tRedefined at " << lineInfo;
8117             throw std::domain_error( oss.str().c_str() );
8118         }
8119     }
8120 
get()8121     TagAliasRegistry& TagAliasRegistry::get() {
8122         static TagAliasRegistry instance;
8123         return instance;
8124 
8125     }
8126 
~ITagAliasRegistry()8127     ITagAliasRegistry::~ITagAliasRegistry() {}
get()8128     ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }
8129 
RegistrarForTagAliases(char const * alias,char const * tag,SourceLineInfo const & lineInfo)8130     RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
8131         try {
8132             TagAliasRegistry::get().add( alias, tag, lineInfo );
8133         }
8134         catch( std::exception& ex ) {
8135             Colour colourGuard( Colour::Red );
8136             Catch::cerr() << ex.what() << std::endl;
8137             exit(1);
8138         }
8139     }
8140 
8141 } // end namespace Catch
8142 
8143 // #included from: ../reporters/catch_reporter_multi.hpp
8144 #define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED
8145 
8146 namespace Catch {
8147 
8148 class MultipleReporters : public SharedImpl<IStreamingReporter> {
8149     typedef std::vector<Ptr<IStreamingReporter> > Reporters;
8150     Reporters m_reporters;
8151 
8152 public:
add(Ptr<IStreamingReporter> const & reporter)8153     void add( Ptr<IStreamingReporter> const& reporter ) {
8154         m_reporters.push_back( reporter );
8155     }
8156 
8157 public: // IStreamingReporter
8158 
getPreferences() const8159     virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
8160         return m_reporters[0]->getPreferences();
8161     }
8162 
noMatchingTestCases(std::string const & spec)8163     virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
8164         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8165                 it != itEnd;
8166                 ++it )
8167             (*it)->noMatchingTestCases( spec );
8168     }
8169 
testRunStarting(TestRunInfo const & testRunInfo)8170     virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE {
8171         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8172                 it != itEnd;
8173                 ++it )
8174             (*it)->testRunStarting( testRunInfo );
8175     }
8176 
testGroupStarting(GroupInfo const & groupInfo)8177     virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
8178         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8179                 it != itEnd;
8180                 ++it )
8181             (*it)->testGroupStarting( groupInfo );
8182     }
8183 
testCaseStarting(TestCaseInfo const & testInfo)8184     virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
8185         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8186                 it != itEnd;
8187                 ++it )
8188             (*it)->testCaseStarting( testInfo );
8189     }
8190 
sectionStarting(SectionInfo const & sectionInfo)8191     virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
8192         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8193                 it != itEnd;
8194                 ++it )
8195             (*it)->sectionStarting( sectionInfo );
8196     }
8197 
assertionStarting(AssertionInfo const & assertionInfo)8198     virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE {
8199         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8200                 it != itEnd;
8201                 ++it )
8202             (*it)->assertionStarting( assertionInfo );
8203     }
8204 
8205     // The return value indicates if the messages buffer should be cleared:
assertionEnded(AssertionStats const & assertionStats)8206     virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
8207         bool clearBuffer = false;
8208         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8209                 it != itEnd;
8210                 ++it )
8211             clearBuffer |= (*it)->assertionEnded( assertionStats );
8212         return clearBuffer;
8213     }
8214 
sectionEnded(SectionStats const & sectionStats)8215     virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
8216         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8217                 it != itEnd;
8218                 ++it )
8219             (*it)->sectionEnded( sectionStats );
8220     }
8221 
testCaseEnded(TestCaseStats const & testCaseStats)8222     virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
8223         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8224                 it != itEnd;
8225                 ++it )
8226             (*it)->testCaseEnded( testCaseStats );
8227     }
8228 
testGroupEnded(TestGroupStats const & testGroupStats)8229     virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
8230         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8231                 it != itEnd;
8232                 ++it )
8233             (*it)->testGroupEnded( testGroupStats );
8234     }
8235 
testRunEnded(TestRunStats const & testRunStats)8236     virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
8237         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8238                 it != itEnd;
8239                 ++it )
8240             (*it)->testRunEnded( testRunStats );
8241     }
8242 
skipTest(TestCaseInfo const & testInfo)8243     virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
8244         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
8245                 it != itEnd;
8246                 ++it )
8247             (*it)->skipTest( testInfo );
8248     }
8249 };
8250 
addReporter(Ptr<IStreamingReporter> const & existingReporter,Ptr<IStreamingReporter> const & additionalReporter)8251 Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
8252     Ptr<IStreamingReporter> resultingReporter;
8253 
8254     if( existingReporter ) {
8255         MultipleReporters* multi = dynamic_cast<MultipleReporters*>( existingReporter.get() );
8256         if( !multi ) {
8257             multi = new MultipleReporters;
8258             resultingReporter = Ptr<IStreamingReporter>( multi );
8259             if( existingReporter )
8260                 multi->add( existingReporter );
8261         }
8262         else
8263             resultingReporter = existingReporter;
8264         multi->add( additionalReporter );
8265     }
8266     else
8267         resultingReporter = additionalReporter;
8268 
8269     return resultingReporter;
8270 }
8271 
8272 } // end namespace Catch
8273 
8274 // #included from: ../reporters/catch_reporter_xml.hpp
8275 #define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
8276 
8277 // #included from: catch_reporter_bases.hpp
8278 #define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
8279 
8280 #include <cstring>
8281 
8282 namespace Catch {
8283 
8284     struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
8285 
StreamingReporterBaseCatch::StreamingReporterBase8286         StreamingReporterBase( ReporterConfig const& _config )
8287         :   m_config( _config.fullConfig() ),
8288             stream( _config.stream() )
8289         {
8290             m_reporterPrefs.shouldRedirectStdOut = false;
8291         }
8292 
getPreferencesCatch::StreamingReporterBase8293         virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
8294             return m_reporterPrefs;
8295         }
8296 
8297         virtual ~StreamingReporterBase() CATCH_OVERRIDE;
8298 
noMatchingTestCasesCatch::StreamingReporterBase8299         virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {}
8300 
testRunStartingCatch::StreamingReporterBase8301         virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE {
8302             currentTestRunInfo = _testRunInfo;
8303         }
testGroupStartingCatch::StreamingReporterBase8304         virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE {
8305             currentGroupInfo = _groupInfo;
8306         }
8307 
testCaseStartingCatch::StreamingReporterBase8308         virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE {
8309             currentTestCaseInfo = _testInfo;
8310         }
sectionStartingCatch::StreamingReporterBase8311         virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
8312             m_sectionStack.push_back( _sectionInfo );
8313         }
8314 
sectionEndedCatch::StreamingReporterBase8315         virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE {
8316             m_sectionStack.pop_back();
8317         }
testCaseEndedCatch::StreamingReporterBase8318         virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE {
8319             currentTestCaseInfo.reset();
8320         }
testGroupEndedCatch::StreamingReporterBase8321         virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE {
8322             currentGroupInfo.reset();
8323         }
testRunEndedCatch::StreamingReporterBase8324         virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE {
8325             currentTestCaseInfo.reset();
8326             currentGroupInfo.reset();
8327             currentTestRunInfo.reset();
8328         }
8329 
skipTestCatch::StreamingReporterBase8330         virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {
8331             // Don't do anything with this by default.
8332             // It can optionally be overridden in the derived class.
8333         }
8334 
8335         Ptr<IConfig const> m_config;
8336         std::ostream& stream;
8337 
8338         LazyStat<TestRunInfo> currentTestRunInfo;
8339         LazyStat<GroupInfo> currentGroupInfo;
8340         LazyStat<TestCaseInfo> currentTestCaseInfo;
8341 
8342         std::vector<SectionInfo> m_sectionStack;
8343         ReporterPreferences m_reporterPrefs;
8344     };
8345 
8346     struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
8347         template<typename T, typename ChildNodeT>
8348         struct Node : SharedImpl<> {
NodeCatch::CumulativeReporterBase::Node8349             explicit Node( T const& _value ) : value( _value ) {}
~NodeCatch::CumulativeReporterBase::Node8350             virtual ~Node() {}
8351 
8352             typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
8353             T value;
8354             ChildNodes children;
8355         };
8356         struct SectionNode : SharedImpl<> {
SectionNodeCatch::CumulativeReporterBase::SectionNode8357             explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
8358             virtual ~SectionNode();
8359 
operator ==Catch::CumulativeReporterBase::SectionNode8360             bool operator == ( SectionNode const& other ) const {
8361                 return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
8362             }
operator ==Catch::CumulativeReporterBase::SectionNode8363             bool operator == ( Ptr<SectionNode> const& other ) const {
8364                 return operator==( *other );
8365             }
8366 
8367             SectionStats stats;
8368             typedef std::vector<Ptr<SectionNode> > ChildSections;
8369             typedef std::vector<AssertionStats> Assertions;
8370             ChildSections childSections;
8371             Assertions assertions;
8372             std::string stdOut;
8373             std::string stdErr;
8374         };
8375 
8376         struct BySectionInfo {
BySectionInfoCatch::CumulativeReporterBase::BySectionInfo8377             BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
BySectionInfoCatch::CumulativeReporterBase::BySectionInfo8378 			BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
operator ()Catch::CumulativeReporterBase::BySectionInfo8379             bool operator() ( Ptr<SectionNode> const& node ) const {
8380                 return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
8381             }
8382         private:
8383 			void operator=( BySectionInfo const& );
8384             SectionInfo const& m_other;
8385         };
8386 
8387         typedef Node<TestCaseStats, SectionNode> TestCaseNode;
8388         typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
8389         typedef Node<TestRunStats, TestGroupNode> TestRunNode;
8390 
CumulativeReporterBaseCatch::CumulativeReporterBase8391         CumulativeReporterBase( ReporterConfig const& _config )
8392         :   m_config( _config.fullConfig() ),
8393             stream( _config.stream() )
8394         {
8395             m_reporterPrefs.shouldRedirectStdOut = false;
8396         }
8397         ~CumulativeReporterBase();
8398 
getPreferencesCatch::CumulativeReporterBase8399         virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
8400             return m_reporterPrefs;
8401         }
8402 
testRunStartingCatch::CumulativeReporterBase8403         virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {}
testGroupStartingCatch::CumulativeReporterBase8404         virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {}
8405 
testCaseStartingCatch::CumulativeReporterBase8406         virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {}
8407 
sectionStartingCatch::CumulativeReporterBase8408         virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
8409             SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
8410             Ptr<SectionNode> node;
8411             if( m_sectionStack.empty() ) {
8412                 if( !m_rootSection )
8413                     m_rootSection = new SectionNode( incompleteStats );
8414                 node = m_rootSection;
8415             }
8416             else {
8417                 SectionNode& parentNode = *m_sectionStack.back();
8418                 SectionNode::ChildSections::const_iterator it =
8419                     std::find_if(   parentNode.childSections.begin(),
8420                                     parentNode.childSections.end(),
8421                                     BySectionInfo( sectionInfo ) );
8422                 if( it == parentNode.childSections.end() ) {
8423                     node = new SectionNode( incompleteStats );
8424                     parentNode.childSections.push_back( node );
8425                 }
8426                 else
8427                     node = *it;
8428             }
8429             m_sectionStack.push_back( node );
8430             m_deepestSection = node;
8431         }
8432 
assertionStartingCatch::CumulativeReporterBase8433         virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
8434 
assertionEndedCatch::CumulativeReporterBase8435         virtual bool assertionEnded( AssertionStats const& assertionStats ) {
8436             assert( !m_sectionStack.empty() );
8437             SectionNode& sectionNode = *m_sectionStack.back();
8438             sectionNode.assertions.push_back( assertionStats );
8439             return true;
8440         }
sectionEndedCatch::CumulativeReporterBase8441         virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
8442             assert( !m_sectionStack.empty() );
8443             SectionNode& node = *m_sectionStack.back();
8444             node.stats = sectionStats;
8445             m_sectionStack.pop_back();
8446         }
testCaseEndedCatch::CumulativeReporterBase8447         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
8448             Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
8449             assert( m_sectionStack.size() == 0 );
8450             node->children.push_back( m_rootSection );
8451             m_testCases.push_back( node );
8452             m_rootSection.reset();
8453 
8454             assert( m_deepestSection );
8455             m_deepestSection->stdOut = testCaseStats.stdOut;
8456             m_deepestSection->stdErr = testCaseStats.stdErr;
8457         }
testGroupEndedCatch::CumulativeReporterBase8458         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
8459             Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
8460             node->children.swap( m_testCases );
8461             m_testGroups.push_back( node );
8462         }
testRunEndedCatch::CumulativeReporterBase8463         virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
8464             Ptr<TestRunNode> node = new TestRunNode( testRunStats );
8465             node->children.swap( m_testGroups );
8466             m_testRuns.push_back( node );
8467             testRunEndedCumulative();
8468         }
8469         virtual void testRunEndedCumulative() = 0;
8470 
skipTestCatch::CumulativeReporterBase8471         virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}
8472 
8473         Ptr<IConfig const> m_config;
8474         std::ostream& stream;
8475         std::vector<AssertionStats> m_assertions;
8476         std::vector<std::vector<Ptr<SectionNode> > > m_sections;
8477         std::vector<Ptr<TestCaseNode> > m_testCases;
8478         std::vector<Ptr<TestGroupNode> > m_testGroups;
8479 
8480         std::vector<Ptr<TestRunNode> > m_testRuns;
8481 
8482         Ptr<SectionNode> m_rootSection;
8483         Ptr<SectionNode> m_deepestSection;
8484         std::vector<Ptr<SectionNode> > m_sectionStack;
8485         ReporterPreferences m_reporterPrefs;
8486 
8487     };
8488 
8489     template<char C>
getLineOfChars()8490     char const* getLineOfChars() {
8491         static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
8492         if( !*line ) {
8493             memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
8494             line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
8495         }
8496         return line;
8497     }
8498 
8499     struct TestEventListenerBase : StreamingReporterBase {
TestEventListenerBaseCatch::TestEventListenerBase8500         TestEventListenerBase( ReporterConfig const& _config )
8501         :   StreamingReporterBase( _config )
8502         {}
8503 
assertionStartingCatch::TestEventListenerBase8504         virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
assertionEndedCatch::TestEventListenerBase8505         virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE {
8506             return false;
8507         }
8508     };
8509 
8510 } // end namespace Catch
8511 
8512 // #included from: ../internal/catch_reporter_registrars.hpp
8513 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
8514 
8515 namespace Catch {
8516 
8517     template<typename T>
8518     class LegacyReporterRegistrar {
8519 
8520         class ReporterFactory : public IReporterFactory {
create(ReporterConfig const & config) const8521             virtual IStreamingReporter* create( ReporterConfig const& config ) const {
8522                 return new LegacyReporterAdapter( new T( config ) );
8523             }
8524 
getDescription() const8525             virtual std::string getDescription() const {
8526                 return T::getDescription();
8527             }
8528         };
8529 
8530     public:
8531 
LegacyReporterRegistrar(std::string const & name)8532         LegacyReporterRegistrar( std::string const& name ) {
8533             getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
8534         }
8535     };
8536 
8537     template<typename T>
8538     class ReporterRegistrar {
8539 
8540         class ReporterFactory : public SharedImpl<IReporterFactory> {
8541 
8542             // *** Please Note ***:
8543             // - If you end up here looking at a compiler error because it's trying to register
8544             // your custom reporter class be aware that the native reporter interface has changed
8545             // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via
8546             // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.
8547             // However please consider updating to the new interface as the old one is now
8548             // deprecated and will probably be removed quite soon!
8549             // Please contact me via github if you have any questions at all about this.
8550             // In fact, ideally, please contact me anyway to let me know you've hit this - as I have
8551             // no idea who is actually using custom reporters at all (possibly no-one!).
8552             // The new interface is designed to minimise exposure to interface changes in the future.
create(ReporterConfig const & config) const8553             virtual IStreamingReporter* create( ReporterConfig const& config ) const {
8554                 return new T( config );
8555             }
8556 
getDescription() const8557             virtual std::string getDescription() const {
8558                 return T::getDescription();
8559             }
8560         };
8561 
8562     public:
8563 
ReporterRegistrar(std::string const & name)8564         ReporterRegistrar( std::string const& name ) {
8565             getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
8566         }
8567     };
8568 
8569     template<typename T>
8570     class ListenerRegistrar {
8571 
8572         class ListenerFactory : public SharedImpl<IReporterFactory> {
8573 
create(ReporterConfig const & config) const8574             virtual IStreamingReporter* create( ReporterConfig const& config ) const {
8575                 return new T( config );
8576             }
getDescription() const8577             virtual std::string getDescription() const {
8578                 return "";
8579             }
8580         };
8581 
8582     public:
8583 
ListenerRegistrar()8584         ListenerRegistrar() {
8585             getMutableRegistryHub().registerListener( new ListenerFactory() );
8586         }
8587     };
8588 }
8589 
8590 #define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
8591     namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
8592 
8593 #define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
8594     namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
8595 
8596 #define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \
8597     namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
8598 
8599 // #included from: ../internal/catch_xmlwriter.hpp
8600 #define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
8601 
8602 #include <sstream>
8603 #include <string>
8604 #include <vector>
8605 #include <iomanip>
8606 
8607 namespace Catch {
8608 
8609     class XmlEncode {
8610     public:
8611         enum ForWhat { ForTextNodes, ForAttributes };
8612 
XmlEncode(std::string const & str,ForWhat forWhat=ForTextNodes)8613         XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes )
8614         :   m_str( str ),
8615             m_forWhat( forWhat )
8616         {}
8617 
encodeTo(std::ostream & os) const8618         void encodeTo( std::ostream& os ) const {
8619 
8620             // Apostrophe escaping not necessary if we always use " to write attributes
8621             // (see: http://www.w3.org/TR/xml/#syntax)
8622 
8623             for( std::size_t i = 0; i < m_str.size(); ++ i ) {
8624                 char c = m_str[i];
8625                 switch( c ) {
8626                     case '<':   os << "&lt;"; break;
8627                     case '&':   os << "&amp;"; break;
8628 
8629                     case '>':
8630                         // See: http://www.w3.org/TR/xml/#syntax
8631                         if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )
8632                             os << "&gt;";
8633                         else
8634                             os << c;
8635                         break;
8636 
8637                     case '\"':
8638                         if( m_forWhat == ForAttributes )
8639                             os << "&quot;";
8640                         else
8641                             os << c;
8642                         break;
8643 
8644                     default:
8645                         // Escape control chars - based on contribution by @espenalb in PR #465
8646                         if ( ( c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' )
8647                             os << "&#x" << std::uppercase << std::hex << static_cast<int>( c );
8648                         else
8649                             os << c;
8650                 }
8651             }
8652         }
8653 
operator <<(std::ostream & os,XmlEncode const & xmlEncode)8654         friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
8655             xmlEncode.encodeTo( os );
8656             return os;
8657         }
8658 
8659     private:
8660         std::string m_str;
8661         ForWhat m_forWhat;
8662     };
8663 
8664     class XmlWriter {
8665     public:
8666 
8667         class ScopedElement {
8668         public:
ScopedElement(XmlWriter * writer)8669             ScopedElement( XmlWriter* writer )
8670             :   m_writer( writer )
8671             {}
8672 
ScopedElement(ScopedElement const & other)8673             ScopedElement( ScopedElement const& other )
8674             :   m_writer( other.m_writer ){
8675                 other.m_writer = CATCH_NULL;
8676             }
8677 
~ScopedElement()8678             ~ScopedElement() {
8679                 if( m_writer )
8680                     m_writer->endElement();
8681             }
8682 
writeText(std::string const & text,bool indent=true)8683             ScopedElement& writeText( std::string const& text, bool indent = true ) {
8684                 m_writer->writeText( text, indent );
8685                 return *this;
8686             }
8687 
8688             template<typename T>
writeAttribute(std::string const & name,T const & attribute)8689             ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
8690                 m_writer->writeAttribute( name, attribute );
8691                 return *this;
8692             }
8693 
8694         private:
8695             mutable XmlWriter* m_writer;
8696         };
8697 
XmlWriter()8698         XmlWriter()
8699         :   m_tagIsOpen( false ),
8700             m_needsNewline( false ),
8701             m_os( &Catch::cout() )
8702         {}
8703 
XmlWriter(std::ostream & os)8704         XmlWriter( std::ostream& os )
8705         :   m_tagIsOpen( false ),
8706             m_needsNewline( false ),
8707             m_os( &os )
8708         {}
8709 
~XmlWriter()8710         ~XmlWriter() {
8711             while( !m_tags.empty() )
8712                 endElement();
8713         }
8714 
startElement(std::string const & name)8715         XmlWriter& startElement( std::string const& name ) {
8716             ensureTagClosed();
8717             newlineIfNecessary();
8718             stream() << m_indent << "<" << name;
8719             m_tags.push_back( name );
8720             m_indent += "  ";
8721             m_tagIsOpen = true;
8722             return *this;
8723         }
8724 
scopedElement(std::string const & name)8725         ScopedElement scopedElement( std::string const& name ) {
8726             ScopedElement scoped( this );
8727             startElement( name );
8728             return scoped;
8729         }
8730 
endElement()8731         XmlWriter& endElement() {
8732             newlineIfNecessary();
8733             m_indent = m_indent.substr( 0, m_indent.size()-2 );
8734             if( m_tagIsOpen ) {
8735                 stream() << "/>\n";
8736                 m_tagIsOpen = false;
8737             }
8738             else {
8739                 stream() << m_indent << "</" << m_tags.back() << ">\n";
8740             }
8741             m_tags.pop_back();
8742             return *this;
8743         }
8744 
writeAttribute(std::string const & name,std::string const & attribute)8745         XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
8746             if( !name.empty() && !attribute.empty() )
8747                 stream() << " " << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << "\"";
8748             return *this;
8749         }
8750 
writeAttribute(std::string const & name,bool attribute)8751         XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
8752             stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\"";
8753             return *this;
8754         }
8755 
8756         template<typename T>
writeAttribute(std::string const & name,T const & attribute)8757         XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
8758             std::ostringstream oss;
8759             oss << attribute;
8760             return writeAttribute( name, oss.str() );
8761         }
8762 
writeText(std::string const & text,bool indent=true)8763         XmlWriter& writeText( std::string const& text, bool indent = true ) {
8764             if( !text.empty() ){
8765                 bool tagWasOpen = m_tagIsOpen;
8766                 ensureTagClosed();
8767                 if( tagWasOpen && indent )
8768                     stream() << m_indent;
8769                 stream() << XmlEncode( text );
8770                 m_needsNewline = true;
8771             }
8772             return *this;
8773         }
8774 
writeComment(std::string const & text)8775         XmlWriter& writeComment( std::string const& text ) {
8776             ensureTagClosed();
8777             stream() << m_indent << "<!--" << text << "-->";
8778             m_needsNewline = true;
8779             return *this;
8780         }
8781 
writeBlankLine()8782         XmlWriter& writeBlankLine() {
8783             ensureTagClosed();
8784             stream() << "\n";
8785             return *this;
8786         }
8787 
setStream(std::ostream & os)8788         void setStream( std::ostream& os ) {
8789             m_os = &os;
8790         }
8791 
8792     private:
8793         XmlWriter( XmlWriter const& );
8794         void operator=( XmlWriter const& );
8795 
stream()8796         std::ostream& stream() {
8797             return *m_os;
8798         }
8799 
ensureTagClosed()8800         void ensureTagClosed() {
8801             if( m_tagIsOpen ) {
8802                 stream() << ">\n";
8803                 m_tagIsOpen = false;
8804             }
8805         }
8806 
newlineIfNecessary()8807         void newlineIfNecessary() {
8808             if( m_needsNewline ) {
8809                 stream() << "\n";
8810                 m_needsNewline = false;
8811             }
8812         }
8813 
8814         bool m_tagIsOpen;
8815         bool m_needsNewline;
8816         std::vector<std::string> m_tags;
8817         std::string m_indent;
8818         std::ostream* m_os;
8819     };
8820 
8821 }
8822 // #included from: catch_reenable_warnings.h
8823 
8824 #define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED
8825 
8826 #ifdef __clang__
8827 #    ifdef __ICC // icpc defines the __clang__ macro
8828 #        pragma warning(pop)
8829 #    else
8830 #        pragma clang diagnostic pop
8831 #    endif
8832 #elif defined __GNUC__
8833 #    pragma GCC diagnostic pop
8834 #endif
8835 
8836 
8837 namespace Catch {
8838     class XmlReporter : public StreamingReporterBase {
8839     public:
XmlReporter(ReporterConfig const & _config)8840         XmlReporter( ReporterConfig const& _config )
8841         :   StreamingReporterBase( _config ),
8842             m_sectionDepth( 0 )
8843         {
8844             m_reporterPrefs.shouldRedirectStdOut = true;
8845         }
8846 
8847         virtual ~XmlReporter() CATCH_OVERRIDE;
8848 
getDescription()8849         static std::string getDescription() {
8850             return "Reports test results as an XML document";
8851         }
8852 
8853     public: // StreamingReporterBase
8854 
noMatchingTestCases(std::string const & s)8855         virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE {
8856             StreamingReporterBase::noMatchingTestCases( s );
8857         }
8858 
testRunStarting(TestRunInfo const & testInfo)8859         virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE {
8860             StreamingReporterBase::testRunStarting( testInfo );
8861             m_xml.setStream( stream );
8862             m_xml.startElement( "Catch" );
8863             if( !m_config->name().empty() )
8864                 m_xml.writeAttribute( "name", m_config->name() );
8865         }
8866 
testGroupStarting(GroupInfo const & groupInfo)8867         virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
8868             StreamingReporterBase::testGroupStarting( groupInfo );
8869             m_xml.startElement( "Group" )
8870                 .writeAttribute( "name", groupInfo.name );
8871         }
8872 
testCaseStarting(TestCaseInfo const & testInfo)8873         virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
8874             StreamingReporterBase::testCaseStarting(testInfo);
8875             m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
8876 
8877             if ( m_config->showDurations() == ShowDurations::Always )
8878                 m_testCaseTimer.start();
8879         }
8880 
sectionStarting(SectionInfo const & sectionInfo)8881         virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
8882             StreamingReporterBase::sectionStarting( sectionInfo );
8883             if( m_sectionDepth++ > 0 ) {
8884                 m_xml.startElement( "Section" )
8885                     .writeAttribute( "name", trim( sectionInfo.name ) )
8886                     .writeAttribute( "description", sectionInfo.description );
8887             }
8888         }
8889 
assertionStarting(AssertionInfo const &)8890         virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { }
8891 
assertionEnded(AssertionStats const & assertionStats)8892         virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
8893             const AssertionResult& assertionResult = assertionStats.assertionResult;
8894 
8895             // Print any info messages in <Info> tags.
8896             if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
8897                 for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
8898                         it != itEnd;
8899                         ++it ) {
8900                     if( it->type == ResultWas::Info ) {
8901                         m_xml.scopedElement( "Info" )
8902                             .writeText( it->message );
8903                     } else if ( it->type == ResultWas::Warning ) {
8904                         m_xml.scopedElement( "Warning" )
8905                             .writeText( it->message );
8906                     }
8907                 }
8908             }
8909 
8910             // Drop out if result was successful but we're not printing them.
8911             if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
8912                 return true;
8913 
8914             // Print the expression if there is one.
8915             if( assertionResult.hasExpression() ) {
8916                 m_xml.startElement( "Expression" )
8917                     .writeAttribute( "success", assertionResult.succeeded() )
8918 					.writeAttribute( "type", assertionResult.getTestMacroName() )
8919                     .writeAttribute( "filename", assertionResult.getSourceInfo().file )
8920                     .writeAttribute( "line", assertionResult.getSourceInfo().line );
8921 
8922                 m_xml.scopedElement( "Original" )
8923                     .writeText( assertionResult.getExpression() );
8924                 m_xml.scopedElement( "Expanded" )
8925                     .writeText( assertionResult.getExpandedExpression() );
8926             }
8927 
8928             // And... Print a result applicable to each result type.
8929             switch( assertionResult.getResultType() ) {
8930                 case ResultWas::ThrewException:
8931                     m_xml.scopedElement( "Exception" )
8932                         .writeAttribute( "filename", assertionResult.getSourceInfo().file )
8933                         .writeAttribute( "line", assertionResult.getSourceInfo().line )
8934                         .writeText( assertionResult.getMessage() );
8935                     break;
8936                 case ResultWas::FatalErrorCondition:
8937                     m_xml.scopedElement( "Fatal Error Condition" )
8938                         .writeAttribute( "filename", assertionResult.getSourceInfo().file )
8939                         .writeAttribute( "line", assertionResult.getSourceInfo().line )
8940                         .writeText( assertionResult.getMessage() );
8941                     break;
8942                 case ResultWas::Info:
8943                     m_xml.scopedElement( "Info" )
8944                         .writeText( assertionResult.getMessage() );
8945                     break;
8946                 case ResultWas::Warning:
8947                     // Warning will already have been written
8948                     break;
8949                 case ResultWas::ExplicitFailure:
8950                     m_xml.scopedElement( "Failure" )
8951                         .writeText( assertionResult.getMessage() );
8952                     break;
8953                 default:
8954                     break;
8955             }
8956 
8957             if( assertionResult.hasExpression() )
8958                 m_xml.endElement();
8959 
8960             return true;
8961         }
8962 
sectionEnded(SectionStats const & sectionStats)8963         virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
8964             StreamingReporterBase::sectionEnded( sectionStats );
8965             if( --m_sectionDepth > 0 ) {
8966                 XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
8967                 e.writeAttribute( "successes", sectionStats.assertions.passed );
8968                 e.writeAttribute( "failures", sectionStats.assertions.failed );
8969                 e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
8970 
8971                 if ( m_config->showDurations() == ShowDurations::Always )
8972                     e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
8973 
8974                 m_xml.endElement();
8975             }
8976         }
8977 
testCaseEnded(TestCaseStats const & testCaseStats)8978         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
8979             StreamingReporterBase::testCaseEnded( testCaseStats );
8980             XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
8981             e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
8982 
8983             if ( m_config->showDurations() == ShowDurations::Always )
8984                 e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
8985 
8986             m_xml.endElement();
8987         }
8988 
testGroupEnded(TestGroupStats const & testGroupStats)8989         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
8990             StreamingReporterBase::testGroupEnded( testGroupStats );
8991             // TODO: Check testGroupStats.aborting and act accordingly.
8992             m_xml.scopedElement( "OverallResults" )
8993                 .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
8994                 .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
8995                 .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
8996             m_xml.endElement();
8997         }
8998 
testRunEnded(TestRunStats const & testRunStats)8999         virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
9000             StreamingReporterBase::testRunEnded( testRunStats );
9001             m_xml.scopedElement( "OverallResults" )
9002                 .writeAttribute( "successes", testRunStats.totals.assertions.passed )
9003                 .writeAttribute( "failures", testRunStats.totals.assertions.failed )
9004                 .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
9005             m_xml.endElement();
9006         }
9007 
9008     private:
9009         Timer m_testCaseTimer;
9010         XmlWriter m_xml;
9011         int m_sectionDepth;
9012     };
9013 
9014      INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
9015 
9016 } // end namespace Catch
9017 
9018 // #included from: ../reporters/catch_reporter_junit.hpp
9019 #define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
9020 
9021 #include <assert.h>
9022 
9023 namespace Catch {
9024 
9025     class JunitReporter : public CumulativeReporterBase {
9026     public:
JunitReporter(ReporterConfig const & _config)9027         JunitReporter( ReporterConfig const& _config )
9028         :   CumulativeReporterBase( _config ),
9029             xml( _config.stream() )
9030         {
9031             m_reporterPrefs.shouldRedirectStdOut = true;
9032         }
9033 
9034         virtual ~JunitReporter() CATCH_OVERRIDE;
9035 
getDescription()9036         static std::string getDescription() {
9037             return "Reports test results in an XML format that looks like Ant's junitreport target";
9038         }
9039 
noMatchingTestCases(std::string const &)9040         virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {}
9041 
testRunStarting(TestRunInfo const & runInfo)9042         virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE {
9043             CumulativeReporterBase::testRunStarting( runInfo );
9044             xml.startElement( "testsuites" );
9045         }
9046 
testGroupStarting(GroupInfo const & groupInfo)9047         virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
9048             suiteTimer.start();
9049             stdOutForSuite.str("");
9050             stdErrForSuite.str("");
9051             unexpectedExceptions = 0;
9052             CumulativeReporterBase::testGroupStarting( groupInfo );
9053         }
9054 
assertionEnded(AssertionStats const & assertionStats)9055         virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
9056             if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
9057                 unexpectedExceptions++;
9058             return CumulativeReporterBase::assertionEnded( assertionStats );
9059         }
9060 
testCaseEnded(TestCaseStats const & testCaseStats)9061         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
9062             stdOutForSuite << testCaseStats.stdOut;
9063             stdErrForSuite << testCaseStats.stdErr;
9064             CumulativeReporterBase::testCaseEnded( testCaseStats );
9065         }
9066 
testGroupEnded(TestGroupStats const & testGroupStats)9067         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
9068             double suiteTime = suiteTimer.getElapsedSeconds();
9069             CumulativeReporterBase::testGroupEnded( testGroupStats );
9070             writeGroup( *m_testGroups.back(), suiteTime );
9071         }
9072 
testRunEndedCumulative()9073         virtual void testRunEndedCumulative() CATCH_OVERRIDE {
9074             xml.endElement();
9075         }
9076 
writeGroup(TestGroupNode const & groupNode,double suiteTime)9077         void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
9078             XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
9079             TestGroupStats const& stats = groupNode.value;
9080             xml.writeAttribute( "name", stats.groupInfo.name );
9081             xml.writeAttribute( "errors", unexpectedExceptions );
9082             xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
9083             xml.writeAttribute( "tests", stats.totals.assertions.total() );
9084             xml.writeAttribute( "hostname", "tbd" ); // !TBD
9085             if( m_config->showDurations() == ShowDurations::Never )
9086                 xml.writeAttribute( "time", "" );
9087             else
9088                 xml.writeAttribute( "time", suiteTime );
9089             xml.writeAttribute( "timestamp", "tbd" ); // !TBD
9090 
9091             // Write test cases
9092             for( TestGroupNode::ChildNodes::const_iterator
9093                     it = groupNode.children.begin(), itEnd = groupNode.children.end();
9094                     it != itEnd;
9095                     ++it )
9096                 writeTestCase( **it );
9097 
9098             xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
9099             xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
9100         }
9101 
writeTestCase(TestCaseNode const & testCaseNode)9102         void writeTestCase( TestCaseNode const& testCaseNode ) {
9103             TestCaseStats const& stats = testCaseNode.value;
9104 
9105             // All test cases have exactly one section - which represents the
9106             // test case itself. That section may have 0-n nested sections
9107             assert( testCaseNode.children.size() == 1 );
9108             SectionNode const& rootSection = *testCaseNode.children.front();
9109 
9110             std::string className = stats.testInfo.className;
9111 
9112             if( className.empty() ) {
9113                 if( rootSection.childSections.empty() )
9114                     className = "global";
9115             }
9116             writeSection( className, "", rootSection );
9117         }
9118 
writeSection(std::string const & className,std::string const & rootName,SectionNode const & sectionNode)9119         void writeSection(  std::string const& className,
9120                             std::string const& rootName,
9121                             SectionNode const& sectionNode ) {
9122             std::string name = trim( sectionNode.stats.sectionInfo.name );
9123             if( !rootName.empty() )
9124                 name = rootName + "/" + name;
9125 
9126             if( !sectionNode.assertions.empty() ||
9127                 !sectionNode.stdOut.empty() ||
9128                 !sectionNode.stdErr.empty() ) {
9129                 XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
9130                 if( className.empty() ) {
9131                     xml.writeAttribute( "classname", name );
9132                     xml.writeAttribute( "name", "root" );
9133                 }
9134                 else {
9135                     xml.writeAttribute( "classname", className );
9136                     xml.writeAttribute( "name", name );
9137                 }
9138                 xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) );
9139 
9140                 writeAssertions( sectionNode );
9141 
9142                 if( !sectionNode.stdOut.empty() )
9143                     xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
9144                 if( !sectionNode.stdErr.empty() )
9145                     xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
9146             }
9147             for( SectionNode::ChildSections::const_iterator
9148                     it = sectionNode.childSections.begin(),
9149                     itEnd = sectionNode.childSections.end();
9150                     it != itEnd;
9151                     ++it )
9152                 if( className.empty() )
9153                     writeSection( name, "", **it );
9154                 else
9155                     writeSection( className, name, **it );
9156         }
9157 
writeAssertions(SectionNode const & sectionNode)9158         void writeAssertions( SectionNode const& sectionNode ) {
9159             for( SectionNode::Assertions::const_iterator
9160                     it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
9161                     it != itEnd;
9162                     ++it )
9163                 writeAssertion( *it );
9164         }
writeAssertion(AssertionStats const & stats)9165         void writeAssertion( AssertionStats const& stats ) {
9166             AssertionResult const& result = stats.assertionResult;
9167             if( !result.isOk() ) {
9168                 std::string elementName;
9169                 switch( result.getResultType() ) {
9170                     case ResultWas::ThrewException:
9171                     case ResultWas::FatalErrorCondition:
9172                         elementName = "error";
9173                         break;
9174                     case ResultWas::ExplicitFailure:
9175                         elementName = "failure";
9176                         break;
9177                     case ResultWas::ExpressionFailed:
9178                         elementName = "failure";
9179                         break;
9180                     case ResultWas::DidntThrowException:
9181                         elementName = "failure";
9182                         break;
9183 
9184                     // We should never see these here:
9185                     case ResultWas::Info:
9186                     case ResultWas::Warning:
9187                     case ResultWas::Ok:
9188                     case ResultWas::Unknown:
9189                     case ResultWas::FailureBit:
9190                     case ResultWas::Exception:
9191                         elementName = "internalError";
9192                         break;
9193                 }
9194 
9195                 XmlWriter::ScopedElement e = xml.scopedElement( elementName );
9196 
9197                 xml.writeAttribute( "message", result.getExpandedExpression() );
9198                 xml.writeAttribute( "type", result.getTestMacroName() );
9199 
9200                 std::ostringstream oss;
9201                 if( !result.getMessage().empty() )
9202                     oss << result.getMessage() << "\n";
9203                 for( std::vector<MessageInfo>::const_iterator
9204                         it = stats.infoMessages.begin(),
9205                         itEnd = stats.infoMessages.end();
9206                             it != itEnd;
9207                             ++it )
9208                     if( it->type == ResultWas::Info )
9209                         oss << it->message << "\n";
9210 
9211                 oss << "at " << result.getSourceInfo();
9212                 xml.writeText( oss.str(), false );
9213             }
9214         }
9215 
9216         XmlWriter xml;
9217         Timer suiteTimer;
9218         std::ostringstream stdOutForSuite;
9219         std::ostringstream stdErrForSuite;
9220         unsigned int unexpectedExceptions;
9221     };
9222 
9223     INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
9224 
9225 } // end namespace Catch
9226 
9227 // #included from: ../reporters/catch_reporter_console.hpp
9228 #define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
9229 
9230 namespace Catch {
9231 
9232     struct ConsoleReporter : StreamingReporterBase {
ConsoleReporterCatch::ConsoleReporter9233         ConsoleReporter( ReporterConfig const& _config )
9234         :   StreamingReporterBase( _config ),
9235             m_headerPrinted( false )
9236         {}
9237 
9238         virtual ~ConsoleReporter() CATCH_OVERRIDE;
getDescriptionCatch::ConsoleReporter9239         static std::string getDescription() {
9240             return "Reports test results as plain lines of text";
9241         }
9242 
noMatchingTestCasesCatch::ConsoleReporter9243         virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
9244             stream << "No test cases matched '" << spec << "'" << std::endl;
9245         }
9246 
assertionStartingCatch::ConsoleReporter9247         virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {
9248         }
9249 
assertionEndedCatch::ConsoleReporter9250         virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {
9251             AssertionResult const& result = _assertionStats.assertionResult;
9252 
9253             bool printInfoMessages = true;
9254 
9255             // Drop out if result was successful and we're not printing those
9256             if( !m_config->includeSuccessfulResults() && result.isOk() ) {
9257                 if( result.getResultType() != ResultWas::Warning )
9258                     return false;
9259                 printInfoMessages = false;
9260             }
9261 
9262             lazyPrint();
9263 
9264             AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
9265             printer.print();
9266             stream << std::endl;
9267             return true;
9268         }
9269 
sectionStartingCatch::ConsoleReporter9270         virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
9271             m_headerPrinted = false;
9272             StreamingReporterBase::sectionStarting( _sectionInfo );
9273         }
sectionEndedCatch::ConsoleReporter9274         virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE {
9275             if( _sectionStats.missingAssertions ) {
9276                 lazyPrint();
9277                 Colour colour( Colour::ResultError );
9278                 if( m_sectionStack.size() > 1 )
9279                     stream << "\nNo assertions in section";
9280                 else
9281                     stream << "\nNo assertions in test case";
9282                 stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
9283             }
9284             if( m_headerPrinted ) {
9285                 if( m_config->showDurations() == ShowDurations::Always )
9286                     stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
9287                 m_headerPrinted = false;
9288             }
9289             else {
9290                 if( m_config->showDurations() == ShowDurations::Always )
9291                     stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
9292             }
9293             StreamingReporterBase::sectionEnded( _sectionStats );
9294         }
9295 
testCaseEndedCatch::ConsoleReporter9296         virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE {
9297             StreamingReporterBase::testCaseEnded( _testCaseStats );
9298             m_headerPrinted = false;
9299         }
testGroupEndedCatch::ConsoleReporter9300         virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE {
9301             if( currentGroupInfo.used ) {
9302                 printSummaryDivider();
9303                 stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
9304                 printTotals( _testGroupStats.totals );
9305                 stream << "\n" << std::endl;
9306             }
9307             StreamingReporterBase::testGroupEnded( _testGroupStats );
9308         }
testRunEndedCatch::ConsoleReporter9309         virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE {
9310             printTotalsDivider( _testRunStats.totals );
9311             printTotals( _testRunStats.totals );
9312             stream << std::endl;
9313             StreamingReporterBase::testRunEnded( _testRunStats );
9314         }
9315 
9316     private:
9317 
9318         class AssertionPrinter {
9319             void operator= ( AssertionPrinter const& );
9320         public:
AssertionPrinter(std::ostream & _stream,AssertionStats const & _stats,bool _printInfoMessages)9321             AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
9322             :   stream( _stream ),
9323                 stats( _stats ),
9324                 result( _stats.assertionResult ),
9325                 colour( Colour::None ),
9326                 message( result.getMessage() ),
9327                 messages( _stats.infoMessages ),
9328                 printInfoMessages( _printInfoMessages )
9329             {
9330                 switch( result.getResultType() ) {
9331                     case ResultWas::Ok:
9332                         colour = Colour::Success;
9333                         passOrFail = "PASSED";
9334                         //if( result.hasMessage() )
9335                         if( _stats.infoMessages.size() == 1 )
9336                             messageLabel = "with message";
9337                         if( _stats.infoMessages.size() > 1 )
9338                             messageLabel = "with messages";
9339                         break;
9340                     case ResultWas::ExpressionFailed:
9341                         if( result.isOk() ) {
9342                             colour = Colour::Success;
9343                             passOrFail = "FAILED - but was ok";
9344                         }
9345                         else {
9346                             colour = Colour::Error;
9347                             passOrFail = "FAILED";
9348                         }
9349                         if( _stats.infoMessages.size() == 1 )
9350                             messageLabel = "with message";
9351                         if( _stats.infoMessages.size() > 1 )
9352                             messageLabel = "with messages";
9353                         break;
9354                     case ResultWas::ThrewException:
9355                         colour = Colour::Error;
9356                         passOrFail = "FAILED";
9357                         messageLabel = "due to unexpected exception with message";
9358                         break;
9359                     case ResultWas::FatalErrorCondition:
9360                         colour = Colour::Error;
9361                         passOrFail = "FAILED";
9362                         messageLabel = "due to a fatal error condition";
9363                         break;
9364                     case ResultWas::DidntThrowException:
9365                         colour = Colour::Error;
9366                         passOrFail = "FAILED";
9367                         messageLabel = "because no exception was thrown where one was expected";
9368                         break;
9369                     case ResultWas::Info:
9370                         messageLabel = "info";
9371                         break;
9372                     case ResultWas::Warning:
9373                         messageLabel = "warning";
9374                         break;
9375                     case ResultWas::ExplicitFailure:
9376                         passOrFail = "FAILED";
9377                         colour = Colour::Error;
9378                         if( _stats.infoMessages.size() == 1 )
9379                             messageLabel = "explicitly with message";
9380                         if( _stats.infoMessages.size() > 1 )
9381                             messageLabel = "explicitly with messages";
9382                         break;
9383                     // These cases are here to prevent compiler warnings
9384                     case ResultWas::Unknown:
9385                     case ResultWas::FailureBit:
9386                     case ResultWas::Exception:
9387                         passOrFail = "** internal error **";
9388                         colour = Colour::Error;
9389                         break;
9390                 }
9391             }
9392 
print() const9393             void print() const {
9394                 printSourceInfo();
9395                 if( stats.totals.assertions.total() > 0 ) {
9396                     if( result.isOk() )
9397                         stream << "\n";
9398                     printResultType();
9399                     printOriginalExpression();
9400                     printReconstructedExpression();
9401                 }
9402                 else {
9403                     stream << "\n";
9404                 }
9405                 printMessage();
9406             }
9407 
9408         private:
printResultType() const9409             void printResultType() const {
9410                 if( !passOrFail.empty() ) {
9411                     Colour colourGuard( colour );
9412                     stream << passOrFail << ":\n";
9413                 }
9414             }
printOriginalExpression() const9415             void printOriginalExpression() const {
9416                 if( result.hasExpression() ) {
9417                     Colour colourGuard( Colour::OriginalExpression );
9418                     stream  << "  ";
9419                     stream << result.getExpressionInMacro();
9420                     stream << "\n";
9421                 }
9422             }
printReconstructedExpression() const9423             void printReconstructedExpression() const {
9424                 if( result.hasExpandedExpression() ) {
9425                     stream << "with expansion:\n";
9426                     Colour colourGuard( Colour::ReconstructedExpression );
9427                     stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n";
9428                 }
9429             }
printMessage() const9430             void printMessage() const {
9431                 if( !messageLabel.empty() )
9432                     stream << messageLabel << ":" << "\n";
9433                 for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
9434                         it != itEnd;
9435                         ++it ) {
9436                     // If this assertion is a warning ignore any INFO messages
9437                     if( printInfoMessages || it->type != ResultWas::Info )
9438                         stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n";
9439                 }
9440             }
printSourceInfo() const9441             void printSourceInfo() const {
9442                 Colour colourGuard( Colour::FileName );
9443                 stream << result.getSourceInfo() << ": ";
9444             }
9445 
9446             std::ostream& stream;
9447             AssertionStats const& stats;
9448             AssertionResult const& result;
9449             Colour::Code colour;
9450             std::string passOrFail;
9451             std::string messageLabel;
9452             std::string message;
9453             std::vector<MessageInfo> messages;
9454             bool printInfoMessages;
9455         };
9456 
lazyPrintCatch::ConsoleReporter9457         void lazyPrint() {
9458 
9459             if( !currentTestRunInfo.used )
9460                 lazyPrintRunInfo();
9461             if( !currentGroupInfo.used )
9462                 lazyPrintGroupInfo();
9463 
9464             if( !m_headerPrinted ) {
9465                 printTestCaseAndSectionHeader();
9466                 m_headerPrinted = true;
9467             }
9468         }
lazyPrintRunInfoCatch::ConsoleReporter9469         void lazyPrintRunInfo() {
9470             stream  << "\n" << getLineOfChars<'~'>() << "\n";
9471             Colour colour( Colour::SecondaryText );
9472             stream  << currentTestRunInfo->name
9473                     << " is a Catch v"  << libraryVersion << " host application.\n"
9474                     << "Run with -? for options\n\n";
9475 
9476             if( m_config->rngSeed() != 0 )
9477                 stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
9478 
9479             currentTestRunInfo.used = true;
9480         }
lazyPrintGroupInfoCatch::ConsoleReporter9481         void lazyPrintGroupInfo() {
9482             if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
9483                 printClosedHeader( "Group: " + currentGroupInfo->name );
9484                 currentGroupInfo.used = true;
9485             }
9486         }
printTestCaseAndSectionHeaderCatch::ConsoleReporter9487         void printTestCaseAndSectionHeader() {
9488             assert( !m_sectionStack.empty() );
9489             printOpenHeader( currentTestCaseInfo->name );
9490 
9491             if( m_sectionStack.size() > 1 ) {
9492                 Colour colourGuard( Colour::Headers );
9493 
9494                 std::vector<SectionInfo>::const_iterator
9495                     it = m_sectionStack.begin()+1, // Skip first section (test case)
9496                     itEnd = m_sectionStack.end();
9497                 for( ; it != itEnd; ++it )
9498                     printHeaderString( it->name, 2 );
9499             }
9500 
9501             SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
9502 
9503             if( !lineInfo.empty() ){
9504                 stream << getLineOfChars<'-'>() << "\n";
9505                 Colour colourGuard( Colour::FileName );
9506                 stream << lineInfo << "\n";
9507             }
9508             stream << getLineOfChars<'.'>() << "\n" << std::endl;
9509         }
9510 
printClosedHeaderCatch::ConsoleReporter9511         void printClosedHeader( std::string const& _name ) {
9512             printOpenHeader( _name );
9513             stream << getLineOfChars<'.'>() << "\n";
9514         }
printOpenHeaderCatch::ConsoleReporter9515         void printOpenHeader( std::string const& _name ) {
9516             stream  << getLineOfChars<'-'>() << "\n";
9517             {
9518                 Colour colourGuard( Colour::Headers );
9519                 printHeaderString( _name );
9520             }
9521         }
9522 
9523         // if string has a : in first line will set indent to follow it on
9524         // subsequent lines
printHeaderStringCatch::ConsoleReporter9525         void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
9526             std::size_t i = _string.find( ": " );
9527             if( i != std::string::npos )
9528                 i+=2;
9529             else
9530                 i = 0;
9531             stream << Text( _string, TextAttributes()
9532                                         .setIndent( indent+i)
9533                                         .setInitialIndent( indent ) ) << "\n";
9534         }
9535 
9536         struct SummaryColumn {
9537 
SummaryColumnCatch::ConsoleReporter::SummaryColumn9538             SummaryColumn( std::string const& _label, Colour::Code _colour )
9539             :   label( _label ),
9540                 colour( _colour )
9541             {}
addRowCatch::ConsoleReporter::SummaryColumn9542             SummaryColumn addRow( std::size_t count ) {
9543                 std::ostringstream oss;
9544                 oss << count;
9545                 std::string row = oss.str();
9546                 for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
9547                     while( it->size() < row.size() )
9548                         *it = " " + *it;
9549                     while( it->size() > row.size() )
9550                         row = " " + row;
9551                 }
9552                 rows.push_back( row );
9553                 return *this;
9554             }
9555 
9556             std::string label;
9557             Colour::Code colour;
9558             std::vector<std::string> rows;
9559 
9560         };
9561 
printTotalsCatch::ConsoleReporter9562         void printTotals( Totals const& totals ) {
9563             if( totals.testCases.total() == 0 ) {
9564                 stream << Colour( Colour::Warning ) << "No tests ran\n";
9565             }
9566             else if( totals.assertions.total() > 0 && totals.assertions.allPassed() ) {
9567                 stream << Colour( Colour::ResultSuccess ) << "All tests passed";
9568                 stream << " ("
9569                         << pluralise( totals.assertions.passed, "assertion" ) << " in "
9570                         << pluralise( totals.testCases.passed, "test case" ) << ")"
9571                         << "\n";
9572             }
9573             else {
9574 
9575                 std::vector<SummaryColumn> columns;
9576                 columns.push_back( SummaryColumn( "", Colour::None )
9577                                         .addRow( totals.testCases.total() )
9578                                         .addRow( totals.assertions.total() ) );
9579                 columns.push_back( SummaryColumn( "passed", Colour::Success )
9580                                         .addRow( totals.testCases.passed )
9581                                         .addRow( totals.assertions.passed ) );
9582                 columns.push_back( SummaryColumn( "failed", Colour::ResultError )
9583                                         .addRow( totals.testCases.failed )
9584                                         .addRow( totals.assertions.failed ) );
9585                 columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
9586                                         .addRow( totals.testCases.failedButOk )
9587                                         .addRow( totals.assertions.failedButOk ) );
9588 
9589                 printSummaryRow( "test cases", columns, 0 );
9590                 printSummaryRow( "assertions", columns, 1 );
9591             }
9592         }
printSummaryRowCatch::ConsoleReporter9593         void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
9594             for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
9595                 std::string value = it->rows[row];
9596                 if( it->label.empty() ) {
9597                     stream << label << ": ";
9598                     if( value != "0" )
9599                         stream << value;
9600                     else
9601                         stream << Colour( Colour::Warning ) << "- none -";
9602                 }
9603                 else if( value != "0" ) {
9604                     stream  << Colour( Colour::LightGrey ) << " | ";
9605                     stream  << Colour( it->colour )
9606                             << value << " " << it->label;
9607                 }
9608             }
9609             stream << "\n";
9610         }
9611 
makeRatioCatch::ConsoleReporter9612         static std::size_t makeRatio( std::size_t number, std::size_t total ) {
9613             std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
9614             return ( ratio == 0 && number > 0 ) ? 1 : ratio;
9615         }
findMaxCatch::ConsoleReporter9616         static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
9617             if( i > j && i > k )
9618                 return i;
9619             else if( j > k )
9620                 return j;
9621             else
9622                 return k;
9623         }
9624 
printTotalsDividerCatch::ConsoleReporter9625         void printTotalsDivider( Totals const& totals ) {
9626             if( totals.testCases.total() > 0 ) {
9627                 std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
9628                 std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
9629                 std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
9630                 while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
9631                     findMax( failedRatio, failedButOkRatio, passedRatio )++;
9632                 while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
9633                     findMax( failedRatio, failedButOkRatio, passedRatio )--;
9634 
9635                 stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
9636                 stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
9637                 if( totals.testCases.allPassed() )
9638                     stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
9639                 else
9640                     stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
9641             }
9642             else {
9643                 stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
9644             }
9645             stream << "\n";
9646         }
printSummaryDividerCatch::ConsoleReporter9647         void printSummaryDivider() {
9648             stream << getLineOfChars<'-'>() << "\n";
9649         }
9650 
9651     private:
9652         bool m_headerPrinted;
9653     };
9654 
9655     INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
9656 
9657 } // end namespace Catch
9658 
9659 // #included from: ../reporters/catch_reporter_compact.hpp
9660 #define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED
9661 
9662 namespace Catch {
9663 
9664     struct CompactReporter : StreamingReporterBase {
9665 
CompactReporterCatch::CompactReporter9666         CompactReporter( ReporterConfig const& _config )
9667         : StreamingReporterBase( _config )
9668         {}
9669 
9670         virtual ~CompactReporter();
9671 
getDescriptionCatch::CompactReporter9672         static std::string getDescription() {
9673             return "Reports test results on a single line, suitable for IDEs";
9674         }
9675 
getPreferencesCatch::CompactReporter9676         virtual ReporterPreferences getPreferences() const {
9677             ReporterPreferences prefs;
9678             prefs.shouldRedirectStdOut = false;
9679             return prefs;
9680         }
9681 
noMatchingTestCasesCatch::CompactReporter9682         virtual void noMatchingTestCases( std::string const& spec ) {
9683             stream << "No test cases matched '" << spec << "'" << std::endl;
9684         }
9685 
assertionStartingCatch::CompactReporter9686         virtual void assertionStarting( AssertionInfo const& ) {
9687         }
9688 
assertionEndedCatch::CompactReporter9689         virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
9690             AssertionResult const& result = _assertionStats.assertionResult;
9691 
9692             bool printInfoMessages = true;
9693 
9694             // Drop out if result was successful and we're not printing those
9695             if( !m_config->includeSuccessfulResults() && result.isOk() ) {
9696                 if( result.getResultType() != ResultWas::Warning )
9697                     return false;
9698                 printInfoMessages = false;
9699             }
9700 
9701             AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
9702             printer.print();
9703 
9704             stream << std::endl;
9705             return true;
9706         }
9707 
testRunEndedCatch::CompactReporter9708         virtual void testRunEnded( TestRunStats const& _testRunStats ) {
9709             printTotals( _testRunStats.totals );
9710             stream << "\n" << std::endl;
9711             StreamingReporterBase::testRunEnded( _testRunStats );
9712         }
9713 
9714     private:
9715         class AssertionPrinter {
9716             void operator= ( AssertionPrinter const& );
9717         public:
AssertionPrinter(std::ostream & _stream,AssertionStats const & _stats,bool _printInfoMessages)9718             AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
9719             : stream( _stream )
9720             , stats( _stats )
9721             , result( _stats.assertionResult )
9722             , messages( _stats.infoMessages )
9723             , itMessage( _stats.infoMessages.begin() )
9724             , printInfoMessages( _printInfoMessages )
9725             {}
9726 
print()9727             void print() {
9728                 printSourceInfo();
9729 
9730                 itMessage = messages.begin();
9731 
9732                 switch( result.getResultType() ) {
9733                     case ResultWas::Ok:
9734                         printResultType( Colour::ResultSuccess, passedString() );
9735                         printOriginalExpression();
9736                         printReconstructedExpression();
9737                         if ( ! result.hasExpression() )
9738                             printRemainingMessages( Colour::None );
9739                         else
9740                             printRemainingMessages();
9741                         break;
9742                     case ResultWas::ExpressionFailed:
9743                         if( result.isOk() )
9744                             printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
9745                         else
9746                             printResultType( Colour::Error, failedString() );
9747                         printOriginalExpression();
9748                         printReconstructedExpression();
9749                         printRemainingMessages();
9750                         break;
9751                     case ResultWas::ThrewException:
9752                         printResultType( Colour::Error, failedString() );
9753                         printIssue( "unexpected exception with message:" );
9754                         printMessage();
9755                         printExpressionWas();
9756                         printRemainingMessages();
9757                         break;
9758                     case ResultWas::FatalErrorCondition:
9759                         printResultType( Colour::Error, failedString() );
9760                         printIssue( "fatal error condition with message:" );
9761                         printMessage();
9762                         printExpressionWas();
9763                         printRemainingMessages();
9764                         break;
9765                     case ResultWas::DidntThrowException:
9766                         printResultType( Colour::Error, failedString() );
9767                         printIssue( "expected exception, got none" );
9768                         printExpressionWas();
9769                         printRemainingMessages();
9770                         break;
9771                     case ResultWas::Info:
9772                         printResultType( Colour::None, "info" );
9773                         printMessage();
9774                         printRemainingMessages();
9775                         break;
9776                     case ResultWas::Warning:
9777                         printResultType( Colour::None, "warning" );
9778                         printMessage();
9779                         printRemainingMessages();
9780                         break;
9781                     case ResultWas::ExplicitFailure:
9782                         printResultType( Colour::Error, failedString() );
9783                         printIssue( "explicitly" );
9784                         printRemainingMessages( Colour::None );
9785                         break;
9786                     // These cases are here to prevent compiler warnings
9787                     case ResultWas::Unknown:
9788                     case ResultWas::FailureBit:
9789                     case ResultWas::Exception:
9790                         printResultType( Colour::Error, "** internal error **" );
9791                         break;
9792                 }
9793             }
9794 
9795         private:
9796             // Colour::LightGrey
9797 
dimColour()9798             static Colour::Code dimColour() { return Colour::FileName; }
9799 
9800 #ifdef CATCH_PLATFORM_MAC
failedString()9801             static const char* failedString() { return "FAILED"; }
passedString()9802             static const char* passedString() { return "PASSED"; }
9803 #else
failedString()9804             static const char* failedString() { return "failed"; }
passedString()9805             static const char* passedString() { return "passed"; }
9806 #endif
9807 
printSourceInfo() const9808             void printSourceInfo() const {
9809                 Colour colourGuard( Colour::FileName );
9810                 stream << result.getSourceInfo() << ":";
9811             }
9812 
printResultType(Colour::Code colour,std::string passOrFail) const9813             void printResultType( Colour::Code colour, std::string passOrFail ) const {
9814                 if( !passOrFail.empty() ) {
9815                     {
9816                         Colour colourGuard( colour );
9817                         stream << " " << passOrFail;
9818                     }
9819                     stream << ":";
9820                 }
9821             }
9822 
printIssue(std::string issue) const9823             void printIssue( std::string issue ) const {
9824                 stream << " " << issue;
9825             }
9826 
printExpressionWas()9827             void printExpressionWas() {
9828                 if( result.hasExpression() ) {
9829                     stream << ";";
9830                     {
9831                         Colour colour( dimColour() );
9832                         stream << " expression was:";
9833                     }
9834                     printOriginalExpression();
9835                 }
9836             }
9837 
printOriginalExpression() const9838             void printOriginalExpression() const {
9839                 if( result.hasExpression() ) {
9840                     stream << " " << result.getExpression();
9841                 }
9842             }
9843 
printReconstructedExpression() const9844             void printReconstructedExpression() const {
9845                 if( result.hasExpandedExpression() ) {
9846                     {
9847                         Colour colour( dimColour() );
9848                         stream << " for: ";
9849                     }
9850                     stream << result.getExpandedExpression();
9851                 }
9852             }
9853 
printMessage()9854             void printMessage() {
9855                 if ( itMessage != messages.end() ) {
9856                     stream << " '" << itMessage->message << "'";
9857                     ++itMessage;
9858                 }
9859             }
9860 
printRemainingMessages(Colour::Code colour=dimColour ())9861             void printRemainingMessages( Colour::Code colour = dimColour() ) {
9862                 if ( itMessage == messages.end() )
9863                     return;
9864 
9865                 // using messages.end() directly yields compilation error:
9866                 std::vector<MessageInfo>::const_iterator itEnd = messages.end();
9867                 const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
9868 
9869                 {
9870                     Colour colourGuard( colour );
9871                     stream << " with " << pluralise( N, "message" ) << ":";
9872                 }
9873 
9874                 for(; itMessage != itEnd; ) {
9875                     // If this assertion is a warning ignore any INFO messages
9876                     if( printInfoMessages || itMessage->type != ResultWas::Info ) {
9877                         stream << " '" << itMessage->message << "'";
9878                         if ( ++itMessage != itEnd ) {
9879                             Colour colourGuard( dimColour() );
9880                             stream << " and";
9881                         }
9882                     }
9883                 }
9884             }
9885 
9886         private:
9887             std::ostream& stream;
9888             AssertionStats const& stats;
9889             AssertionResult const& result;
9890             std::vector<MessageInfo> messages;
9891             std::vector<MessageInfo>::const_iterator itMessage;
9892             bool printInfoMessages;
9893         };
9894 
9895         // Colour, message variants:
9896         // - white: No tests ran.
9897         // -   red: Failed [both/all] N test cases, failed [both/all] M assertions.
9898         // - white: Passed [both/all] N test cases (no assertions).
9899         // -   red: Failed N tests cases, failed M assertions.
9900         // - green: Passed [both/all] N tests cases with M assertions.
9901 
bothOrAllCatch::CompactReporter9902         std::string bothOrAll( std::size_t count ) const {
9903             return count == 1 ? "" : count == 2 ? "both " : "all " ;
9904         }
9905 
printTotalsCatch::CompactReporter9906         void printTotals( const Totals& totals ) const {
9907             if( totals.testCases.total() == 0 ) {
9908                 stream << "No tests ran.";
9909             }
9910             else if( totals.testCases.failed == totals.testCases.total() ) {
9911                 Colour colour( Colour::ResultError );
9912                 const std::string qualify_assertions_failed =
9913                     totals.assertions.failed == totals.assertions.total() ?
9914                         bothOrAll( totals.assertions.failed ) : "";
9915                 stream <<
9916                     "Failed " << bothOrAll( totals.testCases.failed )
9917                               << pluralise( totals.testCases.failed, "test case"  ) << ", "
9918                     "failed " << qualify_assertions_failed <<
9919                                  pluralise( totals.assertions.failed, "assertion" ) << ".";
9920             }
9921             else if( totals.assertions.total() == 0 ) {
9922                 stream <<
9923                     "Passed " << bothOrAll( totals.testCases.total() )
9924                               << pluralise( totals.testCases.total(), "test case" )
9925                               << " (no assertions).";
9926             }
9927             else if( totals.assertions.failed ) {
9928                 Colour colour( Colour::ResultError );
9929                 stream <<
9930                     "Failed " << pluralise( totals.testCases.failed, "test case"  ) << ", "
9931                     "failed " << pluralise( totals.assertions.failed, "assertion" ) << ".";
9932             }
9933             else {
9934                 Colour colour( Colour::ResultSuccess );
9935                 stream <<
9936                     "Passed " << bothOrAll( totals.testCases.passed )
9937                               << pluralise( totals.testCases.passed, "test case"  ) <<
9938                     " with "  << pluralise( totals.assertions.passed, "assertion" ) << ".";
9939             }
9940         }
9941     };
9942 
9943     INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter )
9944 
9945 } // end namespace Catch
9946 
9947 namespace Catch {
9948     // These are all here to avoid warnings about not having any out of line
9949     // virtual methods
~NonCopyable()9950     NonCopyable::~NonCopyable() {}
~IShared()9951     IShared::~IShared() {}
~IStream()9952     IStream::~IStream() CATCH_NOEXCEPT {}
~FileStream()9953     FileStream::~FileStream() CATCH_NOEXCEPT {}
~CoutStream()9954     CoutStream::~CoutStream() CATCH_NOEXCEPT {}
~DebugOutStream()9955     DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {}
~StreamBufBase()9956     StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
~IContext()9957     IContext::~IContext() {}
~IResultCapture()9958     IResultCapture::~IResultCapture() {}
~ITestCase()9959     ITestCase::~ITestCase() {}
~ITestCaseRegistry()9960     ITestCaseRegistry::~ITestCaseRegistry() {}
~IRegistryHub()9961     IRegistryHub::~IRegistryHub() {}
~IMutableRegistryHub()9962     IMutableRegistryHub::~IMutableRegistryHub() {}
~IExceptionTranslator()9963     IExceptionTranslator::~IExceptionTranslator() {}
~IExceptionTranslatorRegistry()9964     IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
~IReporter()9965     IReporter::~IReporter() {}
~IReporterFactory()9966     IReporterFactory::~IReporterFactory() {}
~IReporterRegistry()9967     IReporterRegistry::~IReporterRegistry() {}
~IStreamingReporter()9968     IStreamingReporter::~IStreamingReporter() {}
~AssertionStats()9969     AssertionStats::~AssertionStats() {}
~SectionStats()9970     SectionStats::~SectionStats() {}
~TestCaseStats()9971     TestCaseStats::~TestCaseStats() {}
~TestGroupStats()9972     TestGroupStats::~TestGroupStats() {}
~TestRunStats()9973     TestRunStats::~TestRunStats() {}
~SectionNode()9974     CumulativeReporterBase::SectionNode::~SectionNode() {}
~CumulativeReporterBase()9975     CumulativeReporterBase::~CumulativeReporterBase() {}
9976 
~StreamingReporterBase()9977     StreamingReporterBase::~StreamingReporterBase() {}
~ConsoleReporter()9978     ConsoleReporter::~ConsoleReporter() {}
~CompactReporter()9979     CompactReporter::~CompactReporter() {}
~IRunner()9980     IRunner::~IRunner() {}
~IMutableContext()9981     IMutableContext::~IMutableContext() {}
~IConfig()9982     IConfig::~IConfig() {}
~XmlReporter()9983     XmlReporter::~XmlReporter() {}
~JunitReporter()9984     JunitReporter::~JunitReporter() {}
~TestRegistry()9985     TestRegistry::~TestRegistry() {}
~FreeFunctionTestCase()9986     FreeFunctionTestCase::~FreeFunctionTestCase() {}
~IGeneratorInfo()9987     IGeneratorInfo::~IGeneratorInfo() {}
~IGeneratorsForTest()9988     IGeneratorsForTest::~IGeneratorsForTest() {}
~WildcardPattern()9989     WildcardPattern::~WildcardPattern() {}
~Pattern()9990     TestSpec::Pattern::~Pattern() {}
~NamePattern()9991     TestSpec::NamePattern::~NamePattern() {}
~TagPattern()9992     TestSpec::TagPattern::~TagPattern() {}
~ExcludedPattern()9993     TestSpec::ExcludedPattern::~ExcludedPattern() {}
9994 
~Equals()9995     Matchers::Impl::StdString::Equals::~Equals() {}
~Contains()9996     Matchers::Impl::StdString::Contains::~Contains() {}
~StartsWith()9997     Matchers::Impl::StdString::StartsWith::~StartsWith() {}
~EndsWith()9998     Matchers::Impl::StdString::EndsWith::~EndsWith() {}
9999 
dummy()10000     void Config::dummy() {}
10001 
10002     namespace TestCaseTracking {
~ITracker()10003         ITracker::~ITracker() {}
~TrackerBase()10004         TrackerBase::~TrackerBase() {}
~SectionTracker()10005         SectionTracker::~SectionTracker() {}
~IndexTracker()10006         IndexTracker::~IndexTracker() {}
10007     }
10008 }
10009 
10010 #ifdef __clang__
10011 #pragma clang diagnostic pop
10012 #endif
10013 
10014 #endif
10015 
10016 #ifdef CATCH_CONFIG_MAIN
10017 // #included from: internal/catch_default_main.hpp
10018 #define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
10019 
10020 #ifndef __OBJC__
10021 
10022 // Standard C/C++ main entry point
main(int argc,char * const argv[])10023 int main (int argc, char * const argv[]) {
10024     return Catch::Session().run( argc, argv );
10025 }
10026 
10027 #else // __OBJC__
10028 
10029 // Objective-C entry point
main(int argc,char * const argv[])10030 int main (int argc, char * const argv[]) {
10031 #if !CATCH_ARC_ENABLED
10032     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
10033 #endif
10034 
10035     Catch::registerTestMethods();
10036     int result = Catch::Session().run( argc, (char* const*)argv );
10037 
10038 #if !CATCH_ARC_ENABLED
10039     [pool drain];
10040 #endif
10041 
10042     return result;
10043 }
10044 
10045 #endif // __OBJC__
10046 
10047 #endif
10048 
10049 #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
10050 #  undef CLARA_CONFIG_MAIN
10051 #endif
10052 
10053 //////
10054 
10055 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
10056 #ifdef CATCH_CONFIG_PREFIX_ALL
10057 
10058 #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
10059 #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" )
10060 
10061 #define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "CATCH_REQUIRE_THROWS" )
10062 #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" )
10063 #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "CATCH_REQUIRE_THROWS_WITH" )
10064 #define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" )
10065 
10066 #define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" )
10067 #define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" )
10068 #define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" )
10069 #define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" )
10070 #define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" )
10071 
10072 #define CATCH_CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" )
10073 #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" )
10074 #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CATCH_CHECK_THROWS_WITH" )
10075 #define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
10076 
10077 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
10078 #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
10079 
10080 #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
10081 #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
10082 #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
10083 #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
10084 #define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
10085 
10086 #ifdef CATCH_CONFIG_VARIADIC_MACROS
10087     #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
10088     #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
10089     #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
10090     #define CATCH_REGISTER_TEST_CASE( ... ) INTERNAL_CATCH_REGISTER_TESTCASE( __VA_ARGS__ )
10091     #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
10092     #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
10093     #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
10094 #else
10095     #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
10096     #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
10097     #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
10098     #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description )
10099     #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
10100     #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
10101     #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
10102 #endif
10103 #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
10104 
10105 #define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
10106 #define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
10107 
10108 #define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
10109 
10110 // "BDD-style" convenience wrappers
10111 #ifdef CATCH_CONFIG_VARIADIC_MACROS
10112 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
10113 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
10114 #else
10115 #define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
10116 #define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
10117 #endif
10118 #define CATCH_GIVEN( desc )    CATCH_SECTION( std::string( "Given: ") + desc, "" )
10119 #define CATCH_WHEN( desc )     CATCH_SECTION( std::string( " When: ") + desc, "" )
10120 #define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc, "" )
10121 #define CATCH_THEN( desc )     CATCH_SECTION( std::string( " Then: ") + desc, "" )
10122 #define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc, "" )
10123 
10124 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
10125 #else
10126 
10127 #define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
10128 #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" )
10129 
10130 #define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "REQUIRE_THROWS" )
10131 #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" )
10132 #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "REQUIRE_THROWS_WITH" )
10133 #define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" )
10134 
10135 #define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" )
10136 #define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" )
10137 #define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" )
10138 #define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" )
10139 #define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" )
10140 
10141 #define CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CHECK_THROWS" )
10142 #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
10143 #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CHECK_THROWS_WITH" )
10144 #define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
10145 
10146 #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" )
10147 #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
10148 
10149 #define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
10150 #define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
10151 #define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
10152 #define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
10153 #define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
10154 
10155 #ifdef CATCH_CONFIG_VARIADIC_MACROS
10156     #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
10157     #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
10158     #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
10159     #define REGISTER_TEST_CASE( ... ) INTERNAL_CATCH_REGISTER_TESTCASE( __VA_ARGS__ )
10160     #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
10161     #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
10162     #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
10163 #else
10164     #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
10165     #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
10166     #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
10167     #define REGISTER_TEST_CASE( ... ) INTERNAL_CATCH_REGISTER_TESTCASE( __VA_ARGS__ )
10168     #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
10169     #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
10170     #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
10171 #endif
10172 #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
10173 
10174 #define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
10175 #define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
10176 
10177 #define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
10178 
10179 #endif
10180 
10181 #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
10182 
10183 // "BDD-style" convenience wrappers
10184 #ifdef CATCH_CONFIG_VARIADIC_MACROS
10185 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
10186 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
10187 #else
10188 #define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
10189 #define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
10190 #endif
10191 #define GIVEN( desc )    SECTION( std::string("   Given: ") + desc, "" )
10192 #define WHEN( desc )     SECTION( std::string("    When: ") + desc, "" )
10193 #define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" )
10194 #define THEN( desc )     SECTION( std::string("    Then: ") + desc, "" )
10195 #define AND_THEN( desc ) SECTION( std::string("     And: ") + desc, "" )
10196 
10197 using Catch::Detail::Approx;
10198 
10199 #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
10200 
10201